PowerCMS™
[新着情報] PowerCMS 6.61 / 5.28 / 4.59 の提供を開始 (JVN#39026557) を追加しました。
PowerCMS 4 系のサポートは2026年3月31日をもちまして終了いたします。期限までに PowerCMS 5/6 最新版へのアップグレードをご検討ください。
[ブログ] PowerCMS 6 でのアップデートまとめ を追加しました。
[新着情報] PowerSync 2.1 の提供を開始 を追加しました。
スクロールできます

PowerCMS ブログ

ホーム > PowerCMS ブログ > 設定・管理画面カスタマイズ > スニペット・カスタムフィールドでカスタムフィールドをタブグループにまとめる

2014年06月13日

スニペット・カスタムフィールドでカスタムフィールドをタブグループにまとめる

PowerCMS に同梱されているスニペットフィールドを使うと、任意の UI でカスタムフィールドを作ることが可能です。

PowerCMS ユーザーガイドに掲載されているシンプルな管理画面 UI の作成から、MT タグや JavaScript を活用した高機能な管理画面 UI 作成まで、カスタマイズ次第であらゆる管理画面 UI を作ることができます。

今回はスニペットカスタムフィールドを利用して、任意のカスタムフィールドをタブでグループ化するカスタマイズ Tips を紹介します。

本記事で紹介するサンプルは、PowerCMS 4.03 にて動作確認をしています。

完成図

タブ1を表示した時のカスタムフィールドの状態

タブ2を表示した時のカスタムフィールドの状態

タブ3を表示した時のカスタムフィールドの状態

上記の完成図にするためのスニペット・カスタムフィールドのサンプルが下記になります。

スニペット・カスタムフィールドの設定

タブグループ化するための、記事のカスタムフィールドが複数あることを前提としています。

上記の完成図では、テキスト、チェックボックス、テキスト(複数行)、ラジオボタン、画像のカスタムフィールドが事前にあり、それをグループ化しました。

仮に、今回作成するカスタムフィールドは、ウェブサイトの記事のカスタムフィールドで、それぞれのカスタムフィールドのベースネームが下記であるとします。

  1. テキスト ( websiteentrytext )
  2. チェックボックス ( websiteentrycheckbox )
  3. テキスト複数行 ( websiteentrytextarea )
  4. ラジオボタン ( websiteentryradio )
  5. 画像 ( websiteentryimage )

以下は、スニペット・カスタムフィールドで作成するカスタムフィールドの具体的な設定項目とその値です。

名前

カスタムフィールドグループ

任意の名前を指定してください。

説明

なし

任意の説明文を指定してください。

種類

スニペット

保存後に表示される既定値の設定は後述します。

オプション

  1. websiteentrytext,websiteentrycheckbox___websiteentrytextarea,websiteentryradio___websiteentryimage

スニペット・カスタムフィールドでは、オプションに指定した値をパラメータとしてリクエストに含めることで、任意の値を保存できる仕組みです。

今回のサンプルは、オプションの項目を、本来の用途ではなく、タブグループをどのようにグループ化するかを記述するために使っています。

指定する値は、タブグループに利用するカスタムフィールドのベースネームで、「___」(アンダースコアが三つ)がタブの区切りで、「,」(カンマ)がベースネームの区切りになります。

また、PowerRevision プラグインでは、このオプション値をバックアップファイルとして生成する XML ファイル中のタグ名として利用する制約があるため、「___」(アンダースコアが三つ)の前後に空白などの XML の要素名として利用できない文字を含めることはできません。

上記の設定は、1つ目のタブに、websiteentrytextwebsiteentrycheckbox を表示し、2つ目のタブに、websiteentrytextareawebsiteentryradio を表示し、最後のタブに、ベースネームが websiteentryimage であるカスタムフィールドを表示するという設定になります。

ベースネーム

websiteentrycfgroups

任意のベースネームを指定してください。

テンプレートタグ

websiteentrycfgroups

任意のテンプレートタグを指定してください。

今回のサンプルでは、スニペット・カスタムフィールド自体には値を保存しないため、このタグを利用する機会はありません。

既定値

  1. <div id="cfgroups"></div>
  2. <script type="application/x-mt-js-template" id="cfgroups-tabs-tmpl">
  3. <div id="cfgroups-tabs">
  4. <ul>
  5. [# jQuery.each(tabs, function (i) { #]
  6. <li><a href="#cfgroups-tabs-[#= i + 1 #]">タブ[#= i + 1 #]</a></li>
  7. [# }) #]
  8. </ul>
  9. [# jQuery.each(tabs, function (i) { #]
  10. <div id="cfgroups-tabs-[#= i + 1 #]"></div>
  11. [# }) #]
  12. </div>
  13. </script>
  14. <script>
  15. jQuery(function ($) {
  16. 'use strict';
  17. // 変数を宣言する
  18. var $me, $me_display_option, $cfgroups, options, tabs, html;
  19. // スニペット・カスタムフィールド自身の jQuery オブジェクトをキャッシュする
  20. $me = $('#customfield_<$mt:var name="basename" encode_js="1"$>-field');
  21. // スニペット・カスタムフィールド自身の表示オプションチェックボックスの jQuery オブジェクトをキャッシュする
  22. $me_display_option = $('#custom-prefs-customfield_<$mt:var name="basename" encode_js="1"$>');
  23. // div#cfgroups の jQuery オブジェクトをキャッシュする
  24. $cfgroups = $('#cfgroups');
  25. // オプションの値を変数に代入する
  26. options = '<$mt:var name="options" encode_js="1"$>';
  27. // オプションの値を配列に変換する
  28. tabs = $.map(options.split('___'), function (option) {
  29. return [option.split(/\s*,\s*/)];
  30. });
  31. // script#cfgroups-tabs-tmpl の innerHTML をテンプレートとして、テンプレートをビルドする
  32. // テンプレート内で利用する tabs という変数に、上記の tabs 変数をアサインしている
  33. html = Template.process('tabs', { tabs: tabs }, { tabs: $('#cfgroups-tabs-tmpl').html() });
  34. // スニペット・カスタムフィールド自身が表示されているかどうかを判定するための関数
  35. function isHidden ($me) {
  36. return $me.is(':hidden');
  37. }
  38. // flatten で利用するためのユーティリティ関数
  39. function identity (a) {
  40. return a;
  41. }
  42. // ネストされた配列(2階層まで)をフラットにする関数
  43. function flatten (arr) {
  44. return $.map(arr, identity);
  45. }
  46. // タブグループをレンダリングするための関数
  47. function render () {
  48. // div#cfgroups の innerHTML にテンプレートのビルド結果を反映する
  49. $cfgroups.html(html);
  50. // カスタムフィールドをタブグループの該当タブに移動する
  51. $.each(tabs, function (i) {
  52. var basenames = this;
  53. $.each(basenames, function () {
  54. var basename, $customfield;
  55. basename = this.valueOf();
  56. $customfield = $('#customfield_' + basename + '-field');
  57. // カスタムフィールドの見出し部分はソート不可にするため、
  58. // ソート対象になるクラス名を除去し、最低限のスタイル調整をする
  59. $customfield
  60. .find('.field-header')
  61. .removeClass('field-header')
  62. .css('padding', '5px 10px');
  63. // カスタムフィールドを該当のタブグループに移動する
  64. $customfield.appendTo('#cfgroups-tabs-' + (i + 1));
  65. });
  66. });
  67. // div#cfgroups-tabs をタブ化する
  68. $cfgroups.find('#cfgroups-tabs').tabs();
  69. }
  70. // カスタムフィールドを通常の位置に戻すための関数
  71. function restore () {
  72. $.each(flatten(tabs), function () {
  73. // タブグループ内のカスタムフィールドの jQuery オブジェクトを取得する
  74. var $field = $('#customfield_' + this + '-field');
  75. // カスタムフィードの見出し部分に、クラス名 .field-header を再設定し、ソート可能にする
  76. $field.children().first().addClass('field-header');
  77. // フィールドの並びの最後に移動する
  78. $field.appendTo('#sortable');
  79. });
  80. }
  81. // 自身の表示オプションが変更された時、HTML を組み立て直すためのイベントハンドラ
  82. $me_display_option.on('change', function () {
  83. if ($(this).is(':checked')) {
  84. // 表示オプションが ON になったら、タブグループを表示する
  85. render();
  86. }
  87. else {
  88. // 表示オプションが OFF になったら、タブグループから、本来の場所にカスタムフィールドを移動する
  89. restore();
  90. }
  91. return true;
  92. });
  93. // 自身が非表示であれば何もしない
  94. if (isHidden($me)) return;
  95. // 自身が非表示でなければタブグループを組み立てて表示する
  96. render();
  97. });
  98. </script>

上記が、タブグループを実現するための、スニペット・カスタムフィールドの具体的なロジックになります。

冒頭の <div id="cfgroups"></div> は、JavaScript で生成した DOM を挿入するためのラッパー要素です。

次の、<script type="application/x-mt-js-template" id="cfgroups-tabs-tmpl"> ... </script> で囲まれた部分は、タブグループを描画する HTML の JavaScript テンプレートになります。

JavaScript テンプレートは、Movable Type の管理画面でも利用されている、Movable Type 標準の Template.js という JavaScript テンプレートエンジンを利用しています。

script 要素の type 属性にブラウザが理解できない Media タイプが指定された時、その内容を無視するという特徴を利用して、テンプレートの記述のために利用しています。
※ 本来は script 要素の type 属性に指定する Media タイプは、RFC にて定義された妥当な Media タイプを指定するべきですが、すでに広く使われている手法のため、今回はこの方法を採用しました。

その後の script 要素にて、具体的な処理内容を記述しています。

処理内容を大きく捉えると、共通で使う変数の初期化、ユーティリティ関数の定義、イベントハンドラの登録、メインの処理といった内容が記述されています。コメントをヒントにご確認ください。

jQuery の ready イベントが発火するまでは、通常のカスタムフィールドとして表示され、その要素自体をタブグループ内に移動するため、並び順や表示オプションの状態などはそのまま引き継がれます。(タブグルーブ内の並びはオプションの指定順によって変更します)また、非表示の時は何もしないようにしています。

本サンプルの利点は、スニペット・カスタムフィールド自身で UI を作り込むわけではないため、通常のカスタムフィールドの編集や追加(スニペット・カスタムフィールドのオプションの値を追加する必要はあります)の操作にて UI を変更できる点にあります。

以上、スニペット・カスタムフィールドのカスタマイズの一例をご紹介しました。

スニペット・カスタムフィールドは、管理画面 UI の柔軟なカスタマイズが可能ですので、ぜひご活用ください。

追記

投稿当初、オプション値タブでグループ化する範囲の区切り文字を「|」(バーティカルバー)にしておりましたが、PowerRevision との組み合わせで問題があることが確認されたため、記事中の「|」は、「___」(アンダースコアが三つ)に変更いたしました。


カテゴリー
設定・管理画面カスタマイズ

Recent Entries