作成中...
http://www.symfony-project.org/jobeet/1_2/Doctrine/ja/04
この節では、symfonyの2番目のORMであるDoctrineにおける内容を記載しております。
第4日目のチュートリアルが完了するまでの目安
3時間~10時間
第4日目は、画面系のMVCモデルの解説とテンプレートの解説になります。
フレームワークの重要な要素であるため、さらっと流さず、じっくりと考えて試したいですね。
symfonyは、フロントコントローラタイプのMVCデザインパターンで構成されています。

symfonyの画面表示の方法は、グローバルテンプレートと呼ばれるレイアウトファイル[layout.php]を
ページの雛形にして、
ページ個別のテンプレートを組み合わせて、全体のページを作ります。

イメージファイルとcss(カスケードスタイルシート)をダウンロードします。
ダウンロードしたファイルを、[web/images/] と [web/css/]ディレクトリに配置します。
デフォルトのテンプレートを置き換えて、以下のURLにアクセスしてみました。
http://jobeet.localhost/frontend_dev.php/job
カスケードスタイルシート(CSS)は、[<?php include_stylesheets() ?>]の部分で読み出されます。
このメソッドは、デフォルトでViewレイヤーのアプリケーション設定ファイルである[view.yml]の設定により、読み出します。
デフォルトのview.ymlは以下のようになっています。
default:
http_metas:
content-type: text/html
metas:
#title: symfony project
#description: symfony project
#keywords: symfony, project
#language: en
#robots: index, follow
stylesheets: [main.css]
javascripts: []
has_layout: on
layout: layout
CSSの読み出しは、以下のように階層化されています。
下記のような設定をすれば、テンプレートからスタイルシートを読み出すことができます。
<?php use_stylesheet('main.css') ?>
JavaScriptも同様で、テンプレート内から
<?php use_javascript(’test.js') ?>
のように設定すれば、テンプレートからJavaScriptを読み出すことができます。
もちろん、yml設定ファイルから読み出すことも可能です。
アクションは、クラスメソッドで表されます。
自動で作成された [/apps/frontend/modules/job/actions/actions.class.php]を見てみます。
class jobActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
$this->jobeet_job_list = JobeetJobPeer::doSelect(new Criteria());
}
: (省略)
executeIndexメソッドは、JobeetJobPeerモデルクラスのdoSelectメソッドを呼び出して、jobeet_job_listという名の配列を取得します。
つまり、Jobeet_jobを単純にSELECTした結果をjobeet_job_listという名の配列として取り出すわけですね。
doSelect()メソッドの実体は、jobeet/lib/model/om/BaseJobeetJobPeer.phpに、
public static function doSelect(Criteria $criteria, PropelPDO $con = null)として定義されています。
new Criteria()は、ある意味呪文的なものとして考えました。なぜなら、引数が要求しているから。
jobeet_job_listは、どこに定義されているのでしょうか。
grepで探してみたら、jobeet/apps/frontend/modules/job/templates/indexSuccess.php に定義されていました。
[jobeet_job_list]は、jobeet_jobエンティティのSELECTした結果が格納されています。
jobeet/apps/frontend/modules/job/templates/indexSuccess.php は、Viewクラスにカテゴライズされているので、
チュートリアルでは、「自動的にテンプレート(View)に渡されます。」と書かれているのだと思います。
Properlが作るモデルを理解しないと、ぱっとは理解できませんね。
自動的にコントローラからビューにデータを渡している内容以外に、データを渡したい場合、以下のように
コントローラ(アクション)にプロパティを追加します。
public function executeFooBar(sfWebRequest $request)
{
$this->foo = 'bar';
$this->bar = array('bar', 'baz');
}
テンプレートは、Viewにカテゴライズされる部分です。
自動的に作成される[jobeet/apps/frontend/modules/job/templates/indexSuccess.php]は、次のとおりになります。
<h1>Job List</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>Category</th>
<th>Type</th>
<th>Company</th>
<th>Logo</th>
<th>Url</th>
<th>Position</th>
<th>Location</th>
<th>Description</th>
<th>How to apply</th>
<th>Token</th>
<th>Is public</th>
<th>Is activated</th>
<th>Email</th>
<th>Expires at</th>
<th>Created at</th>
<th>Updated at</th>
</tr>
</thead>
<tbody>
<?php foreach ($jobeet_job_list as $jobeet_job): ?>
<tr>
<td><a href="<?php echo url_for('job/show?id='.$jobeet_job->getId()) ?>"><?php echo $jobeet_job->getId() ?></a></td>
<td><?php echo $jobeet_job->getCategoryId() ?></td>
<td><?php echo $jobeet_job->getType() ?></td>
<td><?php echo $jobeet_job->getCompany() ?></td>
<td><?php echo $jobeet_job->getLogo() ?></td>
<td><?php echo $jobeet_job->getUrl() ?></td>
<td><?php echo $jobeet_job->getPosition() ?></td>
<td><?php echo $jobeet_job->getLocation() ?></td>
<td><?php echo $jobeet_job->getDescription() ?></td>
<td><?php echo $jobeet_job->getHowToApply() ?></td>
<td><?php echo $jobeet_job->getToken() ?></td>
<td><?php echo $jobeet_job->getIsPublic() ?></td>
<td><?php echo $jobeet_job->getIsActivated() ?></td>
<td><?php echo $jobeet_job->getEmail() ?></td>
<td><?php echo $jobeet_job->getExpiresAt() ?></td>
<td><?php echo $jobeet_job->getCreatedAt() ?></td>
<td><?php echo $jobeet_job->getUpdatedAt() ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<a href="<?php echo url_for('job/new') ?>">New</a>
このままだと、余計な部分も表示されしまっているので、それを削るのと同時に、若干見た目を変えて見ましょう。
[jobeet/apps/frontend/modules/job/templates/indexSuccess.php]を以下のように変更します。
<?php use_stylesheet('jobs.css') ?>
<div id="jobs">
<table class="jobs">
<?php foreach ($jobeet_job_list as $i => $job): ?>
<tr class="<?php echo fmod($i, 2) ? 'even' : 'odd' ?>">
<td class="location"><?php echo $job->getLocation() ?></td>
<td class="position">
<a href="<?php echo url_for('job/show?id='.$job->getId()) ?>">
<?php echo $job->getPosition() ?>
</a>
</td>
<td class="company"><?php echo $job->getCompany() ?></td>
</tr>
<?php endforeach; ?>
</table>
</div>
以下のURLにアクセスしてみます。
http://jobeet.localhost/frontend_dev.php/job
見た目が大きく変わりました。
jobeet_job_listに、JOBEET_JOBスキーマの読み出し結果が入っています。
$jobに1レコードが入ります。
even と oddで、CSSクラスを変えることによりスプレッドを見やすくしています。
getLocation()とgetPosition()とgetCompany()により、就業場所、業務、企業名のみ表示するようになっています。
[showSuccess.php]を以下のように修正します。
<?php use_stylesheet('job.css') ?>
<?php use_helper('Text') ?>
<div id="job">
<h1><?php echo $job->getCompany() ?></h1>
<h2><?php echo $job->getLocation() ?></h2>
<h3>
<?php echo $job->getPosition() ?>
<small> - <?php echo $job->getType() ?></small>
</h3>
<?php if ($job->getLogo()): ?>
<div class="logo">
<a href="<?php echo $job->getUrl() ?>">
<img src="/uploads/jobs/<?php echo $job->getLogo() ?>"
alt="<?php echo $job->getCompany() ?> logo" />
</a>
</div>
<?php endif; ?>
<div class="description">
<?php echo simple_format_text($job->getDescription()) ?>
</div>
<h4>How to apply?</h4>
<p class="how_to_apply"><?php echo $job->getHowToApply() ?></p>
<div class="meta">
<small>posted on <?php echo $job->getCreatedAt('m/d/Y') ?></small>
</div>
<div style="padding: 20px 0">
<a href="<?php echo url_for('job/edit?id='.$job->getId()) ?>">
Edit
</a>
</div>
</div>
次に、アクションクラスの[executeShow]メソッドを以下のように書き換えます。
public function executeShow(sfWebRequest $request)
{
$this->job = JobeetJobPeer::retrieveByPk($request->getParameter('id'));
$this->forward404Unless($this->job);
}
修正を確認してみます。
以下のURLにアクセスしてみます。
http://jobeet.localhost/frontend_dev.php/job
レイアウトのほかで、固定的に表示したいコンテンツがある場合、スロットを使用します。

動的にタイトルを変更するために、スロットを追加します。
<title>
<?php if (!include_slot('title')): ?>
Jobeet - Your best job board
<?php endif; ?>
</title>
レイアウトPHPに、スロット埋め込み用のコードを埋め込みます。
また、テンプレートの部分に、スロットヘルパーを定義します。
<?php slot('title') ?>
<?php echo sprintf('%s is looking for a %s', $job->getCompany(), $job->getPosition()) ?>
<?php end_slot(); ?>