テンプレート

Pyramid は、 2 つのテンプレートエンジン Mako および Chameleon の アダプターを含んでいます。 Mako は Pylons のデフォルトエンジンなので 馴染みがあるでしょう。他のエンジンに対するサードパーティのアダプターが 利用可能です: “pyramid_jinja2” (Jinja2 アダプター)、 “pyramid_chameleon_gensi” (部分的な Genshi エミュレーター) など。

Mako 設定

Pylons で Mako を使用するために、設定の中でテンプレート検索パスを 指定しなければなりません:

[app:main]
...
mako.directories = pyramidapp:templates

これによって renderer="/mytemplate.mak" のような相対的なテンプレート パスや renderer="/mytemplate.mak" のような疑似 URL パスが使えるように なります。さらに、これによってテンプレートが他のテンプレートから継承したり、 他のテンプレートをインポートしたり、他のテンプレートをインクルードしたり することが可能になります。この設定なしでは、レンダラー引数は asset スペック構文でなければならず、テンプレートは他のテンプレートを起動する ことができないでしょう。

“mako.” 接頭辞を持つすべての設定は Mako の TemplateLookup コンストラクタに渡されます。例えば、

mako.strict_undefined = true
mako.imports =
     from mypackage import myfilter
mako.filters = myfilter
mako.module_directory = %(here)s/data/templates
mako.preprocessor = mypackage.mako_preprocessor

”.mak” または ”.mako” で終わるテンプレートファイル名は Mako レンダラー に送られます。 ”.html” のような他の拡張子が使いたければ、 main 関数に これを入れてください:

config.add_renderer(".html", "pyramid.mako_templating.renderer_factory")

Mako レンダラーが正確にどのように実装されているかに関してさらなる質問が あれば、ソースを見るのが一番です: pyramid.mako_templating 。 どの引数の値が何を引き起こすかを確認するために、ソースコードと Mako ドキュメンテーションを照合することができます。

注意: Beacon sessons (訳注: Beaker session のこと?) を設定していない アプリケーションで “mako.strict_undefined” を true にセットしたら、 それは debug ツールバーを壊しました。ツールバーテンプレートには “% if” によって保護されていない sloppy (不注意、だらしない) な プレースホルダーがいくつかあるのかもしれません。

注意2: テンプレートパスの代わりに asset スペックを渡すことができる はずですが、私はそれを動作させることができませんでした。

Chameleon

Chameleon は Zope に由来する XML ベースのテンプレート言語です。 それには Genshi とのいくつかの類似点があります。そのファイル名拡張子 は .pt (「ページテンプレート」) です。

Chameleon の利点:

  • XML ベースの構文。
  • テンプレートは well-formed な XHTML でなければなりません。これは出力 が well-formed であることを示唆します (ただし保証はされません)。 いずれかの変数プレースホルダーが “structure” とマークされる場合、 テンプレートに無効な XML を挿入することが可能です。
  • Pyramid の中で国際化サポートがしっかりしています。
  • 速度は Mako と同じくらい高速です (XML テンプレート言語にも関わらず)。
  • プレースホルダー構文 “${varname or expression}” は Chameleon, Mako, Genshi で共通です。
  • Chameleon には非 XML 入力を受け付けるテキストモードがあります。 ただし、 “${varname}” を除き制御構造はすべて失われます。

Chameleon の欠点:

  • XML ベースの構文。
  • ファイル名は相対パスではなく asset スペック構文でなければなりません: renderer="mypackage:templates/foo.pt", renderer="templates/foo.pt" 。 ラッパー view_config デコレータを書かない限り “templates/” 接頭辞を 省略することはできません。
  • テンプレートのルックアップはありません。したがって、テンプレートを あらかじめ変数にロードしておかない限り、あるテンプレートを別の テンプレートの内部から起動することはできません。
  • テンプレートが well-formed な XML でなければ、見た目の良い、少なくとも ユーザが何らかの内容を読むことができるページがブラウザに表示される 代わりに、ユーザは無条件に「内部サーバーエラー」を得るでしょう。
  • Mako と Pyramid が動作するすべてのプラットフォームでは動作しません (CPython および Google App Engine のみ)。

レンダラーグローバル変数

レンダラーがテンプレートを起動する場合は常に、テンプレートネームスペース にはビューが返した辞書に加えて以下のシステム変数のすべての変数が含まれて います:

request, req

現在のリクエスト。

view

ビューインスタンス (クラスベースのビューの場合) または関数 (関数ベースのビューの場合)。インスタンス属性を直接読むことができます: view.foo

context

コンテキスト (request.context と同じ)。 (Mako にはこの名前を 持った内蔵の変数があるので Mako において可視ではありません; 代わりに request.context を使用します。)

renderer_name

完全修飾されたレンダラー名。たとえば ”zzz:templates/foo.mako” 。

renderer_info

属性 name, package, type を持つオブジェクト。

Akhet デモは、 helpers モジュール h 、URL ジェネレーター url 、 セッション変数 session などのような他の変数をすべてのテンプレートに 注入する方法を示しています。

サイトテンプレート

ほとんどのサイトは、すべてのページが同じルックアンドフィール (ヘッダー、 サイドバー、フッター) を持つことを保証するためにページテンプレートと 結合したサイトテンプレートを使用するでしょう。Mako の継承は、サイト テンプレートからページテンプレートを継承することを簡単にします。これは 非常に単純なサイトテンプレートです:

<!DOCTYPE html>
<html>
  <head>
    <title>My Application</title>
  </head>
  <body>

<!-- *** BEGIN page content *** -->
${self.body()}
<!-- *** END page content ***-->

  </body>
</html>

... また、それを使用するページテンプレートは:

<%inherit file="/site.html" />

<p>
  Welcome to <strong>${project}</strong>, an application ...
</p>

より精巧な例が Akhet デモの中にあります。