Zend_Feed_Writer.xml 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  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 <acronym>RSS</acronym> 2.0 as
  11. specified by the <acronym>RSS</acronym> Advisory Board (<acronym>RSS</acronym> 2.0.11).
  12. It does not deviate from these standards. It does, however, offer a simple Extension
  13. system which allows for any extension and module for either of these two specifications
  14. to be implemented if they are not provided out of the box.
  15. </para>
  16. <para>
  17. In many ways, <classname>Zend_Feed_Writer</classname> is the inverse of
  18. <classname>Zend_Feed_Reader</classname>. Where <classname>Zend_Feed_Reader</classname>
  19. focused on providing an easy to use architecture fronted by getter methods,
  20. <classname>Zend_Feed_Writer</classname> is fronted by similarly named setters or
  21. mutators. This ensures the <acronym>API</acronym> won't pose a learning curve to anyone
  22. familiar with <classname>Zend_Feed_Reader</classname>.
  23. </para>
  24. <para>
  25. As a result of this design, the rest may even be obvious. Behind the scenes, data set on
  26. any <classname>Zend_Feed_Reader</classname> object is translated at render time onto a
  27. DOMDocument object using the necessary feed elements. For each
  28. supported feed type there is both an Atom 1.0 and <acronym>RSS</acronym> 2.0 renderer.
  29. Using a DOMDocument rather a templating solution has numerous advantages,
  30. the most obvious being the ability to export the DOMDocument for
  31. additional processing and relying on <acronym>PHP</acronym> <acronym>DOM</acronym> for
  32. correct and valid rendering.
  33. </para>
  34. <para>
  35. As with <classname>Zend_Feed_Reader</classname>, <classname>Zend_Feed_Writer</classname>
  36. is a standalone replacement for <classname>Zend_Feed</classname>'s Builder architecture
  37. and is not compatible with those classes.
  38. </para>
  39. </sect2>
  40. <sect2 id="zend.feed.writer.architecture">
  41. <title>Architecture</title>
  42. <para>
  43. The architecture of <classname>Zend_Feed_Writer</classname> is very simple. It has two
  44. core sets of classes: containers and renderers.
  45. </para>
  46. <para>
  47. The containers include the <classname>Zend_Feed_Writer_Feed</classname> and
  48. <classname>Zend_Feed_Writer_Entry</classname> classes. The Entry classes can be attached
  49. to any Feed class. The sole purpose of these containers is to collect data about the
  50. feed to generate using a simple interface of setter methods. These methods perform some
  51. data validity testing. For example, it will validate any passed <acronym>URI</acronym>s,
  52. dates, etc. These checks are not tied to any of the feed standards. The container
  53. objects also contain methods to allow for fast rendering and export of the final feed,
  54. and these can be reused at will.
  55. </para>
  56. <para>
  57. While there are two data containers, there are four renderers - two matching container
  58. renderers per support feed type. The renderer accept a container, and based on its
  59. content attempt to generate a valid feed. If the renderer is unable to generate a valid
  60. feed, perhaps due to the container missing an obligatory data point, it will report this
  61. by throwing an <classname>Exception</classname>. While it is possible to ignore
  62. <classname>Exception</classname>s, this removes the default safeguard of ensuring you
  63. have sufficient data set to render a wholly valid feed.
  64. </para>
  65. <para>
  66. Due to the system being divided between data containers and renderers, it can make
  67. Extensions somewhat interesting. A typical Extension offering namespaced feed and entry
  68. level elements, must itself reflect the exact same architecture, i.e. offer feed and
  69. entry level data containers, and matching renderers. There is, fortunately, no complex
  70. integration work required since all Extension classes are simply registered and
  71. automatically used by the core classes. We'll meet Extensions in more detail at the end
  72. of this section.
  73. </para>
  74. </sect2>
  75. <sect2 id="zend.feed.writer.getting.started">
  76. <title>Getting Started</title>
  77. <para>
  78. Using <classname>Zend_Feed_Reader</classname> is as simple as setting data and
  79. triggering the renderer. Here is an example to generate a minimal Atom 1.0 feed.
  80. </para>
  81. <programlisting language="php"><![CDATA[
  82. /**
  83. * Create the parent feed
  84. */
  85. $feed = new Zend_Feed_Writer_Feed;
  86. $feed->setTitle('Paddy\'s Blog');
  87. $feed->setLink('http://www.example.com');
  88. $feed->setFeedLink('http://www.example.com/atom', 'atom');
  89. $feed->addAuthor(array(
  90. 'name' => 'Paddy',
  91. 'email' => 'paddy@example.com',
  92. 'uri' => 'http://www.example.com',
  93. ));
  94. $feed->setDateModified(time());
  95. $feed->addHub('http://pubsubhubbub.appspot.com/');
  96. /**
  97. * Add one or more entries. Note that entries must
  98. * be manually added once created.
  99. */
  100. $entry = $feed->createEntry();
  101. $entry->setTitle('All Your Base Are Belong To Us');
  102. $entry->setLink('http://www.example.com/all-your-base-are-belong-to-us');
  103. $entry->addAuthor(array(
  104. 'name' => 'Paddy',
  105. 'email' => 'paddy@example.com',
  106. 'uri' => 'http://www.example.com',
  107. ));
  108. $entry->setDateModified(time());
  109. $entry->setDateCreated(time());
  110. $entry->setDescription('Exposing the difficultly of porting games to English.');
  111. $entry->setContent(
  112. 'I am not writing the article. The example is long enough as is ;).'
  113. );
  114. $feed->addEntry($entry);
  115. /**
  116. * Render the resulting feed to Atom 1.0 and assign to $out.
  117. * You can substitute "atom" with "rss" to generate an RSS 2.0 feed.
  118. */
  119. $out = $feed->export('atom');
  120. ]]></programlisting>
  121. <para>
  122. The output rendered should be as follows:
  123. </para>
  124. <programlisting language="xml"><![CDATA[
  125. <?xml version="1.0" encoding="utf-8"?>
  126. <feed xmlns="http://www.w3.org/2005/Atom">
  127. <title type="text">Paddy's Blog</title>
  128. <subtitle type="text">Writing about PC Games since 176 BC.</subtitle>
  129. <updated>2009-12-14T20:28:18+00:00</updated>
  130. <generator uri="http://framework.zend.com" version="1.10.0alpha">
  131. Zend_Feed_Writer
  132. </generator>
  133. <link rel="alternate" type="text/html" href="http://www.example.com"/>
  134. <link rel="self" type="application/atom+xml"
  135. href="http://www.example.com/atom"/>
  136. <id>http://www.example.com</id>
  137. <author>
  138. <name>Paddy</name>
  139. <email>paddy@example.com</email>
  140. <uri>http://www.example.com</uri>
  141. </author>
  142. <link rel="hub" href="http://pubsubhubbub.appspot.com/"/>
  143. <entry>
  144. <title type="html"><![CDATA[All Your Base Are Belong To
  145. Us]]]]><![CDATA[></title>
  146. <summary type="html">
  147. <![CDATA[Exposing the difficultly of porting games to
  148. English.]]]]><![CDATA[>
  149. </summary>
  150. <published>2009-12-14T20:28:18+00:00</published>
  151. <updated>2009-12-14T20:28:18+00:00</updated>
  152. <link rel="alternate" type="text/html"
  153. href="http://www.example.com/all-your-base-are-belong-to-us"/>
  154. <id>http://www.example.com/all-your-base-are-belong-to-us</id>
  155. <author>
  156. <name>Paddy</name>
  157. <email>paddy@example.com</email>
  158. <uri>http://www.example.com</uri>
  159. </author>
  160. <content type="html">
  161. <![CDATA[I am not writing the article.
  162. The example is long enough as is ;).]]]]><![CDATA[>
  163. </content>
  164. </entry>
  165. </feed>
  166. ]]></programlisting>
  167. <para>
  168. This is a perfectly valid Atom 1.0 example. It should be noted that omitting an
  169. obligatory point of data, such as a title, will trigger an
  170. <classname>Exception</classname> when rendering as Atom 1.0. This will differ for
  171. <acronym>RSS</acronym> 2.0 since a title may be omitted so long as a description is
  172. present. This gives rise to Exceptions that differ between the two standards depending
  173. on the renderer in use. By design, <classname>Zend_Feed_Writer</classname> will not
  174. render an invalid feed for either standard unless the end-user deliberately elects to
  175. ignore all Exceptions.
  176. </para>
  177. </sect2>
  178. <sect2 id="zend.feed.writer.setting.feed.data.points">
  179. <title>Setting Feed Data Points</title>
  180. <para>
  181. Before you can render a feed, you must first setup the data necessary for
  182. the feed being rendered. This utilises a simple setter style <acronym>API</acronym>
  183. which doubles as an initial method for validating the data being set. By design, the
  184. <acronym>API</acronym> closely matches that for <classname>Zend_Feed_Reader</classname>
  185. to avoid undue confusion and uncertainty.
  186. </para>
  187. <para>
  188. <classname>Zend_Feed_Writer</classname> offers this <acronym>API</acronym> via its data
  189. container classes <classname>Zend_Feed_Writer_Feed</classname> and
  190. <classname>Zend_Feed_Writer_Entry</classname>. These classes merely store
  191. all feed data in type-agnostic manner, meaning you may reuse any data
  192. container with any renderer without requiring additional work. Both classes
  193. are also amenable to Extensions, meaning that an Extension may define its own
  194. container classes which are registered to the base container classes as extensions, and
  195. are checked when any method call triggers the base container's
  196. <methodname>__call()</methodname> method.
  197. </para>
  198. <para>
  199. Here's a summary of the Core <acronym>API</acronym> for Feeds. You should note it
  200. comprises not only the basic <acronym>RSS</acronym> and Atom standards, but also
  201. accounts for a number of included Extensions bundled with
  202. <classname>Zend_Feed_Writer</classname>. The naming of these
  203. Extension sourced methods remain fairly generic - all Extension
  204. methods operate at the same level as the Core <acronym>API</acronym> though we do allow
  205. you to retrieve any specific Extension object separately if required.
  206. </para>
  207. <table>
  208. <title>Feed Level API Methods</title>
  209. <tgroup cols="2">
  210. <tbody>
  211. <row>
  212. <entry><methodname>setId()</methodname></entry>
  213. <entry>
  214. Set a unique ID associated with this feed. For Atom 1.0
  215. this is an atom:id element, whereas for <acronym>RSS</acronym> 2.0 it
  216. is added as a guid element. These are optional so long as a link is
  217. added, i.e. the link is set as the ID.
  218. </entry>
  219. </row>
  220. <row>
  221. <entry><methodname>setTitle()</methodname></entry>
  222. <entry>Set the title of the feed.</entry>
  223. </row>
  224. <row>
  225. <entry><methodname>setDescription()</methodname></entry>
  226. <entry>Set the text description of the feed.</entry>
  227. </row>
  228. <row>
  229. <entry><methodname>setLink()</methodname></entry>
  230. <entry>
  231. Set a <acronym>URI</acronym> to the <acronym>HTML</acronym> website
  232. containing the same or
  233. similar information as this feed (i.e. if the feed is from a blog,
  234. it should provide the blog's <acronym>URI</acronym> where the
  235. <acronym>HTML</acronym> version of the entries can be read).
  236. </entry>
  237. </row>
  238. <row>
  239. <entry><methodname>setFeedLinks()</methodname></entry>
  240. <entry>
  241. Add a link to an <acronym>XML</acronym> feed, whether the feed being
  242. generated or an alternate <acronym>URI</acronym> pointing to the same
  243. feed but in a different format. At a minimum, it is recommended to
  244. include a link to the feed being generated so it has an identifiable
  245. final <acronym>URI</acronym> allowing a client to track its location
  246. changes without necessitating constant redirects. The parameter is an
  247. array of arrays, where each sub-array contains the keys "type" and
  248. "uri". The type should be one of "atom", "rss", or "rdf". If a type is
  249. omitted, it defaults to the type used when rendering the feed.
  250. </entry>
  251. </row>
  252. <row>
  253. <entry><methodname>setAuthors()</methodname></entry>
  254. <entry>
  255. Sets the data for authors. The parameter is an array of arrays
  256. where each sub-array may contain the keys "name", "email" and
  257. "uri". The "uri" value is only applicable for Atom feeds since
  258. <acronym>RSS</acronym> contains no facility to show it. For
  259. <acronym>RSS</acronym> 2.0, rendering will create two elements - an
  260. author element containing the email reference with the name in brackets,
  261. and a Dublin Core creator element only containing the name.
  262. </entry>
  263. </row>
  264. <row>
  265. <entry><methodname>setAuthor()</methodname></entry>
  266. <entry>
  267. Sets the data for a single author following the same
  268. format as described above for a single sub-array.
  269. </entry>
  270. </row>
  271. <row>
  272. <entry><methodname>setDateCreated()</methodname></entry>
  273. <entry>
  274. Sets the date on which this feed was created. Generally
  275. only applicable to Atom where it represents the date the resource
  276. described by an Atom 1.0 document was created. The expected parameter
  277. may be a <acronym>UNIX</acronym> timestamp or a
  278. <classname>Zend_Date</classname> object.
  279. </entry>
  280. </row>
  281. <row>
  282. <entry><methodname>getDateModified()</methodname></entry>
  283. <entry>
  284. Sets the date on which this feed was last modified. The expected
  285. parameter may be a <acronym>UNIX</acronym> timestamp or a
  286. <classname>Zend_Date</classname> object.
  287. </entry>
  288. </row>
  289. <row>
  290. <entry><methodname>setLanguage()</methodname></entry>
  291. <entry>
  292. Sets the language of the feed. This will be omitted unless set.
  293. </entry>
  294. </row>
  295. <row>
  296. <entry><methodname>getGenerator()</methodname></entry>
  297. <entry>
  298. Allows the setting of a generator. The parameter should be an
  299. array containing the keys "name", "version" and "uri". If omitted
  300. a default generator will be added referencing
  301. <classname>Zend_Feed_Writer</classname>, the current Zend Framework
  302. version and the Framework's <acronym>URI</acronym>.
  303. </entry>
  304. </row>
  305. <row>
  306. <entry><methodname>setCopyright()</methodname></entry>
  307. <entry>Sets a copyright notice associated with the feed.</entry>
  308. </row>
  309. <row>
  310. <entry><methodname>setHubs()</methodname></entry>
  311. <entry>
  312. Accepts an array of Pubsubhubbub Hub Endpoints to be rendered in
  313. the feed as Atom links so that PuSH Subscribers may subscribe to
  314. your feed. Note that you must implement a Pubsubhubbub Publisher in
  315. order for real-time updates to be enabled. A Publisher may be
  316. implemented using
  317. <classname>Zend_Feed_Pubsubhubbub_Publisher</classname>.
  318. </entry>
  319. </row>
  320. <row>
  321. <entry><methodname>setCategories()</methodname></entry>
  322. <entry>
  323. Accepts an array of categories for rendering, where each element is
  324. itself an array whose possible keys include "term", "label" and
  325. "scheme". The "term" is a typically a category name suitable for
  326. inclusion in a <acronym>URI</acronym>. The "label" may be a human
  327. readable category name supporting special characters (it is encoded
  328. during rendering) and is a required key. The "scheme" (called the domain
  329. in <acronym>RSS</acronym>) is optional but must be a valid
  330. <acronym>URI</acronym>.
  331. </entry>
  332. </row>
  333. </tbody>
  334. </tgroup>
  335. </table>
  336. </sect2>
  337. <sect2 id="zend.feed.writer.setting.entry.data.points">
  338. <title>Setting Entry Data Points</title>
  339. <para>
  340. Here's a summary of the Core <acronym>API</acronym> for Entries and Items. You should
  341. note it comprises not only the basic <acronym>RSS</acronym> and Atom standards, but
  342. also accounts for a number of included Extensions bundled with
  343. <classname>Zend_Feed_Writer</classname>. The naming of these
  344. Extension sourced methods remain fairly generic - all Extension
  345. methods operate at the same level as the Core <acronym>API</acronym> though we do allow
  346. you to retrieve any specific Extension object separately if required.
  347. </para>
  348. <table>
  349. <title>Entry Level API Methods</title>
  350. <tgroup cols="2">
  351. <tbody>
  352. <row>
  353. <entry><methodname>setId()</methodname></entry>
  354. <entry>
  355. Set a unique ID associated with this feed. For Atom 1.0
  356. this is an atom:id element, whereas for <acronym>RSS</acronym> 2.0 it is
  357. added as a guid element. These are optional so long as a link is
  358. added, i.e. the link is set as the ID.
  359. </entry>
  360. </row>
  361. <row>
  362. <entry><methodname>setTitle()</methodname></entry>
  363. <entry>Set the title of the feed.</entry>
  364. </row>
  365. <row>
  366. <entry><methodname>setDescription()</methodname></entry>
  367. <entry>Set the text description of the feed.</entry>
  368. </row>
  369. <row>
  370. <entry><methodname>setLink()</methodname></entry>
  371. <entry>
  372. Set a <acronym>URI</acronym> to the <acronym>HTML</acronym> website
  373. containing the same or
  374. similar information as this feed (i.e. if the feed is from a blog,
  375. it should provide the blog's <acronym>URI</acronym> where the
  376. <acronym>HTML</acronym> version of the entries can be read).
  377. </entry>
  378. </row>
  379. <row>
  380. <entry><methodname>setFeedLinks()</methodname></entry>
  381. <entry>
  382. Add a link to an <acronym>XML</acronym> feed, whether the feed being
  383. generated or an alternate <acronym>URI</acronym> pointing to the same
  384. feed but in a different format. At a minimum, it is recommended to
  385. include a link to the feed being generated so it has an identifiable
  386. final <acronym>URI</acronym> allowing a client to track its location
  387. changes without necessitating constant redirects. The parameter is an
  388. array of arrays, where each sub-array contains the keys "type" and
  389. "uri". The type should be one of "atom", "rss", or "rdf". If a type is
  390. omitted, it defaults to the type used when rendering the feed.
  391. </entry>
  392. </row>
  393. <row>
  394. <entry><methodname>setAuthors()</methodname></entry>
  395. <entry>
  396. Sets the data for authors. The parameter is an array of arrays
  397. where each sub-array may contain the keys "name", "email" and
  398. "uri". The "uri" value is only applicable for Atom feeds since
  399. <acronym>RSS</acronym> contains no facility to show it. For
  400. <acronym>RSS</acronym> 2.0, rendering will create two elements - an
  401. author element containing the email reference with the name in brackets,
  402. and a Dublin Core creator element only containing the name.
  403. </entry>
  404. </row>
  405. <row>
  406. <entry><methodname>setAuthor()</methodname></entry>
  407. <entry>
  408. Sets the data for a single author following the same
  409. format as described above for a single sub-array.
  410. </entry>
  411. </row>
  412. <row>
  413. <entry><methodname>setDateCreated()</methodname></entry>
  414. <entry>
  415. Sets the date on which this feed was created. Generally
  416. only applicable to Atom where it represents the date the resource
  417. described by an Atom 1.0 document was created. The expected parameter
  418. may be a <acronym>UNIX</acronym> timestamp or a
  419. <classname>Zend_Date</classname> object.
  420. </entry>
  421. </row>
  422. <row>
  423. <entry><methodname>getDateModified()</methodname></entry>
  424. <entry>
  425. Sets the date on which this feed was last modified. The expected
  426. parameter may be a <acronym>UNIX</acronym> timestamp or a
  427. <classname>Zend_Date</classname> object.
  428. </entry>
  429. </row>
  430. <row>
  431. <entry><methodname>setLanguage()</methodname></entry>
  432. <entry>
  433. Sets the language of the feed. This will be omitted unless set.
  434. </entry>
  435. </row>
  436. <row>
  437. <entry><methodname>getGenerator()</methodname></entry>
  438. <entry>
  439. Allows the setting of a generator. The parameter should be an
  440. array containing the keys "name", "version" and "uri". If omitted
  441. a default generator will be added referencing
  442. <classname>Zend_Feed_Writer</classname>, the current Zend Framework
  443. version and the Framework's <acronym>URI</acronym>.
  444. </entry>
  445. </row>
  446. <row>
  447. <entry><methodname>setCopyright()</methodname></entry>
  448. <entry>Sets a copyright notice associated with the feed.</entry>
  449. </row>
  450. <row>
  451. <entry><methodname>setHubs()</methodname></entry>
  452. <entry>
  453. Accepts an array of Pubsubhubbub Hub Endpoints to be rendered in
  454. the feed as Atom links so that PuSH Subscribers may subscribe to
  455. your feed. Note that you must implement a Pubsubhubbub Publisher in
  456. order for real-time updates to be enabled. A Publisher may be
  457. implemented using
  458. <classname>Zend_Feed_Pubsubhubbub_Publisher</classname>.
  459. </entry>
  460. </row>
  461. <row>
  462. <entry><methodname>setCategories()</methodname></entry>
  463. <entry>
  464. Accepts an array of categories for rendering, where each element is
  465. itself an array whose possible keys include "term", "label" and
  466. "scheme". The "term" is a typically a category name suitable for
  467. inclusion in a <acronym>URI</acronym>. The "label" may be a human
  468. readable category name supporting special characters (it is encoded
  469. during rendering) and is a required key. The "scheme" (called the domain
  470. in <acronym>RSS</acronym>) is optional but must be a valid
  471. <acronym>URI</acronym>.
  472. </entry>
  473. </row>
  474. </tbody>
  475. </tgroup>
  476. </table>
  477. </sect2>
  478. </sect1>