RSS-каналы в CakePHP
Не так давно я заметил, что Thunderbird больше не импортирует и не обновляет недействительные (частично) RSS-каналы. Ну хорошо.., мои то каналы всегда были такими, как я предполагал. В то время (4 года назад) я не знал, что тег «author» использовался только для адресов электронной почты, а не для имен пользователей. Стоит сказать, что по-простому обработать «dc: creator» вместо «author» было невозможно.
Так что в моей той ленте была и эта и еще несколько других «ошибок». Но они работали, поэтому я никогда не беспокоился. До недавнего времени.
Обновив больше приложений до 2 версии(2.x), я понял, что теперь у нас есть такие замечательные View классы для других типов данных (Json, Csv, Xml). И так как RSS в значительной степени все таки является XML, я подумал, какого черта мы все еще используем действительно старую и частично работающую архитектуру helper + view + layout?
Ее нужно обновить до View класса, а также IMO. Поэтому я открыл тикет и принялся за обсуждение.
Цели:
-
Осуществить поддержку действий без просмотра через сериализацию.
-
Избавиться от абсурдных и многословных «встроенных» объявлений пространства имен.
-
Упростить использование пространств имен и их префиксов (автоматически добавляются только те, которые фактически используются).
-
Осуществить поддержку CDATA (неэкранированный контент).
Сначала, я просто выбросил весь вспомогательный код в классе. Но это, на самом деле, не сработало, поскольку рендеринг существующего кода визуализирует каждый элемент сам по себе, таким образом, не имея никакой информации о глобальных пространствах имен.Мне пришлось отказаться от всего этого и начать с нуля, ориентируясь на то, как работает XmlClass.
Поэтому я использовал свой старый фид для того, чтобы постепенно заставить его работать снова, используя готовую структуру массива и только один вызов Xml::fromArray () в самом конце.
Я поместил класс в Tools плагин и добавил несколько базовых тестов.
Если вы подключите плагин, не забудьте вызвать CakePlugin::load('Tools') или CakePlugin::loadAll().
Использование:
Сначала нам нужно действие, чтобы вывести наш фид с помощью Router::parseExtensions(array('rss')) (в вашем файле маршрутов или bootstrap файле) и получить к нему доступ через:
/controller/action.rss
Нам также нужно добавить $ this-> viewClass = 'Tools.Rss' к каждому действию, которое выводит RSS, так как компонент RequestHandler переключается только для основных классов Xml и Json View.
Базовый фид содержит как минимум заголовок, описание и ссылку как для канала, так и для элементов. Также рекомендуется добавить ссылку atom: на местоположение самого канала.
$this->viewClass = 'Tools.Rss'; // Important if you do not have an auto-switch for the rss extension $atomLink = array('controller' => 'topics', 'action' => 'feed', 'ext' => 'rss'); // example controller and action $data = array( 'channel' => array( 'title' => 'Channel title', 'link' => 'http://channel.example.org', 'description' => 'Channel description', 'atom:link' => array('@href' => $atomLink), ), 'items' => array( array('title' => 'Title One', 'link' => 'http://example.org/one', 'author' => 'one@example.org', 'description' => 'Content one'), array('title' => 'Title Two', 'link' => 'http://example.org/two', 'author' => 'two@example.org', 'description' => 'Content two'), ) ); $this->set(array('data' => $data, '_serialize' => 'data'));
Кроме того имеется возможность использовать одно из уже встроенных пространств имен - например, если вы хотите отобразить имя пользователя в сообщении вместо электронной почты (что вы по-идее должны^^).Вы также можете добавить контент как CDATA. Описание должно быть простым текстом, поэтому, если у вас есть HTML-разметка, не забудьте удалить ее для описания, но передайте ее неэкраннировано в теге content namespace.
Расширяемость:
Вы можете легко зарегистрировать новые пространства имен, к примеру , для поддержки каналов данных Google (xmlns: g = "http://base.google.com/ns/1.0"):
$data = array( 'document' => array( 'namespace' => array( 'g' => 'http://base.google.com/ns/1.0' ) ) 'channel' => array( ... ), 'items' => array( array('g:price' => 25, ...), ) ); $this->set(array('data' => $data, '_serialize' => 'data'));
Так что забудьте, про этот сложный способ настроить RSS-каналы через просмотр файлов. Этот путь вернее.
Сопоставление View классов
В документации вы узнаете, как использовать отображение классов представления (view class mapping) для автоматического ответа с RssView на каждый запрос к расширению rss:
'rss' => 'Tools.Rss'
Использование parseExtensions() и RequestHandler избавит вас от дополнительной строки конфигурации представления в действиях.
Передача параметров:
Если вам нужно передать параметры в это представление, используйте строки запроса:
.../action.rss?key1=value1&key2=value2
Перспективы в будущем:
Есть еще много того, что можно реализовать.К примеру, этот пример по-прежнему не обрабатывает все возможные варианты использования.Также стоит обсудить, можно ли дополнительно обобщить класс не только для поддержки RSS-каналов, но и для других типов каналов.