カスタムフィールド

カスタムフィールドはコンテンツ(ページ・コレクション・モジュール・カレンダー)に任意の入力項目を用意できる機能です。

たとえば、お知らせ記事用のコンテンツタイプに、お知らせ種類を選択するためのラジオボタンを用意するという場合に、カスタムフィールドを活用することができます。

カスタムフィールドはフィールド設定ファイル(system/config/fields.php)に定義します。 定義されたカスタムフィールドは、各コンテンツで同様に利用することができます。

カスタムフィールドを利用する

フィールド設定ファイル(system/config/fields.php)には、いくつかのカスタムフィールドがあらかじめ定義されています。 それらのカスタムフィールドはコンテンツ設定ファイルで指定すると利用できます。

デフォルトで用意されるカスタムフィールド:
フィールドタイプ名 ラベル 説明
p 段落 p要素を出力します。
ul 順序なしリスト ul要素を出力します。
ol 順序リスト ol要素を出力します。
table_2 テーブル(2列) 2列のテーブルを出力します。
text テキスト 1行テキストを出力します。
textarea テキストエリア 複数行テキストを出力します。
heading 見出し h1からh6要素を出力します。
select セレクトボックス プルダウンメニューで選択された内容を出力します。
radio ラジオボタン ラジオボタンで選択された内容を出力します。
checkbox チェックボックス チェックボックスで選択された内容を出力します。あるいは if文での条件分岐に利用します。
checkboxes チェックボックス(複数選択) 同じname属性で複数選択できるチェックボックスです。
image 画像 画像を出力します。
richtext リッチテキスト リッチテキストエディター(Wysiwygエディター)で編集された内容を出力します。
link リンク 入力されたリンクテキストとURLでリンクを出力します。
file ファイル ファイルコンテンツへのリンクを用意するためのフィールドです。URL・ファイル名・ファイルサイズを指定できます。 ファイル名の指定を省略した場合は、URLからファイル名部分を取り出して表示します。
url URL URLを入力できます。画像にリンクを貼る場合などリンクテキストが不要な場合に利用できます。
date 日付 日付(年月日)を入力するためのフィールドです。管理画面では日付選択ポップアップメニューが表示されます。
datetime 日時 日時(年月日 時分秒)を入力するためのフィールドです。管理画面では日時選択ポップアップメニューが表示されます。
card カード タイトルと本文欄を持つカード型の部品を出力します。
html HTML HTMLを入力できます。
twig Twigテンプレート Twigを入力できます。
number 数値 数値を3桁毎のカンマ区切りで出力します。
price 価格 数値の後に「円」を付けて出力します。
links リンクリスト リンクフィールドを利用できるコンテナフィールドです。
module モジュール モジュールを表示します。
content コンテント さまざまなフィールドをブロックで管理できるコンテナフィールドです。

コンテンツ設定ファイル(pages.php, collections.php, modules.php, calendars.php)の各コンテンツタイプの fields 項目に利用したいフィールドを指定します。 たとえば、ページコンテンツのお知らせ記事用の info_article タイプで、リンクフィールドを使いたい場合はページコンテンツ設定ファイル(system/config/pages.php)で次のように指定します。

return [
    'info_article' => [
        'label' => 'お知らせ記事',
         // ... 省略
        'fields' => [
            'info_link' => [ // (このコンテンツタイプ内で識別するための)フィールド名
                'type' => 'link', // フィールドタイプ名
            ],
        ],
    ],
];

fields 項目にフィールドを列挙します。キーはこのコンテンツタイプでフィールドを識別するための任意の名前を指定します。ここでは、'info_link' を指定しています。 'type' には fields.php で定義されているフィールドタイプ名(link)を指定します。

このように利用したいフィールドタイプを指定すると、コンテンツ編集画面に該当フィールドの入力部品が表示されてデータを登録できるようになります。 登録されたデータはテンプレートで次のように記述すると出力されます。

{{ field('info_link') }}

field() 関数の引数の 'info_link' はページコンテンツ設定ファイルで指定したフィールド名を指定します。

カスタムフィールド設定

カスタムフィールドの設定ファイルは system/config/fields.php です。この設定ファイルに定義したフィールドは各コンテンツ(ページ・コレクション・モジュール・カレンダー)で利用できます。 この設定ファイルはPHPの配列で定義されます。配列のキーがフィールドタイプ名になりその要素にいくつかの項目を定義できます。

設定ファイルのフォーマットと設定項目について説明します。
設定ファイルフォーマット:

<?php

return [
    'フィールドタイプ名' => [
        // フィールドタイプの設定項目
        'inputs' => [
            'インプット名' => [
                // インプットの設定項目
            ],
            // ... 以降のインプット設定
        ],
    ],
    // ... 以降のフィールドタイプ設定
];

フィールドタイプの設定項目:

項目 説明
label リンクリスト 入力画面で項目名を表示する際のラベルとして使われる。
required_label 1 フィールドラベルに「必須」を表示したい場合は 1 を指定します。
※ 2.0.1で追加された機能です。
input_template content 入力テンプレートを指定します。
output_template link_list 出力テンプレートを指定します。
inputs インプット(入力部品)設定を列挙します。
container 1 コンテナフィールドの場合は 1 を指定します。
fields
['link']
コンテナフィールドの場合に、コンテナに配置できるフィールドタイプ名を指定します。
preview_input text プレビュー時に出力部品を囲う要素のdata-id属性を指定する。出力テンプレートで field_data_id() を指定している場合はこの項目は不要です。
preview_tag div プレビュー時に出力部品を囲う要素を指定する。省略した場合のデフォルトは span になります。
wrap_div 1 デフォルトでは、コンテナフィールドは子フィールドの内容をそのまま出力します。 子フィールドがフレーズコンテンツ(インライン要素)の場合にはブロックが縦にきれいに並ばない場合があります。 この対策としてコンテナフィールドの子フィールドとして出力される場合だけ、フィールドを div 要素で囲いたい場合はこの設定項目に 1 を指定します。

インプット(inputs)の設定項目:

項目 説明
label リンク文字列 入力部品ラベル。バリデーションエラーが発生した場合はこのラベルが表示されます。
rule required バリデーションルールを |(パイプ記号)区切りで列挙できます。
value リンク 入力部品の初期値を指定できます。
options
[
    '' => 'なし',
    'lead' => 'リード',
],
セレクトボックスやラジオボタンなどの選択肢を列挙します。
attr
[
    'rows' => '10',
    'placeholder' => 'ここに複数行のテキストを入力してください。',
],
入力要素(input, select, textarea)の属性を指定します。 ここで指定された属性は、入力テンプレートで input_attr 関数を使うことで、追加の属性を出力することができます。
format json リスト(順序なし・あり)やテーブルフィールドのように、編集画面で入力部品数が増減するフィールドの場合は、値に「json」を指定します。

設定例

    'link' => [ // フィールドタイプ名
        'label' => 'リンク',
        'inputs' => [
            'href' => [
                'label' => 'URL',
                'rule' => '',
                'value' => '',
            ],
            'text' => [
                'label' => 'リンク文字列',
                'rule' => '',
                'value' => 'リンク',
            ],
        ],
    ],

カスタムフィールドテンプレート

カスタムフィールドそれぞれに入力テンプレートと出力テンプレートを持ちます。

入力テンプレートは、コンテンツ編集画面でinput要素などの入力部品を表示するために使われます。
例:

<div class="form-group row">
  <label class="col-xl-3 form-control-label" for="{{ input_id('text') }}">{{ field.label }}</label>
  <div class="col-xl-9">
    <input type="text" id="{{ input_id('text') }}" name="{{ input_name('text') }}" class="form-control"
           value="{{ form.field('text') }}" placeholder="">
    {{ form.error(input_id('text'))|raw }}
  </div>
</div>

出力テンプレートは、公開ページでカスタムフィールドの内容を出力するために使われます。
例:

{{ field.text }}

フィールドの出力テンプレートに割り当てられる変数:

変数名 説明
fieldName フィールド名(例;main_image)が格納されます。 フィールドタイプ名ではありません。コンテンツ設定の fields 項目直下のキー名が該当します。
field フィールドに登録された値を配列で保持します。フィールド設定の inputs で src というキー名で定義した場合は {{ field.src }} という記述で出力することができます。
config フィールドの設定値の配列です。fileds.php で定義した内容をコンテンツ設定(pages.php, collections.php, modules.php, calendars.php)で上書きした内容を保持します。

基本的には入出力テンプレートはフィールド毎に用意しますが、他のフィールド名を指定すると他のフィールドの入出力テンプレートを利用することができます。 そのため、入力部品が同じで出力だけ変えたい場合には出力テンプレートだけを作成すれば良いということになります。

入出力テンプレートはサイトテーマの inputs, outputs ディレクトリに保存します。 デフォルトで用意されるフィールドは cms テーマ(public/themes/cms/views/)の inputs, outputs ディレクトリに用意されています。 ただし、cms テーマは製品側のファイルのため、それらのファイルを書き換えても製品をアップデートしたタイミングで変更した内容が消えてしまいます。 この内容を変更したい場合は、同名のファイルをサイトテーマ側に配置することで優先して利用される仕組みです。

テンプレートが選択される順序は次になります。
linksフィールドの出力テンプレートの例:

順序 output_template設定 サイトテーマ内のテンプレートファイル パス
1. あり(my_links) あり public/themes/site/views/outputs/my_links.twig
2. あり(my_links) 無し public/themes/cms/views/outputs/my_links.twig
3. 無し あり public/themes/site/views/outputs/links.twig
4. 無し 無し public/themes/cms/views/outputs/links.twig

※ 入力テンプレートの場合は output(s) を input(s) に読み替えてください。
※ 上記の「site」は、cms.php の theme 設定に「site」を指定している場合の例になります。

独自項目とカスタムフィールド設定の上書き

フィールド設定では、規定されていない独自の項目を定義することができます。
imageフィールドで class 項目を定義する例。(system/config/fields.php)

'image' => [
    'label' => '画像',
    // ... 省略
    'class' => 'img-fluid',
],

フィールド設定の項目は config 変数に格納されて、フィールドの出力テンプレートに渡されます。次のように {{ config.class }} という記述で出力することができます。(例:themes/cms/views/outputs/image.twig)

{% if field.src %}
  <img src="{{ field.src|resize(field.resize) }}" class="{{ config.class }}" alt="{{ field.alt }}" {{ field_data_id('src') }}>
{% endif %}

コンテンツタイプ設定(ページ・コレクション・モジュール・カレンダー)ではフィールドの定義を上書きすることができます。 次は、カスタムフィールド設定(system/config/fields.php)で定義した image フィールドを type に指定しています。label, class はこのコンテンツ設定で上書きするために指定しています。

'left_image' => [
    'label' => '左ボックス画像',
    'type' => 'image',
    'class' => 'img-fluid img-thumbnail',
],

独自カスタムフィールドを用意する

デフォルトで用意されているカスタムフィールドとは別に、独自にカスタムフィールドを定義して利用することができます。 独自にカスタムフィールドを定義すると、任意の入力項目を設けたり、公開サイトのデザインに合わせた出力に対応することができます。

フィールド設定ファイルに独自フィールドの定義を追加して、入出力テンプレートを作成すれば独自カスタムフィールドを用意することができます。 独自に用意するカスタムフィールドはデフォルトのカスタムフィールドと同じ仕組みで動作するので、デフォルトのカスタムフィールドのつくりが参考になります。

textareaフィールドを元に特定のクラスが指定されたdiv要素を出力する独自カスタムフィールドを定義する例を示します。 fields.php の textarea フィールドをコピーして独自のフィールドタイプ名とラベルとインプットテンプレートを指定します。

    'lead_text' => [
        'label' => 'リード文',
        'input_template' => 'textarea',
        'inputs' => [
            'textarea' => [
                'label' => 'リード文',
                'rule' => '',
                'value' => '',
            ],
        ],
    ],

input_template に textarea を指定すると、textareaフィールド用の入力テンプレートを利用できるので、別途用意する必要はありません。

出力テンプレートを作成します。
public/site/views/outputs/lead_text.twig

<div class="lead" {{ field_data_id('textarea') }}>
{{ field.textarea|nl2br }}
</div>

この例では入力テンプレートはtextarea用を流用したので、設定の定義と出力テンプレートを準備するだけで独自のカスタムフィールドを作成できました。

コンテナフィールド

カスタムフィールドの1つの種類にコンテナフィールドがあります。 コンテナフィールドは他のフィールドをブロックとして配置できるコンテナを持ちます。

コンテナフィールドの設定例:

    'content' => [
        'label' => 'コンテンツ',
        'container' => 1,
        'fields' => [
            'p_class',
            'text',
            'textarea',
            'heading',
            'card',
            'richtext',
            'image',
            'ul',
            'ol',
            'table_2',
            'html',
            'module',
        ],
    ],

フィールドタイプ設定で container 項目に 1 を指定したフィールドがコンテナフィールドになります。 fields 項目にそのコンテナフィールドで利用できるフィールドタイプを列挙します。

入力テンプレートではコンテナ領域を表示します。出力テンプレートではコンテナ内の子フィールドを順番に出力します。 テンプレートのつくりはコンテナフィールドではない他のフィールドとは異なりますが、デフォルトで用意されるコンテナフィールドのテンプレートを参考に独自のコンテナフィールドを作成することもできます。

入力テンプレートの例:

<div class="mb-3 block-field">
  <label class="col-xl-3 form-control-label" for="{{ input_id('title') }}">{{ field.label }}</label>
  <div class="block-container mb-2" data-container="{{ fieldName }}">
    {% for index, row in form.fieldContainer(fieldName) %}
      {% for childFieldName, childField in row %}
        {{ set_field(childFieldName, fieldName, index) }}
        {% set childFieldConfig = form.getChildField(childFieldName, fieldName) %}
        {% include input_template_path(childFieldName, childFieldConfig) ignore missing with {'field':childFieldConfig} %}
      {% endfor %}
    {% endfor %}
  </div>
  <div>
    {% for addFieldName, addField in field.fields %}
      <input type="button" class="btn btn-sm btn-outline-primary" value="{{ addField.label }}"
           data-add-filed-name="{{ addFieldName }}" data-filed-name="{{ fieldName }}">
    {% endfor %}
  </div>
</div>

出力テンプレートの例:

<div>
  {% for index, row in field %}
    {% for childFieldName, childField in row %}
      <div>
        {{ child_field(childFieldName, index, fieldName) }}
      </div>
    {% endfor %}
  {% endfor %}
</div>