ステップ・バイ・ステップで Craft CMS を使って質問と答えをやり取りできるサービスを作ってみるシリーズのステップ7です。引き続きテンプレートを実装します。
こんにちは。この記事は「Craft CMS Advent Calendar 2021」22日目の記事です。
Craft CMS を使って質問と答えをやり取りできるサービスをステップ・バイ・ステップで作ってみるという企画をやっていて、今日はその7日目です。
前回の STEP 6 でトップページのテンプレートを実装しましたので、さらに実装を進めていきます。
その前に、現状のテンプレートだと、ログインセッションが切れると下図のようなエラーがでます。
このエラーは「null
の id
にアクセスできません」ということで、つまり currentUser.id
の currentUser
が null
なので id
が取れませんよ、という意味です。currentUser
はログイン中のユーザー情報が入ってくるので、ログインセッションが切れてしまっているのでこれが null
になっているわけです。
これについては追って実装しますので、今は一度管理画面にログインして実装を進めましょう。
今日の記事を書くに当たって、「プロジェクト」というフィールドを一つ追加しました。もしまだ作成されていない場合は STEP 2 を再確認して「プロジェクト」フィールドを追加しておいてください(今日の記事の中では使いません)。
今回はプロジェクトの個別ページを実装します。ここには質問と答えをリストアップしたいと思います。
まず、templates
ディレクトリに _pages
というディレクトリを作成し、その中に下記のテンプレートを書いた project.twig
を作成します。
{#=======================================================
#
# Extends, Imports
#
=======================================================#}
{% extends '_layout/base-page.twig' %}
{#=======================================================
#
# ページ固有変数・処理
#
=======================================================#}
{#=======================================================
#
# 共通変数
#
=======================================================#}
{#=======================================================
#
# 出力
#
=======================================================#}
{% block contentBody %}
<h1>{{ entry.title }}</h1>
{% endblock %}
この状態で、先日作成したトップページでプロジェクトをクリックすると下図のようにプロジェクト名が表示されます。
もしここで entry
が定義されていないといった類いのエラーが出たら、管理画面で「設定 > セクション > プロジェクト」に移動し「サイト設定」のところの「テンプレート」が「_pages/project
」になっているか確認してください。
次にプロジェクトに「質問・答え」を紐付けるため、「エントリ > プロジェクト」から各プロジェクトの編集画面に移動します。
紐付ける「質問」を選択します。ここでは質問だけを紐付ければOKです。
質問が紐付いたのを確認して保存します。
これで質問がプロジェクトに紐付きました。
続いて、project.twig を下記のように変更し、プロジェクトに紐付いた質問を表示します。
{#=======================================================
#
# Extends, Imports
#
=======================================================#}
{% extends '_layout/base-page.twig' %}
{#=======================================================
#
# ページ固有変数・処理
#
=======================================================#}
{% set comments = entry.comments.all() %}
{#=======================================================
#
# 共通変数
#
=======================================================#}
{#=======================================================
#
# 出力
#
=======================================================#}
{% block contentBody %}
<h1>{{ entry.title }}</h1>
{% if comments|length %}
<ul>
{% for comment in comments %}
<li><a href="{{ comment.url }}">{{ comment.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
具体的には、「ページ固有変数・処理」のところに下記の1行を追加し、プロジェクトの「質問・答え」フィールドで選択した質問を取得しています。
{% set comments = entry.comments.all() %}
そして、「出力」の「block contentBody
」のところでループでそれを取り出します。
{% block contentBody %}
<h1>{{ entry.title }}</h1>
{% if comments|length %}
<ul>
{% for comment in comments %}
<li><a href="{{ comment.url }}">{{ comment.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
これで下図のように質問が表示されました。
最後に質問に紐付いた答えを表示させます。contentBody
の中身を下記のように変更します。
{% block contentBody %}
<h1>{{ entry.title }}</h1>
{% if comments|length %}
<ul>
{% for comment in comments %}
{% if comment.commentTitle %}
<li>{{ comment.commentTitle }}</li>
{% endif %}
<li>{{ comment.body }}</li>
{% set descendants = craft.entries().descendantOf(comment).all() %}
{% for descendant in descendants %}
<li style="margin-left: {{ descendant.level - 1 }}em;">{{ descendant.body }}</li>
{% endfor %}
{% endfor %}
</ul>
{% endif %}
{% endblock %}
ポイントは {% set descendants = craft.entries().descendantOf(comment).all() %}
のところです。
これは、ループ中の comment
に紐付いている子孫(descendant
)をすべて取得する、という意味です。
見た目で分かりやすいように style="margin-left: {{ descendant.level - 1 }}em;"
を付けて孫の答えたちはインデントしています。
今日はここまでにしましょう。