MTのテーマ設計手法をベースにCraft CMSのテンプレート作成を考えてみた

これは Craft CMS Advent Calendar 2017 18日目の記事です。

普段の業務は、Movable Typeの実装しかしていないのですがCraft CMSではどのように設計していくか考えていました。
なるべくMTテンプレートの考え方をそのまま使っていきたいと思っていました。

mt:SetVarTemplateはMacroで表現

MTでよく使うmt:SetVarTemplateと同じことをCraftでも実装するためにはMacroを使って表現します。
以下の例は単純なボタンモジュールを作ったときの例になります。

MTML(Movable Type)

汎用的に使うパーツ(HTML)をSetVarTemplateで定義してあげて、出力応じて値をいれておくようにしています。

  // template_component.mtml(テンプレートモジュールとして定義)
<mt:Ignore>ボタンのモジュール</mt:Ignore>
<mt:SetVarTemplate name="_base_button" key="button" note="ボタン">
<div class="button">
  <a class="button__link" href="<mt:Var name="_button_link" _default="/path/to/" />">
    <mt:Var name="_button_name" _default="指定なしのデフォルトのボタン名" />
  </a>
</div>
</mt:SetVarTemplate>
  // 出力側テンプレート(インデックステンプレート・アーカイブテンプレート etc)
<mt:Include module="component" parent="1" />
<mt:Var name="_base_button" key="button" _button_link="/path/" _button_name="ボタンの名前" note="_base_buttonを実行" />

Twig (Carft CMS)

Twigでは、Macroという関数を定義しておくことでmt:SetVarTemplateのような感覚で使うことができます。
component.htmlやcomponent.twigのように定義しているmacroをまとめておき出力したいテンプレートでimportして使うことできます。

  // component.html or component.twig
{% macro _base_button(_button_link, _button_name) %}
<div class="button">
  <a class="button__link" href="{{ _button_link | default('/path/to/') }}">
    {{ _button_name | default('指定なしのデフォルトのボタン名') }}
  </a>
</div>
{% endmacro %}
  // 出力側テンプレート
{% import 'component.html' as component %}
{{ component._base_button('/path/', 'ボタンの名前') }}

MTお決まりのConfigテンプレートモジュール

MTの実装では、サイトの設定や定数などをセットしてブログ間で使える値をテンプレートモジュールを作って構築します。(私の場合)
Craftでも同様のことをしておきたくなりますね。自分だけかもですが。。
mt:SetVarsのようなものを用意する例になります。

MTML(Movable Type)

以下のようなMTMLでSetVarsで必要な値をセットしておきます。
MTではblog_idやtitleやdescriptionなど汎用的に使う定数をセットして使用しています。

  // template_config.mtml(テンプレートモジュールとして定義)
<mt:Ignore>ボタンのモジュール</mt:Ignore>
<mt:SetVars>
dateformat=%Y.%m.%d
blogid_all=1,2,3
blogid_website=1
blogid_basename=0
base_title=ウェブサイトのタイトル
base_keywords=テスト,テスト,テスト,テスト,テスト,テスト
base_sitedomain=www.exsapmle.com
base_ogpimageurl=http/**/ogimage.png
regex_replace=/(http|https):\/\/.+?\//
</mt:SetVars>
  // 出力側テンプレート(インデックステンプレート・アーカイブテンプレート etc)
<mt:Include module="config" parent="1" />
<mt:Var name="base_sitedomain" />  // www.exsapmle.com

また、MTはテンプレートごとに同じ変数名(グローバル変数のため)を上書きすることができます。
configのテンプレートモジュールの読み込んだあとに再SetVarするとそれ以降は、再定義した変数になります。

グローバル汚染してしまう問題もあるのですが、うまく使えばテンプレートごとに値を変更して分岐させることができます。
以下は単純にbase_titleを上書きしてみた例になります。

  // 出力側テンプレート:ブログ(お知らせ)
<mt:Include module="config" parent="1" />
<mt:SetVars>
base_title=お知らせのタイトル
</mt:SetVars>
<mt:Var name="base_title" />  // お知らせのタイトル

Twig (Carft CMS)

Twigでも同様に変数をセットすることができます。
単体の変数にする場合は、{{ set hoge = ‘ほげの値です’ }} のような書き方ができます。
SetVarsのようにオブジェクトのように定義しておきたいですね。そういった場合は以下のような書き方になります。

  // default.html(親のテンプレート):defaultの値をすべて格納する
{%
  set default = {
    dateformat : '%Y.%m.%d',
    title: 'デフォルトのタイトル',
    description : 'デフォルトの説明文が入ります。'
  }
%}
{% include '_layouts/_partial/html_head.html' %}
{% block content %}
{% endblock %}
{% include '_layouts/_partial/script.html' %}
{% include '_layouts/_partial/html_foot.html' %}
  // _entry.html(出力で定義している変数)
{% extends "_layouts/default" %}
{% 
  set config = {
    title : '記事のタイトルが入ります。',
    description : 'サイトの説明文が入ります。サイトの説明文が入ります。サイトの説明文が入ります。サイトの説明文が入ります。'
  }
%}

configの値が無ければ、defaultで定義した変数をセットするような形の例になります。

  // headタグ内のtitleのイメージ(html_head.twig)
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>{{ config.title | default(default.title) }}</title>
  <meta name="description" content="{{ config.description | default(default.description) }}">
  <meta property="og:title" content="{{ config.title | default(default.title) }}">
</head>
<body>

Craft用のベーステンプレートを作っていきたい

単純な例での紹介になりますが、まだまだ実務での構築経験がないのでテンプレートの書き方などは手探りな感じです。 年明けくらいにはCraft用のベーステンプレートを作っておきたいーと思いながら軽い気持ちで作っていきたいと思います。

Author

札幌でフロントエンドエンジニアとして働いています。好きな音楽はSIAM SHADE!
SIAM SHADEの六人目のメンバーとして日々ロックを愛し続けている。
HTML,CSS,JavaScriptをベースにCMS構築が得意です。
HAMWORKS社員 https://ham.works