一日目にfrontendアプリケーションを作成しましたが、このアプリケーションの具体的な実装はapps/frontendディレクトリに書いていくことになります。
まずapps/frontend/templates/layout.phpを見てみます。
このファイルは、index.phpおよびfrontend_dev.phpを呼び出したときに必ず呼び出されるテンプレートになります。
全体的なレイアウトをここで設定し、後ほど書いていく個別テンプレートは全部$sf_contentに入る、という形になります。
チュートリアルのfrontend/templates/layout.phpをコピペします。
また、CSSと画像ファイルをそれぞれweb/css/とweb/images/に設置します。
http://symfony.localhost/frontend_dev.php/job
を開いてみると、いきなりグラフィカルな画面になっています。
なに?解説が手抜き?気にするな。
さて、ここからようやくSymfonyの気持ち悪い機能を繙いていくことになります。
テンプレの各所にinclude_stylesheets()とかurl_for('job/index')といった見慣れない関数が鎮座しています。
これらはSymfonyで定義される色々な機能を呼び出すヘルパーです。
で、最初にも書きましたがSymfonyにはこういった機能の一覧/検索がないんですよね。
おかげで延々パッケージやチュートリアル、リファレンスを探し回される羽目になります。
include_stylesheets()はapps/frontend/config/view.ymlからstylesheetsハッシュを拾ってきて<link rel>タグにして表示します。
include_javascripts()は同様にjavascriptsハッシュを<script>タグで表示します。
上書きする前に存在したinclude_http_metas()やinclude_title()等を含め、これらのインクルード関数はAssetヘルパーに属しているのですが、そのことを先に知っていないとAPIリファンレンスで調べることができないという。
apps/frontend/config/view.ymlはフロントエンドを経由する全てのテンプレートに適用されますが、一部のモジュールのみ、一部のビューのみに設定を行うこともできます。
apps/frontend/modules/job/config/view.ymlを設定することでjobモジュールに、さらにその中でindexSuccess:とビューを指定することでビュー単位に指定できます。
アクションを触ってみます。
http://symfony.localhost/frontend_dev.php/job
はhttp://symfony.localhost/frontend_dev.php/job/indexと解釈されます。
そしてweb/frontend_dev.phpからapps/frontend/modules/job/actions/actions.class.phpが呼び出され、その中のexecuteIndexアクションが実行されることになります。
アクションで実行されている内容は実質わずか一行です。
$this->jobeet_job_list = Doctrine::getTable('JobeetJob')->createQuery('a')->execute();
簡単に言うとDoctrineを使用してJobeetJobを呼び出し、全レコードを取得して$this->jobeet_job_listに投入する、という内容です。
さて、executeIndex()はテンプレートへの変数のセットとかテンプレートの呼び出しといったことを一切行っていません。
どうなっているのでしょうか。
何も書かなかった場合、アクション名と同じテンプレートが自動的に呼び出されます。
今回のexecuteIndex()の場合は、テンプレートとしてapps/frontend/modules/job/templates/indexSuccess.phpが適用されます。
さらにその結果がapps/frontend/templates/layout.phpの$sf_contentに入ります。
で、apps/frontend/modules/job/templates/indexSuccess.phpを見てみると、いきなり
foreach ($jobeet_job_list as $jobeet_job)
とか書いてあります。
実は、アクションで$this->hogeに入れた内容はテンプレートからいきなり$hogeで呼ぶことができるのです。
なんとなく怖い。
$jobeet_job_listにはDoctrineの巨大なオブジェクトが入っていますが、イテレータを実装しているので配列として扱うことができます。
各行を表す$jobeet_jobに対し、$jobeet_job->getId()または$jobeet_job->idでjobeet_job.idを取得することができます。
Doctrineの便利なところは$jobeet_job->JobeetCategory->getName()とリレーションを辿っていけるところですが今回はそれは無いようです。
現在はどう見ても不要なカラムまで全部表示しているので、必要な部分だけを表示するようにします。
まあ例によってチュートリアルのapps/frontend/modules/job/templates/indexSuccess.phpをコピペするだけですが。
詳細画面に移動するとURLが次のようになります。
http://symfony.localhost/frontend_dev.php/job/show/id/2
jobアクションのexecuteShowが実行されます。
$request->getParameter('id')で/id/2の値、即ち2が取得されます。
Doctrine::getTable('JobeetJob')->find(2);
とすると主キーが2であるカラムを一件拾ってきます。
非常にわかりにくいので、
Doctrine::getTable('JobeetJob')->findOneById(2);
と引いてくるカラムと件数を明記した方がいいでしょう。
返ってくる値はどちらも同じです。
このfindBy系のメソッドは例によってスキーマから自動作成されており、findByEmailでjobeet_job.emailが一致したのを全件検索、findOneByTypeでjobeet_job.typeが一致する先頭一件を取得といった書き方ができます。
executeShowアクションから使用されるテンプレートはapps/frontend/modules/job/templates/showSuccess.phpです。
デフォルトでは全てのカラムが表示されていますので、これまたチュートリアルをコピペしましょう。
何故かテンプレート内のjobeet_jobオブジェクト名が$jobに変わっているので、アクションもそちらに合わせて変更します。
テンプレートの頭にuse_helper('Text')というのが入っていますが、これを記述することでヘルパーの一種であるTextHelperが使用できるようになります。
AssetHelperは何も書かずに使えたのに何故?
さあ?
use_helperを書かずに使用できるのはAssetHelper、CacheHelper、EscapingHelper、HelperHelper、PartialHelper、TagHelper、UrlHelperです。
何この不平等。
ていうかここらへんのことAPIリファレンスの何処にも書かれていないように見えるんですが。
次にスロットの説明が出てきます。
スロットはPartialHelperに含まれるのでuse_helper宣言をせずにいきなり使用できます。
スロットは出力制御みたいなもので、単に変数に値を代入するものです。
1
2
3
|
slot('title');
print('あいうえお');
end_slot();
|
とすると、slot()からend_slot()までで挟まれた部分が全て変数titleに入ります。
1
|
include_slot('title');
|
とすることでその内容を表示することができます。
次に404です。
アクション内で$this->forward404Unless($hoge)とした場合、$hoge==falseであれば404ページを表示します。
変なリクエストとかを簡単にはじけるので便利。
そのうち404ページのカスタマイズ方法も出てくるかと思いますが現状不明。
最後にリクエストとレスポンスメソッド一覧表が出てきますが、何故こんな大事なものをチュートリアルの片隅に載せるんだ。
sfWebResponseの使い方は此処には書いてありませんが、getResponseメソッドで呼ぶことができます。
$this->getResponse()->setCookie('hoge','fuga');
といったふうに使用します。
>本日のチュートリアルの最初の方でview.ymlとテンプレートの両方でスタイルシートやJavaScriptを管理するやり方を見ました。
>結局2つのテクニックともレスポンスオブジェクトのaddStylesheet()とaddJavascript()メソッドを使います。
唐突に出てきていきなりなんのこっちゃ?という感じですが、最初の方で出てきたinclude_javascripts()はその中で
$this->getResponse()->addJavascript()
的なことをやっているよ、という意味です。
中を見る限りなんかちょっと違うようなかんじだったのですがまあいいか。
Symfonyの記事一覧