これは Craft CMS Advent Calendar 2017 8日目の記事です。
今回は備忘録を兼ねて、日付や数値の範囲を指定しつつ Twig テンプレートでエントリを絞り込む方法について、ご紹介します。
投稿日で絞り込む
投稿日で絞り込むには、2つの方法があります。
after / before を利用する場合
サンプルとして {{ now }}
で取得できる日付を利用して、1年前に投稿されたエントリを取得してみます。
{# 1年前の日付をセット #}
{% set targetDate = now | date_modify('-1 year') %}
{# 1年前の翌日をセット #}
{% set targetNextDate = targetDate | date_modify('+1 day') %}
{# after / before で日付を絞り込み #}
{% for entry in craft.entries.after(targetDate).before(targetNextDate).find() %}
{% if loop.first %}<ul>{% endif %}
<li>{{ entry.title }}</li>
{% if loop.last %}</ul>{% endif %}
{% endfor %}
now | date_modify('-1 year')
で1年前の日付を取得し、変数にセットしたものを利用して targetDate | date_modify('+1 day')
でその翌日を取得します。
after
は指定日を含み before
は指定日を含まないため、1年前に投稿されたエントリだけを絞り込めます。
指定可能な日時の書式なども掲載されていますので、公式ドキュメントも参考にしてください。
craft.entries | Templating Reference | Craft CMS
https://craftcms.com/docs/templating/craft.entries#after
postDate を利用する場合
こちらは、2017年12月1日から今日までのエントリを絞り込んでみます。
{% for entry in craft.entries.postDate('and', '>= 2017-12-01', '< 2017-12-09').find() %}
{% if loop.first %}<ul>{% endif %}
<li>{{ entry.title }}</li>
{% if loop.last %}</ul>{% endif %}
{% endfor %}
ポイントとなる .postDate('and', '>= 2017-12-01', '< 2017-12-09')
の日付指定は .after('2017-12-01').before('2017-12-09')
と記述した場合と同じ結果になります。
数値で絞り込む
「数字」タイプのフィールドの場合、先の postDate
と同様の記述で範囲指定が可能です。
下記サンプルでは num_price
というハンドル名のフィールドが 1000〜9999 の値を持つエントリを絞り込みます。
{% for entry in craft.entries.num_price('and', '>= 1000', '< 10000').find() %}
{% if loop.first %}<ul>{% endif %}
<li>{{ entry.title }}</li>
{% if loop.last %}</ul>{% endif %}
{% endfor %}
他にも .num_price('>= 1000')
や.num_price('= 1000')
のように単独の条件を指定することもできます。
年や月で絞り込む
最後に、年別や月別アーカイブの一覧をサンプルにしてみます。
{# すべてのエントリを取得 #}
{% set allEntries = craft.entries.limit(null) %}
{# 年ごとにグループ化したエントリをループ処理 #}
{% for year, yearlyEntries in allEntries | group("postDate.year") %}
<h2><a href="/?year={{ year }}">{{ year }}</a></h2>
<ul>
{# 月ごとにグループ化したエントリをループ処理 #}
{% for month, monthlyEntries in yearlyEntries | reverse | group("postDate | date('m')") %}
<li><a href="/?year={{ year }}&month={{ month }}">{{ month | replace('/^0/', '') }}月</a></li>
{% endfor %}
</ul>
{% endfor %}
allEntries | group("postDate.year")
では、投稿年をキー・年ごとのエントリを値とするグループ化を行なっています。
このループ処理内で yearlyEntries | reverse | group("postDate | date('m')")
とすることで、さらに月ごとにグループ化します。このとき、デフォルトでは月の出力が逆(12月が先頭)になってしまうため reverse
フィルタを利用しています。
なお、公式ドキュメントではアーカイブをページ分割する方法なども紹介されていますので、あわせてご覧ください。
Creating an “Archive” Page for Entries | Support | Craft CMS
https://craftcms.com/support/entry-archive
まとめ
書き方を覚えれば、比較的柔軟に絞り込みができるのはやはり便利ですね。
また便利そうな記述方法を思いついたら、共有します。