Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_Feed_Writer Component Proposal

Proposed Component Name Zend_Feed_Writer
Developer Notes
Proposers Pádraic Brady
Revision 1.1 - 20 September 2009 (wiki revision: 6)

Table of Contents

1. Overview

Why Propose A Replacement For Zend_Feed's Feed Creation Features?

Back in 2008, I proposed Zend_Feed_Reader as a means to layer a user friendly API on top of Zend_Feed when consuming feeds. In a short time, the proposal evolved after more and more Zend_Feed inconsistencies were discovered. For example, there was no consistent API once you left the basic usage, namespaces were not handled correctly, RDF support was non-existent (the current solution muddles namespaces even more), and in brief it forced developers to write an abstraction layer on top of it to make it work.

Zend_Feed_Reader took a different approach, targeting an implementation which used the DOM and XPath queries coupled with an internal implementation which was capable of understanding the various RSS and Atom standards. This was all built around a simple intuitive and extendable API to eliminate the guesswork users needed as well as the need to implement abstraction layers which differed wildly across projects. Zend_Feed_Reader is now a standalone component with no ties to Zend_Feed.

Zend_Feed_Writer follows an identical ideology - focusing on getting the job done with minimal effort using as simple an API as possible. The component should make transferring your data into an Atom 1.0 or RSS 2.0 feed painless. And it should do this while maintaining a rigorous and unforgiving adherence to standards.

About Zend_Feed_Writer

The main differences from Zend_Feed will be very obvious. Zend_Feed_Writer will present a fixed method based API which must be clearly defined either in the core classes, or the set of currently loaded Extensions. These will help define namespaces, element positioning and syntax, and actively prevent the construction of malformed feeds. Two initial standards will be enforced: RSS 2.0 (specifically the RSS Advisory Board 2.0.11 recommendations) and Atom 1.0. The full range of Atom 1.0 will be available, as standard, as an RSS Extension where warranted (e.g. including URI's for an RSS feed's source XML which borrows from the Atom namespace). This will contrast with Zend_Feed's reliance on chained property assignments which require greater knowledge of the standards, and are not easily reduced to common steps for both RSS and Atom.

Zend_Feed_Writer will not utilise templating. Templating is a fast, effective solution for building feeds but it's also restrictive, encourages assumptions as to namespaces and positioning, and relies on templated strings which are prone to error and add to maintenance problems. Instead, Zend_Feed_Writer will build its feeds from scratch using the PHP DOM which at the end of the day requires less base code since everything is condensed into DOM operations. DOM access will be available at all levels for manipulation outside of Zend_Feed_Writer (just as Zend_Feed_Reader offers easy access to Feed/Entry level DOMElement objects). It also ensures user Extensions have complete access to manipulate a feed in progress as needed.

In short, Zend_Feed_Writer is the obvious missing partner to Zend_Feed_Reader, completing support for consuming and building feeds.

2. References

Basic implementation with Atom support

3. Component Requirements, Constraints, and Acceptance Criteria

  • MUST understand the valid structure of RSS 2.0 and Atom 1.0 documents
  • MUST enforce valid structures raising Exceptions on illegal actions or when missing elements are detected
  • MUST allow the API to be extended via Extensions
  • MUST present an API which is consistent whether the feed being built is RSS or Atom
  • MUST expose the underlying parent DOMDocument or DOMElement object for external manipulation
  • MAY be capable of importing Zend_Feed_Reader objects for manipulation/editing (preferred future feature)

4. Dependencies on Other Framework Components


5. Theory of Operation

Since neither RSS or Atom assign any significance to the order of elements, there is no need for any complex wiring. So the simplest solution is to implement Zend_Feed_Writer as two branches of classes. The first implement a fixed method API, e.g. methods like setTitle() and getTitle(). In isolation, these classes are nothing more than container objects which can be manipulated at any time. The real work is performed by the second branch of classes implementing Zend_Feed_Writer_RendererInterface. These, including all Renderers registered from Extensions, will form a simple render queue with a DOMDocument object representing either a Feed or Entry passed along the queue so each Renderer can append additional elements or edit others. The final result is then constructed by importing all root Entry elements into the Feed level DOM. The term "Renderer" is probably not even the most suitable one since the actual XML string produced is a simple saveXML() call on the final DOMDocument, but it will suffice for now.

6. Milestones / Tasks

  • Milestone 1: Publish and have proposal approved with Zend comments to resolve
  • Milestone 2: Complete initial component with unit tests
  • Milestone 3: Complete testing against a selection of web-based/desktop feed readers
  • Milestone 4: Verify that code operates under PHP 5.3/6.0-dev
  • Milestone 5: Complete documentation

7. Class Index

  • Zend_Feed_Writer
  • Zend_Feed_Writer_Entry
  • Zend_Feed_Writer_RendererInterface
  • Zend_Feed_Writer_Renderer_Feed_Rss
  • Zend_Feed_Writer_Renderer_Feed_Atom
  • Zend_Feed_Writer_Renderer_Entry_Rss
  • Zend_Feed_Writer_Renderer_Entry_Atom
  • Zend_Feed_Writer_Renderer_Extension_FeedAbstract
  • Zend_Feed_Writer_Renderer_Extension_EntryAbstract
    Others may be determined during development

8. Use Cases

Full working example:

Output from the above:

9. Class Skeletons



proposal proposal Delete
proposals proposals Delete
zend_feed zend_feed Delete
zend_feed_reader zend_feed_reader Delete
zend_webservices zend_webservices Delete
xml xml Delete
rss rss Delete
atom atom Delete
feed feed Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Aug 03, 2009

    <p>great job Padraic, this zend_feed is very nice</p>

    <p>about entries importing, i don't know this library much, but is it possible to use a generic class for entries like Zend_Feed_Entry_Interface or Zend_Feed_Entry_Abstract?</p>

    <p>both entries from reader and writer can extends/implements these classes<br />
    especially interface, because you could use the methods to translate entries between feed_reader and feed_writer</p>

  2. Aug 04, 2009

    <p>You hit on the main piece of functionality I've omitted so far <ac:emoticon ac:name="wink" />. At present, you can either a)read entries/feeds or b) write entries/feeds. I will be including editing support but at a later time once the Writer has solidified its API.</p>

    <p>At present, the Writer and Reader components use separate interfaces. The Writer should implement the Reader interfaces (but not the other way around) since it ensures the retrieval methods are consistent. The Writer also allows for editing - exporting a written feed triggers a new round of DOM construction each time - so changes are always factored in.</p>

    <p>The way editing would work, is twofold. 1) Import an instance of the Reader into the Writer for editing, or 2) use a convenience method on the Reader to achieve this without needing to instantiate a Writer object yourself.</p>

  3. Oct 29, 2009

    <ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Acceptance</ac:parameter><ac:rich-text-body>
    <p>This proposal is accepted for immediate development in the incubator as-is.</p></ac:rich-text-body></ac:macro>

  4. Feb 22, 2011

    <p>Zend_Feed_Writer is released into the stable branch. Maybe we can archive this proposal <ac:emoticon ac:name="smile" /></p>