MVC パラダイムでは、 ビュー はモデルのプレゼンテーションを管理します。
ビューはユーザが見て、対話するインタフェースです。 ウェブアプリケーショ ンにおいて、これは歴史的に HTML インタフェースです。 HTML は依然として ウェブアプリケーションのための代表的なインタフェースですが、新しいビュー オプションが急速に現れています。
それには Macromedia Flash や JSON 、それに XHTML, XML/XSL, WML, ウェブ サービスのような代替のマークアップ言語で表現されたビューがあります。ウェ ブアプリケーションが REST API の形式で特別なビューを提供して、プログラ ムにデータモデルを読み書きできるようにすることはますます一般的になって います。
より複雑な API は、データモデルに対するさらに異なる種類のビューである SOAP サービスを経由して全く容易に実装されます。
RDF (セマンティックウェブを支援するグラフベースの表現スキーム) の採用が 増えていることは、機械可読性に関して強い重み付けがなされるという展望を もたらします。
アプリケーションでこれらのインタフェースのすべてを扱うのはますます困難 になっています。 MVC の大きな利点の 1 つは、これらのインタフェースを作 成することがより簡単になり、多くの異なったビューをサポートして、それに よって広範囲なサービスを提供するウェブアプリの開発がより簡単になること です。
通常、ビューではどんな重要な処理も起こりません。 それは単にデータを出力 して、ユーザ (またはアプリケーション) がそのデータにアクセスするための 手段として機能します。このことは、オンラインストアであっても従業員リス トであっても変わりません。
テンプレートレンダリングエンジンは、ビューのプレゼンテーションに関する タスクを扱うための一般的な選択です。
処理されたテンプレートを返すために、コントローラはそれをレンダリングし て結果を返さなければなりません:
from helloworld.lib.base import BaseController, render
class HelloController(BaseController):
def sample(self):
return render('/sample.mako')
デフォルトの Mako テンプレートエンジンを使用すると、Mako は helloworld/templates ディレクトリから sample.mako とい うテンプレートファイルを検索します。(ここで、プロジェクトが ‘helloworld’ であると仮定します)
ここで使用された render() 関数は、実際には Pylons の render_mako() 関数のためにプロジェクトの base.py で定義された別名です。
オブジェクトをテンプレートに渡すために、 Pylons 標準の方法は、それらを コントローラ の中で tmpl_context オブジェ クト (それはコントローラとテンプレートの中ではデフォルトで c という別 名にエイリアスされています) に追加することです:
import logging
from pylons import request, response, session, tmpl_context as c
from pylons.controllers.util import abort, redirect_to
from helloworld.lib.base import BaseController, render
log = logging.getLogger(__name__)
class HelloController(BaseController):
def index(self):
c.name = "Fred Smith"
return render('/sample.mako')
テンプレートで変数を使用します:
Hi there ${c.name}!
tmpl_context オブジェクトはあらゆるリクエストの始めに作成されま す。それはデフォルトで AttribSafeContextObj クラ スのインスタンスです。このクラスは属性安全なオブジェクトです。つまり、 存在 しない 属性へのアクセスは AttributeError エラーを投げる 代わりに 空文字列を返します。
これはデフォルトとして機能するので、テンプレートで使用するには便利です。
Hi there ${c.name}
これは c.name が設定されていないときにも動作し、厳格な ContextObj コンテキストオブジェクトを使用したとき よりも少し短く書くことができます。
tmpl_context オブジェクトの厳格なバージョンに切り替えるには、 config/environment.py で (config.init_app の後に) 以下を追加し ます:
config['pylons.strict_c'] = True
一般的なオブジェクトに簡単にアクセスできるように、デフォルトですべての テンプレートの中で参照できるいくつかの変数があります。テンプレートのグ ローバルスコープに存在する利用可能な名前に関する完全リストは以下の通り です:
新しい Pylons プロジェクトは、プロジェクトの config/environment.py の中でテンプレートエンジンがセットアップ された状態で開始します。このセクションでは、 Mako テンプレート検索オブ ジェクトを作成して、それをテンプレートレンダリング関数で使用するために app_globals オブジェクトに取り付けます。
# these imports are at the top
from mako.lookup import TemplateLookup
from pylons.error import handle_mako_error
# this section is inside the load_environment function
# Create the Mako TemplateLookup, with the default auto-escaping
config['pylons.app_globals'].mako_lookup = TemplateLookup(
directories=paths['templates'],
error_handler=handle_mako_error,
module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
input_encoding='utf-8', default_filters=['escape'],
imports=['from webhelpers.html import escape'])
テンプレートエンジンは config/environment.py で構成されて render 関数によって使用されるので、追加のテンプレートエンジンや、単一の テンプレートエンジンの異なる設定をセットアップするのも trivial です。し かし、追加のテンプレートエンジンオブジェクトを利用するためには、カスタ ムな render 関数がしばしば必要になるでしょう。
admin に対して別のテンプレートディレクトリを使い、通常のテンプレートディ レクトリに fall back する追加の Mako テンプレートローダーの例:
# Add the additional path for the admin template
paths = dict(root=root,
controllers=os.path.join(root, 'controllers'),
static_files=os.path.join(root, 'public'),
templates=[os.path.join(root, 'templates')],
admintemplates=[os.path.join(root, 'admintemplates'),
os.path.join(root, 'templates')])
config['pylons.app_globals'].mako_admin_lookup = TemplateLookup(
directories=paths['admin_templates'],
error_handler=handle_mako_error,
module_directory=os.path.join(app_conf['cache_dir'], 'admintemplates'),
input_encoding='utf-8', default_filters=['escape'],
imports=['from webhelpers.html import escape'])
それは追加のテンプレート検索インスタンスを加えます。次にそれを利用す る カスタム render 関数 が必要です:
Pylons が提供する render_mako() 関数との唯一の 違いは、 mako_lookup の代わりに mako_admin_lookup をデフォルトで使 用することです。
カスタム render 関数を書くことで、 (例えば Genshi でデフォルトの render_genshi() の機能性を越えるような) テンプ レートエンジンの特定の特徴にアクセスしたり、テンプレートエンジンの追加 サポートを加えることができます。
キャッシュ機能を簡単に使用できるようにするとともに、テンプレートの中で 有用な共通の Pylons グローバル変数を簡単にインクルードできるようにする、 render 関数とともに使用する 2 つのヘルパー関数が提供されています。 pylons_globals() と cached_template() 関数も使うことができ ます。
一般に、カスタム render 関数はプロジェクトの lib/ ディレクトリの中 (おそらく base.py) に置かれます。
これはプロジェクトの lib/base.py で見られるような Genshi render 関 数のサンプルです。それは結果を文字列に完全にレンダリングせず、また c を使う代わりにテンプレートのグローバルな名前空間の中で使用で きる辞書が渡されると仮定します。そして、レンダリングされた文字列の代わ りに Genshi のストリームを返します。
from pylons.templating import pylons_globals
def render(template_name, tmpl_vars):
# First, get the globals
globs = pylons_globals()
# Update the passed in vars with the globals
tmpl_vars.update(globs)
# Grab a template reference
template = globs['app_globals'].genshi_loader.load(template_name)
# Render the template
return template.generate(**tmpl_vars)
pylons_globals() 関数を使うと、 config/environment.py の中でテンプレートエンジンが取り付けられ た app_globals オブジェクトを受け取るのが簡単になります。
Changed in version 0.9.7: 0.9.7 より以前は、すべてのテンプレートが ‘Buffet’ と呼ばれる層を通 して扱われていました。Buffet では、どんなカスタマイズも追加の plugin モジュールがインストールされる必要があるため、この層はしばし ばテンプレートエンジンのカスタマイズを難しくしました。Pylons 0.9.7 は現在、 Buffet プラグイン層の使用を非推奨 (deprecated) としています。
See also
pylons.templating - Pylons テンプレート API
テンプレートライブラリは ビュー を扱い、モデルを提示します。それはブ ラウザに送られる (X)HTML コード、 CSS 、 および Javascript を生成します。 (このセクションの例では、プロジェクトルートは ``myapp`` です)
動的なウェブコンテンツを生成するテンプレートは myapp/templates に保存 され、静的なファイルは myapp/public に保存されます。
その両方がサーバルートから serve されます。 名前の衝突があれば、静的 なファイルが優先的に serve されます
myapp/templates に base.mako というファイルを作成してください。そし て、以下のように編集してください:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
${self.head_tags()}
</head>
<body>
${self.body()}
</body>
</html>
上の非常に基本的なベーステンプレートを Mako によってレンダリングされる すべてのページで使用することができます。これはアプリケーションに一貫し た外観を与えるのに役立ちます。
myapp/templates に my_action.mako という名前の別のファイルを作成し てください。そして、以下のように編集してください:
<%inherit file="/base.mako" />
<%def name="head_tags()">
<!-- add some head tags here -->
</%def>
<h1>My Controller</h1>
<p>Lorem ipsum dolor ...</p>
このファイルは base.mako によって呼ばれる関数を定義します。
すべてのアプリケーションページが単一のファイル (この場合 base.mako) を参照するなら、アプリケーションの一貫した印象をより簡単に達成できます。
コントローラのアクションでは、 return() 値として以下を使用してくださ い。
return render('/my_action.mako')
さあ、アクションを実行しましょう。通常ブラウザで http://localhost:5000/my_controller/my_action のようなページを訪問 することになります。ブラウザで View Source を選択すると、以下の出力が 明らかになるでしょう:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<!-- add some head tags here -->
</head>
<body>
<h1>My Controller</h1>
<p>Lorem ipsum dolor ...</p>
</body>
</html>