ユニットグループで写真をまとめてタイル状のレイアウトにする PhotoCollage.js の実装

Facebook の複数枚写真をアップロードした際に、Facebook のような 写真をレイアウトしてくれる JavaScriptライブラリ「PhotoCollage.js」を利用できるように実装する方法をご紹介します。



PhotoCollage.js の特徴

  • いろいろな HTML に対応しています。
  • 表示している画像とリンク先は別で扱うようにしています。
  • smartPhoto.js の利用も考慮して設計されています。
  • 画像のパスは src なのか data-src なのか指定も可能です。
  • 生成されるHTMLソースの各所に Class や attribute の設定が可能です。

オプション

以下のようなオプションを設定できるようになっています。



variable description default
gap Spacing between images 5px
srcAttribute Image source src
margin Album spacing 0px 0px 10px 0px
imgClass img tag class none
aClass a tag class none
aAttribute a tag attribute none

ダウンロード

GitHub に公開されていますので、そちらからダウンロードしてご利用ください。

https://github.com/appleple/PhotoCollage

a-blog cms のブログテーマで利用するには

CSS と JavaScript のファイルをご自身の blog テーマディレクトリに入れてください。

  • /css/photocollage.css
  • /js/photo-collage.bundle.js

_entry.html に追加

@section("head-link")
@parent
<link rel="stylesheet" href="/css/photocollage.css" />
@endsection
 
@section("head-js")
@parent
  <script src="/js/photo-collage.bundle.js"></script>
  <script>
    document.addEventListener("DOMContentLoaded", function () {
      const elements = document.getElementsByClassName('js-photocollage');
      Array.from(elements).forEach((element, index) => {
        element.classList.add('js-photoCollage-' + index)
        new PhotoCollage(".js-photoCollage-" + index, {
          srcAttribute: "data-src",
          gap: "5px",
          margin: "0px 0px 35px 10px",
          imgClass: "js-lazy-load",
          aAttribute: {
            "data-group": "group-" + index,
            "data-rel": "SmartPhoto",
          }
        });
      });
    });
  </script>
@endsection

17行目の margin を margin: "0px 0px 35px 10px" と設定をしました。
21行目の "data-rel": "SmartPhoto" に変更することで、a-blog cms の SmartPhoto が動作させることができます。

css/photocollage.css を修正

a-blog cms のユニットの仕様の関係で左右に 10px 狭くしないといけない関係で、width : 100% のところを -20px 減らすように /css/photocollage.css の .photocollage を修正しています。

.photocollage {
  position: relative;
  /* width: 100%; */
  width:calc(100% - 20px);
  height:100%;
}
@media screen and (max-width: 1024px) {
  .photocollage {
    width: calc(100% - 20px);
    height:100%;
  }
}

a-blog cms の管理画面の設定

編集画面設定のユニットグループにクラスは js-photocollage とし、ラベルは自由ですが photocollage としておきます。



投稿画面の指定として

ユニットグループ設定で、photocollage を選択します。解除するには、1カラム を選択することで以下のユニットは JavaScript のライブラリの対象外になります。



たくさんの写真を撮って、それをブログの記事に、まとめて貼っておきたい。全部みたい時には SmartPhoto の機能でスライドして見ることも可能です。

https://github.com/appleple/PhotoCollage

メディアに登録された画像を利用するメディアバナーモジュール

メディアバナーモジュールとは

Ver.2.10のメディア機能のアップデートに伴い、登録したメディアを有効活用できるように バナーモジュールの後継としてメディアバナーモジュールをあらたに追加しました。このモジュールを使うとメディアに登録した画像の中から画像を選択して、バナーモジュールのように利用することができます。 バナーモジュールよりも画像を登録する際の使い勝手が大きく向上しており、エントリー編集ページのようなユニット形式で画像を登録することができます。 モジュール側で利用できる変数はバナーモジュールと同じです。

バナーモジュールよりも優れている点

バナーモジュールでは同じ画像を別のバナーモジュールでも利用したい場合、そのモジュールのためにわざわざ画像をアップロードする必要がありました。メディアバナーモジュールではすでにアップロードされた画像をメディアから選択できるので、同じ画像をわざわざモジュールごとにアップロードする手間が省けます。 また複数の画像をドラッグ&ドロップで一度に登録することができます。

使い方

管理画面 > モジュールIDより、「モジュールIDを作成」ボタンをクリックします。新規モジュールID作成ボタンにてモジュールに「Media_Banner」を選択し、他の項目は任意に設定し作成します。


作成後は 表示設定に以下のようにバナーを登録するための項目が追加されています。


エントリー作成画面と非常に似たUIになっており、追加ボタンから「メディア」を追加し、項目を増やしていくことができます。 追加した項目同士はエントリーと同じでドラッグ&ドロップで順番を変えることができるようになっています。


ファイルのドラッグ&ドロップ

またファイルをドラッグ&ドロップして一度に複数枚アップロードすることも可能になっています。


アップロードしたファイルの編集

また、Media_Bannerモジュールはメディア機能をそのまま利用しているため、その場でアップロードしたメディアを編集できるのも特徴です。



メディア編集モーダルウィンドウを表示

ナビゲーションモジュールの中でテンプレートを呼び出す方法

ナビゲーションモジュールについては基本的には、管理画面から手動で自由にラベル・リンクを設定し、更新可能にするためのモジュールですが、例えば「採用情報」のコンテンツ以下のエントリーを追加した際に自動で増えるようなメニューに実装したいと思ったことはありませんでしょうか。

Navigation モジュールの設定



採用情報の公開のチェックを外し非表示にします。右側の(追加)ボタンをクリックし、ナビゲーションを 1行追加してください。

ここで、ラベルに acms://bid/1/cid/7/tpl/navi.html と記述します。 こうする事で、ラベルを編集する際に、acms:// で a-blog cms を再度実行し、bid=1 & cid=7の条件テンプレートnavi.html をラベルに編集することになります。

この機能は、1.x から実装されている機能ではありましたが、1回表示する際に a-blog cms をもう一度動作させて結果を取得する という事で、2倍の負荷になる事から、あまり推奨される記述ではありませんでした。推奨されない裏技として封印されてきていました。これを解決するために、テンプレートの部分的書き出し という機能で回避するという手段も用意されています。

しかし、Ver. 2.11.0 からモジュールID のキャッシュ機能ができた事から、本番環境では モジュールID キャッシュ を有効(0分 → 60分) にする事で、60分に1回しか2回動かさないことができるようになりました。

Navigationモジュール のテンプレートを修正

<!-- BEGIN_MODULE Navigation id="nav_global" -->
<nav class="navbar" aria-label="メインメニュー">
@include("/admin/module/setting.html")
<!-- BEGIN navigation:loop -->
	<!-- BEGIN ul#front --><ul><!-- END ul#front -->
		<!-- BEGIN li#front --><li {attr}><!-- END li#front -->
			<!-- BEGIN link#front --><!-- BEGIN_IF [{url}/nem] --><a href="{url}" {attr} target="{target}"><!-- END_IF --><!-- END link#front -->
			{label}[raw]
			<!-- BEGIN link#front --><!-- BEGIN_IF [{url}/nem] --></a><!-- END_IF --><!-- END link#front -->
			<!-- BEGIN li#rear --></li><!-- END li#rear -->
	<!-- BEGIN ul#rear --></ul><!-- END ul#rear -->
<!-- END navigation:loop -->
<a href="#top" class="acms-hide-tb acms-hide-pc">メニューを閉じる</a>
</nav>
<!-- END_MODULE Navigation -->

<!-- BEGIN link#front --> 〜 <!-- END link#front --> の中に IFブロックを書いて、{url} が無い時に <a> を消すように修正します。<!-- BEGIN link#end --> </a> <!-- END link#end --> のままでは IFブロックの変数 {url} が出せないので、link#end のブロックは link#front に変更しています。

これで、通常の動きと、acms:// を書いた時どちらでも大丈夫なります。

navi.html の作成

<!-- BEGIN_MODULE Entry_List id="recruit_navi" -->
<a href="%{HOME_URL}recruit/">採用情報</a>
  <ul>
    <!-- BEGIN entry:loop -->
    <li class="js-link_match_location"><a href="{url}">{title}</a></li>
    <!-- END entry:loop -->
  </ul>
<!-- END_MODULE Entry_List -->

acms:// で「モジュールID」も設定できるようにすることができると汎用的に使えるテンプレートになるのですが、{{module_id}} のような変数が使える前の時代に用意され、変わっていない機能なので、ここでは recruit_navi のモジュールID固定で用意することになります。



acms://bid/1/cid/7/tpl/navi.html と書いてたので、カテゴリーID にチェックをつけていますが、モジュールID でカテゴリーを指定してしまう書き方でも大丈夫です。

acms://bid/1/field/gnavi/on/tpl/navi.html

また、field/name/value を追加してカスタムフィールドにチェックがあるものだけをメニューに表示させるような書き方もできます。

config.system.yaml の修正

最近のバージョンでは、tpl の利用について制限が加えられていますので、特定のファイルのみを tpl 利用可能に設定する必要があります。

allow_tpl_path

allow_tpl_path: [navi.html]

forbid_tpl_inheritance_when_path_unresolved や forbid_tpl_url_context が on の場合、除外するパスを設定します。例: [news.html,hoge/custom.html] カンマ区切りで指定

html_format_validate

html_format_validate: off

htmlフォーマットでない場合は404で返す設定になります。

この場合、include ディレクトリや admin のディレクトリにあるファイルなどがURLを指定すると表示できてしまう事になりますので、.htaccess などで表示できないように設定をするようにしてください。