【Craft 3 サイト構築の基本】インデックスページのテンプレート作成(実装編)

これは Craft CMS Advent Calendar 2018 25日目の記事です。
連載「サンプル制作で覚える Craft 3 サイト構築の基本」として、「準備編」に引き続き、インデックスページのテンプレートを作成します。

ここでは、次の作業を行います。

  1. 対象テンプレートの確認
  2. 基本コードの定義
  3. 「サービス」インデックスページの作成
  4. 「ワークス」インデックスページの作成
  5. 「トップページ」の作成

工程ごとの差分データは「素材データ専用リポジトリ vol-17 ブランチ」にコミットしてあります。

作業にあたって

今回の作成対象である「トップページ」「サービス(インデックス)」「ワークス(インデックス)」セクションのエントリは空の状態です。詳細ページの場合と同様、表示を確認する前にダミーの情報を登録するか、「Craft 3 のデモコンテンツをインストールしてみよう」で紹介している公式デモサイトを別途ローカル環境に用意し、当該ページのテキストをコピーするなどしてください。

対象テンプレートの確認

ここで修正対象となるテンプレートは次の通りです。

templates
├── index.html
├── services/
│   └── _index.html
└── work/
    └── _index.html

それぞれ シングル タイプのセクションのテンプレートとして定義されているもので、ファイル自体は作成済みの想定です。

基本コードの定義

body のクラスをセット

「トップページ」のインデックステンプレートに変数をセットし、定義済みスタイルの適用に必要なクラスが body タグに追加されるようにします。【参考コミット】

コーディングデータからメインコンテンツ部分のコピー

「サービス」「ワークス」「トップページ」それぞれのインデックステンプレート main ブロックに、メインコンテンツ部分のマークアップをコピーします。【参考コミット】

「サービス」インデックスページの作成

「大見出し」「本文」フィールドの出力

「大見出し」と「本文」フィールドは {% if %} タグで入力値がある場合のみ出力します。【参考コミット】

「サービス」セクションに含まれるエントリの出力

「サービス」一覧のマークアップは、エントリ1件分を残して削除します。【参考コミット】

{# 「サービス」セクションのエントリを取得 #}
{% set serviceEntries = craft.entries.section('services').all() %}

{# 「サービス」セクションのエントリ一覧 #}
{% for serviceEntry in serviceEntries %}
  (中略)
{% endfor %}

「サービス」セクションのエントリを取得して、ループ処理で必要なデータを出力しましょう。【参考コミット】

「ワークス」インデックスページの作成

「大見出し」「本文」フィールドの出力

ここでも「大見出し」と「本文」フィールドは {% if %} タグで入力値がある場合のみ出力します。【参考コミット】

異なるセクションでもフィールド構成が同じであればテンプレートの Twig コードを共通化できるため、この部分をモジュール化してもよいでしょう。

「ワークス」セクションに含まれるエントリの出力

「ワークス」一覧では最新1件のみマークアップが異なり、さらにそれ以降のすべてのエントリはコンテナ要素で囲まれるよう分岐処理が必要なため、loop 関連の変数を利用します。【参考コミット】

 {# 「ワークス」セクションのエントリを取得 #}
{% set workEntries = craft.entries.section('work').all() %}

{# 「ワークス」セクションのエントリ一覧 #}
{% for workEntry in workEntries %}
  {% if loop.first %}
    {# ループの最初のみ出力 #}
    (中略)
  {% else %}
    {# ループのインデックス番号が2なら、コンテナ要素の開始タグを出力 #}
    {% if loop.index == 2 %}
      <div class="flex">
    {% endif %}

      {# ループの最初以外で出力 #}
      (中略)

    {# ループの最後なら、コンテナ要素の閉じタグを出力 #}
    {% if loop.last %}
      </div><!-- /.flex -->
    {% endif %}
  {% endif %}
{% endfor %}

なお、{% for %} タグ内で利用できる変数については、Twig の公式リファレンス「The loop variable」を参照してください。

分岐処理を記述できたら、エントリごとのデータ出力に関するコードを定義します。【参考コミット】

「トップページ」の作成

「ヒーロー画像」フィールドの出力

「ヒーロー画像」フィールドにセットされたアセットを取得して、出力します。【参考コミット】

{# 「ヒーロー画像」フィールドを取得 #}
{% set heroImage = entry.heroImage.one() %}

{# 「ヒーロー画像」がセットされている場合のみ出力 #}
{% if heroImage %}
  <img src="{{ heroImage.getUrl({ height: 916 }) }}" alt="{{ heroImage.title }}"/>
{% endif %}

ここでは、テンプレート出力に heroImage.getUrl({ height: 916 }) で「高さ」の上限を指定しつつサムネイル画像を生成しています。

「ワークス」一覧を最新3件のみ出力

判別しやすいよ「ワークス」一覧のマークアップはエントリ1件分を残して削除しておきます。【参考コミット】

{# 「ワークス」セクションのエントリ最新3件を取得 #}
{% set workEntries = craft.entries.section('work').limit(3).all() %}

エントリは最新3件のみ取得できればよいため、limit(3) とします。あとは、従来通り出力したい内容を定義していきましょう。【参考コミット】

「お客様の声」フィールドを出力

ブロックが含まれない可能性がある行列フィールド「お客様の声」は、length フィルタを利用して判別処理を加えます。【参考コミット】

{# 「お客様の声」がセットされている場合のみ出力 #}
{% if entry.testimonials | length %}
  <section id="testimonials">
    <div class="flex">
      {# ブロックのループ処理 #}
      {% for block in entry.testimonials.all() %}
        (中略)
      {% endfor %}
    </div><!-- /.flex -->
  </section><!-- /#testimonials -->
{% endif %}

「クライアントロゴ」フィールドを出力

「クライアントロゴ」フィールドは複数選択可能な「アセット」フィールドのため、ループ処理を定義します。【参考コミット】

{# 「クライアントロゴ」フィールドを取得 #}
{% set clientLogos = entry.clientLogos.all() %}

{# 「クライアントロゴ」フィールドのアセット一覧 #}
{% for clientLogo in clientLogos %}
  <li>
    <img src="{{ clientLogo.getUrl() }}" alt="{{ clientLogo.title }}"/>
  </li>
{% endfor %}

ここでは clientLogo.getUrl() の形でサムネイル画像を生成していないため、Craft 3 の管理画面でロゴ画像を登録する時点でサイズを揃えておく必要があります。

まとめ

ここではインデックスページにあたる「サービス」「ワークス」「トップページ」のテンプレートを作成してみました。
データの取得分岐(存在チェック)出力(フォーマット) の組み合わせにより、ページごとのコンテンツ構成が変わっていても柔軟にカスタマイズできるが魅力ですね。

なお、ほぼひと通り解説したつもりなので連載「サンプル制作で覚える Craft 3 サイト構築の基本」はこれにて一旦終了とします。ご不明点などありましたら @BUN までお気軽にお声がけください。

comments powered by Disqus