Zend_Feed_Writer es el componente hermano de
Zend_Feed_Reader responsable de generar feeds para su salida. Soporta
la especificación Atom 1.0 (RFC 4287) y
RSS 2.0 tal como la especifica el RSS Advisory Board
(RSS 2.0.11). No se desvía de estos estándares. Sin embargo,
ofrece un sencillo sistema de extensiones que permite implementar cualquier extensión y
módulo para cualquiera de estas dos especificaciones si no vienen incluidos de
fábrica.
En muchos sentidos, Zend_Feed_Writer es el inverso de
Zend_Feed_Reader. Mientras que Zend_Feed_Reader
se centra en ofrecer una arquitectura fácil de usar apoyada en métodos getter,
Zend_Feed_Writer se apoya en setters o mutadores con nombres
similares. Esto garantiza que la API no suponga una curva de
aprendizaje para quien esté familiarizado con Zend_Feed_Reader.
Como resultado de este diseño, el resto puede incluso resultar obvio. Tras bambalinas,
los datos establecidos en cualquier objeto contenedor de datos de
Zend_Feed_Writer se traducen, en el momento del renderizado, a un
objeto DOMDocument usando los elementos de feed necesarios. Para cada
tipo de feed soportado existe tanto un renderizador Atom 1.0 como uno RSS 2.0.
Usar una clase DOMDocument en lugar de una solución de plantillas tiene numerosas ventajas,
siendo la más obvia la capacidad de exportar el DOMDocument para
procesamiento adicional y confiar en PHP DOM para
un renderizado correcto y válido.
Al igual que Zend_Feed_Reader, Zend_Feed_Writer
es un reemplazo independiente para la arquitectura Builder de Zend_Feed
y no es compatible con dichas clases.
La arquitectura de Zend_Feed_Writer es muy sencilla. Cuenta con dos
conjuntos principales de clases: contenedores de datos y renderizadores.
Los contenedores incluyen las clases Zend_Feed_Writer_Feed y
Zend_Feed_Writer_Entry. Las clases Entry pueden adjuntarse
a cualquier clase Feed. El único propósito de estos contenedores es recopilar datos sobre el
feed a generar mediante una sencilla interfaz de métodos setter. Estos métodos realizan
algunas pruebas de validez de los datos. Por ejemplo, validarán cualquier URI,
fecha, etc. que se les pase. Estas comprobaciones no están vinculadas a ninguna de las
definiciones de los estándares de feed. Los objetos contenedores también contienen métodos
que permiten un renderizado y exportación rápidos del feed final, y estos pueden
reutilizarse a voluntad.
Además de las clases principales de contenedor de datos, existen dos clases adicionales
específicas de Atom 2.0: Zend_Feed_Writer_Source y
Zend_Feed_Writer_Deleted. La primera implementa los elementos
source de Atom 2.0, que transportan metadatos del feed de origen para una entrada
específica dentro de un feed agregado (es decir, el feed actual no es la fuente original
de la entrada). La segunda implementa el RFC de Atom Tombstones
que permite a los feeds llevar referencias a entradas que han sido eliminadas.
Aunque existen dos tipos principales de contenedores de datos, hay cuatro renderizadores:
dos renderizadores de contenedor coincidentes por cada tipo de feed soportado. Cada
renderizador acepta un contenedor y, en función de su contenido, intenta generar un
marcado de feed válido. Si el renderizador no puede generar un marcado de feed válido,
quizás debido a que al contenedor le falta un dato obligatorio, lo notificará lanzando
una Exception. Aunque es posible ignorar las
Exceptions, esto elimina la salvaguarda predeterminada
de asegurar que se dispone de datos suficientes para renderizar un feed completamente
válido.
Para explicarlo con más claridad, puede construir un conjunto de contenedores de datos para un feed en el que hay un contenedor Feed, al que se han añadido algunos contenedores Entry y un contenedor Deleted. Esto forma una jerarquía de datos que se asemeja a un feed normal. Cuando se realiza el renderizado, esta jerarquía tiene sus piezas pasadas a los renderizadores correspondientes, y los feeds parciales (todos DOMDocuments) se ensamblan después para crear un feed completo. En el caso de los contenedores Source o Deleted (Tombstone), estos se renderizan solo para Atom 2.0 y se ignoran para RSS.
Debido a que el sistema está dividido entre contenedores de datos y renderizadores, esto puede hacer que las extensiones resulten algo interesantes. Una extensión típica que ofrezca elementos con espacio de nombres a nivel de feed y de entrada debe reflejar ella misma esa misma arquitectura, es decir, ofrecer contenedores de datos a nivel de feed y de entrada, y los renderizadores correspondientes. Afortunadamente, no se requiere ningún trabajo de integración complejo, ya que todas las clases de extensión simplemente se registran y son utilizadas automáticamente por las clases principales. Conoceremos las extensiones con más detalle al final de esta sección.
Usar Zend_Feed_Writer es tan sencillo como establecer datos y
disparar el renderizador. Aquí hay un ejemplo para generar un feed Atom 1.0 mínimo.
Como esto demuestra, cada feed o entrada usa un contenedor de datos independiente.
/**
* Create the parent feed
*/
$feed = new Zend_Feed_Writer_Feed;
$feed->setTitle('Paddy\'s Blog');
$feed->setLink('http://www.example.com');
$feed->setFeedLink('http://www.example.com/atom', 'atom');
$feed->addAuthor(array(
'name' => 'Paddy',
'email' => 'paddy@example.com',
'uri' => 'http://www.example.com',
));
$feed->setDateModified(time());
$feed->addHub('http://pubsubhubbub.appspot.com/');
/**
* Add one or more entries. Note that entries must
* be manually added once created.
*/
$entry = $feed->createEntry();
$entry->setTitle('All Your Base Are Belong To Us');
$entry->setLink('http://www.example.com/all-your-base-are-belong-to-us');
$entry->addAuthor(array(
'name' => 'Paddy',
'email' => 'paddy@example.com',
'uri' => 'http://www.example.com',
));
$entry->setDateModified(time());
$entry->setDateCreated(time());
$entry->setDescription('Exposing the difficultly of porting games to English.');
$entry->setContent(
'I am not writing the article. The example is long enough as is ;).'
);
$feed->addEntry($entry);
/**
* Render the resulting feed to Atom 1.0 and assign to $out.
* You can substitute "atom" with "rss" to generate an RSS 2.0 feed.
*/
$out = $feed->export('atom');
La salida renderizada debería ser la siguiente:
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title type="text">Paddy's Blog</title>
<subtitle type="text">Writing about PC Games since 176 BC.</subtitle>
<updated>2009-12-14T20:28:18+00:00</updated>
<generator uri="http://framework.zend.com" version="1.10.0alpha">
Zend_Feed_Writer
</generator>
<link rel="alternate" type="text/html" href="http://www.example.com"/>
<link rel="self" type="application/atom+xml"
href="http://www.example.com/atom"/>
<id>http://www.example.com</id>
<author>
<name>Paddy</name>
<email>paddy@example.com</email>
<uri>http://www.example.com</uri>
</author>
<link rel="hub" href="http://pubsubhubbub.appspot.com/"/>
<entry>
<title type="html"><![CDATA[All Your Base Are Belong To
Us]]></title>
<summary type="html">
<![CDATA[Exposing the difficultly of porting games to
English.]]>
</summary>
<published>2009-12-14T20:28:18+00:00</published>
<updated>2009-12-14T20:28:18+00:00</updated>
<link rel="alternate" type="text/html"
href="http://www.example.com/all-your-base-are-belong-to-us"/>
<id>http://www.example.com/all-your-base-are-belong-to-us</id>
<author>
<name>Paddy</name>
<email>paddy@example.com</email>
<uri>http://www.example.com</uri>
</author>
<content type="html">
<![CDATA[I am not writing the article.
The example is long enough as is ;).]]>
</content>
</entry>
</feed>
Este es un ejemplo Atom 1.0 perfectamente válido. Cabe destacar que omitir un
dato obligatorio, como un título, disparará una
Exception al renderizar como Atom 1.0. Esto será diferente para
RSS 2.0, ya que un título puede omitirse siempre que se incluya una
descripción. Esto da lugar a excepciones que difieren entre ambos estándares dependiendo
del renderizador en uso. Por diseño, Zend_Feed_Writer no
renderizará un feed inválido para ninguno de los estándares a menos que el usuario final
decida deliberadamente ignorar todas las excepciones. Esta salvaguarda incorporada se
añadió para garantizar que los usuarios sin conocimientos profundos de las especificaciones
correspondientes tengan un poco menos de que preocuparse.
Antes de poder renderizar un feed, primero debe configurar los datos necesarios para
el feed que se va a renderizar. Esto utiliza una sencilla API de
estilo setter que a su vez sirve como un método inicial de validación de los datos
establecidos. Por diseño, la API coincide estrechamente con la de
Zend_Feed_Reader para evitar confusión e incertidumbre
innecesarias.
![]() |
Nota |
|---|---|
Los usuarios han comentado que la falta de una notación sencilla basada en arrays para los datos de entrada provoca extensos tramos de código. Esto se abordará en una versión futura. |
Zend_Feed_Writer ofrece esta API a través de
sus clases contenedoras de datos Zend_Feed_Writer_Feed y
Zend_Feed_Writer_Entry (sin mencionar las clases específicas de
Atom 2.0 y las de extensión). Estas clases simplemente almacenan
todos los datos del feed de forma independiente del tipo, lo que significa que puede
reutilizar cualquier contenedor de datos con cualquier renderizador sin necesitar trabajo
adicional. Ambas clases también son susceptibles de ser extendidas, lo que significa que
una extensión puede definir sus propias clases contenedoras que se registran en las
clases contenedoras base como extensiones, y se comprueban cuando cualquier llamada a
método dispara el método __call() del contenedor base.
Aquí hay un resumen de la API Core para Feeds. Debe tener en cuenta
que comprende no solo los estándares básicos de RSS y Atom, sino que
también contempla una serie de extensiones incluidas junto con
Zend_Feed_Writer. La nomenclatura de estos
métodos provenientes de extensiones sigue siendo bastante genérica: todos los métodos de
extensión operan al mismo nivel que la API Core, aunque también
permitimos recuperar cualquier objeto de extensión específico por separado si es
necesario.
La API a nivel de feed para datos está contenida en
Zend_Feed_Writer_Feed. Además de la API
detallada a continuación, la clase también implementa las interfaces
Countable e Iterator.
Tabla 33.7. Métodos de la API a nivel de feed
setId() |
Establece un ID único asociado con este feed. Para Atom 1.0 esto es un elemento atom:id, mientras que para RSS 2.0 se añade como un elemento guid. Estos son opcionales siempre que se añada un enlace, es decir, el enlace se establece como el ID. |
setTitle() |
Establece el título del feed. |
setDescription() |
Establece la descripción de texto del feed. |
setLink() |
Establece una URI al sitio web HTML que contiene la misma o similar información que este feed (es decir, si el feed proviene de un blog, debe proporcionar la URI del blog donde se pueda leer la versión HTML de las entradas). |
setFeedLinks() |
Añade un enlace a un feed XML, ya sea el feed que se está generando o una URI alternativa que apunte al mismo feed pero en un formato diferente. Como mínimo, se recomienda incluir un enlace al feed que se está generando para que tenga una URI final identificable que permita a un cliente rastrear sus cambios de ubicación sin necesitar redirecciones constantes. El parámetro es un array de arrays, donde cada subarray contiene las claves "type" y "uri". El type debe ser uno de "atom", "rss" o "rdf". |
addAuthors() |
Establece los datos de los autores. El parámetro es un array de arrays donde cada subarray puede contener las claves "name", "email" y "uri". El valor "uri" solo aplica para feeds Atom, ya que RSS no dispone de forma de mostrarlo. Para RSS 2.0, el renderizado creará dos elementos: un elemento author que contiene la referencia de email con el nombre entre paréntesis, y un elemento creator de Dublin Core que solo contiene el nombre. |
addAuthor() |
Establece los datos de un único autor siguiendo el mismo formato de array descrito anteriormente para un único subarray. |
setDateCreated() |
Establece la fecha en la que se creó este feed. Generalmente
solo aplicable a Atom, donde representa la fecha en la que se creó el
recurso descrito por un documento Atom 1.0. El parámetro esperado
puede ser una marca de tiempo UNIX o un objeto
Zend_Date.
|
setDateModified() |
Establece la fecha en la que se modificó por última vez este feed. El
parámetro esperado puede ser una marca de tiempo UNIX o
un objeto Zend_Date.
|
setLastBuildDate() |
Establece la fecha en la que se construyó por última vez este feed. El
parámetro esperado puede ser una marca de tiempo UNIX o
un objeto Zend_Date. Esto solo se
renderizará para feeds RSS 2.0 y se renderiza
automáticamente como la fecha actual por defecto cuando no se establece
explícitamente.
|
setLanguage() |
Establece el idioma del feed. Se omitirá a menos que se establezca. |
setGenerator() |
Permite establecer un generador. El parámetro debe ser un
array que contenga las claves "name", "version" y "uri". Si se omite,
se añadirá un generador por defecto que hace referencia a
Zend_Feed_Writer, la versión actual de Zend
Framework y la URI del Framework.
|
setCopyright() |
Establece un aviso de copyright asociado con el feed. |
addHubs() |
Acepta un array de endpoints Hub de Pubsubhubbub para renderizarlos en
el feed como enlaces Atom, de modo que los suscriptores PuSH puedan
suscribirse a su feed. Tenga en cuenta que debe implementar un Publisher
de Pubsubhubbub para que se habiliten las actualizaciones en tiempo real.
Un Publisher puede implementarse usando
Zend_Feed_Pubsubhubbub_Publisher.
El método addHub() permite añadir
un único hub a la vez.
|
addCategories() |
Acepta un array de categorías para renderizar, donde cada elemento es a
su vez un array cuyas posibles claves incluyen "term", "label" y
"scheme". El "term" es típicamente un nombre de categoría adecuado para
su inclusión en una URI. El "label" puede ser un
nombre de categoría legible por humanos que soporte caracteres especiales
(se codifica en HTML durante el renderizado) y es
una clave requerida. El "scheme" (denominado domain en
RSS) es opcional pero debe ser una
URI válida. El método
addCategory() permite añadir una única categoría
a la vez.
|
setImage() |
Acepta un array de metadatos de imagen para una imagen RSS o un logo Atom. Atom 1.0 solo requiere una URI. RSS 2.0 requiere una URI, un enlace HTML y un título de imagen. RSS 2.0 opcionalmente puede enviar un ancho, alto y descripción de imagen. El parámetro array puede contener estos usando las claves: uri, link, title, description, height y width. El enlace HTML de RSS 2.0 debe apuntar a la página HTML de la fuente del feed. |
createEntry() |
Devuelve una nueva instancia de
Zend_Feed_Writer_Entry. Este es el contenedor de
datos a nivel de entrada. Las nuevas entradas no se asignan
automáticamente al feed actual, por lo que debe llamar explícitamente a
addEntry() para añadir la entrada al renderizado.
|
addEntry() |
Añade una instancia de Zend_Feed_Writer_Entry
al contenedor de feed actual para su renderizado.
|
createTombstone() |
Devuelve una nueva instancia de
Zend_Feed_Writer_Deleted. Este es el contenedor
de datos a nivel de Tombstone de Atom 2.0. Las nuevas entradas no se
asignan automáticamente al feed actual, por lo que debe llamar
explícitamente a addTombstone() para añadir la
entrada eliminada al renderizado.
|
addTombstone() |
Añade una instancia de Zend_Feed_Writer_Deleted al
contenedor de feed actual para su renderizado.
|
removeEntry() |
Acepta un parámetro que indica un índice de array de la entrada a eliminar del feed. |
export() |
Exporta toda la jerarquía de datos a un feed XML. El
método tiene dos parámetros. El primero es el tipo de feed, uno de "atom"
o "rss". El segundo es un booleano opcional para establecer si se
lanzan excepciones. El valor por defecto es TRUE.
|
![]() |
Nota |
|---|---|
Además de estos setters, también existen getters correspondientes para recuperar
datos del contenedor de datos Entry. Por ejemplo, |
Aquí hay un resumen de la API Core para Entries e Items. Debe tener
en cuenta que comprende no solo los estándares básicos de RSS y Atom,
sino que también contempla una serie de extensiones incluidas junto con
Zend_Feed_Writer. La nomenclatura de estos
métodos provenientes de extensiones sigue siendo bastante genérica: todos los métodos de
extensión operan al mismo nivel que la API Core, aunque también
permitimos recuperar cualquier objeto de extensión específico por separado si es
necesario.
La API a nivel de entrada para datos está contenida en
Zend_Feed_Writer_Entry.
Tabla 33.8. Métodos de la API a nivel de entrada
setId() |
Establece un ID único asociado con esta entrada. Para Atom 1.0 esto es un elemento atom:id, mientras que para RSS 2.0 se añade como un elemento guid. Estos son opcionales siempre que se añada un enlace, es decir, el enlace se establece como el ID. |
setTitle() |
Establece el título de la entrada. |
setDescription() |
Establece la descripción de texto de la entrada. |
setContent() |
Establece el contenido de la entrada. |
setLink() |
Establece una URI al sitio web HTML que contiene la misma o similar información que esta entrada (es decir, si el feed proviene de un blog, debe proporcionar la URI del artículo del blog donde se pueda leer la versión HTML de la entrada). |
addAuthors() |
Establece los datos de los autores. El parámetro es un array de arrays donde cada subarray puede contener las claves "name", "email" y "uri". El valor "uri" solo aplica para feeds Atom, ya que RSS no dispone de forma de mostrarlo. Para RSS 2.0, el renderizado creará dos elementos: un elemento author que contiene la referencia de email con el nombre entre paréntesis, y un elemento creator de Dublin Core que solo contiene el nombre. |
addAuthor() |
Establece los datos de un único autor siguiendo el mismo formato descrito anteriormente para un único subarray. |
setDateCreated() |
Establece la fecha en la que se creó este feed. Generalmente
solo aplicable a Atom, donde representa la fecha en la que se creó el
recurso descrito por un documento Atom 1.0. El parámetro esperado
puede ser una marca de tiempo UNIX o un objeto
Zend_Date. Si se omite, se usará la fecha y
hora actuales.
|
setDateModified() |
Establece la fecha en la que se modificó por última vez este feed. El
parámetro esperado puede ser una marca de tiempo UNIX o
un objeto Zend_Date. Si se omite, se usará la
fecha y hora actuales.
|
setCopyright() |
Establece un aviso de copyright asociado con el feed. |
addCategories() |
Acepta un array de categorías para renderizar, donde cada elemento es a
su vez un array cuyas posibles claves incluyen "term", "label" y
"scheme". El "term" es típicamente un nombre de categoría adecuado para
su inclusión en una URI. El "label" puede ser un
nombre de categoría legible por humanos que soporte caracteres especiales
(se codifica durante el renderizado) y es una clave requerida. El
"scheme" (denominado domain en RSS) es opcional
pero debe ser una URI válida. El método
addCategory() permite añadir una única categoría
a la vez.
|
setCommentCount() |
Establece el número de comentarios asociados con esta entrada. El renderizado difiere entre RSS y Atom 2.0 según el elemento o atributo necesario. |
setEnclosure() |
Añade un enclosure a la entrada. El parámetro array puede contener las claves 'uri', 'type' y 'length'. Solo 'uri' es obligatorio para Atom, aunque los demás también deben proporcionarse o el renderizado RSS (donde son obligatorios) lanzará una excepción. |
setCommentLink() |
Establece un enlace a una página HTML que contiene los comentarios asociados con esta entrada. |
setCommentFeedLink() |
Establece un enlace a un feed XML que contiene los comentarios asociados con esta entrada. El parámetro es un array que contiene las claves "uri" y "type", donde el type es uno de "rdf", "rss" o "atom". |
setCommentFeedLinks() |
Igual que setCommentFeedLink() excepto que
acepta un array de arrays, donde cada subarray contiene los
parámetros esperados de setCommentFeedLink().
|
setEncoding() |
Establece la codificación del texto de la entrada. Por defecto será UTF-8, que es la codificación preferida. |
![]() |
Nota |
|---|---|
Además de estos setters, también existen getters correspondientes para recuperar datos del contenedor de datos Entry. |
![[Note]](images/note.png)