はなゐろぐ

主に技術関係の覚え書きです。

Timberを使ってWordpressテーマをTwigで書く

2020年5月22日

Twig とは

Twigとは、PHP製のテンプレートエンジン。

<span class="foo"><?php echo $hoge; ?></span>

PHPだとこう書くところを、こんな風に簡潔に表記できます。

<span class="foo">{{ hoge }}</span>

はじめに

Timber とは

Timberとは、WordpressテーマをTwigで書けるようにするプラグイン。プラグインとしてでなく、Composerで依存パッケージとして取り込むこともできます。

こんな感じでかなり簡潔に書けます。これは、Timber側で投稿データをテンプレート(Twig)ファイルに渡してくれているからですね。もちろん、独自に値を渡すこともできます。

<?php
$thumb_id = get_post_thumbnail_id($post->ID);
$url = wp_get_attachment_url($thumb_id);
?>
<img src="<?php echo $url; ?>" alt="Thumbnail for <?php echo $post->post_title; ?>" />
<img src="{{ post.thumbnail.src }}" alt="Thumbnail for Timber" />

Timber を導入するメリット

単純にコードがシンプルで読みやすくなることです。個人的に、ロジック(いわゆるPHPの)部分をいちいち<?php ?>で囲うのが面倒ですし、囲み忘れによるエラーにもうんざりします。個人的に、Twigの機能である継承(extend)がDreamweaverライクに共通部分を管理できて良い感じ。

また、ロジックとテンプレートを分割できることも大きいです。通常の書き方だとロジックがテンプレートの中に入っており、コーディングの心得がない人にはとっつきづらいですよね。コードを間違えてしまいエラーになり、よりいっそう苦手意識が増幅したり…。そういった人にも、Twigを使うことで学習コストを低くおさえつつコーディング作業に入ってもらうことができます。

導入

インストールする

プラグインとしてインストールする

他のプラグインと同様、WordPress.orgからダウンロードして、wp-content/pluginsにディレクトリをコピーすればよいです。

プラグインとしてインストールした場合、テーマを使っている限り(当たり前ですが)有効化しないとエラーになりますのでご注意を。

Composer でインストールする

Composerでもインストールできます。テーマでのみ使うので、テーマにインストールするのが自然です。

$ composer require timber/timber

インストールが終わったら、テーマから読み込ませます。

functions.php
<?php
require_once( __DIR__ . '/vendor/autoload.php' );
$timber = new Timber\Timber();

スターターテーマをインストールする

必須ではないですが、これをベースに書き始めるのが圧倒的に楽です。

starter-themeをダウンロードしてwp-content/themesにコピー。有効化し、正常に動作することを確認できたら完了です。

ディレクトリ構造

starter-themeから少し変更した、私が普段使っているディレクトリ構造を紹介します。

mytheme/
  templates/ # テンプレートファイルをここにまとめて格納
    layouts/ # レイアウトファイル
      base.twig # 全ページで共通のコード(headなど)
      ...
    partials/ # パーツファイル
      footer.twig
      gnav.twig
      header.twig
      ...
    404.twig
    archive.twig
    index.twig
    page.twig
    single.twig
    ...
  vendor/ # Composerでインストールしたライブラリ
  404.php # ここから下はロジック
  archive.php
  functions.php
  index.php
  page.php
  single.php
  composer.json # その他
  composer.lock
  screenshot.png
  style.css

リストに入っているファイルは最低限なので、必要に応じて足します。例えば固定ページ専用テンプレートならpage-{slug}.twig、アーカイブ専用テンプレートならarchive-{slug}.twigといった風に、テンプレートファイルを増やすだけです。

テーマの書き方

だいたいのことは公式ドキュメントを参照すれば解決するのですが、記事一覧ページを例に紹介します。

まずarchive.phpで記事を取得します(スターターテーマには最初から書かれています)。

archive.php
<?php
$context['posts'] = new Timber\PostQuery();

archive.phpで定義した$context['posts']が、archive.twigへpostsとして渡されます。このように$contextに要素を追加することで、ロジックからテンプレートへ値を渡すことができます。添字がそのまま変数になります。

archive.twig
{% for post in posts %}
  {% include 'article.twig' %}
{% endfor %}

ループの中でさらにarticle.twigが呼ばれます。こうして切り出しておくことで、よくあるトップページのお知らせとパーツを使い回すことができます。

article.twig
<article class="article-news">
  {% if post.get_thumbnail %}
    {% set thumbnail = post.thumbnail.src('thumbnail') %}
  {% else %}
    {% set thumbnail = theme.link~"/assets/images/common/noimage.png" %}
  {% endif %}
  <div class="article-news__thumbnail">
    <img src="{{ thumbnail }}">
  </div>
  <div class="article-news__body">
    <date class="article-news__date">{{ post.post_date|date('Y年m月d日(D)') }}</date>
    {% if post.category %}
      <span class="article-news__category">{{ post.category }}</span>
    {% endif %}
    <h3 class="article-news__title">{{ post.title }}</h3>
    <p class="article-news__excerpt">{{ post.preview.length(120).read_more('') }}</p>
    <a href="{{ post.link }}" class="readmore">more</a>
  </div>
</article>

サムネイルサイズや日付フォーマットなど案件によって変わる部分については、関数やフィルタを使って整形もできます。

おわりに

日本語の記事が少なかったので最初は少し手こずりましたが、慣れればサクサクコーディングできて楽です。お試しあれ。