忍者ブログ

uthorofotus iruc

プログラムを組むために考えたり憶えたりした、いろいろなことを記録していきます。タイトルの読みは「ウソロフォトス イルーク」

[26]  [25]  [24]  [23]  [22]  [21]  [20]  [19]  [18]  [17]  [16

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

askeet day eleven:syndication feed の解説

askeetチュートリアルの11日目『フィードを付ける』です。ユーザが楽にaskeetの更新をチェック出来るようにRSSフィードを付けます。

11日目チュートリアルの日本語版はありません。本家英語版はこちらです。

■これまでのsymfony(Previously on symfony)
askeetにいろいろと機能を付けてきましたので、すでにβ版と呼んで良いくらいになっています。ここでの問題は、常連ユーザがaskeetサイトの更新情報をチェックしやすいようにニュースフィード(RSS)を実装します。

■人気のある質問フィード(Popular questions feed)
▽ヘッダのフィードリンク(Link to the feed in the head)
htmlヘッダにRSSフィードへのリンクを設定するには、レイアウトテンプレートのheadタグ内でauto_discovery_link_tag関数を使えばよいです。この関数を実行するとAssetヘルパーが自動的に読み込まれます。

▽プラグインのインストール(Install the plug-in)
symfonyではフィード生成のためにsfFeedプラグインが用意されていますので、それをインストールして使います。チュートリアルそのままのコマンドだとエラーが出るかもしれません。
プラグインのインストールエラー

pearを使ってプラグインをインストールしているようですが、バージョン依存の関係がおかしいのでしょうか。以下のコマンドを使って、symfonyサイトから直接データを取得します。この際。pakeソースを見たところ、プロジェクト内のプラグインディレクトリにしかインストールしないようなので、local指定は特にいりません。

symfony plugin-install http://plugins.symfony-project.com/sfFeedPlugin

インストール先は askeet/plugins/sfFeedPlugin/ となります。

▽アクションの作成(Create the action)
フィードを生成するためのアクションを作成します。init-moduleコマンドでfeedモジュールを作成した後、popularアクションを追加します。feed/indexアクションはいらないで消しましょう。

このアクションでは最新の質問を、設定ファイルで指定された分だけ取得します。質問には投稿者名も入りますので、doSelectJoinUserを使います。そのデータとフィードタイトルなどを先ほどインストールしたsfFeedプラグインに渡します。これでフィードが生成できます。フィードに載せる質問の数を設定ファイルに指定しておきましょう。

▽ビュー設定の変更(Change the view configuration)
フィードにはhtmlタグは不要ですので、レイアウトテンプレートを使用しないようにします。"template:   feed"の指定により、どんなアクションを実行しても必ずfeedSuccess.phpテンプレートを使うようになります。

▽テンプレートの作成(Write the template)
アクションで生成したフィードデータをそのまま表示します。

▽動作テスト(Test it)
手持ちのRSSリーダを使うか、テキストエディタで中身を見て確認しましょう。

wget http://askeet/feed/popular
less popular

■魔法(The magic)
symfonyは魔法を使います。魔法とは、アクションからQuestionモデルクラスを渡された際、getUserメソッドを使ってユーザデータを取得し、投稿者名・メールアドレスをフィードに入れてくれます。また、質問のURLを出す際にはルーティングルールを参照して、ルールにあったURLをフィードに入れてくれます。

▽インターフェースの改良(Interface improvements)
ルーティングルールを設定しておきます。レイアウトテンプレートにあるauto_discovery_link_tag関数のリンク先指定もルーティング名に直しておきましょう。

▽RSS画像(RSS image)
RSSへリンクを張る際、分かりやすいアイコンを使います。アイコン画像をSubversionから取得し、そのアイコンを使ってRSSへのリンクを生成するヘルパー関数を作成します。

cd web/images/
wget http://svn.askeet.com/trunk/web/images/feed.gif
cd ../../

サイドバーテンプレートのpopular questionsリンクの後ろに追加しておきます。Globalヘルパーの読み込みも必要です。また、チュートリアルではlink_to_rss関数をテンプレートで使っていますが間違っています。link_to_feed関数を使ってください。

  <li><?php echo link_to('popular questions', '@popular_questions') ?> <?php echo link_to_feed('popular questions', '@feed_popular_questions') ?></li>

dev環境でフィードの動作確認をする際、デバッグツールバーが表示されてはフィードの書式が崩れてしまうので、表示しないようにします。feedモジュールのアクションに以下のメソッドを追加しておくと良いでしょう。feedモジュール内のアクションを実行する前に、必ずこのメソッドが実行されるようになります。

  public function preExecute()
  {
    sfConfig::set('sf_web_debug', false);
  }

フィード画像

■また明日(See you Tomorrow)
12日目はsymfonyを使ってeメールを送れるようにします。ユーザが自分のパスワードを忘れてしまうかもしれませんから。

■課題
11日目の課題は、最新の回答と最新の質問、指定した質問に関する回答のフィード3種類を実装します。

まずは、ルーティングルールから先に決めてしまいます。apps/frontend/config/routing.yml に以下の内容を追加します。

# feeds
feed_recent_answers:
  url:   /feed/recent_answers
  param: { module: feed, action: recentAnswers }

feed_recent_questions:
  url:   /feed/recent
  param: { module: feed, action: recent }

feed_question:
  url:   /feed/question/:stripped_title
  param: { module: feed, action: question }

その次はテンプレートにフィードへのリンクを付けましょう。まずは、サイドバーのテンプレート apps/frontend/modules/sidebar/templates/_default.php の修正です。

<ul>
  <li><?php echo link_to('popular questions', '@homepage') ?> <?php echo link_to_feed('popular questions', '@feed_popular_questions') ?></li>
  <li><?php echo link_to('latest questions', '@recent_questions') ?> <?php echo link_to_feed('latest questions', '@feed_recent_questions') ?></li>
  <li><?php echo link_to('latest answers', '@recent_answers') ?> <?php echo link_to_feed('latest answers', '@feed_recent_answers') ?></li>
</ul>

質問の詳細question/showにも、その質問に関する回答を得るためのフィードを付けます。質問タイトルの後ろに置くのが分かりやすいでしょう。

<h2><?php echo $question->getTitle() ?><?php echo link_to_feed('this question feed', '@feed_question?stripped_title='.$question->getStrippedTitle()) ?></h2>

最後に apps/frontend/modules/feed/actions/actions.class.php へアクションを追加します。フィードの最大件数は全部一緒で良いでしょう。

 public function executeRecentAnswers()
  {
    // questions
    $c = new Criteria();
    $c->addDescendingOrderByColumn(AnswerPeer::CREATED_AT);
    $c->setLimit(sfConfig::get('app_feed_max'));
    $answers = AnswerPeer::doSelectJoinUser($c);

    $feed = sfFeed::newInstance('rss201rev2');

    // channel
    $feed->setTitle('Recent answers on askeet');
    $feed->setLink('@recent_answers');
    $feed->setFeedUrl('@feed_recent_answers');
    $feed->setDescription('A list of the most recent question answers on the askeet site.');

    // items
    $feed->setFeedItemsRouteName('@recent_answers');
    $feed->setItems($answers);

    $this->feed = $feed;
  }

  public function executeRecent()
  {
    // questions
    $c = new Criteria();
    $c->addDescendingOrderByColumn(QuestionPeer::CREATED_AT);
    $c->setLimit(sfConfig::get('app_feed_max'));
    $questions = QuestionPeer::doSelectJoinUser($c);

    $feed = sfFeed::newInstance('rss201rev2');

    // channel
    $feed->setTitle('Recent questions on askeet');
    $feed->setLink('@recent_questions');
    $feed->setFeedUrl('@feed_recent_questions');
    $feed->setDescription('A list of the most recent questions asked on the askeet site.');

    // items
    $feed->setFeedItemsRouteName('@question');
    $feed->setItems($questions);

    $this->feed = $feed;
  }

  public function executeQuestion()
  {
    $question = QuestionPeer::getQuestionFromTitle($this->getRequestParameter('stripped_title'));
    $this->forward404Unless($question);

    // answers
    $c = new Criteria();
    $c->add(AnswerPeer::QUESTION_ID, $question->getId());
    $c->addDescendingOrderByColumn(AnswerPeer::CREATED_AT);
    $c->setLimit(sfConfig::get('app_feed_max'));
    $answers = AnswerPeer::doSelect($c);

    $feed = sfFeed::newInstance('rss201rev2');

    // channel
    $feed->setTitle($question->getTitle().' feed');
    $feed->setLink('@question?stripped_title='.$question->getStrippedTitle());
    $feed->setFeedUrl('@feed_question?stripped_title='.$question->getStrippedTitle());
    $feed->setDescription('Latest answers to the question: '.$question->getTitle());

    // items
    $feed->setItems($answers);

    $this->feed = $feed;
  }

以上で完了です。キャッシュをクリアして、動作の確認を行います。なお、feedのテンプレートはfeedSuccess.phpをそのまま使いますので、何も修正しません。

PR

この記事にコメントする

お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード   Vodafone絵文字 i-mode絵文字 Ezweb絵文字

この記事へのトラックバック

この記事にトラックバックする:

askeet day twelve:Emails の解説 HOME askeet day ten:Alter data with Ajax forms の解説

プロフィール

HN:
flyfront
性別:
非公開
自己紹介:
PHPプログラマ。東京でsymfonyな仕事してます。

HNはflyfrontですが、
仕事関係ではr_koike名義を使ってる場合もあります。

Wassr

カレンダー

11 2017/12 01
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

最新コメント

[01/02 通りすがり]
[10/18 flyfront]

バーコード

アクセス解析

忍者ブログ [PR]
Template by repe