読者です 読者をやめる 読者になる 読者になる

FitzgeraldでTwigを使う、など

Dev PHP

Fitzgeraldのビューは素のPHPだけど、これをTwigに置き換える方法。

両方とも触り始めたばかりなので、間違ってるかも。

Twigのファイルはlibに置いた。

lib/fitzgerald.phpのTemplate#render()メソッドを、以下のように書き換える。

<?php

  public function render($locals) {
    require_once $this->root . 'lib/Twig/Autoloader.php';
    Twig_Autoloader::register();

    $loader = new Twig_Loader_Filesystem($this->root . 'views');
    $twig = new Twig_Environment($loader, array(
      /* オプションはご自由に */
      'cache'       => $this->root . 'tmp/cache',
      'auto_reload' => true
    ));

    $template = $twig->loadTemplate($this->fileName . '.html');
    return $template->render($locals);
  }

app.php

<?php

include('lib/fitzgerald.php');

class Application extends Fitzgerald {
  public function greeting($name) {
    $greeting = 'Hello';
    return $this->render('greeting', compact('greeting', 'name'));
  }
}

$app = new Application();
$app->get('/:name', 'greeting');
$app->run();

views/greeting.html

<h1>{{ greeting|e }}, {{ name|e }}</h1>


これで、'/Hoge'にアクセスすると、'Hello, Hoge'と表示される。
app.phpからの呼び出し($this->render())はそのままでいけた。

クエリー文字列対応

Fitzgeraldは、どうやらクエリー文字列(?name=Hoge)を使えないようになっていてあまりよろしくないので、
無理矢理対応するようにしてみた。

lib/fitzgerald.phpのUrl#__construct()に1行追加する。

<?php

  public function __construct($httpMethod, $url, $conditions=array(), $mountPoint) {
    $requestMethod = $_SERVER['REQUEST_METHOD'];
    $requestUri = str_replace($mountPoint, '', $_SERVER['REQUEST_URI']);
    /* ↓を追加 */
    $requestUri = str_replace('?' . $_SERVER["QUERY_STRING"], '', $requestUri);

Twigからセッション/リクエストオブジェクトにアクセスする

Fitzgeraldはテンプレートにsessionとrequestを渡していて、素のPHPテンプレートだと

<?= $request->name ?>

でアクセスできる。でもTwigで

{{ request.name }}

としても表示されない。


リクエストオブジェクト(RequestWrapper)は、以下のようにマジックメソッドを使っている。

<?php

class RequestWrapper {
  public function __get($key) {
    global $_REQUEST;
    return isset($_REQUEST[$key]) ? $_REQUEST[$key] : null;
  }

  public function __set($key, $value) {
    global $_REQUEST;
    $_REQUEST[$key] = $value;
    return $value;
  }
}

Twig for Template Designersの"Variables"の項を見ると、プロパティやメソッドの有無をチェックしていて、マジックメソッドはだめなのか、と思っていた。


その後、Recipesの"Using dynamic Object Properties"の項で、「マジックメソッド使うなら__isset()を実装しろ」と書いてあったので、RequestWrapperに、

<?php

  public function __isset($key) {
    global $_REQUEST;
    return isset($_REQUEST[$key]);
  }

を追加したら、Twigでアクセスできるようになった。