In Defiance of Titles

Just another WordPress.com weblog

Posts Tagged ‘modules

A Reusable Zend Framework Content Module

with 3 comments

As a sort of proof of concept for the ideas I discussed in my previous post, I’ve put together the first draft of what could become a very helpful reusable module. With this post, I’d like to introduce my new Zend Framework “content” module, which provides several abstract components for a reusable model layer, along with a concrete framework for building a variety of content types sharing a common database-based persistence layer. With some (OK, a lot of) refinements, a module like this could easily form the foundation of an extremely extensible Zend Framework-based content management system.

You can check out the current trunk by issuing the following svn command in your project’s modules directory:

svn checkout http://jazzslider.org/svn/zf-content/trunk content

Here’s a more detailed look at the features:

  • First off, it provides a reusable abstract model-and-mapper[1] system with sensible defaults for persisting those models in a MySQL database (other kinds of persistence layers are easily supported). Both pieces incorporate a plugin architecture similar to that used in Zend_Controller_Action, so that new functionality can be added to all models compositionally.
  • It also provides a concrete implementation of all this called Content_Model_Post; this model is essentially just your basic revision-controlled title-and-body content type. The nice thing about the post model is that it’s designed to be extended; if you need additional fields, you simply need to write a child class and a mapper plugin that describes how to find the extra data. (The design concept owes a lot to the Drupal CCK module, but without any of the administrative bells and whistles; this module is still very much a programmer’s toolkit.)
  • The view layer for the posts system comes with a few handy helpers and filters; the filters are mainly for implementing things like HTMLPurifier, Markdown, GeSHi syntax highlighting, etc. in the view layer when rendering your content. The idea is described in more detail in one of my previous posts, but the solution I’ve implemented here is much better. One caveat: the filters won’t work unless you’ve got the associated libraries installed somewhere in your include_path (as described in the INSTALL.txt file in the root of the project).

I’m releasing the current version of the source code under the GPL for now so that anyone who wants to can see how it works; that said, I wouldn’t say it’s ready for use in a high-profile production environment, owing to a couple of factors:

  • While the system does keep track of content authorship right out of the box, it would do a much better job of it if it knew how its parent application kept track of the current user. The only expectation it enforces is that when you assign an author to a post, it either has to be a Zend_Acl_Role_Interface object implementation or a string role ID that can be resolved to such an object at runtime (you can control this part of the process through a model plugin). Once I’ve written my reusable “users” module, things may work more predictably.
  • While we’re on the subject of related modules…one of my next projects is to develop a “comments” module that provides comments to all posts (and all dependent content types). For that matter, I’d also like to piece together something that allows for tag-based content classification. These will all be separate, optional modules, in keeping with the idea that people should be able to drop in what they want and leave the rest aside.
  • The process of designing a new dependent content type is still a little over-complicated; I’m going to try writing a tutorial soon, and when I do, I’d love some feedback on how to simplify the process.
  • The code is not yet unit tested; I wasn’t quite sure of the best way to bootstrap my unit tests now that Zend_Application is involved, and so far I haven’t found any definitive guides on the matter. I’ll be looking into that soon, and if what I discover is useful I’ll certainly make a post about it.

At any rate, please take a look and tell me what you think; remember, this mainly serves as a proof of concept for some of the stuff I’ve been talking about in previous posts…and once I’ve got the other helper modules put together, I think it’ll be a lot clearer what I’m aiming at. Anyway, thanks for reading!

Footnotes

  1. [Back] The data mapper logic in this module accomplishes some of the same purposes as the proposed Zend_Db_Mapper component, but is in no way intended (or suitable) to replace it. My goal here was mainly to demonstrate how such logic could be built out as a distributable, reusable plug-and-play module now that Zend_Application_Resource_Modules is out of the gate. I’m looking forward to future developments on Zend_Db_Mapper, and if it finds its way into the official framework you can bet I’ll be using it for projects like this.
Advertisements

Written by jazzslider

June 15, 2009 at 6:38 am

Posted in Computers

Tagged with , , , ,

Distributing Zend Framework Modules

with 8 comments

It’s been almost a month now since the release of Zend Framework 1.8, and although I was very excited about some of the new features, it’s taken me awhile to digest that excitement into something bloggable. As a result, I apologize if I’m a bit late to the party…but I’d like to take a moment nonetheless to discuss the implications of my favorite 1.8 feature: Zend_Application_Resource_Modules.

Zend Framework has provided what it calls a “conventional modular directory structure” for quite some time now: specifically, Zend Framework modules are supposed to “[allow] you to separate different MVC applications into self-contained units, and re-use them with different front controllers”. Unfortunately, up until 1.8, I have never found this to be entirely accurate. Based on module architectures I’d seen in full-stack content management systems, I’d always kind of hoped that installing a module would be as easy as this:

  1. Download the source code and copy it into your application’s modules directory.
  2. Hooray, it works now!

Now, this was true enough for modules that only provided a couple controllers and view scripts, but the second you introduced, say, controller plugins or models in the include_path, you’d have to modify your application-level bootstrap file, providing it with detailed knowledge of what the module provides. Because of this, the framework hasn’t really inspired a lot of distributable, reusable third-party modules; after all, the process for installing them would actually have looked something like this:

  1. Download the source code and copy it into your application’s modules directory.
  2. Adjust your application entry point (index.php) to include the module’s models folder in the include_path.
  3. Adjust your application-level bootstrap file to register the new modules directory with the front controller, if you haven’t configured it that way already.
  4. Adjust your application-level bootstrap file to register any plugins or plugin paths it might provide.
  5. Install any database schemas that might have come with the module.
  6. Hooray, it works now!

The problem here is that the parent application (and the person installing it) has to know all sorts of nitty-gritty details about how the module does its business. In my opinion, a truly “self-contained” module would be able to handle a lot of the above process all by itself, without any modifications to the parent application; otherwise, it’s not really self-contained, and not particularly easy to distribute to other developers.

Enter 1.8

However, as I mentioned earlier, this situation has changed dramatically in Zend Framework 1.8, due to a wonderful little component called Zend_Application_Resource_Modules. Among other things, it provides the following:

  • Modules can now provide their own bootstrapping logic; no more need to register module-provided plugins, paths, etc. in the application-wide bootstrap file.
  • Autoloading of common types of module-provided classes is now automatically set up for you; no more need to add modules to your include_path, or even to require_once your module class files before you use them.

See the benefit? All of the application-level configuration we used to have to do can now be encapsulated in a bootstrap process provided as a part of the module itself. This cuts the above workflow down to something like this:

  1. Download the source code and copy it into your application’s modules directory.
  2. Install any database schemas that might have come with the module.
  3. Hooray, it works now!

Suddenly, the prospect of downloading somebody else’s reusable module is a lot more appealing.

Some further issues

You’ll notice, however, that this still doesn’t quite match my first ideal workflow. Although Zend_Application_Resource_Modules provides a lot of assistance in getting your modules bootstrapped once they’re installed, it cannot yet provide much assistance with the installation process itself. As a result, if you’re trying to install a distributed module that involves database schemas, you’ll still have to install those by hand.

It’s also worth noting that Zend_Application_Resource_Modules does not yet provide a way to track and enforce module dependencies. For the most part this isn’t necessary; by the time everything is bootstrapped, all module-provided code is available through autoloading. However, there are a couple of situations in which it would be necessary:

  • If Module A needs to use a class provided by Module B during Module A’s own bootstrap, Module B must have been bootstrapped first…otherwise the autoloader for Module B’s classes won’t be ready yet.
  • If Module A provides a plugin that, for whatever reason, assumes that a plugin from Module B always fires before it, then Module B’s plugins need to be registered before Module A’s.

I’m working (in my copious spare time) on a distributable module of my own right now that could really benefit from both dependency tracking and database installation…but with how much better module architecture has already gotten in 1.8, I can only assume that future releases will be even more elegant. In the meantime, keep an eye out for my new module; I’d love the benefit of community review once it’s ready.

Written by jazzslider

May 21, 2009 at 7:43 pm