symfony 1.1は異なるフォーマットとmime-typeのネイティブのサポート機能を導入します。
このことは同じモデルとコントローラはリクエストされたフォーマットに基づいて異なるテンプレートを持つことを意味します。
デフォルトのフォーマットはHTMLのままですが、symfonyはfactories.yml
ファイルで定義されたいくつかのフォーマットをそのままサポートします:
request: class: sfWebRequest param: formats: txt: text/plain js: [application/javascript, application/x-javascript, text/javascript] css: text/css json: [application/json, application/x-json] xml: [text/xml, application/xml, application/x-xml] rdf: application/rdf+xml atom: application/atom+xml
それぞれのフォーマットは1つもしくは複数のmime-typeに関連づけされます。
これらのmime-typeはHTTPのAccept
ヘッダーを解析することでリクエストされたフォーマットを自動的に決定するために使われます。
ブラウザーをとおしてデータを利用可能なものにしてWebサービスとして公開したい場合にこれはとても重宝します。
レスポンスのフォーマットを変更するには、下記のようにWebサービスのクライアントがAccept
ヘッダーを変更することだけが必要です:
$ curl -H "Accept: application/xml" http://ws.example.com/api/article # データのXML表現を取得するため $ curl -H "Accept: application/json" http://ws.example.com/api/article # データのJSON表現を取得するため
異なるフォーマットをサポートすることは異なるテンプレートを作ることと同じぐらい簡単です。
Webサービスがapi/article
アクションによって管理されることを前提とします。
HTML、XMLとJSONフォーマットをサポートするために、apps/frontend/modules/api/templates
の中で作らなければならないテンプレートの一覧です:
- articleSuccess.php
- articleSuccess.xml.php
- articleSuccess.json.php
デフォルトでは、symfonyは、フォーマットに従ってContent-Type
レスポンスの変更を行い、HTMLではないフォーマットに対しては、レイアウトを無効にします。
パーシャルとレイアウトでさえもリクエストされたフォーマットに基づいて異なることがあります。
たとえば、list
パーシャルをテンプレートの中に含める場合、ロードされたパーシャルの名前は現在のフォーマットに依存します:
- _list.php
- _list.xml.php
- _list.json.php
別の例を考えてみましょう。
スタイルシートもしくはJavaScriptファイルをすぐに作りたいとします。
これらの事例においてHTTPのAccept
ヘッダーは常に当てにできないので、ルーティングルールのsf_format
変数を利用することでフォーマットの種類を強制できます。
動的なスタイルシート用のルートを作る方法は次のとおりです:
css1: url: /css/dynamic1.css param: { module: css, action: dynamic, sf_format: css }
1つのアクションに対して複数のフォーマットを許可するためにURLパターンの中でsf_format
変数を使うこともできます:
api_article: url: /api/article.:sf_format param: { module: api, action: article } requirements: sf_format: (?:html|xml|json)
たいていの場合、新しいフォーマットをサポートするためにアクションのコードを変更する必要はありません; しかしフォーマットのために何か特別なことを本当に行う必要がある場合、現在のフォーマットを取得してそれに応じてふるまうために$request->getRequestFormat()
を呼び出すことができます。
Ok、お待ちかねのお話です!
iPhone用に最適化されたWebサイトを作りたい場合を考えてみましょう。
デフォルトではiphone
フォーマットは存在しませんが設定するのはかなり簡単です。
最初に、iPhoneから由来するリクエストを決定する方法が必要です。
User-Agent
ヘッダーがMobile
とSafari
の単語を含む場合、ブラウザがiPhoneであることを安全に推測できます。request.filter_parameters
イベント用のリスナーを登録することでこのロジックをProjectConfiguration
クラスに設置できます:
// config/ProjectConfiguration.class.php class ProjectConfiguration extends sfProjectConfiguration { public function setup() { // ... $this->dispatcher->connect('request.filter_parameters', array($this, 'filterRequestParameters')); } public function filterRequestParameters(sfEvent $event, $parameters) { $request = $event->getSubject(); if (preg_match('#Mobile/.+Safari#i', $request->getHttpHeader('User-Agent'))) { $request->setRequestFormat('iphone'); } return $parameters; } }
これで、リクエストが来るたびにfilterParameters()
メソッドが呼び出され、ブラウザーがiPhoneの場合にリクエストフォーマットがiphone
に変更されます。
これでお終いです!
iPhoneから来るすべてのリクエストは*Success.php
テンプレートの代わりに*Success.iphone.php
テンプレートを使います。
iPhoneのために特別なスタイルシートもしくはJavaScriptファイルを使いたい場合(たとえばiui libraryを使う場合)、view.configure_format
をリスニングすることでビューを設定することもできます:
class ProjectConfiguration extends sfProjectConfiguration { public function setup() { // ... $this->dispatcher->connect('view.configure_format', array($this, 'configureIPhoneFormat')); } public function configureIPhoneFormat(sfEvent $event) { if ('iphone' == $event['format']) { // CSS、JavaScriptもしくは望むものを追加する } } }
symfony 1.1の新しいフォーマットのサポートのおかげで、Webサービス、APIもしくはiPhoneを開発することは簡単になりました。新しいフォーマットをサポートする機能を追加する作業は新しいテンプレートの一式を作る作業と同じくらい簡単です。
This work is licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License license.