Инструменты пользователя

Инструменты сайта


limb2:ru:howtos:rss

Создание RSS-feed при помощи Limb2

RSS - неотъемлемая часть любого часто обновляемого проекта. В данном документе мы покажем, как можно создать RSS-feed при помощи Limb и WACT.

Допустим, что нам необходимо сделать RSS-feed для последних новостей и документов.

Создадим простейший скрипт last-news-feed.php, который будет делать вот что:

  • получать последние новости и документы,
  • объединять полученные объекты и сортировать их по дате последней модификации. Если даты равны, то будет применять еще один сортировочный механиз (например, по заголовку),
  • нормализовать аттритуры hrefs для того, чтобы сделать их абсолютными, то есть href='/root/test/../new' должен стать href='http://yourdomain.com/root/new'
  • передавать обработанные данные в WACT шаблон

Следующий код во многом не требует дополнительных комментариев:

<?php
require_once('setup.php');
require_once(LIMB_DIR . '/core/template/template.class.php');
require_once(LIMB_DIR . '/core/fetcher.class.php');
require_once(LIMB_DIR . '/core/lib/http/uri.class.php');
require_once(LIMB_DIR . '/core/lib/util/array_dataset.class.php');
require_once(LIMB_DIR . '/core/lib/system/sys.class.php');
 
define('CONTENT_LOCALE_ID', DEFAULT_CONTENT_LOCALE_ID);
 
//сортировка, используемая в uasort
function sorter($a, $b)
{
  $date1 = $a['modified_date'];
  $date2 = $b['modified_date'];
 
  if ($date1 == $date2)
  {
    if($a['node_id'] > $b['node_id'])
      return -1;
    else
      return 1;
  }
 
  return ($date1 > $date2) ? -1 : 1;
}
 
//функция, которая конвертирует относительные ссылки в абсолютные, используя базовый путь
function fix_hrefs($base_path, $content)
{
  $GLOBALS['base_path'] = $base_path;
  return preg_replace_callback('~href=("|\')?([^"\'>\s]+)("|\')?~', '_replace_callback', $content);
}
 
function _replace_callback($matches)
{
  if(preg_match('~(https?|ftp)://~', $matches[2]))
    return $matches[0];
 
  $url = get_qualified_url($GLOBALS['base_path'], $matches[2]);
 
  return "href='{$url}'";
}
 
function get_qualified_url($base_path, $raw_path)
{
  $path = $raw_path;
 
  if($path{0} != '/')
  {
    $uri = new uri($base_path . '/' . $path); 
    $uri->normalize_path();
    $path = $uri->get_path();
  }
 
  return 'http://' . $_SERVER['HTTP_HOST'] . $path;
}
 
// получаем новости
$counter = 0;
$params = array(
  'limit' => 3,
  'order' => array('modified_date' => 'DESC')
);
 
$arr_news = fetch('news_object', $counter, $params, 'fetch_accessible');
 
// получаем документы
$params = array(
  'limit' => 3,
  'order' => array('modified_date' => 'DESC')
);
$arr_documents = fetch('document', $counter, $params, 'fetch_accessible');
 
// объединяем и сортируем данные
$arr = array_merge($arr_documents, $arr_news);
 
uasort($arr, 'sorter');
 
foreach($arr as $key => $data)
{
  // делаем все ссылки в контенте абсолютными
  $arr[$key]['annotation'] = fix_hrefs($data['path'], $data['annotation']);
  // делаем uri до объекта абсолютным
  $arr[$key]['path'] = get_qualified_url($data['path'], $data['path']);
}
 
// создаем источник данных для шаблона
$ds = new array_dataset($arr);
 
// перадаем данные в шаблон
$template = new template('/rss/last_news.rss');
$template->set('xml', '<!--l version="1.0" encoding="utf-8-->');
 
$news = & $template->find_child('last_news');
$news->register_dataset($ds);
 
// выводим результат
header("Content-Type: application/xml");
$template->display();
 
?>

А теперь шаблон:

{$xml}
<!DOCTYPE rss [<!ENTITY % HTMLlat1 PUBLIC "-//W3C//ENTITIES Latin 1 for XHTML//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">]>
<rss version="0.92" xml:base="http://YourDomain.com">
 
<channel>
 <title>YourDomain.com last news</title>
 <link>http://YourDomain.com</link>
 <description>YourDomain.com site</description>
 <language>en</language>
 
<grid:LIST id='last_news'>
 <grid:ITERATOR>
 
  <item>
   <title>{$title}</title>
   <link>{$path}</link>
   <description>
      <core:HTMLSPECIALCHARS hash_id='annotation'>
   </description>
   <pubDate>
    <locale:DATE_FORMAT hash_id='modified_date' locale_format='short_date_time' type='stamp'>
   </pubDate>
  </item>
 
  </grid:ITERATOR>
</grid:LIST>
 
</channel>
</rss>

Обратите внимание, что мы используем тег <core:HTMLSPECIALCHARS> для того, чтобы очистить html-код, а также тег <locale:DATE_FORMAT> для вывода локализованной даты.

Теперь поместим этот скрипт в PROJECT_DIR/last-news-feed.php и шаблон в PROJECT_DIR/design/main/templates/rss/last_news.rss. Далее ставим ссылку на RSS-feed где-нибудь на странице сайта, например так:

<a href='/last-news-feed.php'><img src='/design/main/images/xml.gif'></a>

Вот и все!

Обсуждение

Ваш комментарий. Вики-синтаксис разрешён:
   __    ____   ___   __  __  _____
  / /   / __/  / _ \ / / / / / ___/
 / /__ / _/   / // // /_/ / / (_ / 
/____//___/  /____/ \____/  \___/
 
limb2/ru/howtos/rss.txt · Последние изменения: 2010/11/10 10:02 (внешнее изменение)