Агрегация и модуль Feeds

Две недели назад, когда я еще изо всех сил загорал на пляже, на сайте компании Trellon внезапно появилась шестая статья цикла "20 API за 20 дней" (20 дней, my ass). В статье рассказывается о модуле Feeds и о том, что он умеет. Также упоминается процесс создания собственных плагинов на примере парсера. Статья, на мой взгляд, никакая, особенно по сравнению с предыдущими. Добрая половина статьи занята пересказом на разные лады того, как модуль Feeds хорош, потому что "ООП, расширяем и импортирует все подряд". А собственно API модуля, то есть основной теме цикла, посвящено лишь 2 врезки кода без достойных объяснений, не говоря уже о живых и актуальных примерах. Но, как говорится, назвался груздем - заткнись и переводи. Так что вашему вниманию предлагается перевод шестой статьи цикла "20 API за 20 дней".

Оригинальная статья: Feeds ans Aggregation.
Автор: Мартин Грабовцин.

Агрегация и модуль Feeds

Агрегация новостей из RSS-лент всегда была одной из сильных сторон Друпала. В отличие от других платформ CMS, где агрегация доступна только через сторонние модули, в Друпале она уже достаточно давно встроена в ядро. Наличие агрегации позволяет пользователям вытягивать новости с многочисленных веб-сайтов, автоматически распределять их по категориям и выводить вместе с другим содержимым сайта.

Хотя стандартный aggregator весьма полезен сам по себе, были разработаны и другие, расширяющие его возможности модули. Модуль Aggregation заходит дальше обычной синдикации содержимого и позволяет осуществлять аутентификацию и импортировать собственные XML-схемы. Модуль FeedAPI позволяет импортировать новостное содержимое прямо в сайт и интегрировать его с другими модулями, такими как Views, CCK и Organic Groups. Также FeedAPI умеет синдицировать другие популярные XML-форматы, такие как KML, iCal и другие. Вместе эти модули серьезно расширяют функционал агрегации в Друпале.

Как это обычно бывает со всеми хорошими идеями, рано или поздно появляются идеи еще лучше. Модуль Feeds - преемник FeedAPI, решает ряд проблем, существовавших в ранних модулях агрегации. Также он предоставляет довольно подробный API для связи с новостными лентами, содержащими данные разного типа. В данной заметке мы сфокусируемся на способах работы с ним.

Достоинства модуля Feeds

В компании Trellon мы используем модуль Feeds для решения клиентских задач очень часто и далеко не только для сбора содержимого из RSS-лент. Это не просто парсер XML, и потому важно понять следующие способы применения модуля Feeds:

Агрегация данных из разных источников
Модуль Feeds поддерживает агрегацию лент RSS, а также умеет импортировать данные из других источников, таких как CSV-файлы, страницы HTML и загруженные на сервер документы. Это значит, что вы сможете использовать модуль Feeds в качестве инструмента для импорта загружаемого на сайт необходимого содержимого. Например, дампов данных из других систем, которые нужно передать в Друпал.

Расширение модуля Feeds
Модуль Feeds обладает полноценным API, позволяющим расширять базовый функционал в собственных модулях. Вы сможете написать свои функции скачивания новостей (далее, фетчеры - прим. пер.), парсеры и препроцессоры без особых усилий. Благодаря расширяемости у разработчиков теперь есть единый метод решения задач по импорту данных.

Постановка лент в очередь задач
Одной из серьезных проблем модуля FeedsAPI является работа на сайтах с большим количеством новостных лент, в ситуациях, когда Друпал не может эффективно обработать множество источников новостей за раз (что вносит сумятицу). API очередей (Queue API - прим. пер.) позволяет хранить обрабатываемые ленты как задачи и вызывать их для скачивания и обработки новостей по мере готовности Друпала.

Переносимость лент
В модуле Feeds также есть API для хранения и распространения лент прямо в коде модулей. Это значит, что если разработчику для работы модуля необходимо, чтобы была включена та или иная лента, можно описать ее прямо в этом же модуле. Таким образом ленты легко переносить между разными серверами.

ООП и CTools
Модуль Feeds глубоко интегрирован с CTools и использует объектно-ориентированный подход в коде. Хотя это и может вызвать затруднения у разработчиков, не привыкших к ООП, такой подход обеспечивает более эффективную разработку новых парсеров через механизм наследования классов.

Перечисленные функции представляют собой важный инструментарий для расширения Друпала. Модуль Feeds полезен для регулярного импорта и обработки перед отображением всех видов содержимого, а не только RSS-лент. Постановка импорта в очередь запланированных задач создает поддержку транзакций, за началом и окончанием каждой можно следить и управлять ими. А возможность экспортировать ленты между серверами с помощью модулей означает, что теперь комплексные ленты можно передавать во множество систем, что дает нам новые стратегии по перемещению данных с одного сайта на другой.

Расширение модуля Feeds с помощью плагинов

Самое главное преимущество Feeds над модулем FeedAPI - это то, что Feeds написан с использованием ООП и модуля CTools. Однако этот момент может смутить разработчиков, так как в результате разработка несколько отходит от модели хуков, использующейся при расширении других частей Друпала.

CTools предоставляет прототипы для самых разных аспектов загрузки данных из ленты. Эти прототипы и нужно использовать для создания плагинов. Именно через плагины модуль Feeds можно расширить собственным импортом (тут как-будто незаконченная фраза - прим. пер.)...

У модуля Feeds есть существенное преимущество перед FeedAPI: он написан с применением ООП и модуля CTools. Это значит, что вы сможете расширить его без особых усилий. Модуль Feeds поддерживает три типа плагинов:

  • Фетчер - плагин ответственен за считывание данных из разных источников. В модуль Feeds включены фетчеры FeedsHTTPFetcher и FeedsFileFetcher. Реализация собственных фетчеров позволит Feeds получать данные из самых разных источников. Например, можно написать фетчер внешней базы данных. Любой фетчер должен получать на входе только необработанные данные.
  • Парсер - этот плагин получает и упорядочивает данные от фетчера. Парсер должен преобразовывать необработанные данные в поддерживаемом формате в структуру PHP. Это означает, что RSS-парсер получает данные от HTTP-фетчера и преобразовывает полученный XML в структуры данных, содержащие информацию о сообщениях (заголовок, тело, имя автора и дату публикации).
  • Процессор - плагин представляет собой последнюю часть стека обработки в модуле Feeds. Он получает и обрабатывает структурированные данные от парсера. Обработка может использовать любой необходимый код, например, создавать новые ноды или пользователей. В модуле Feeds уже есть процессор данных (Data processor), который умеет заполнять таблицы БД данными, полученными от парсера.
Каждый новый плагин должен наследовать базовый класс, то есть новый парсер должен наследовать класс FeedsParser и т.п. Через механизм наследования плагинов Feeds определяет, какие плагины какого типа реализуются в новом модуле. Вот так нужно реализовывать hook_feeds_plugin():
function MYMODULE_feeds_plugins() {
  $info = array();
  $info['MymoduleXMLParser'] = array(
    'name' => 'Custom XML',
    'description' => 'Parses custom data from XML source.',
    'handler' => array(
      'parent' => 'FeedsParser', // Плагин должен быть прямым или непрямым наследником классов FeedsFetcher, FeedsParser или FeedsProcessor.
      'class' => 'MymoduleXMLParser',
      'file' => 'MymoduleXMLParser.inc',
      'path' => drupal_get_path('module', 'MYMODULE'),
    ),
  );
  return $info;
}
Функция возвращает массив, в котором объявляется, что в модуле есть новый класс MymoduleXMLParser в файле MymoduleXMLParser.inc. Это стандартное определение плагина, известное по модулю CTools. Все новые классы-парсеры должны переопределять два приведенных ниже метода. Для фетчеров и процессоров нужно переопределять другие методы.
class MymoduleXMLParser extends FeedsParser {
  /**
  * Переопределение метода parse()
  */
  public function parse(FeedsSource $source, FeedsFetcherResult $fetcher_result)) {
    // эта функция должна обрабатывать исходные данные и создавать выходной объект для возврата
    $result = new FeedsParserResult();
    $item = array('field1' => 'value');
    $result->addItem($item);
    //возвращаем результаты
    return $result;
  }
/** * Функция возвращает список полей, возвращаемых парсером */ public function getMappingSources() { return array( 'field1' => array( 'name' => t('Item URL (link)'), 'description' => t('URL of the feed item.'), ), ); } }

Структура плагинов модуля Feeds - очень гибкая, а для агрегации разных типов данных из разных источников плагины можно комбинировать.

Статус модуля в Drupal 7

Feeds - самый гибкий модуль-агрегатор в Друпале, его используют на многих сайтах. Теперь, когда для Drupal 7 вышла бета, еще больше людей поставят D7 на сайты. Хорошая новость в том, что и Feeds и CTools уже портированы в D7. На данный момент - в альфа-версии. Так что мы ожидаем, что модуль Feeds будет по-прежнему заправлять всеми задачами агрегации данных.

Комментарии