A look at Drupal

Important Notice: This article is about changes occurring to zZine Magazine's site[1]. At the time of writing, www.zzine.org uses the old site, and not the Drupal-based one presented in this article, which is currently under construction[18].

"Why can't we log who edits the articles?"
"Can we send newsletters?"
"We should really have a members' area..."

zZine.org[1] is a scratch-built site, coded from the ground up to offer zZine journalists, editors and readers all the functionalities and features they wanted. I'm not totally against sites being coded from scratch, but what happens if something needs to be fixed, or new functionalities have to be implemented and you realize that the code cannot be extended or patched easily?

Case Study: zZine Magazine

zZine Magazine is an online magazine which publishes not only IT-related and other articles on a weekly basis, but also monthly publications containing CyberArmy[2] digests, special columns, and featured articles. A team of journalists, researchers, editors, publishers and outside contributors has access to the zZine site to write, submit, and edit articles, manage publications and perform various other tasks through a password-protected administration area. This is common to approximately 75% of the websites on the Internet: they have a front-end to present content to the general public and a semi-hidden administration backend which is normally more difficult and tedious to code. That's why someone started developing Content Management Systems[3]: ready-made, fully-featured administrative back-ends for creating and managing almost any kind of website, from blogs to eCommerce portals.

Could a CMS be used for zZine Magazine? Probably - zZine doesn't need any innovative or advanced features, just a bunch of commonly-used functionalities like:

  • Add, delete, edit and publish articles

  • Customizable user permissions, ideally role-based
  • (writer, editor, publisher, etc.)
  • Creating and managing monthly publications

  • Editor's tests

  • User signups, notifications, etc.

  • RSS feed generation

  • Sending newsletters to subscribers

  • Logging user actions

Some members of my team raised some concerns regarding the usage of a CMS, which were mostly based on our past experience with just a particular product and not CMSes in general. Everybody agreed that if we were to go back to a CMS, we had to choose the best this time: something flexible, easy to use, fast, search-engine friendly, and extensible. I spent some time researching CMSes, because while I knew that there's no such thing as the best CMS, there was certainly a CMS that was best for our needs.

Making the right choice

In the past, I had played around with Xoops[4] when I first thought about creating websites, and I used Mambo[5] for some other sites. I admit that I never actually spent time creating complex Mambo components and modules, but I must say that in the end I felt somehow tied to third-party modules and unable to understand how they really worked: Mambo seemed to give developers too much freedom, and had neither a solid API nor conventions to follow, at least when I used it.

So I decided to have a look around again, starting from the two most important sites people should look at when choosing the most suitable CMS for their work.
The first site is CMS Matrix[6] which - as the name implies - provides a really handy matrix, or chart, to compare the various features offered by nearly all CMS available, both proprietary and open-source.

I remember choosing Mambo last time I used the matrix simply because it appeared to be one of the most feature-rich. This is actually something not to do when choosing a CMS: always concentrate on what your site needs rather than what the CMS is able to offer. Otherwise, you run the risk of having too much to work with.

The other important website to visit when choosing a Content Management System is OpenSourceCMS[7], which basically allows you to try a demo of every open source CMS online. This is perhaps more useful, but also much more time-consuming: it's better to narrow down the list of possible CMSes after checking CMS Matrix and then try each one rather than just picking one at random.

At this point, an experienced CyberArmy staff member[8] suggested Drupal[9]. I asked her why, and she simply said that it seemed to be the best choice according to zZine's needs, as it basically offered all the features we were looking for, either natively or through modules. She also admitted to be biased, as she's actually part of Drupal's documentation team and involved with Drupal development[10].

Before making any kind of commitment, I checked out Drupal's website to see how they organized things, and I was quite impressed. I immediately noticed the Handbooks section[11], which contains all the official Drupal documentation and it seemed pretty much complete. No "under construction", "please write content here" or "we're a new project, help us write the documentation" notes, just a load of good-quality documentation, including a fully documented and stable API![12]

This surprised me, because some projects I came across, even really good ones, lacked a proper documentation section. I think this is a common problem with new open source projects, and Drupal for this reason gave me the impression to be quite mature and useable already. After visiting the very clear and organized Downloads Section[13], I downloaded the CMS and a few modules and installed it on my laptop.


Drupal needs three things to run:

  • A web server - Apache is fine, and ISS is reported to be working

  • PHP - Either version 4 or 5, Drupal started supporting PHP5 since 4.6.0 release

  • A PHP-compatible database - MySQL or PostgreSQL is recommended

I used a WAMP[14] installation to test Drupal. First of all, I created a MySQL database, granting ALL privileges to the database user accessing the Drupal database. When I uploaded the site to the remote server, later on, I had some problems because the LOCK TABLES privilege wasn't granted by the host. Drupal requires this, so I had to contact my host to solve the problem. I then imported the database scheme located in the database directory under the installation directory and modified the configuration settings (sites/default/settings.php) to allow Drupal to access the database. Installation complete.

Drupal was now up and running with the default configuration settings, with a minimum of fuss. For all the details concerning the installation process, consult the exhaustive documentation.[15] I didn't read it when I installed it, but it can really be useful in some situations.

There are actually two non-critical things to consider if you're planning to use Drupal for a medium-sized project: the first involves changing a few settings on php.ini, in particular increasing the amount of memory allocated to PHP from 8MB to 16MB, especially if you're planning to use either a lot of simple modules or a few complex ones, and the second is setting up your crontab to execute http://www.yoursite.com/cron.php every hour or so. This is required by some semi-essential modules like the site-wide search, but a common alternative (if you don't want to setup the cron task manually) is the poorman's cron module[15], which I used myself and found to be workable.

Keeping your site under control

Perhaps one of the best things Drupal has to offer is a rock-solid general-purpose administrative backend. The first thing I found in the backend which really impressed me (and that also I never found in another CMS) is the ability to create custom role-based user accounts and access permissions for everything: every module can be configured so that, for example, not all people can see its output and just a few can administer and modify it.

For zZine, I created four types of accounts:

    [*]Administrator - Able to access everything and change every setting of the site
    [*]Publisher - Able to write, edit and publish every kind of content on the site, but not able to administer user accounts, permissions and similar administrator-only tasks.
    [*]Editor - Able to write and edit anything on the site, but not to publish it.
    [*]Writer - Able to write articles, blogs and similar content, but in some cases not allowed to edit it.

These were precisely the account types I was looking for in a CMS. Granted, other products offer them by default, but having pre-defined account types is one thing, and being able to customize them completely is another.

User accounts are great, but sometimes it's good to know what the users of your sites are doing as well. On our old site we had user accounts for editors and administrators, and even if only a few people had access we had no way to determine who edited an article or who published something unless that person told us. Drupal comes with a radical solution to this: Almost every action is automatically logged by the watchdog core module. Every website error, every page not found, and every PHP or MySQL error is logged, as well as every content submission or modification. Page accesses, meanwhile, can be logged through the statistics module.

Themes & Templates

"We shouldn't use a CMS: I don't want zZine to have the overly used *nuke-style look." I've heard this too many times. Sometimes people associate the word "CMS" with "lack of original design", and that's not true by any means, especially for Drupal. Of course, there are plenty of ready made themes[16] which can be freely used or modified for any Drupal-based site.

I must confess that when I first saw the themes section I feared that Drupal "themes" used their own template engine, like some CMSes do nowadays, but I was wrong: currently Drupal supports some template engines[17] but also pure PHP-based ones. Theme engines do their job wonderfully and can offer some interesting features, but templates written natively in PHP tend to perform better, simply because there's no extra parsing or additional overhead involved.

I decided to have a look at a standard PHP theme. Basically, it's nothing more than a PHP-enriched xHTML file and its corresponding stylesheet. There are a few functions which must be used to perform particular tasks, like showing the main navigation links, but nothing too hard to understand. It's also very customizable. In fact, we're already working on a custom zZine theme, which doesn't seem any harder than coding a standard xHTML template. As design should always be the last thing to worry about, I decided to use a temporary template I created by slightly modifying an existing one.[18]

To switch or not to switch?

When creating a new site for an organization which already has one, there's something very important to consider: what happens to the old data?
Assuming the old site was dynamic and using a database of some sort, there are three possibilities:

  • Don't bother doing anything: any data on the old site will not be transferred to the new one.

  • Make the old website available somewhere else as an
  • archive of old documents.
  • Import all the data from the old site to the new one.

Obviously we went straight for the third one, which is the most difficult to implement, but it was necessary: there were over 1000 articles on the old site-

Of course, in reality, I didn't even mention the possibility of using Drupal until I figured out a way to import the old data into the new database structure. Never praise features or convince people to switch unless you're 100% sure you can handle the situation. Luckily for me, it turned out that everything could be imported easily enough.

The first difference I found between Drupal and zZine was that we didn't really have proper user accounts. Every article had an author, but it was stored as a field in the article's record, and that was all. Drupal, on the other hand, supports (and perhaps requires) user accounts - everything present on the site must be written or edited by an existing user.

The solution I cam eup with was rather drastic: I created about 120 user accounts, retrieving usernames from the articles and inserting them through a custom PHP script into Drupal's user table. Of course, those users never registered on the new site[18], so I didn't personalize the accounts at all: I simply put a notice on the first page asking everyone who contributed to zZine before to contact me in some way to enable their account with a valid email address.

After this initial difficulty, importing articles was relatively easy. Pretty much every type of content in Drupal is, in its simplest form, a node. Nodes have a title, which is a teaser generated automatically from the body text, and an author (the node table in the database has more fields, but these are the key ones for us). Essentially, Drupal's two default models for writing stories and pages write data to this table only. The most important thing to understand about Drupal is that almost every module used to create something on the site - an article, a blog entry, even songs - will use the node table, and add everything else on other tables. This makes the whole system much easier to administer: every node can potentially be extended in any way by third party modules!

What about categories? Well, Drupal has become famous for its taxonomy module: whereas most CMSes only support, or in fact impose, a one- or two-level hierarchy for categories, Drupal's taxonomy module supports the creation of as many different terms to describe data as you can think of. Each piece of content (categorization can be applied to any node, and since almost everything is a node-) can belong to none or n different categories, which can be nested in a n-level hierarchy. Since the zZine articles were already divided into categories, I imported all of them directly into Drupal. On the old zZine site, every article could have at most one category, which is fine, but it's good to know that we can now configure the system to support a more advanced categorizing system.

After importing the articles, the last important thing to transfer to the new site were the zZine Publications. Publications are what we call the article collections that we release as an issue every month. I could have created a new module for this, and it wouldn't have been that hard, but there was already an excellent module for that. This was pure luck, but the epublish[19] module seemed like it was tailored specifically for our needs.

Drupal API and Modules

We were lucky enough to be able to use existing modules for the main functionalities of our site, but in some cases you might not be able to find exactly what you're looking for.

In our case, even if we could have used the story module, which is part of the default installation, for zZine articles (stories have a body, a teaser, a title and an author, exactly like our articles) we decided not to. I wanted our editors and writers to know what to use when submitting articles, and the name "stories" sounds a bit too ambiguous for my liking. So, I decided to have a look at the standard story module to see how modules work, and create something similar.

Note: I'm curious by nature and I didn't read anything in the Drupal API[12], or about developing custom modules; I looked at the story module without any prior knowledge of Drupal's conventions.

All I found in the story module was a bunch of functions like:

* Implementation of hook_node_name().
function story_node_name($node) {
return t('story');

which seemed to be enough to tell the Drupal core what to do. I was used to Mambo components, where developers have more liberty to do what they want, including outputting HTML code anywhere. Drupal is nothing like that; on the contrary, it has its own structure and coding conventions that developers have to follow when creating custom modules. Even if a simple function like the one above is fully commented, it has to have a standard indentation (two spaces) and an obviously standardized name. I noticed that all the functions similar to this one started with "story_", so I created a new file named zzarticle.module, copied and pasted the story module code into it, and changed every function accordingly, like this:

* Implementation of hook_node_name().
function zzarticle_node_name($node) {
return t('zZine Article');

Trivial enough, and it worked fine! I put my shamefully copied module in the /modules directory and I was able to create "zZine Articles" (which were nothing but stories with a different name).

At this point I decided to have a proper look at the API, and read about hooks:

"Drupal's module system is based on the concept of "hooks". A hook is a PHP function that is named foo_bar(), where "foo" is the name of the module (whose filename is thus foo.module) and "bar" is the name of the hook. Each hook has a defined set of parameters and a specified result type.
To extend Drupal, a module need simply implement a hook. When Drupal wishes to allow intervention from modules, it determines which modules implement a hook and call that hook in all enabled modules that implement it. [-]"

A hook was used for the previously mentioned function, and this was diligently commented:

* Implementation of hook_node_name().

This made me understand how Drupal is actually geared towards developers and at the same time suitable for non-technical users. Wait a minute, what if someone is not familiar with PHP and still needs custom modules and features? Is there any way to extend Drupal without having to physically code new things? Yes, there is, and two modules come to mind:

    [*]Webform - allows the creation of any kind of web form. Users can customize field types, values, labels and messages. The module also provides ways to process forms by either saving data to the database or emailing it, which we can use for things like the Editor's Test and surveys.
    [*]Flexynode - This module is simple and powerful - it allows users to create their own content types without coding a single line. In my example, I cloned the story module to create the zZine Article content type. This is easy to do, and functional, but what happens if someone wants to include an additional field to the article submission form? I can probably do this using hooks, but if I was lazy I could do the same thing with the flexynode module. I actually used this module for our podcast section[20], and it did an excellent job.


For now I must say I'm very happy with what Drupal has to offer, and if there's something we need for the site, we can code it ourselves and then integrate it into Drupal.
One of the major strengths of this CMS is definitely its developer-friendliness: while other CMSes mainly focus on users at the price of limiting extensibility and trapping developers into predefined modules, Drupal even encourages developers to integrate their code into the existing structure, opening virtually unlimited possibilities. Granted, it may seem difficult to understand at first, some people I talked to told me that 'Drupal is too complex' or has a rather steep learning curve, but I just think everything becomes clearer after reading parts of the vast documentation section: this is the only price to pay, and believe me, it is definitely worthwhile.


[1] zZine Magazine: http://www.zzine.org
[2] CyberArmy Community: http://www.cyberarmy.net
[3] Content Management System, Wikipedia page: http://en.wikipedia.org/wiki/Content_management_system
[4] Xoops - Official Page http://www.xoops.org/
[5] Mambo - Official Page: http://www.mamboserver.com
[6]CMS Matrix: http://cmsmatrix.org/
[7] Open Source CMS: http://opensourcecms.com/
[8] Snarkles's CyberArmy Profile: http://www.cyberarmy.net/~snarkles
[9] Drupal - Official Page: http://www.drupal.org
[10]Webchick's Drupal Profile: http://drupal.org/user/24967
[11] Drupal - Handbooks: http://www.drupal.org/handbooks/
[12] Drupal API: http://drupaldocs.org/api/head
[13] Drupal Downloads: http://www.drupal.org/project/
[14] WAMP Server Package: http://www.wampserver.com
[15] Drupal - Installing and Upgrading documentation: http://drupal.org/node/258
[16] Drupal - Themes: http://drupal.org/project/Themes
[17] Drupal - Theme Engines: http://drupal.org/node/509
[18] zZine Beta site: http://beta.zzine.org
[19] Drupal - ePublish module: http://drupal.org/project/epublish
[20] zZine Podcasts: http://beta.zzine.org/podcasts