Yii: Добавление RSS-ленты на сайт, с использованием библиотеки Zend_Feed из Zend Framework

Yii: Добавление RSS-ленты на сайт, с использованием библиотеки Zend_Feed из Zend Framework Делаем ленту RSS на нашем сайте, работающем на фреймворке Yii. Будем использовать для RSS библиотеку из Zend Framework

Будем использовать существующую функциональную часть для RSS, которая реализована в другом фреймворке - Zend Framework. 

1) Скачиваем и устанавливаем (всё просто) последнюю версию Zend Framework - http://framework.zend.com/download/latest. Нам понадобится только один компонент из этого фреймворка - Zend_Feed, поэтому достаточно минимальной версии Zend.

Создадим в папке /protected специальную папку - vendors, в которую закачаем папку /library/Zend из скачанного архива. Убедимся, что существует /protected/vendors/Zend/Feed.php

2) Этот компонент Zend_Feed сэкономит нам время, чтобы он правильно заработал, нам осталось передать ему данные в правильном формате. Добавим метод actionFeed() в контроллер CommentController (мы не стали создавать отдельный контроллер для ленты). Вот этот метод:

public function actionFeed()
	{
		if(isset($_GET['id'])) $materialId = intval($_GET['id']);
		else $materialId = null;
		
		$comments = Comment::model()->findRecentComments(20, $materialId);
		//convert from an array of comment AR class instances to an name=>value array for Zend
		$entries=array();
		
		foreach($comments as $comment) 
		{
			$entries[]=array( 
				'title'=>$comment->material->title,
				'link'=>CHtml::encode($this->createAbsoluteUrl('material/view',array('id'=>$comment->material->id, 'alias'=>$comment->material->alias,))),
				'description'=> $comment->author . ' says:<br>' . $comment->content,
				'lastUpdate'=>strtotime($comment->create_time), 
				'author'=>$comment->author,
			);
		}

		//now use the Zend Feed class to generate the Feed 
		// generate and render RSS feed 
		$feed=Zend_Feed::importArray(array(
			'title' => 'LOCO Comments Feed', 
			'link' => $this->createUrl(''),
			'charset' => 'UTF-8',
			'entries'  => $entries,
		), 'rss'); 
		
		$feed->send();
	}

Сначала мы проверяем если выбрана конкретная статья, тогда будет формироваться RSS комментариев для этой статьи, если $materialId не установлен, то - RSS всех последних комментариев. Дальше $comment вернёт нам массив записей-комментариев из модели Comment. Циклом foreach мы этот массив проходим и формируем то, чего ждёт компонент Zend_Feed на вход. А он ждёт простой массив $entries[], каждый элемент в котором в свою очередь тоже является простым ассоциативным массивом пар name=>array. Чтобы всё заработало нам достаточно прописать - title, link, description.

Ещё мы использовали метод createAbsoluteUrl(), чтобы получить абсолютный путь. Также использовали CHTML::encode, чтобы раскодировать html сущности (например & -> &amp;), иначе Zend_Feed выдаст ошибку.

Когда всё сформировано, используем метод importArray(), он принимает массив. Затем посылаем $feed->send(), чтобы сформатировать RSS и отправить верные headers клиенту.

3) В начало контроллера CommentController.php добавим:

        Yii::import('application.vendors.*'); 
	require_once('Zend/Feed.php'); 
	require_once('Zend/Feed/Rss.php');

и в метод CommentController::accessRules():

public function accessRules()
	{
		return array(
			array('allow',  // allow all users to access 'index' and 'view' actions.
				'actions'=>array('index','feed'),
				'users'=>array('*'),
			),
...

Всё, теперь смотрим - http://loco.ru/comment/feed

Или с использованием дружеских URL - http://loco.ru/commentfeed.xml

Для этого в config/main.php прописали:

'urlManager'=>array(
        	'urlFormat'=>'path',
        	'rules'=>array(
				'materials/<id:\d+>/commentfeed'=>array('comment/feed', 'urlSuffix'=>'.xml', 'caseSensitive'=>false),
				'commentfeed'=>array('comment/feed', 'urlSuffix'=>'.xml', 'caseSensitive'=>false),
...

 

4) И последнее, добавим в шаблон ссылки ленты. В MaterialController::actionIndex() добавим:

Yii::app()->clientScript->registerLinkTag(
			'alternate', 
			'application/rss+xml', 
			$this->createUrl('comment/feed'));

Это вставит в html в область <head> ссылку:

<link rel="alternate" type"application/rss+xml" href="/commentfeed.xml">

Также можно поступить и для actionView().

 

Источник: loco.ru

almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

Вы можете почитать все статьи от almix'а.



Другие статьи по этой теме:

Комментарии (6)     Подпишитесь на RSS комментариев к этой статье.

6 комментариев

#161
BS говорит:
January 7, 2012 at 02:21 pm
Как то не круто подключать к этому делу ещё один грамоздкий фреймворк
#163
Илья говорит:
January 9, 2012 at 03:07 pm
автор не подключает весь фремворк, он берет библиотеку, к стати zend тем и хорош что его можно по кусочкам разобрать на свои нужды. и ничего плохого ни в одном из смыслов тут нет.
#164
BS говорит:
January 10, 2012 at 03:07 pm
тогда если нет нужды в других компанентах зенда, достаточно папок uri и feed
#169
Саша говорит:
January 11, 2012 at 01:22 pm
А присутствие всех папок Zend, если они не используются, это плохо? Просто он небольшой, на сервере много не занимает Mb. Я не знаю задействует ли больше ресурсов строка

Yii::import('application.vendors.*');

BS, как вы считаете? А без папки uri будет работать?
#170
BS говорит:
January 11, 2012 at 01:35 pm
Я оставлял только эти 2 папки, всё работало, без uri не будет.
если не используются то и не влияют.
#171
Саша говорит:
January 11, 2012 at 02:31 pm
просмотрел бегло, там есть место, где Feed.php обращается к Zend_Uri, возможно поэтому папка uri нужна. Но тогда всё изучить и проверять надо, и тогда выбросить ненужное. А целиком если без изменений оставить, то заранее расчитываю, что возникающие проблемы в коде уж точно не с Zend связаны.