Zend_Feed_Writer.xml 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.feed.writer">
  4. <title>Zend_Feed_Writer</title>
  5. <sect2 id="zend.feed.writer.introduction">
  6. <title>Introduction</title>
  7. <para>
  8. <classname>Zend_Feed_Writer</classname> is the sibling component to
  9. <classname>Zend_Feed_Reader</classname> responsible for generating feeds for output. It
  10. supports the Atom 1.0 specification (RFC 4287) and RSS 2.0 as specified by the RSS
  11. Advisory Board (RSS 2.0.11). It does not deviate from these standards. It does, however,
  12. offer a simple Extension system which allows for any extension/module for either of
  13. these two specifications to be implemented if they are not provided out of the box.
  14. </para>
  15. <para>
  16. In many ways, <classname>Zend_Feed_Writer</classname> is the inverse of
  17. <classname>Zend_Feed_Reader</classname>. Where <classname>Zend_Feed_Reader</classname>
  18. focused on providing an easy to use architecture fronted by getter methods,
  19. <classname>Zend_Feed_Writer</classname> is fronted by similarly named setters or
  20. mutators. This ensures the API won't pose a learning curve to anyone familiar with
  21. <classname>Zend_Feed_Reader</classname>.
  22. </para>
  23. <para>
  24. As a result of this design, the rest may even be obvious. Behind the scenes, data set on
  25. any <classname>Zend_Feed_Reader</classname> object is translated at render time onto a
  26. <classname>DOMDocument</classname> object using the necessary feed elements. For each
  27. supported feed type there is both an Atom 1.0 and RSS 2.0 renderer. Using a
  28. <classname>DOMDocument</classname> rather a templating solution has numerous advantages,
  29. the most obvious being the ability to export the <classname>DOMDocument</classname> for
  30. additional processing and relying on PHP DOM for correct and valid rendering.
  31. </para>
  32. <para>
  33. As with <classname>Zend_Feed_Reader</classname>, <classname>Zend_Feed_Writer</classname>
  34. is a standalone replacement for <classname>Zend_Feed</classname>'s Builder architecture
  35. and is not compatible with those classes.
  36. </para>
  37. </sect2>
  38. <sect2 id="zend.feed.writer.architecture">
  39. <title>Architecture</title>
  40. <para>
  41. The architecture of <classname>Zend_Feed_Writer</classname> is very simple. It has two
  42. core sets of classes: containers and renderers.
  43. </para>
  44. <para>
  45. The containers include the <classname>Zend_Feed_Writer_Feed</classname> and
  46. <classname>Zend_Feed_Writer_Entry</classname> classes. The Entry classes can be attached
  47. to any Feed class. The sole purpose of these containers is to collect data about the
  48. feed to generate using a simple interface of setter methods. These methods perform some
  49. data validity testing. For example, it will validate any passed URIs, dates, etc. These
  50. checks are not tied to any of the feed standards. The container objects also contain
  51. methods to allow for fast rendering and export of the final feed, and these can be
  52. reused at will.
  53. </para>
  54. <para>
  55. While there are two data containers, there are four renderers - two matching container
  56. renderers per support feed type. The renderer accept a container, and based on its
  57. content attempt to generate a valid feed. If the renderer is unable to generate a valid
  58. feed, perhaps due to the container missing an obligatory data point, it will report this
  59. by throwing an <classname>Exception</classname>. While it is possible to ignore
  60. <classname>Exception</classname>s, this removes the default safeguard of ensuring you
  61. have sufficient data set to render a wholly valid feed.
  62. </para>
  63. <para>
  64. Due to the system being divided between data containers and renderers, it can make
  65. Extensions somewhat interesting. A typical Extension offering namespaced feed and entry
  66. level elements, must itself reflect the exact same architecture, i.e. offer feed and
  67. entry level data containers, and matching renderers. There is, fortunately, no complex
  68. integration work required since all Extension classes are simply registered and
  69. automatically used by the core classes. We'll meet Extensions in more detail at the end
  70. of this section.
  71. </para>
  72. </sect2>
  73. <sect2 id="zend.feed.writer.getting.started">
  74. <title>Getting Started</title>
  75. <para>
  76. Using <classname>Zend_Feed_Reader</classname> is as simple as setting data and
  77. triggering the renderer. Here is an example to generate a minimal Atom 1.0 feed.
  78. </para>
  79. <programlisting language="php"><![CDATA[
  80. /**
  81. * Create the parent feed
  82. */
  83. $feed = new Zend_Feed_Writer_Feed;
  84. $feed->setTitle('Paddy\'s Blog');
  85. $feed->setLink('http://www.example.com');
  86. $feed->setFeedLink('http://www.example.com/atom', 'atom');
  87. $feed->addAuthor(array(
  88. 'name' => 'Paddy',
  89. 'email' => 'paddy@example.com',
  90. 'uri' => 'http://www.example.com',
  91. ));
  92. $feed->setDateModified(time());
  93. $feed->addHub('http://pubsubhubbub.appspot.com/');
  94. /**
  95. * Add one or more entries. Note that entries must
  96. * be manually added once created.
  97. */
  98. $entry = $feed->createEntry();
  99. $entry->setTitle('All Your Base Are Belong To Us');
  100. $entry->setLink('http://www.example.com/all-your-base-are-belong-to-us');
  101. $entry->addAuthor(array(
  102. 'name' => 'Paddy',
  103. 'email' => 'paddy@example.com',
  104. 'uri' => 'http://www.example.com',
  105. ));
  106. $entry->setDateModified(time());
  107. $entry->setDateCreated(time());
  108. $entry->setDescription('Exposing the difficultly of porting games to English.');
  109. $entry->setContent('I am not writing the article. The example is long enough as is ;).');
  110. $feed->addEntry($entry);
  111. /**
  112. * Render the resulting feed to Atom 1.0 and assign to $out.
  113. * You can substitute "atom" with "rss" to generate an RSS 2.0 feed.
  114. */
  115. $out = $feed->export('atom');
  116. ]]></programlisting>
  117. <para>
  118. The output rendered should be as follows:
  119. </para>
  120. <programlisting language="xml">
  121. &#60;?xml version="1.0" encoding="utf-8"?&#62;
  122. &#60;feed xmlns="http://www.w3.org/2005/Atom"&#62;
  123. &#60;title type="text"&#62;Paddy's Blog&#60;/title&#62;
  124. &#60;subtitle type="text"&#62;Writing about PC Games since 176 BC.&#60;/subtitle&#62;
  125. &#60;updated&#62;2009-12-14T20:28:18+00:00&#60;/updated&#62;
  126. &#60;generator uri="http://framework.zend.com" version="1.10.0alpha"&#62;
  127. Zend_Feed_Writer
  128. &#60;/generator&#62;
  129. &#60;link rel="alternate" type="text/html" href="http://www.example.com"/&#62;
  130. &#60;link rel="self" type="application/atom+xml" href="http://www.example.com/atom"/&#62;
  131. &#60;id&#62;http://www.example.com&#60;/id&#62;
  132. &#60;author&#62;
  133. &#60;name&#62;Paddy&#60;/name&#62;
  134. &#60;email&#62;paddy@example.com&#60;/email&#62;
  135. &#60;uri&#62;http://www.example.com&#60;/uri&#62;
  136. &#60;/author&#62;
  137. &#60;link rel="hub" href="http://pubsubhubbub.appspot.com/"/&#62;
  138. &#60;entry&#62;
  139. &#60;title type="html"&#62;&#60;![CDATA[All Your Base Are Belong To Us]]&#62;&#60;/title&#62;
  140. &#60;summary type="html"&#62;
  141. &#60;![CDATA[Exposing the difficultly of porting games to English.]]&#62;
  142. &#60;/summary&#62;
  143. &#60;published&#62;2009-12-14T20:28:18+00:00&#60;/published&#62;
  144. &#60;updated&#62;2009-12-14T20:28:18+00:00&#60;/updated&#62;
  145. &#60;link rel="alternate" type="text/html" href="http://www.example.com/all-your-base-are-belong-to-us"/&#62;
  146. &#60;id&#62;http://www.example.com/all-your-base-are-belong-to-us&#60;/id&#62;
  147. &#60;author&#62;
  148. &#60;name&#62;Paddy&#60;/name&#62;
  149. &#60;email&#62;paddy@example.com&#60;/email&#62;
  150. &#60;uri&#62;http://www.example.com&#60;/uri&#62;
  151. &#60;/author&#62;
  152. &#60;content type="html"&#62;
  153. &#60;![CDATA[I am not writing the article. The example is long enough as is ;).]]&#62;
  154. &#60;/content&#62;
  155. &#60;/entry&#62;
  156. &#60;/feed&#62;
  157. </programlisting>
  158. <para>
  159. This is a perfect Atom 1.0 example. It should be noted that omitting an obligatory point
  160. of data, such as a title, will trigger an <classname>Exception</classname> when
  161. rendering as Atom 1.0. This will differ for RSS 2.0 since a title may be omitted so long
  162. as a description is present. This gives rise to Exceptions that differ between the two
  163. standards depending on the renderer in use. By design,
  164. <classname>Zend_Feed_Writer</classname> will not render an invalid feed for either
  165. standard unless the end-user deliberately elects to ignore all Exceptions.
  166. </para>
  167. </sect2>
  168. </sect1>