PHP Object Hierarchies

Ever since I wrote the first draft of the Widgets plugin, I've had a fetish for structuring data as object hierarchies in PHP. There is so much you can do with such tiny snippets of code, why wouldn't you want to represent things that way? Some minds call it "too complicated" while others, like mine, consider it the peak of simplicity.

It is a more common design pattern than you might think. If you are using Firefox with the DOM browser, you can see just such a hierarchy in every single page you view on the web. Each node, from little ones like <em>this</em> and <a href="http://w3.org">this</a&gt; to the one that encompasses the entire application window, is an object with a class and methods and attributes and children.

Nobody saw the first draft of the Widgets plugin except myself and Matt. The basic idea was to start with a Widget class from which all widgets would derive. Each widget would therefore inherit certain basic methods: get_options, set_options, display_control, display_widget. The benefit of abstracting these methods is that the API can be preserved even while massive changes are made to the implementation. For example, we might want to start storing all widget options together in a single table row instead of one row for each widget. As long as get_options and set_options kept their interfaces, the underlying code could be improved without forcing 3rd-party widget developers to update their code and telling bloggers to update their dozens of widgets.

And that's just the base class. New classes could quickly be written to deal with special needs by extending the Widget class, adding or replacing methods as needed. The first extending class I wrote was a Widget Container class. Its job was to manage its own array of child Widgets. This would be a top-level Widget to contain all of the other widgets, but also as a movable child widget that contained other movable widgets. By replacing the display_widget method with code to wrap and fire the display_widget methods of the child objects, we have a working parent and a simple hierarchy. What is most exciting about this is that you don't need a giant set of nested foreach loops to output the entire widget tree. The top-level container's display_widget method starts the chain reaction and each descendant widget takes care of itself.

Once you have this kind of extensible hierarchy in place, you might as well just get rid of the entire theme and call everything a widget. The body node of the html document is a container widget. Its children are widgets with linear markup whether the CSS aligns them as columns or rows or any other way. The loop is a widget. The sidebar is a widget with many widgets for children. Widgets control their own display on the blog as well as on the widget admin page, so a container could arrange its children horizonally or vertically or any other way allowed by the supported presentation model.

You now have a drag-and-drop markup creation suite that is infinitely extensible: plugins can provide new widgets and containers by defining classes that derive from Widget. PHP lets us find any class by its parentage, so we do away with the registration API functions. All you have to do is define a class that extends Widget and your widget is added to the palette.
I had almost all of this working and the hardest part of the task was picking myself up off the ground after frequent fits of laughter due to the ease and simplicity of the coding. The only thing in this description that wasn't implemented was the display of containers in the admin screen and this was primarily due to the limitations of the javascript toolkit I had chosen for the job. It was going to take several times the effort just to make the containers draggable.

And with that, we decided to go with a more familiar API for widgets, using functions instead of objects, registration instead of auto-discovery, sidebar instead of whole-blog. Perhaps the OO theme will happen some day. 

12 Comments

  1. Now, that is really, really cool. Totally, beautifully geeky. Any chance I could play with a copy?

  2. Looking forward to the OOed version.

  3. WP became big because the real developers put what THEY believed was right into it. I think if you really liked this system, you should have used it; afterall, what’s popular isn’t always what’s right.

  4. As far as making the themes themselves OO, my biggest concern is simply ensuring that the simplicity of making themes for non programmers is perserved. A brief example to illustrate: working with WP themes is a dream. Working with Gallery themes is a nightmare. The difference is that WP makes calling it’s php functions so simple. You know HTML, you can use the codex and learn what you need to. Gallery on the other hand uses Smarty, and I’ve just about given up trying to learn it.

    Please, keep the calls to WP within themes easy, easy, easy to do!

  5. Don’t worry, Jay. If this OO theme ever happens, it won’t supplant the existing theme system. It’ll be a theme just like any other, with the exception that it’s the most flexible theme ever.

    Keep in mind that the only thing the outlined system would do is produce markup and minimal CSS for layout. It would still require CSS for design, branding, graphics, whatever. You’d be able to add any design CSS you like, much like the Classic theme’s markup is a baseline for stylesheet-only themes.

  6. Right Andy. I figured that. It wouldn’t be much of theme if didn’t allow for the same html and CSS markup! What I was specifically referring to was the way “components” (for example a list of categories as links to their respective pages) are so easily called in WP themes. One php line. It’s so clean that a person who doesn’t know much about PHP or even WP can look up that information and just drop it.

    I’d hate to see a theme where the PHP now as to be structured with OOP so that people who didn’t know much OOP (I’m one of those shamefully) would now find it difficult to call WP “compenents” into their themes.

    I understand the power of OOP, and can conceptually understand how this would provide a “better” theme. All I was suggesting is that one of WPs most amazing features is the ease with which it’s themes can be built.

    That’s all I’m hoping remains.

  7. But with PHP6 being almost a true OOP language and PHP5 being partially so, it’s become a Catch-22.

    PHP needs OOP to evolve, it has “maxed out” its non-OOP potential; yet nevertheless developers are refusing to even upgrade to PHP5 because of it.

    PHP needs it to improve, and it needs developers & community to remain no. 1 yet at the end of the day, if it evolves it loses the developers, and if it doesn’t; well let’s just say ASP.NET is on the loom :(

  8. I’ve been using OOP PHP in a recent project and I have to say, it’s what PHP programmers need to use if PHP is going to go anywhere. OOP provides so much flexibility, abstraction, and ease of use. Anyone who doesn’t understand OOP could just take a course on it (or Java for that matter). The point is that it makes PHP more mature, more structured and much more useful.

  9. adviaboli

     /  May 15, 2006

    sounds very promising (and i don’t know php ;o)

  10. NBrew

     /  June 2, 2006

    Man, you’re so right on about all Elements decending from a parent Widget. I’m implementing the concept as we speak for a freight building app. Compartmentalizing and consistently knowing how to interact with every object is a beautiful thing.

  1. The BinnsBlog » Objects: simplicity itself
  2. donncha’s blog » Links For Friday, May 5, 2006
Follow

Get every new post delivered to your Inbox.

Join 1,670 other followers

%d bloggers like this: