Archive for the ‘jobeet’ Category
jobeet5日目 ルーティング
ORMはDoctrineによるjobeetプロジェクト、5日目はルーティングです。
現在、ローカルにあるページのURLは、どれも、/job.php?id=1など、意味の分からないものになっていますが、
これらを、/job/show/id/1など、意味のあるURLにして表示させるような設定を学びます。
ルーティングは内部URIと外部URLを管理しますし、リクエストを受け取った時、ルーティングはURLを解析して内部URIに変換します。私も、普段何気なく、routing.ymlというファイルで、URLを設定したりしていますが、URLを適切なものに変換して、”ソースコードの内部構造を分からないように表示させる”、というセキュリティ強化という面もあるようです。(知りませんでした!)
jobeet5日目の内容は、4日目までに作成したページのURLを、意味のあるものに変換する、という作業です。
参考サイトはこちら!
homepageルートのmodule変数の値をjobに変更します
# apps/frontend/config/routing.yml
homepage:
url: /
param: { module: job, action: index }
homepageルートを使うようにレイアウト内の Jobeetロゴのリンクを変更します。
<!-- apps/frontend/templates/layout.php -->
<h1>
<a href="<?php echo url_for('@homepage') ?>">
<img src="/images/jobeet.gif" alt="Jobeet Job Board" />
</a>
</h1>
これで、jobeetのトップページのロゴをクリックすると、jobeetのページにリンクが貼られました。
次に、求人ページのURLを意味のあるものにしていきます。
routing.ymlファイルを編集しファイルの冒頭にjob_show_user`ルートを追加します。
job_show_user:
url: /job/:company/:location/:id/:position
param: { module: job, action: show }
indexSuccess.php内で呼び出されるurl_for()を変更
url_for('job/show?id='.$job->getId().'&company='.$job->getCompany().
'&location='.$job->getLocation().'&position='.$job->getPosition())
ここまでで、jobeetのページは
http://jobeet.kokoro/frontend_dev.php/job/Sensio+Labs/Paris%2C+France/1/Web+Developer
というURLで表示されます。
これを、
http://jobeet.kokoro/frontend_dev.php/job/sensio-labs/paris-france/1/web-developer
という、綺麗にルーティングされたページにしていきます。
全ての非ASCII文字をハイフン(-)に置き換えたカラム値にする(上記の、%2C+、などの記号を全て-にします) JobeetJobファイルを開いて、クラスへ下記のメソッドを追加します。
// lib/model/doctrine/JobeetJob.class.php
public function getCompanySlug()
{
return Jobeet::slugify($this->getCompany());
}
public function getPositionSlug()
{
return Jobeet::slugify($this->getPosition());
}
public function getLocationSlug()
{
return Jobeet::slugify($this->getLocation());
}
lib/Jobeet.class.phpファイルを作り slugifyメソッドを追加します。
// lib/Jobeet.class.php
class Jobeet
{
static public function slugify($text)
{
// 文字ではないもしくは数値ではないものすべてを-に置き換える
$text = preg_replace('/\W+/', '-', $text);
// トリムして小文字に変換する
$text = strtolower(trim($text, '-'));
return $text;
}
}
routing.ymlの、job_show_userルートでバーチャルアクセサで実際のカラムの名前を置き換えます。
job_show_user:
url: /job/:company_slug/:location_slug/:id/:position_slug
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: show }
requirements:
id: \d+
sf_method: [get]
.ymlファイルを変更した後は、symfonyのキャッシュをクリアします。
$ php symfony cc
Jobeetオブジェクトを読み取るためにルートオブジェクトを使うexecuteShow()メソッドを変更します。
class jobActions extends sfActions
{
public function executeShow(sfWebRequest $request)
{
$this->job = $this->getRoute()->getObject();
$this->forward404Unless($this->job);
}
// ...
}
routing.ymlファイルを以下に修正します。
# apps/frontend/config/routing.yml
job:
class: sfDoctrineRouteCollection
options: { model: JobeetJob }
job_show_user:
url: /job/:company_slug/:location_slug/:id/:position_slug
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: show }
requirements:
id: \d+
sf_method: [get]
# default rules
homepage:
url: /
param: { module: job, action: index }
default_index:
url: /:module
param: { action: index }
default:
url: /:module/:action/*
上記のob ルートは実際には下記に示す 7つのsfDoctrineRouteルートを自動的に生成しています。
job:
url: /job.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: list }
param: { module: job, action: index, sf_format: html }
requirements: { sf_method: get }
job_new:
url: /job/new.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: new, sf_format: html }
requirements: { sf_method: get }
job_create:
url: /job.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: create, sf_format: html }
requirements: { sf_method: post }
job_edit:
url: /job/:id/edit.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: edit, sf_format: html }
requirements: { sf_method: get }
job_update:
url: /job/:id.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: update, sf_format: html }
requirements: { sf_method: put }
job_delete:
url: /job/:id.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: delete, sf_format: html }
requirements: { sf_method: delete }
job_show:
url: /job/:id.:sf_format
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: show, sf_format: html }
requirements: { sf_method: get }
すべてのURLに対してルートを定義してみます。jobルートはJobeetアプリケーションを記述するために必要なすべてのルールを定義するので、 routing.yml設定ファイルからデフォルトのルートを削除もしくはコメントアウトします。
# apps/frontend/config/routing.yml
#default_index:
# url: /:module
# param: { action: index }
#
#default:
# url: /:module/:action/*
ここまでで、jobeet5日目の内容は終わりです。
参考テキストの、「アクションテンプレートにおけるルーティング」の辺りの理解が今ひとつですが、URLのルーティング自体は完了です。6日目以降に、理解不足の部分のシワ寄せが来ないといいのですが。。。。また、私たちが開発しているサイトで、どの辺りを参照すれば良いのか、makiさんに質問してみようと思います。
関連する投稿
Jobeet4日目 ControllerとView
ORMはDoctrineでのJobeetプロジェクト、間髪入れず、4日目です。
参考サイトはこちら
3日目で作成したモジュールの基本的カスタマイズをしつつ、
symfony独特のグローバルテンプレート(レイアウト)の性質や、設定ファイルの定義、サイトの構造を理解していきます。
まず、apps/frontend/templates/layout.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="/images/logo.jpg" 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="/images/jobeet-mini.png" />
powered by <a href="http://www.symfony-project.org/">
<img src="/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>
次に、画像ファイルをダウンロードし、 web/images へ
スタイルシートファイルをダウンロードし、 web/css ディレクトリに配置(上書き)します。
ファビコンをダウンロードし、web/ディレクトリに設置します。
http://jobeet.kokoro/frontend_dev/new
を確認すると、以下のように。
※http://jobeet.kokoro/frontend_dev/job は、リストが崩れて表示されますが、この時点ではまだ大丈夫です。
jobs.cssファイルはホームページに必要とされるときだけ読み込まれ、 job.cssファイルは求人ページだけに適用されます。 view.ymlファイルは単一モジュール単位でカスタマイズすることができます。アプリケーションのview.ymlファイルはmain.cssだけを持つように変更します。
# apps/frontend/config/view.yml stylesheets: [main.css]
jobモジュールのViewをカスタマイズするには、 apps/frontend/modules/job/configディレクトリでview.ymlファイルを生成します。
# apps/frontend/modules/job/config/view.yml
indexSuccess:
stylesheets: [jobs.css]
showSuccess:
stylesheets: [job.css]
indexSuccess.phpテンプレート(デフォルト)を、以下に変更します。
<div class="br30"></div>
[lang='css']
<!-- 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>
[/lang]
これにより、http://interndev.kokoro/frontend_dev.php/jobは、以下のようにキレイに見えるようになりました。
showSuccess.phpファイルを開いて、下記コードに置き換えます。
<!-- apps/frontend/modules/job/templates/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 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>
テンプレートは求人情報を表示するためアクションから渡される$job変数を使います。テンプレートへ渡す変数を$jobeet_jobから$jobへリネームするので、 showアクションの該当箇所を変更します(変数が2カ所にあることに注意してください)
// apps/frontend/modules/job/actions/actions.class.php
public function executeShow(sfWebRequest $request)
{
$this->job = Doctrine::getTable('JobeetJob')-> find($request->getParameter('id'));
$this->forward404Unless($this->job);
}
http://interndev.kokoro/frontend_dev.php/job のSensio Lab のリンク先↑
見た目変更系は以上です。
スロットと、レイアウトを変更していきます。
動的にタイトルを変更するためにレイアウトにスロットを追加します。
// apps/frontend/templates/layout.php
<title><?php include_slot('title') ?></title>
各スロットは(title)という名前で定義され、include_slot()ヘルパーで表示されます。今からshowSuccess.phpテンプレートの始めに求人ページのコンテンツについて定義したslot()ヘルパーを使うようにします。
// apps/frontend/modules/job/templates/showSuccess.php
<?php slot(
'title',
sprintf('%s is looking for a %s', $job->getCompany(), $job->getPosition()))
?>
テンプレート内で同じタイトルを何回も繰り返す代わりに、レイアウトでデフォルトのタイトルを定義します。
// apps/frontend/templates/layout.php
<title>
<?php if (!include_slot('title')): ?>
Jobeet - Your best job board
<?php endif; ?>
</title>
4日目に行う作業は以上になりますが、それぞれ、symfony独特の意味があり、オブジェクト指向フレームワークならではの、慣れない部分がたくさんありました。説明しようと思っても、今はまだ難しいので(実は3日目からです・・・・)、手を動かして、理解できた部分を追記していこうと思います。
そういう学習法の方が、Jobeetプロジェクトも進むのではと、感じました。



