D: スクロールを予測させるテーブルユニットを作ってみよう

先日弊社で新しいOSS(ScrollHint)を公開しました。このJavaScriptを使うと下のデモようにコンテンツが表示エリアをはみ出した時に、そのコンテンツに対してスクロール可能領域にボックスシャドウをかけ、さらにコンテンツが表示エリアに入った瞬間にスクロールを促すためのアイコンが表示されます。

Col1 Col2 Col3
Lorem ipsum dolor sit. Lorem ipsum dolor sit. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, magnam.
Lorem ipsum dolor sit. Lorem ipsum dolor sit. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, magnam.
Lorem ipsum dolor sit. Lorem ipsum dolor sit. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, magnam.

課題

以下の画像のようにエントリー編集画面のテーブルユニットより「スクロールを促すテーブル」を選択すると、表側の画面でScrollHintが適応されたテーブルを表示できるようにする。


エントリー編集画面

Col1 Col2 Col3
Lorem ipsum dolor sit. Lorem ipsum dolor sit. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, magnam.
Lorem ipsum dolor sit. Lorem ipsum dolor sit. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, magnam.
Lorem ipsum dolor sit. Lorem ipsum dolor sit. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et, magnam.

1. JavaScriptを使ってテーブルユニットの選択項目を増やす

Ver.2.8よりテーブルユニットのテーブル自体に対してクラスを追加することができるように下の図のようにセレクトボックスが追加されました。


デフォルトでは、「スクロールするテーブル」しか選択できませんが、この項目はJavaScriptより増やすことが可能です。以下のように、その項目のラベル名とその項目が選択された際にテーブルに付与するクラス名を記述します。

ACMS.Ready(function(){  
 ACMS.Config.aTableOption.push({
    label: 'スクロールを促すテーブル', 
    value: 'js-scrollable'
  });
});

2. 表側ベージでjs-scrollable というクラス名が振られた要素に対して、ScrollHintを実行する

はじめにhead内に以下のコードを書いて ScrollHint を読み込みます。

<link rel="stylesheet" href="https://unpkg.com/scroll-hint@latest/css/scroll-hint.css">
<script src="https://unpkg.com/scroll-hint@latest/js/scroll-hint.min.js"></script>

次に、以下のようなJavaScriptを記述してScrollHintを実行します。

document.addEventListener('DOMContentLoaded', function(){
    new ScrollHint('.js-scrollable', {
      applyToParents: true,
      i18n: {
        scrollable: 'スクロールできます'
      }
  });
});

ハンズオンは以上になります。ぜひ、ScrollHintを使ってみてください!

AMPPS2.4でのa-blog cmsの利用


AMPPS2.4での注意点

AMPPSはローカルにapache, mysql, php の環境を用意できるソフトになります。 標準でa-blog cmsを動かすのに必要なioncubeが入っていてa-blog cmsのローカル開発環境として便利です。


しかし、2014/05/16日現在最新のAMPPS2.4をphp5.4で動かすとioncubeが標準で入っていないようで、 a-blog cmsを動作させることが出来ません。

※php5.3では動作を確認しています

手動でioncubeのインストールを試みたのですが、うまくいかず様子みている状態です。 AMPPS2.4の場合は、php5.3をご利用頂くか、他の環境をご利用ください。

動的フォームのためのテンプレート

動的フォームのテンプレートはメールのテンプレート、入力フォームと入力確認画面のテンプレートがあります。フォームの項目は動的に出力されるため自由なカスタマイズはできないのですが、文面や署名などはテンプレートから変更することができます。

テンプレートについて

テンプレートはsystemテーマに置いてあります。変更するときはご利用しているテーマ内にコピーしてきてください。 /themes/利用中のテーマ/include/form/adminsubject.txt

メールのテンプレート

管理者宛メールの件名

/themes/system/include/form/adminsubject.txt

管理者宛メールの本文

/themes/system/include/form/adminbody.txt

一般宛メールの件名

/themes/system/include/form/subject.txt

一般宛メールの本文

/themes/system/include/form/body.txt

入力フォームと入力確認画面のテンプレート

formタグや入力フォームと入力確認画面のテンプレートを読み込んでいます

/themes/system/include/form/unit.html

完了画面のテンプレートは、デフォルトだと「thanks.html」が指定されています

/bid/%{BID}/eid/%{EID}/tpl/thanks.html

この時、URLコンテキスト「tpl」によって、thanks.html を指定していることによって、Ver. 2.11.25 以上をお使いの場合は、そのままでは動きません。 「private/config.system.yaml」の allow_tpl_path に 「thanks.html」を指定ください。これはセキュリティ上の仕様変更によるものになります。詳細

allow_tpl_path: [thanks.html]

入力フォームのテンプレート

/themes/system/include/form/input.html

入力確認画面のテンプレート

/themes/system/include/form/confirm.html

メールの署名を変更

メールの署名は /themes/system/include/form/adminbody.txt と /themes/system/include/form/body.txt に記述されています。ご利用のテーマにコピーしてきて署名を変更します。  
/themes/ご利用テーマ/include/form/body.txt

%{BLOG_NAME}

〒000-0000
○○県○○○市○○区 ××の××の××
電話番号: 123-456-7890
E-mail: ■■■@■■■■.■■

A: ポストインクルードで読み込んできたコンテンツにMasonryレイアウトを適応する

a-blog cmsにはACMS.addListener という特定のイベントに対して処理を挟み込めるAPIが用意されています。 このAPIを使うことにより、エントリーのユニットの追加時やカスタムフィールドグループの項目を増やした時など特定のタイミングで任意の処理を挟み込むことができます。 例えば、ポストインクルードで読み込んで来たコンテンツに対してウェブフォントを適応したいというケースなどにも有効です。 下は、ウェブフォントのサービスであるFONTPLUSをポストインクルード時に再実行する処理のサンプルになります。

ACMS.addListener("acmsAfterPostInclude", function() {
  FONTPLUS.reload();
});

ACMS..addListenerに用意されているイベント



イベント名 実行タイミング
acmsReady 組み込みJSが実行できるタイミングで発火するイベント
acmsAdminReady 管理画面用の組み込みJSが実行出来る段階で発火するイベント
acmsDispatch 組み込みJSのディスパッチが終わった段階で発火するイベント
acmsAddUnit エントリーの編集画面にてユニットが追加された際に発火するイベント
acmsAfterPostInclude ポストインクルードが完了したタイミングで発火するイベント
acmsAdminDelayedContents ダイアログや、タブなど後から表示されるコンテンツが表示されるタイミングで発火するイベントです。

今回はこのAPIを利用してポストインクルードが実行された後にそのコンテンツに対してMasonryレイアウトを適応してみましょう。 Masonryレイアウトとはアイテムがタイル状に引き詰められたレイアウトで、以下のMasonryというJavaScriptライブラリを使用することで実装可能です。


Masonry

課題

site2018テーマのお知らせページでMasonryレイアウトを利用した一覧ページを作ってみましょう。ただし「もっと読み込む」ボタンが押されたタイミングで次のページのエントリーサマリーを読み込み、そのコンテンツに再びMasonryレイアウトを適応するものとします。

※デフォルトでお知らせに登録されているエントリー数はあまり多くないので、ハンズオンのために20件ほど増やしておくことをオススメします。


もっと読み込むボタンを押す前


もっと読み込むボタンを押した後

1. リソースの読み込み

まず、Masonryレイアウトに必要な下の2つのJavaScriptを読み込みます。

<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>

2. themes/site2018/news/index.html の書き換え

@include("/include/entry/body.html")となっている箇所を下のようなソースコードに書き換えます。この部分にMasonryレイアウトが適応されることになります。

<div class="acms-grid js-masonry">
  @include("/include/entry/masonry.html")
</div>

3. ポストインクルードで読み込むテンプレートの記述

themes/site2018/include/entry/masonry.html を作成し、以下のようなHTMLを記述します。先ほどのMasonryレイアウトの中に実際に入ってくるエントリーサマリーを記述しています。今回、モジュールIDをnews_summaryとしています。

<!-- BEGIN_MODULE Entry_Summary id="news_summary" -->
  <!-- BEGIN unit:loop -->
  <!-- BEGIN entry:loop -->
  <div class="acms-col-4">
    <a href="{url}" class="acms-thumbnail">
      <!-- BEGIN image:veil -->
      <img src="%{ROOT_DIR}{path}" alt="{alt}">
      <!-- END image:veil -->
      <!-- BEGIN noimage -->
      <img src="/images/default/noimage.gif" alt="">
      <!-- END noimage -->
      <h3>{title}</h3>
      <p>{summary}</p>
    </a>
  </div>
  <!-- END entry:loop -->
  <!-- END unit:loop -->
  <!-- BEGIN forwardLink -->
  <form action="%{ROOT_BLOG_URL}" method="post" class="js-post_include acms-col-4">
    <input type="hidden" name="tpl" value="/include/entry/masonry.html" />
    <input type="hidden" name="page" value="{forwardPage}" />
    <input type="submit" name="ACMS_POST_2GET" value="もっと読み込む" class="acms-btn"/>
  </form>
  <!-- END forwardLink -->
<!-- END_MODULE Entry_Summary -->

4. JavaScriptの適応

以下のようなJavaScriptを記述して、ポストインクルード実行後に読み込んだコンテンツに対して、再びMasonryレイアウトが適応されるようにします。

var msnry = new Masonry('.js-masonry');
imagesLoaded('.js-masonry', function () {
  msnry.layout();
});
ACMS.addListener('acmsAfterPostInclude', function (e) {
  imagesLoaded('.js-masonry', function () {
    msnry.destroy();
    msnry = new Masonry('.js-masonry');
    msnry.layout();
  });
});

5. モジュールIDの作成

先ほどthemes/site2018/include/entry/masonry.html に記述したモジュールID news_summary を管理画面から作成しましょう。管理画面 > モジュールID よりモジュールIDを新規作成していただけます。この際に下の図のように、カテゴリーIDとページの引数にチェックをつけておきましょう。これでポストインクルード実行の際に、次のページのエントリーサマリーを読み込んで表示することができます。


ハンズオンは以上です。ポストインクルードで読み込んだコンテンツに対してJavaScriptを適応したいケースは多いと思います。今後ぜひ、ACMS.addListenerを活用してみてください。

動的フォームの動的項目と静的項目の共存

動的フォームの入力フォームと確認画面のテンプレートをカスタマイズすることでHTMLのカスタムフィールドを埋め込むこともできます。例えば、お名前のフォーム項目は必ずフォームに必要だから予め固定のカスタムフィールドにするだとか、都道府県の項目はいれたいけど都道府県を入力フォームから入れていくのは大変だったりします。動的フォームの項目を一部HTMLで記述されたカスタムフィールドにすることができます。

HTMLで記述されたカスタムフィールドを埋め込む

動的フォームにHTMLで記述されたカスタムフィールドを埋め込むときは動的フォームパーツの上か下に埋め込むことになります。動的フォームのパーツの間にHTMLのカスタムフィールドを埋め込むことができず、順番を自由に設定することはできません。
例えば都道府県のHTMLのカスタムフィールドを埋め込んでみましょう。

入力フォームに埋め込む

動的フォームの入力フォームのテンプレート /themes/system/include/form/input.html をご利用のテーマにコピーしてきます。
/themes/ご利用のテーマ/include/form/input.html

Form2_Unitモジュールのcolumn:loopの外にHTMLで記述されたカスタムフィールドを記述してください。

<tr>
  <th>都道府県</th>
  <td>
  <select class="formSelect" name="pref_code">
    <option value="" selected="selected">選択してください ▼</option>
    <option value="北海道"\{pref_code:selected#北海道\}>北海道</option>
      
    <option value="青森県"\{pref_code:selected#青森県\}>青森県</option>
    <option value="岩手県"\{pref_code:selected#岩手県\}>岩手県</option>
    <option value="宮城県"\{pref_code:selected#宮城県\}>宮城県</option>
    <option value="秋田県"\{pref_code:selected#秋田県\}>秋田県</option>
    <option value="山形県"\{pref_code:selected#山形県\}>山形県</option>
    <option value="福島県"\{pref_code:selected#福島県\}>福島県</option>
    <option value="茨城県"\{pref_code:selected#茨城県\}>茨城県</option>
    <option value="栃木県"\{pref_code:selected#栃木県\}>栃木県</option>
    <option value="群馬県"\{pref_code:selected#群馬県\}>群馬県</option>
      
    <option value="埼玉県"\{pref_code:selected#埼玉県\}>埼玉県</option>
    <option value="千葉県"\{pref_code:selected#千葉県\}>千葉県</option>
    <option value="東京都"\{pref_code:selected#東京都\}>東京都</option>
    <option value="神奈川県"\{pref_code:selected#神奈川県\}>神奈川県</option>
    <option value="新潟県"\{pref_code:selected#新潟県\}>新潟県</option>
    <option value="富山県"\{pref_code:selected#富山県\}>富山県</option>
    <option value="石川県"\{pref_code:selected#石川県\}>石川県</option>
    <option value="福井県"\{pref_code:selected#福井県\}>福井県</option>
    <option value="山梨県"\{pref_code:selected#山梨県\}>山梨県</option>
      
    <option value="長野県"\{pref_code:selected#長野県\}>長野県</option>
    <option value="岐阜県"\{pref_code:selected#岐阜県\}>岐阜県</option>
    <option value="静岡県"\{pref_code:selected#静岡県\}>静岡県</option>
    <option value="愛知県"\{pref_code:selected#愛知県\}>愛知県</option>
    <option value="三重県"\{pref_code:selected#三重県\}>三重県</option>
    <option value="滋賀県"\{pref_code:selected#滋賀県\}>滋賀県</option>
    <option value="京都府"\{pref_code:selected#京都府\}>京都府</option>
    <option value="大阪府"\{pref_code:selected#大阪府\}>大阪府</option>
    <option value="兵庫県"\{pref_code:selected#兵庫県\}>兵庫県</option>
      
    <option value="奈良県"\{pref_code:selected#奈良県\}>奈良県</option>
    <option value="和歌山県"\{pref_code:selected#和歌山県\}>和歌山県</option>
    <option value="鳥取県"\{pref_code:selected#鳥取県\}>鳥取県</option>
    <option value="島根県"\{pref_code:selected#島根県\}>島根県</option>
    <option value="岡山県"\{pref_code:selected#岡山県\}>岡山県</option>
    <option value="広島県"\{pref_code:selected#広島県\}>広島県</option>
    <option value="山口県"\{pref_code:selected#山口県\}>山口県</option>
    <option value="徳島県"\{pref_code:selected#徳島県\}>徳島県</option>
    <option value="香川県"\{pref_code:selected#香川県\}>香川県</option>
      
    <option value="愛媛県"\{pref_code:selected#愛媛県\}>愛媛県</option>
    <option value="高知県"\{pref_code:selected#高知県\}>高知県</option>
    <option value="福岡県"\{pref_code:selected#福岡県\}>福岡県</option>
    <option value="佐賀県"\{pref_code:selected#佐賀県\}>佐賀県</option>
    <option value="長崎県"\{pref_code:selected#長崎県\}>長崎県</option>
    <option value="熊本県"\{pref_code:selected#熊本県\}>熊本県</option>
    <option value="大分県"\{pref_code:selected#大分県\}>大分県</option>
    <option value="宮崎県"\{pref_code:selected#宮崎県\}>宮崎県</option>
    <option value="鹿児島県"\{pref_code:selected#鹿児島県\}>鹿児島県</option>
      
    <option value="沖縄県"\{pref_code:selected#沖縄県\}>沖縄県</option>
  </select>
  <input type="hidden" name="field[]" value="pref_code" />
  </td>
</tr>

HTMLで記述されたカスタムフィールドの都道府県が追加されました。カスタムフィールドの変数が認識されるように変数の前にバックスラッシュ(\)でエスケープをします。



確認画面に項目を追加する

フォームの確認画面にも追加したHTMLのカスタムフィールドを追加してください。
Form2_Unitモジュールのcolumn:loopの外にHTMLで記述されたカスタムフィールドを追加します。
/themes/ご利用のテーマ/include/form/confirm.html

先ほど追加した都道府県の場合は以下のようになります。こちらもカスタムフィールドの変数にエスケープして記述します。

<tr>
  <th>都道府県</th>
  <td>\{pref_code\}</td>
</tr>

メールのテンプレートに項目を追加する

入力フォームと確認画面にHTMLで記述されたカスタムフィールドを追加してきました。追加したHTMLで記述されたカスタムフィールドの変数をメールのテンプレートにも記述する必要があります。メールのテンプレートもご利用のテーマにコピーしてきてからカスタマイズをしてください。

/themes/ご利用のテーマ/include/form/body.txt
/themes/ご利用のテーマ/include/form/adminbody.txt

追加する場所はForm2_Unitモジュールの外に追加してください。
メールのテンプレートはカスタムフィールドの変数にエスケープは必要ありません。

メールアドレス  : {email}<!-- BEGIN_MODULE Form2_Unit -->
<!-- BEGIN column:loop --><!-- BEGIN text -->
{label}  : \{form-unit-{utid}\}<!-- END text --><!-- BEGIN textarea -->
{label}  : \{form-unit-{utid}\}<!-- END textarea --><!-- BEGIN radio -->
{label}  : \{form-unit-{utid}\}<!-- END radio --><!-- BEGIN select -->
{label}  : \{form-unit-{utid}\}<!-- END select --><!-- BEGIN checkbox -->
{label}  : <!-- BEGIN\ form-unit-{utid}:loop -->\{form-unit-{utid}\} <!-- END\ form-unit-{utid}:loop --><!-- END checkbox -->
<!-- END column:loop --><!-- END_MODULE Form2_Unit -->
都道府県  : {pref_code}

このような方法で動的フォームにHTMLで記述されたカスタムフィールドを埋め込むことができます。

補足

ver 2.6.1.0よりradio,select,checkboxのループ内にて項目の連番変数 {i} を出力するように追加されました。
下記サンプルコードを参考にしてください。内容は一部抜粋しています。

 <!-- BEGIN radio -->
 <tr>
  <th><label>{label}</label></th>
  <td class="acms-radio">
   <!-- BEGIN radio#val:loop -->
   <label class="acms-form-radio"><input type="radio" name="form-unit-{utid}" value="{value}"\{form-unit-{utid}:checked#{value}\}>
   <i class="acms-ico-radio"></i>
   {value}:{i}
   </label><!-- END radio#val:loop -->
  </td>
 </tr><!-- END radio -->