リンクを張るほうがようやく完成したので、次はリンク先を作成します。
リンク先はcategoryモジュールという別個のモジュールにしてしまうので、とりあえずコマンドラインから骨組みを作成します。
> php symfony generate:module frontend category
次に前回url:slugとか書いていた部分に対してその実体を作成します。
>categoryテーブル用にslugカラムを追加する必要があります:
>このslugカラムはDoctrineのSluggableビヘイビアによって考慮されます。
>JobeetCategoryモデルのビヘイビアを有効にすればすべてが考慮されます。
駄目だ、何度読んでも意味がわからない。
Doctrineのドキュメントでようやくそれっぽい記述を発見しました。
スキーマにテーブル名:actAs:Sluggable:というオプションを記述しておけば、テーブル自体にはカラムを作成しないけどモデル的にはカラムが存在するように振る舞う、というような内容のようです。
あと、"Sluggable ビヘイビア"でようやくslugの意味がわかったわ。
何故Doctrineのサイト自身にこれを適用していないんだろう?
スキーマファイル、JobeetCategory:actAs:内に以下を追加します。
config/doctrine/schema.yml
スキーマを書き換えたのでデータベースを作り直します。
例によって直接DBを触った内容は全削除されます。
>php symfony doctrine:build-all-reload --no-confirmation
slugフィールドが作成されていました。なんだそれ。
この定義により、JobeetCategory::save()メソッド等で保存を行った際、jobeet_category.nameをslugifyした結果が勝手にslugフィールドに入るようになります。
さて、slugフィールドが実在するようになったので、今日スキーマに書いた
url: /category/:slug
の:slugは実在のカラムを参照できるようになり、せっかく書いたJobeetCategory::getSlug()は不要となります。
あったとしても元のメソッドがオーバーライドされるだけですが、まあ意味がないので削除しましょう。
ようやく画面表示コントローラとテンプレートの作成です。
ルーティングでparam: {module: category,action: show }と定義しているのでcategoryActions::executeShow()が呼び出されます。
apps/frontend/modules/category/actions/actions.class.php
apps/frontend/modules/category/templates/showSuccess.php
ようやくカテゴリ単位で閲覧を行えるようになりました。
なにげに10件しか表示されていないのですが、それはまた今度。
先にパーシャルテンプレートを解説します。
テンプレートをよく見てみると、apps/frontend/modules/job/templates/indexSuccess.phpとapps/frontend/modules/category/templates/showSuccess.phpの<table class="jobs">
の中身は全く同じです。
こういう場合、共通する部分だけ別のファイルに書き出して共有を行うことができます。
apps/frontend/modules/job/templates/_list.php
include_partial()でインクルードを行うことができます。
<?php include_partial('job/list'); ?>とすると、jobモジュール内のlistテンプレート、すなわちapps/frontend/modules/job/templates/_list.phpがそのまま取得できます。
注意点としては、変数はそのままでは全く渡されないということです。
上記apps/frontend/modules/category/templates/showSuccess.phpから単にinclude_partial('job/list');としただけでは、_list.php内の$jobsは空っぽです。
共通して変数を使いたい場合は、第二引数で渡す必要があります。
よって、上記showSuccess.phpのテーブル表示部分はこのようになります。
apps/frontend/modules/category/templates/showSuccess.php
トップ画面の方も修正しましょう。
apps/frontend/modules/job/templates/indexSuccess.php
ちなみにトップ画面の場合、同じモジュール内にあるのでモジュール名を省略してinclude_partial('list')と書くこともできます。
Symfonyの記事一覧
リンク先はcategoryモジュールという別個のモジュールにしてしまうので、とりあえずコマンドラインから骨組みを作成します。
> php symfony generate:module frontend category
次に前回url:slugとか書いていた部分に対してその実体を作成します。
>categoryテーブル用にslugカラムを追加する必要があります:
>このslugカラムはDoctrineのSluggableビヘイビアによって考慮されます。
>JobeetCategoryモデルのビヘイビアを有効にすればすべてが考慮されます。
駄目だ、何度読んでも意味がわからない。
Doctrineのドキュメントでようやくそれっぽい記述を発見しました。
スキーマにテーブル名:actAs:Sluggable:というオプションを記述しておけば、テーブル自体にはカラムを作成しないけどモデル的にはカラムが存在するように振る舞う、というような内容のようです。
あと、"Sluggable ビヘイビア"でようやくslugの意味がわかったわ。
何故Doctrineのサイト自身にこれを適用していないんだろう?
スキーマファイル、JobeetCategory:actAs:内に以下を追加します。
config/doctrine/schema.yml
1
2
3
4
|
JobeetCategory:
actAs:
Sluggable:
fields: [name]
|
スキーマを書き換えたのでデータベースを作り直します。
例によって直接DBを触った内容は全削除されます。
>php symfony doctrine:build-all-reload --no-confirmation
1
2
3
4
5
6
7
8
9
10
|
CREATE TABLE IF NOT EXISTS `jobeet_category` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`slug` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
UNIQUE KEY `sluggable_idx` (`slug`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
|
slugフィールドが作成されていました。なんだそれ。
この定義により、JobeetCategory::save()メソッド等で保存を行った際、jobeet_category.nameをslugifyした結果が勝手にslugフィールドに入るようになります。
さて、slugフィールドが実在するようになったので、今日スキーマに書いた
url: /category/:slug
の:slugは実在のカラムを参照できるようになり、せっかく書いたJobeetCategory::getSlug()は不要となります。
あったとしても元のメソッドがオーバーライドされるだけですが、まあ意味がないので削除しましょう。
ようやく画面表示コントローラとテンプレートの作成です。
ルーティングでparam: {module: category,action: show }と定義しているのでcategoryActions::executeShow()が呼び出されます。
apps/frontend/modules/category/actions/actions.class.php
1
2
3
|
public function executeShow(sfWebRequest $request){
$this->category = $this->getRoute()->getObject();
}
|
apps/frontend/modules/category/templates/showSuccess.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
use_stylesheet('jobs.css') slot('title', sprintf('Jobs in the %s category', $category->getName()))
<div class="category">
<div class="feed">
<a href="">Feed</a>
</div>
<h1> echo $category </h1>
</div>
<table class="jobs">
foreach ($category->getActiveJobs() as $i => $job):
<tr class=" echo fmod($i, 2) ? 'even' : 'odd' ">
<td class="location">
echo $job->getLocation()
</td>
<td class="position">
echo link_to($job->getPosition(), 'job_show_user', $job)
</td>
<td class="company">
echo $job->getCompany()
</td>
</tr>
endforeach;
</table>
|
ようやくカテゴリ単位で閲覧を行えるようになりました。
なにげに10件しか表示されていないのですが、それはまた今度。
先にパーシャルテンプレートを解説します。
テンプレートをよく見てみると、apps/frontend/modules/job/templates/indexSuccess.phpとapps/frontend/modules/category/templates/showSuccess.phpの<table class="jobs">
の中身は全く同じです。
こういう場合、共通する部分だけ別のファイルに書き出して共有を行うことができます。
apps/frontend/modules/job/templates/_list.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<table class="jobs">
foreach ($jobs as $i => $job):
<tr class=" echo fmod($i, 2) ? 'even' : 'odd' ">
<td class="location">
echo $job->getLocation()
</td>
<td class="position">
echo link_to($job->getPosition(), 'job_show_user', $job)
</td>
<td class="company">
echo $job->getCompany()
</td>
</tr>
endforeach;
</table>
|
include_partial()でインクルードを行うことができます。
<?php include_partial('job/list'); ?>とすると、jobモジュール内のlistテンプレート、すなわちapps/frontend/modules/job/templates/_list.phpがそのまま取得できます。
注意点としては、変数はそのままでは全く渡されないということです。
上記apps/frontend/modules/category/templates/showSuccess.phpから単にinclude_partial('job/list');としただけでは、_list.php内の$jobsは空っぽです。
共通して変数を使いたい場合は、第二引数で渡す必要があります。
よって、上記showSuccess.phpのテーブル表示部分はこのようになります。
apps/frontend/modules/category/templates/showSuccess.php
1
|
include_partial('job/list', array('jobs' => $category->getActiveJobs()))
|
トップ画面の方も修正しましょう。
apps/frontend/modules/job/templates/indexSuccess.php
1
2
3
|
include_partial('job/list',
array('jobs' => $category->getActiveJobs(
sfConfig::get('app_max_jobs_on_homepage'))))
|
ちなみにトップ画面の場合、同じモジュール内にあるのでモジュール名を省略してinclude_partial('list')と書くこともできます。
Symfonyの記事一覧
PR
トラックバック
トラックバックURL: