昨日、あなた独自のsymfonyアプリケーションの開発を始めました。 やめないでください。symfonyをさらに学ぶので、アプリケーションに新しい機能を追加し、どこかでそれをホストし、コミュニティと共有しようと努めてください。
今日は完全に異なる題材に移ります。
求人情報を探している場合、新しいものが投稿されるとすぐに知らせが来ることが望ましいでしょう。 1時間ごとにWebサイトを確認するのはあまり便利ではないので、Jobeetのユーザーに最新情報を提供するために求人情報のフィードを追加します。
フォーマット
symfonyフレームワークはフォーマットとMIME-Typeをネイティブにサポートします。
これは同じModelとControllerがリクエストされたフォーマットに基づいて異なるテンプレートを持つことを意味します。
デフォルトのフォーマットはHTMLですが、txt
、js
、css
、json
、xml
、rdf
もしくはatom
のように、symfonyはいくつかのフォーマットをそのまま使えます。
フォーマットはリクエストオブジェクトのsetRequestFormat()
メソッドを使って設定できます:
$request->setRequestFormat('xml');
しかしたいていの場合、フォーマットはURLに埋め込まれます。
このケースの場合、特別な変数sf_format
が対応するルートで使われる場合、symfonyは自動的に設定します。
求人リストに関して、リストのURLは次のとおりです:
http://jobeet.localhost/frontend_dev.php/job
このURLは次の内容と同等です:
http://jobeet.localhost/frontend_dev.php/job.html
両方のURLは同等です。
sfDoctrineRouteCollection
クラスによって生成されたルートは拡張子としてsf_format
を持ちhtml
はデフォルトのフォーマットだからです。
app:routes
タスクを実行することであなた自身で確認できます:
フィード
最新のjobフィード
異なるテンプレートを作成することで異なるフォーマットを簡単にサポートできます。
最新の求人情報用にAtomフィードを作るには、indexSuccess.atom.php
テンプレートを作ります:
<!-- apps/frontend/modules/job/templates/indexSuccess.atom.php --> <?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <title>Jobeet</title> <subtitle>Latest Jobs</subtitle> <link href="" rel="self"/> <link href=""/> <updated></updated> <author><name>Jobeet</name></author> <id>Unique Id</id> <entry> <title>Job title</title> <link href="" /> <id>Unique id</id> <updated></updated> <summary>Job description</summary> <author><name>Company</name></author> </entry> </feed>
デフォルトでは、symfonyはフォーマットに従ってContent-Type
レスポンスを変更しHTMLではないすべてのフォーマットに関して、レイアウトは無効です。
Atomフィードに関して、symfonyはContent-Type
をapplication/atom+xml; charset=utf-8
に変更します。
Jobeetのフッターにおいて、フィードへのリンクを更新します:
<!-- apps/frontend/templates/layout.php --> <li class="feed"> <a href="<?php echo url_for('@job?sf_format=atom') ?>">Full feed</a> </li>
内部URIは変数として追加されるsf_format
を伴うjob
リストに対して同じです。
ブラウザーがフィードを自動的に検出できるように<link>
タグをレイアウトのheadセクションに追加します:
<!-- apps/frontend/templates/layout.php --> <link rel="alternate" type="application/atom+xml" title="Latest Jobs" href="<?php echo url_for('@job?sf_format=atom', true) ?>" />
href
リンク属性に関して、url_for()
ヘルパーの2番目の引数のおかげで絶対URLが使われます。
Atomテンプレートヘッダーを次のコードで置き換えます:
<!-- apps/frontend/modules/job/templates/indexSuccess.atom.php --> <title>Jobeet</title> <subtitle>Latest Jobs</subtitle> <link href="<?php echo url_for('@job?sf_format=atom', true) ?>" rel="self"/> <link href="<?php echo url_for('@homepage', true) ?>"/> <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', strtotime(Doctrine::getTable('JobeetJob')->getLatestPost()->getCreatedAt())) ?></updated> <author> <name>Jobeet</name> </author> <id><?php echo sha1(url_for('@job?sf_format=atom', true)) ?></id>
created_at
の日付をタイムスタンプとして取得するためにstrtotime()
関数の使い方に注目してください。
最新投稿の日付を得るには、getLatestPost()
メソッドを作ります:
// lib/model/doctrine/JobeetJobTable.class.php class JobeetJobTable extends Doctrine_Table { public function getLatestPost() { $q = Doctrine_Query::create() ->from('JobeetJob j'); $this->addActiveJobsQuery($q); return $q->fetchOne(); } // ... }
フィードエントリは次のコードで生成できます:
<!-- apps/frontend/modules/job/templates/indexSuccess.atom.php --> <?php use_helper('Text') ?> <?php foreach ($categories as $category): ?> <?php foreach ($category->getActiveJobs(sfConfig::get('app_max_jobs_on_homepage')) as $job): ?> <entry> <title> <?php echo $job->getPosition() ?> (<?php echo $job->getLocation() ?>) </title> <link href="<?php echo url_for('job_show_user', $job, true) ?>" /> <id><?php echo sha1($job->getId()) ?></id> <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', strtotime($job->getCreatedAt())) ?></updated> <summary type="xhtml"> <div xmlns="http://www.w3.org/1999/xhtml"> <?php if ($job->getLogo()): ?> <div> <a href="<?php echo $job->getUrl() ?>"> <img src="http://<?php echo $sf_request->getHost().'/uploads/jobs/'.$job->getLogo() ?>" alt="<?php echo $job->getCompany() ?> logo" /> </a> </div> <?php endif; ?> <div> <?php echo simple_format_text($job->getDescription()) ?> </div> <h4>How to apply?</h4> <p><?php echo $job->getHowToApply() ?></p> </div> </summary> <author> <name><?php echo $job->getCompany() ?></name> </author> </entry> <?php endforeach; ?> <?php endforeach; ?>
リクエストオブジェクト($sf_request
)のgetHost()
メソッドは現在のホストを返します。
企業ロゴの絶対パスを作る際に重宝します。
カテゴリの最新求人フィード
Jobeetのゴールの1つはよりターゲットを絞った求人情報を見つための手助けになることです。 ですので、それぞれのカテゴリ用のフィードを提供する必要があります。
最初に、異なるフォーマット用のサポートを追加するためにcategory
ルートを更新しましょう:
// apps/frontend/config/routing.yml category: url: /category/:slug.:sf_format class: sfDoctrineRoute param: { module: category, action: show, sf_format: html } options: { model: JobeetCategory, type: object } requirements: sf_format: (?:html|atom)
これで、category
ルートはhtml
とatom
フォーマットの両方を理解します。
テンプレートのカテゴリフィードへのリンクを更新します:
<!-- apps/frontend/modules/job/templates/indexSuccess.php --> <div class="feed"> <a href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom')) ?>">Feed</a> </div> <!-- apps/frontend/modules/category/templates/showSuccess.php --> <div class="feed"> <a href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom')) ?>">Feed</a> </div>
最後のステップはshowSuccess.atom.php
テンプレートを作ることです。
しかしこのフィードは求人の一覧も表示するので、_list.atom.php
パーシャルを作ることでフィードエントリを生成するコードをリファクタリングできます。
html
フォーマットに関して、パーシャルはフォーマット専用です:
<!-- apps/frontend/job/templates/_list.atom.php --> <?php use_helper('Text') ?> <?php foreach ($jobs as $job): ?> <entry> <title><?php echo $job->getPosition() ?> (<?php echo $job->getLocation() ?>)</title> <link href="<?php echo url_for('job_show_user', $job, true) ?>" /> <id><?php echo sha1($job->getId()) ?></id> <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', strtotime($job->getCreatedAt())) ?></updated> <summary type="xhtml"> <div xmlns="http://www.w3.org/1999/xhtml"> <?php if ($job->getLogo()): ?> <div> <a href="<?php echo $job->getUrl() ?>"> <img src="http://<?php echo $sf_request->getHost().'/uploads/jobs/'.$job->getLogo() ?>" alt="<?php echo $job->getCompany() ?> logo" /> </a> </div> <?php endif; ?> <div> <?php echo simple_format_text($job->getDescription()) ?> </div> <h4>How to apply?</h4> <p><?php echo $job->getHowToApply() ?></p> </div> </summary> <author> <name><?php echo $job->getCompany() ?></name> </author> </entry> <?php endforeach; ?>
求人フィードのテンプレートを簡略化するために_list.atom.php
パーシャルを使うことができます:
<!-- apps/frontend/modules/job/templates/indexSuccess.atom.php --> <?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <title>Jobeet</title> <subtitle>Latest Jobs</subtitle> <link href="<?php echo url_for('@job?sf_format=atom', true) ?>" rel="self"/> <link href="<?php echo url_for('@homepage', true) ?>"/> <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', strtotime(Doctrine::getTable('JobeetJob')->getLatestPost()->getCreatedAt())) ?></updated> <author> <name>Jobeet</name> </author> <id><?php echo sha1(url_for('@job?sf_format=atom', true)) ?></id> <?php foreach ($categories as $category): ?> <?php include_partial('job/list', array('jobs' => $category->getActiveJobs(sfConfig::get('app_max_jobs_on_homepage')))) ?> <?php endforeach; ?> </feed>
最後に、showSuccess.atom.php
テンプレートを作ります:
<!-- apps/frontend/modules/category/templates/showSuccess.atom.php --> <?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <title>Jobeet (<?php echo $category ?>)</title> <subtitle>Latest Jobs</subtitle> <link href="<?php echo url_for('category', array('sf_subject' => $category, 'sf_format' => 'atom'), true) ?>" rel="self" /> <link href="<?php echo url_for('category', array('sf_subject' => $category), true) ?>" /> <updated><?php echo gmstrftime('%Y-%m-%dT%H:%M:%SZ', strtotime($category->getLatestPost()->getCreatedAt())) ?></updated> <author> <name>Jobeet</name> </author> <id><?php echo sha1(url_for('category', array('sf_subject' => $category), true)) ?></id> <?php include_partial('job/list', array('jobs' => $pager->getResults())) ?> </feed>
メインの求人情報フィードに関して、カテゴリ用の最新の求人情報の日付が必要です:
// lib/model/doctrine/JobeetCategory.class.php class JobeetCategory extends BaseJobeetCategory { public function getLatestPost() { $jobs = $this->getActiveJobs(1); return $jobs[0]; } // ... }
また明日
symfonyの多くの機能と同じように、ネイティブのフォーマットサポートによって難なくフィードをWebサイトに追加できます。
今日は、求職者のユーザーエクスペリエンスを強化しました。 明日は、Webサービスを提供することで職の投稿者に優れた公開機能を提供する方法を見ることになります。
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.