(これはHTML v2のドキュメントです。以前のTwig v1を使用するHTML v1も利用可能です。)

HTML

インストール

HTML表示のためにcomposerでTwig v2のモジュールをインストールします。

composer require madapaja/twig-module ^2.0

次にhtmlコンテキストファイルsrc/Module/HtmlModule.phpを用意してTwigModuleをインストールします。

namespace MyVendor\MyPackage\Module;

use BEAR\AppMeta\AppMeta;
use Madapaja\TwigModule\TwigModule;
use Ray\Di\AbstractModule;

class HtmlModule extends AbstractModule
{
    protected function configure()
    {
        $this->install(new TwigModule);
    }
}

bootstrap/web.phppublic/index.phpのコンテキストを変更してhtmlを有効にします。

$context = 'cli-html-app'; // 'htm-app'

テンプレート

1つのリソースクラスに1つのテンプレートファイルがリソースクラスファイルと同じsrctemplatesフォルダに必要です。 例えばsrc/Page/Index.phpにはsrc/Resource/Page/Index.html.twigvar/templates/Page/Index.html.twigが必要です。

テンプレートにリソースの bodyがアサインされます。

例)

src/Page/Index.php

class Index extend ResourceObject
{
    public $body = [
        ['greeting' => 'Hello BEAR.Sunday']
    ];
}

src/Page/Index.twig.php または var/templates/Page/Index.twig.php

<h1>{{ greeting }}</h1>

出力

php bootstrap/web.php get /
200 OK
content-type: text/html; charset=utf-8

<h1>Hello BEAR.Sunday</h1>

リソースのアサイン

リソースクラスのプロパティを参照するにはリソース全体がアサインされる_roを参照します。

例)

Todos.php

class Todos extend ResourceObject
{
    public $code = 200;

    public $text = [
        'name' => 'BEAR';
    ];    

    public $body = [
        ['title' => 'run']
    ];
}

Todos.html.twig

{{ _ro.code }} // 200
{{ _ro.text.name }} // 'BEAR'
{% for todo in _ro.body %}
  {{ todo.title }} // 'run'
{% endfor %}

ビューの階層構造

リソースクラス単位でビューを持つ事ができます。構造を良く表し、キャッシュもリソース単位で行われるので効率的です。

例)app://self/todosを読み込むpage://self/index

app://self/todos

class Todos extends ResourceObject
{
    use AuraSqlInject;
    use QueryLocatorInject;

    public function onGet() : ResourceObject
    {
        $this->body = $this->pdo->fetchAll($this->query['todos_list'])
        return $this;
    }
}
{% for todo in _ro.body %}
  {{ todo.title }}</td>
{% endfor %}

page://self/index

class Index extends ResourceObject
{
    /**
     * @Embed(rel="todos", src="app://self/todos")
     */
    public function onGet() : ResourceObject
    {
        return $this;
    }
}
{% extends 'layout/base.html.twig' %}
{% block content %}
  {{ todos|raw }}
{% endblock %}

拡張

TwigをaddExtension()メソッドで拡張する場合には、拡張を行うTwigのProviderクラスを用意しTwig_EnvironmentクラスにProvider束縛します。

use Ray\Di\Di\Named;
use Ray\Di\ProviderInterface;

class MyTwigProvider implements ProviderInterface
{
    private $twig;

    /**
     * @Named("original")
     */
    public function __construct(\Twig_Environment $twig)
    {
        // $twig is an original \Twig_Environment instance
        $this->twig = $twig;
    }

    public function get()
    {
        // Extending Twig
        $this->twig->addExtension(new MyTwigExtension());

        return $this->twig;
    }
}
class HtmlModule extends AbstractModule
{
    protected function configure()
    {
        $this->install(new TwigModule);
        $this->bind(\Twig_Environment::class)->toProvider(MyTwigProvider::class)->in(Scope::SINGLETON);
    }
}

モバイル

モバイルサイト専用のテンプレートを使用するためにはMobileTwigModuleを加えてインストールします。

class HtmlModule extends AbstractModule
{
    protected function configure()
    {
        $this->install(new TwigModule);
        $this->install(new MobileTwigModule);
    }
}

index.html.twigの代わりにIndex.mobile.twig存在すれば優先して使用されます。変更の必要なテンプレートだけを用意する事ができます。

カスタム設定

コンテンキストに応じてオプション等を設定したり、テンプレートのパスを追加する場合は@TwigPaths@TwigOptionsに設定値を束縛します。

注)キャッシュを常にvar/tmpフォルダに生成するので特にプロダクション用の設定などは特に必要ありません。

namespace MyVendor\MyPackage\Module;

use Madapaja\TwigModule\Annotation\TwigDebug;
use Madapaja\TwigModule\Annotation\TwigOptions;
use Madapaja\TwigModule\Annotation\TwigPaths;
use Madapaja\TwigModule\TwigModule;
use Ray\Di\AbstractModule;

class AppModule extends AbstractModule
{
    protected function configure()
    {
        $this->install(new TwigModule);

        // テンプレートパスの指定
        $appDir = dirname(dirname(__DIR__));
        $paths = [
            $appDir . '/src/Resource',
            $appDir . '/var/templates'
        ];
        $this->bind()->annotatedWith(TwigPaths::class)->toInstance($paths);

        // オプション
        // @see http://twig.sensiolabs.org/doc/api.html#environment-options
        $options = [
            'debug' => false,
            'cache' => $appDir . '/tmp'
        ];
        $this->bind()->annotatedWith(TwigOptions::class)->toInstance($options);
        
        // debugオプションのみを指定する場合
        $this->bind()->annotatedWith(TwigDebug::class)->toInstance(true);
    }
}