テンプレートエンジン - 1(基礎)

a-blog cmsのテンプレートエンジン

a-blog cmsは独自のテンプレートエンジンを備え、標準のGETモジュールはすべてこのテンプレートエンジンを通して実装されています。ここではそのTemplateクラスの使用方法を説明します。

Templateクラス

Templateクラスはテンプレートをもとに、与えられたデータに応じて情報を加工して出力します。

$Tpl = new Template($this->tpl);

$this->tpl

$this->tpl には、テンプレート上における、BEGIN_MODULE〜END_MODULEまでの間の文字列が自動で格納されています。

<html>
<body>
    <!-- BEGIN_MODULE Sample_UseTpl -->
    <!-- ここから -->
    <p>{hoge} and {fuga}</p>
    <!-- BEGIN foo --><p>{bar}</p><!-- END foo -->
    <!-- ここまでが$this->tplには入ってくる -->
    <!-- END_MODULE Sample_UseTpl -->
</body>
</html>

addメソッド

addメソッドは、ブロックや変数をテンプレートに加えるメソッドです。

  • ブロック: ある範囲を表示するためや、繰り返し(ループ)をする テンプレート要素
  • 変数: 動的に表示を変わってくるテンプレート要素

サンプル

// get module
$Tpl = new Template($this->tpl);

// ブロックの追加
$Tpl->add('notFound');

// 変数の追加
$Tpl->add(null [
  'hoge' => 'hello world.'
]);

// html
<h1>{hoge}</h1>

<!-- ブロックの追加がされていないと以下の表示はされない -->
<!-- BEGIN notFound -->404 Not Found<!-- END notFound -->

getメソッド

getメソッドは、加えられた情報をもとにテンプレート処理を解決し、その結果の文字列を取得するメソッドです。通常はreturnするときにそのまま呼び出します。

サンプル

function get()
{
  $Tpl = new Template($this->tpl);

  $Tpl->add('notFound');
  $Tpl->add(null, [
    'hoge' => 'hello world.'
  ]);

  return $Tpl->get();
}

ACMS_Correctorクラス (校正オプションの利用)

モジュールのテンプレート内で校正オプションを利用する場合は、ACMS_Correctorクラスのインスタンスを同時に渡します。 これにより以下のように変数に対して校正オプションを利用できるようになります。

サンプル

$Tpl = new Template($this->tpl, new ACMS_Corrector());

$Tpl->add(null, [
  'hoge' => date('Y-m-d H:i:s'),
]);

// html
<p>{hoge}[datetime('Y年m月d日 H時i分)]</p>

// 表示
<p>2017年01月01日 12時59分</p>

全体のサンプル(まとめ)

テンプレート(HTML形式)

<html>
<body>
    <!-- BEGIN_MODULE Sample_UseTpl -->
    <p>{hoge} and {fuga}</p>
    <!-- BEGIN foo --><p>{bar}</p><!-- END foo -->
    <!-- END_MODULE Sample_UseTpl -->
</body>
</html>

Sample_UseTplモジュール

<?php

namespace Acms\Custom\GET\Sample;

use ACMS_GET;
use Template;
use ACMS_Corrector;

/*
 * path: extension/acms/GET/Sample/UseTpl.php
 */
class UseTpl extends ACMS_GET
{
  function get()
  {
    // Templateクラス
    $Tpl  = new Template($this->tpl, new ACMS_Corrector());

    // <!-- BEGIN foo --> ~ <!-- END foo --> の中の {bar} にテキストを代入
    $Tpl->add('foo', array('bar' => 'fooブロックの中のbar変数'));

    // ブロックを介さない、モジュール直下の変数 {hoge} と {fuga} にテキストを代入
    $Tpl->add(null, [
      'hoge' => 'ほげ', 'fuga' => 'ふが'
    ]);

    // テンプレートを処理済みの文字列としてreturn
    return $Tpl->get();
  }
}

実行結果

<html>
<body>
    <p>ほげ and ふが</p>
    <p>fooブロックの中のbar変数</p>
</body>
</html>

テンプレートエンジン - 2(ループブロック、入れ子のブロック)

ブロック制御

前回はTemplateクラスのブロックと変数の制御について説明しました。今回はのようなループするブロックと、入れ子構造になっているブロックの出力について説明します。

ループの追加を行う

Templateクラスのaddメソッドは次のような引数を持ちます。

$Tpl->add( ブロック名(文字列), ブロック内変数( 連想配列 ) );

以下のようにaddメソッドで同じ名前のブロックを繰り返し追加することでループ構造を作ります。

テンプレート (HTML形式)

<html>
<body>
    <!-- BEGIN_MODULE Sample_Loop -->
    <ul>
        <!-- BEGIN data:loop -->
        <li>id : {id} {name} ( {kana} ) </li>
        <!-- END data:loop -->
    </ul>
    <!-- END_MODULE Sample_Loop -->
</body>
</html>

Sample_Loopモジュール

<?php

namespace Acms\Custom\GET\Sample;

use ACMS_GET;
use Template;
use ACMS_Corrector;

class Loop extends ACMS_GET
{
    function get()
    {
        $Tpl = new Template($this->tpl, new ACMS_Corrector());

        $loopData = array();
        $loopData[] = array(
            'id'       => '1',
            'name'     => '山田太郎',
            'kana'     => 'やまだたろう',
        );

        $loopData[] = array(
            'id'       => '2',
            'name'     => '鈴木次郎',
            'kana'     => 'すずきじろう',
        );

        $loopData[] = array(
            'id'       => '3',
            'name'     => '佐藤三郎',
            'kana'     => 'さとうさぶろう',
        );

        foreach ( $loopData as $loop ) {
            $Tpl->add('data:loop', $loop);
        }

        return $Tpl->get();
    }
}

実行結果

<html>
<body>
    <ul>
        <li>id : 1 山田太郎 ( やまだたろう )</li>
        <li>id : 2 鈴木次郎 ( すずきじろう )</li>
        <li>id : 3 佐藤三郎 ( さとうさぶろう )</li>
    </ul>
</body>
</html>

入れ子の順番

ブロックの追加は、入れ子の中の深い位置のブロック(子にあたるブロック)から順に追加します。ブロックを配列で表現して追加するときは、配列の先頭が追加する目標のブロック名であり、以降は親のブロック名をあらわすことに注意してください。

入れ子のテンプレート

<html>
<body>
<!-- BEGIN_MODULE Sample_Nest -->
    <!-- BEGIN year -->
        <!-- BEGIN month -->
            <!-- BEGIN day -->
            <!-- END day -->
        <!-- END month -->
    <!-- END year -->
<!-- END_MODULE Sample_Nest -->
</body>
</html>

Sample_Nestモジュール

<?php

namespace Acms\Custom\GET\Sample;

use ACMS_GET;
use Template;
use ACMS_Corrector;

class Nest extends ACMS_GET
{
    function get()
    {
        $Tpl     = new Template($this->tpl, new ACMS_Corrector());

        $Tpl->add( array('day', 'month', 'year') );

        $Tpl->add( array('month', 'year') );

        $Tpl->add( 'year' );

        return $Tpl->get();
    }
}

入れ子構造のループを追加する

ひとつのループの中で更に別のループがあるような入れ子型のループを作成します。以下のように、ブロック名の引数を配列にすることでループの中に別のループを追加できます。この入れ子型のブロックの追加はループに限らず共通です。

以下はカテゴリーのループ構造の中に、エントリーのループが加わる処理の例です。

    foreach ( $categories as $category ) {
        foreach ( $entries as $entry ) {
            // entry:loopを追加
            $Tpl->add(array('entry:loop', 'category:loop'), $entry);
        }
        // category:loopを追加
        $Tpl->add('category:loop', $category);
    }