Jobeetをやってみる 4日目
ControllerとViewの扱いを学ぶために以下のページを作成する
- jobsのリスト表示
- 新しいjobの作成
- 作成済のjobの更新
- jobの削除
JobeetのCSSとJavaScriptと画像ファイル
以下の場所からそれぞれ入手可能
- http://www.symfony-project.org/get/jobeet/images.zip
- web/images/ に保存
- http://www.symfony-project.org/get/jobeet/css.zip
- web/css/ に保存
- http://www.symfony-project.org/get/jobeet/favicon.ico
- web/ に保存
JavaScriptは web/js/ に保存する
CSSファイルについて
CSSはテンプレート内で include_stylesheets() を呼び出すと読み込むタグを出力する。
何を呼び出すかは、view.ymlにて設定できる
# apps/frontend/config/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, jobs.css, job.css, print: { media: print }] javascripts: [] has_layout: on layout: layout
こうすると以下のようなタグが出力されるようになる
<link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" /> <link rel="stylesheet" type="text/css" media="screen" href="/css/jobs.css" /> <link rel="stylesheet" type="text/css" media="screen" href="/css/job.css" /> <link rel="stylesheet" type="text/css" media="print" href="/css/print.css" />
このままだと、全てのページで4つのCSSを読み込むようになってしまうので個々のページで必要なCSSファイルを読み込むように変更する
まずは先程変更した設定ファイルを元に戻す
# apps/frontend/config/view.yml stylesheets: [main.css]
そして個々のページでそれぞれのCSSファイルを読み込むように変更を加える
# apps/frontend/modules/job/config/view.yml indexSuccess: stylesheets: [jobs.css] showSuccess: stylesheets: [job.css]
または
<?php /* apps/frontend/modules/job/indexSuccess.php */ ?> <?php use_stylesheet('jobs.css') ?> <?php /* apps/frontend/modules/job/showSuccess.php */ ?> <?php use_stylesheet('job.css') ?>
レイアウトを変更する
<?php /* apps/frontend/templates/layout.php */ ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>Jobeet - Your best job board</title> <link rel="shortcut icon" href="/favicon.ico" /> <?php include_javascripts() ?> <?php include_stylesheets() ?> </head> <body> <div id="container"> <div id="header"> <div class="content"> <h1><a href="/job"><img src="http://www.symfony-project.org/images/jobeet.gif" alt="Jobeet Job Board" /></a></h1> <div id="sub_header"> <div class="post"> <h2>Ask for people</h2> <div> <a href="/job/new">Post a Job</a> </div> </div> <div class="search"> <h2>Ask for a job</h2> <form action="" method="get"> <input type="text" name="keywords" id="search_keywords" /> <input type="submit" value="search" /> <div class="help"> Enter some keywords (city, country, position, ...) </div> </form> </div> </div> </div> </div> <div id="content"> <?php if ($sf_user->hasFlash('notice')): ?> <div class="flash_notice"> <?php echo $sf_user->getFlash('notice') ?> </div> <?php endif; ?> <?php if ($sf_user->hasFlash('error')): ?> <div class="flash_error"> <?php echo $sf_user->getFlash('error') ?> </div> <?php endif; ?> <div class="content"> <?php echo $sf_content ?> </div> </div> <div id="footer"> <div class="content"> <span class="symfony"> <img src="http://www.symfony-project.org/images/jobeet-mini.png" /> powered by <a href="http://www.symfony-project.org/"><img src="http://www.symfony-project.org/images/symfony.gif" alt="symfony framework" /></a> </span> <ul> <li><a href="">About Jobeet</a></li> <li class="feed"><a href="">Full feed</a></li> <li><a href="">Jobeet API</a></li> <li class="last"><a href="">Affiliates</a></li> </ul> </div> </div> </div> </body> </html>
テンプレートを変更する
<?php /* apps/frontend/modules/job/templates/indexSuccess.php */ ?> <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>
<?php /* apps/frontend/modules/job/templates/showSuccess.php */ ?> <?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="http://www.symfony-project.org/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 date('m/d/Y', strtotime($job->getCreatedAt())) ?></small> </div> <div style="padding: 20px 0"> <a href="<?php echo url_for('job/edit?id='.$job->getId()) ?>"> Edit </a> </div> </div>
テンプレートの中で利用する変数を $jobeet_job から $job に変更したので、Actionの中も変更する
<?php public function executeShow(sfWebRequest $request) { $this->job = Doctrine::getTable('JobeetJob')->find(array($request->getParameter('id'))); $this->forward404Unless($this->job); }
Slots
Slotとはテンプレートの中で共通の部分を作成する機能のことをいう
効果範囲は表示に利用した、全テンプレートになるので layout で定義すれば全てのページで同じ部分を利用することができます。
例えば layout.php のTitleの部分をSlot化する
<?php /* apps/frontend/templates/layout.php */ ?> <?php if (!include_slot('title')): ?> <title>Jobeet - Your best job board</title> <?php endif; ?>
include_slot()にて定義されたSlotを呼び出します。
また、定義されていない場合は null なので、if文を使って「定義されていない場合」のテキストも用意することができます。
Slotの定義は各々のテンプレート内にて定義します。
定義方法には2種類あり、メソッドタイプとブロックタイプがあります。
<?php /** * apps/frontend/modules/job/templates/showSuccess.php * method type */ ?> <?php slot( 'title', sprintf('<title>%s is looking for a %s</title>', $job->getCompany(), $job->getPosition())) ?>
<?php /** * apps/frontend/modules/job/templates/showSuccess.php * block type */ ?> <?php slot('title') ?> <title><?php sprintf('%s is looking for a %s', $job->getCompany(), $job->getPosition())) ?></title> <?php end_slot(); ?>
forward()
PHPのオーバーロード技術を使って、様々なショートカットが実現されてます。
先程出てきた $this->forward404Unless($this->job); は
<?php if (!$this->job) { $this->forward('default', '404'); }
と同じ意味となってます。
他には
<?php // $this->forward404If($this->job); if ($this->job) { $this->forward404(); } // $this->forward404(); $this->forward('default', '404');
RequestとResponse
Requestのリスト (ブラウザから送られてくる値)
symfonyでの書き方 | 同等のコード |
---|---|
getMethod() | $_SERVER['REQUEST_METHOD'] |
getUri() | $_SERVER['REQUEST_URI'] |
getReferer() | $_SERVER['HTTP_REFERER'] |
getHost() | $_SERVER['HTTP_HOST'] |
getLanguages() | $_SERVER['HTTP_ACCEPT_LANGUAGE'] |
getCharsets() | $_SERVER['HTTP_ACCEPT_CHARSET'] |
isXmlHttpRequest() | $_SERVER['X_REQUESTED_WITH'] == 'XMLHttpRequest' |
getHttpHeader() | $_SERVER |
getCookie() | $_COOKIE |
isSecure() | $_SERVER['HTTPS'] |
getFiles() | $_FILES |
getGetParameter() | $_GET |
getPostParameter() | $_POST |
getUrlParameter() | $_SERVER['PATH_INFO'] |
getRemoteAddress() | $_SERVER['REMOTE_ADDR'] |