PowerCMS X ブログ

2025-12-23

管理画面テンプレートの一部を静的化して表示速度を高速化する

PowerCMS Xのセールスポイントの1つは動作が高速で軽快なことですが、オブジェクトの作成・編集画面に表示する項目を増やしすぎると当然その分テンプレートのビルドに時間がかかるようになります。通常の運用であれば問題ないケースがほとんどだと思いますが、管理画面テンプレートを静的化して表示速度を高速化する方法をご紹介します。大量のオブジェクトを登録するようなケースで参考にしていただければと思います。

リレーション(数値)型・階層表示のテンプレート

カテゴリなど、階層を持ったオブジェクトへのリレーション (複数または単一) を設定しているとします。この例では記事に対するカテゴリとしますが、他のケースでもやることは同じです。カテゴリが数万件もあるようなサイトは稀だと思いますが、ある案件では郵便番号に対応するモデルを作成したので、数万件に及びました。当然表示には相応の時間がかかります。

カスタマイズした記事カテゴリの選択画面のスクリーンショット

要件

  • カテゴリ (案件では郵便番号に対応した市区町村) 数万件を階層付きオブジェクトとして管理
  • プライマリ選択のボタンは不要
  • 最上位のオブジェクトにチェックを入れたとき、配下の要素にすべてチェックが入るようにする

ビューとURLマップを作成する

ブロックタグ「nestableobjects」 別ウィンドウで開きますを利用して、再帰的に階層を表示するビューを作成します。

チェックボックスのクラス名や名前は管理画面に準じて設定してください。対応したURLマップを作成します。ファイル出力「静的」に設定します。出力先は仮に「include/column_categories.tmpl」とします。

<mt:setvar name="__col_name__" value="categories"><mt:unless trim_space="3"><div class="row form-group">
  <div class="col-lg-2">
    <mt:trans phrase="Categories">
    <i class="fa fa-asterisk required" aria-hidden="true"></i>
    <span class="sr-only"><mt:trans phrase="Required"></span>
  </div>
  <div class="col-lg-10">
    <mt:setvartemplate name="nestable_obj_list">
    <mt:nestableobjects model="category" parent_id="$_parent_id">
        <mt:if name="__first__"><ul class="nestableobjects-list"></mt:if>
        <mt:ifinarray array="category_labels" value="$label">
        <mt:else>
          <mt:setvar name="category_labels" value="$label" function="push">
          <li>
            <label class="custom-control custom-checkbox">
              <input type="checkbox"
                id="<mt:var name="__col_name__">_cb_<mt:var name="id">"
                class="custom-control-input watch-changed categories <mt:if name="parent_id">parent_category-<mt:var name="_parent_id"><mt:else>parent_category</mt:if>" name="categories[]" value="<mt:var name="id">">
              <span class="custom-control-indicator"></span>
              <span class="custom-control-description">
                <mt:var name="label" escape>
              </span>
            </label>
            <mt:if name="has_children">
              <mt:var name="id" setvar="_parent_id">
              <mt:var name="nestable_obj_list">
            </mt:if>
          </li>
        </mt:ifinarray>
        <mt:if name="__last__"></ul></mt:if>
    </mt:nestableobjects>
    </mt:setvartemplate>
    <div class="relation_nestable_list" id="categories">
      <mt:setvar name="_parent_id" value="0">
      <div id="nestable_list-categories">
      <mt:var name="nestable_obj_list">
      </div>
    </div>
    <div class="mt-2">
      <input type="text" class="form-control" readonly id="disp_categories">
    </div>
  </div>
</div></mt:unless>

選択部分を JavaScriptでセットする

PowerCMS Xのオブジェクト編集画面では、object_カラム名に値がセットされています。リレーションの場合は配列で格納されています。記事カテゴリの場合は、「object_categories」となります。

環境依存性を下げるために、mt:websitepathでパスを取得して、それに繋げた形で <mt:include>タグを呼び出すと良いでしょう。

代替テンプレートについては、以下を参照ください。

設置場所は「代替テンプレートのパス/include/edit/entry/column_categories.tmpl」となります。

<mt:setvarblock name="categories_tmplate_path"><mt:websitepath workspace_id="1">/include/column_categories.tmpl</mt:setvarblock>
<mt:include file="$categories_tmplate_path">
<script>
<mt:loop name="object_categories">
  var checkbox_id = '#categories_cb_<mt:var name="__value__">';
  $(checkbox_id).prop( 'checked', true );
</mt:loop>
</script>

親カテゴリをチェックした時に、配下の項目にチェックを入れる

このケースでは、2階層限定でですが、最上位のカテゴリに「.parent_category」クラスを付与しています。下層の項目には「.parent_category-[カテゴリのID]」というクラスを付けていますので、これを利用します。

<script>
$('.parent_category').change(function(){
    let thisId = $(this).attr('id');
    thisId = thisId.replace( 'categories_cb_', '');
    const className = '.parent_category-' + thisId;
    $(className).prop('checked', $(this).prop('checked'));
});
</script>

最後に一手間、選択項目を可視化する

このUIに数万項目が含まれているとしたら、どこを選択しているのかを探すのも一苦労です。そこで、要件にはありませんが、選択されている項目を見えるようにします。readonlyな input textを下部に追加して、画面を開いた時、項目の選択をした時に値をセットするようにします。

カスタマイズした記事カテゴリの選択画面のスクリーンショット(読み取り専用のinput textを追加)

<script>
$('.categories').change(function(){
    disp_categories();
});
disp_categories();
function disp_categories () {
    const selected_categories = [];
    $('.categories').each(function(){
        if ( $(this).prop('checked') ) {
            selected_categories.push( $(this).parent().find('.custom-control-description').html() );
        }
    });
    $('#disp_categories').val( selected_categories.join( ', ' ) );
}
</script>

カスタマイズは以上となります。高速化され、使い勝手も向上して、担当者の評価も上々です。ぜひお試しください。

カテゴリー:技術情報 | テンプレート作成Tips

投稿者:Junnama Noda

ブログ内検索

アーカイブ


日本語
ふりがな付き
English
简体中文
繁體中文
한국어