Dec 17 2008
Dec 17

This January I'm headed out to scenic Denver, Colorado to co-teach two of three sessions of an Intro to Drupal 6.x class with Growing Venture Solutions. The course is targeted towards people who are new to Drupal and covers several levels of site administration as well as using essential Drupal modules such as Views and CCK (Content Construction Kit), image handling with Imagecache, and creating sophisticated landing pages using Panels. Then we'll cover theming/templating and finally module development, performance and security best practices.
The course happens over three Saturdays, so students can go home (or back to work), tinker around and return brimming with questions and enthusiasm about turning their Drupal sites up to eleven.
If you're thinking of attending, it's best to secure a spot at the pre-2009 discounted rate.
You can read more about the course on the GVS website.

Hope to see you there!
(photo credit:

Dec 17 2008
Dec 17

Drupal's popularity has lately been rising. It's a great platform for setting up content management systems and community driven sites. Here, I'll give a general overview of Drupal and build a simple site for a fake client. We'll begin with outlining the client's needs, installing and configuring a few modules, creating user roles and assigning permissions, and finally we'll add in some content. We won't go into theming, as it's a bit out of the scope of this article.

1. A fake client

Let's start off with a fake client.

SmartMarks is a small marketing consulting firm, with 4 employees. Each employee would like their own blog. The site will need a few pages in addition to the blogs:

  • Home
  • About
  • Contact
  • Links
  • Blogs

Shannon, the business owner, wants full control over the site. The rest of the employees (Bill, Jean, and Terry) should only be able to write blog entries, but Bill may publish links.

The contact us form will accept the user's name, phone, email, and a short message. Submissions of the contact form should be sent only to Shannon.

Sounds pretty simple, huh? Well with Drupal, a lot of this core functionality is already built in. We'll use as much of the core functionality as we can, and we'll add in a few other modules to make building this site a breeze!

2. Install some stuff

First, start out by installing Drupal. I'll be developing this one on my local machine, but you can install it anywhere you wish. For this tutorial, I'll be working with Drupal 6.x.

To install Drupal, simply download ( and unpack it, create your database, and visit http://localhost/ (or your own dev URL). Installation should be relatively simple for ya.

You'll need to create a config file. You can copy /webroot/sites/default/default.settings.php to /webroot/sites/default/settings.php. Be sure to make it writable to the server. Also, leave a copy of sites/default/default.settings.php where it is; Drupal will use it during installation.

After your config file is created, you can go ahead and install Drupal.

On the next screen, you'll setup the first account for the site. This is the main administrator, or super user. This user will have permission to do anything and everything on the site.

And you can go ahead and specify a few server settings. If your server is configured for mod_rewrite URL rewriting, then you can go ahead and enable Clean URLs now. This will change your URLs from something like /?q=node/3 to just /node/3.

After successful installation, you can visit the site and login as the superuser.

3. Get some modules

For this site, we'll be using a few contributed modules. We'll have to download those and activate them before we can use them.

All modules that you'll install will be placed in the directory /webroot/sites/all/modules. If the modules directory doesn't exist there, just make a new one and name it modules.

Make sure to download the modules compatible with the version of Drupal that you're using. I'm using Drupal 6.x.

4. Admin Menu

This module is a must have for working with Drupal. It's not totally necessary, but it will save you loads of time.

Download it over at and place it in /webroot/sites/all/modules

PathAuto & Token

Next, go grab a copy of PathAuto and Token. PathAuto is a module that will have Drupal automatically generate nice URLs. PathAuto requires Token to work.

Meta Tags (Nodewords)

Originally titled NodeWords, the Meta Tags module allows users to specify common meta tags, like meta keywords and meta description.

Get a copy of this module over at

CCK (Content Construction Kit)

CCK allows you to easily create new content types, without ever having to write any code! We'll use this for the company's external links section.

Get CCK at


The views module allows you to configure custom views for displaying content. They're very useful when you have complex content types and categories. Here we'll use Views to display Links.

Get the Views module at

Install some modules

After you've downloaded and unpacked the above modules into /webroot/sites/all/modules, you can go ahead and install them.

Visit http://localhost/admin/build/modules to turn some of them on.

For this site, we'll need to install the following. Simply check the boxes and click "Save configuration".

  • Administration - Administration Menu
  • Core - Blog
  • Core - Contact
  • Core - Path
  • Content - Content
  • Content - Text
  • Other - Meta tags
  • Other - Pathauto
  • Other - Token
  • Views - Views
  • Views - Views UI

5. Content Types

Before we work with users and roles, we'll create our Links content type. Each Link will need a title, URL, and short description.

What's a node?

Almost every piece of content in Drupal is stored as a single node. All nodes have a title and an optional description. By creating content types, you can add fields to the content type to extend the node.

In our case, each Link will need one additional field that's not provided by default, the URL.

Create a Link content type

We'll create a content type called Link. We'll then add a field to the content type called URL.

Visit http://localhost/admin/content/types/add

In the name field, enter the human-readable name. In the type field, enter a unique name for the type. The system will use this name internally. You can make it up, but generally it'll look like a variable name, lowercase and underscored. Also enter a short description of the content type.

Next we'll modify slightly this content type from the general node. In the "Submission form settings" group, instead of "Body", we'll title the body field "Short Description".

Next, we'll edit the "Workflow settings." Allow the link to be published by default, and disable automatic promotion to the front page.

And finally, disable comments on the Links.

Save the content type. If you visit the "Create Content" page, you'll now see the new content type, Link.

Additional fields with CCK

So we've got our base Link content type set up. But we need to add an additional field to each Link: URL. Visit http://localhost/content/types and "Manage fields" for content type Link.

Add a field titled "url", and name it "field_url". Choose text data and text field.

Save it. Another page will come up, with some more options. The defaults are ok for this, so just contine by clicking "Save field settings". After this, the Link content type should appear like this:


Now let's set up a view for our new content type, Links.

Views can become quite complex, but for our example, we'll keep it very simple. We'll make a page view that displays Links. Plain and simple

Visit http://localhost/admin/build/views to get started. Click the tab "Add" to create a new view.

Name the view "Links" and choose type node.

The next few pages can grow quite complex, but be paitent. A bit of practice will get you more comfortable with views.

Firstly, we'll want our Links view to be a full page. So add a page display.

We'll have to make some settings next. Change the name and title of the view to Links. Set the "Row Style" to node, and choose to display teaser and links.

Make sure you're clicking "Update Default Display" every time.

Set the Path to "links". This will be the URL path and our page view will show up at http://localhost/links.

Then set a menu for the view. Choose "Normal menu entry", title it Links, and put it into Primary Links. (More on menus a bit later).

The Basic Settings area should be similar to this by now:

And finally for the view, we'll need to setup a filter. The filter will allow us to restrict the view to only display nodes of type "link".

Add a filter by using the "+" button at the top of the Filters box.

Scroll down until you find the filter titled "Node: Type". Check it's box, then add it as a filter.

Choose a node type of "Link".

At this point, our whole view should look very simliar to the following.

Save the view. We'll come back to it later.

7. Users, Roles, & Permissions

Next we'll set up some user roles and permissions, and then we'll create some real users. Refer to the site requirements above to refresh on what our users need to be able to do.

User settings

Only SmartMarks staff will be able to have accounts. Public registration will not be necessary for this site. So we need to restrict regsitration at http://localhost/admin/user/settings and disallow public registration.


We'll need a couple of roles. Since Shannon wants full control, we'll need an Admin role. Since Bill can modify certain things that others can't we'll setup a Manager role. And finally, the rest of SmartMarks' employees will need to belong to an Employee role.

Visit http://localhost/admin/user/roles to get started.

Create a role titled Admin.

Repeat the process to create two more roles, Manager and Employee. We should have something like this now.


Next, we'll define permissions for each of the roles. Visit http://localhost/admin/user/permissions to set up permissions. Set them up like so.

You may be wondering why we didn't give Manager too many permissions. This is because we'll set Bill to also be part of the Employee role, so Manager simply needs to be able to add and edit links. All of the permissions associated with Employee will be granted to Bill.

Now that we've got roles and permissions going, we can create our sites' users.

User Role Shannon Admin Bill Employee, Manager Jean Employee Terry Employee

Go ahead and create these users at http://localhost/user/user/create, assigning roles to each of them. We should end up with something like this on http://localhost/admin/user/user:

8. Creating Content... Finally!

And finally we can start creating content. We're well over halfway done at this point.

Create pages

First off, let's begin with the home page. Visit http://localhost/content/add to create a new Page.

Enter the page title and some sample content for the home page. Set up a menu item for this page. You may also enter some meta tag info if you'd like.

Leave the URL alias setting alone. We'll let Pathauto handle it, and we'll set that up shortly.

Save the page and create another for the About page.

If you now visit the main page, you'll notice that we've got a menu already going. These items come from the pages we just made and from the view we made for Links earlier.

Create some Links

Next, we'll create a few links. Visit the create content page again, but this time choose Link. Create a few links.

After we've created a few links, we can visit the view for Links. Visit http://localhost/links to see our links. Here's what I've got. Remember this is coming from the view we made earlier.

Contact form

Drupal's built-in Contact module is totally sufficient for SmartMarks. We'll just need to set it up. Visit http://localhost/admin/build/contact and click "Add Category" to begin.

Add a category for "General Enquiries", enter Shannon's email as the only recipient, and set "Selected" to yes. This will cause this category to be the default for the contact form. (You could setup multiple categories to handle contact submissions for areas such as Sales, Support, etc.)

You may now view your contact form at http://localhost/contact

Create some blog entries

Last of the content, we'll make a few sample blog entries. We could log out, and then log back in as each user individually, creating a blog entry under each. Or, since you're already logged in as superuser, you can create a few entries and change the author to each user.

Visit http://localhost/node/add/blog and create a sample entry.

Under the authoring info, enter shannon. This entry will become Shannon's first blog entry.

Repeat that to create a blog entry for the other users (bill, terry, jean). Then visit http://localhost/blog to see the user blogs.

9. Finishing touches

We still have a few things to tidy up before we're done. We need to setup pathauto to handle automatic URL aliases, finish our menu, check out each user account, and then we'll add a few blocks to demonstrate a little about blocks.


Let's start with menus. We've already created a few menu items beneath the Primary Links menu. We did this when we created the view for Links and when we created each static page.

Visit http://localhost/admin/build/menu. Here you'll see several menus available. Choose Primary Links.

Choose "Add item". We'll create an item for the Contact form.

Note that the path is relative to the site root. So don't enter "/contact"; just enter "contact".

Repeat the above to create another menu item for user blogs, using a path of "blog". Then visit the tab "List items" to view all the menu items within the Primary Links menu. Now we can reorder the items using the drag and drop handles on the left.

Make sure to save!!!

Now our primary links in the header should be complete and sorted.


Next up, we'll setup pathauto to handle our nice URLs. Visit http://localhost/admin/build/path.

Before we configure paths, let's remove any existing URL aliases. You can do this by visiting the tab "Delete Aliases", then just go ahead and choose all aliases and delete them.

Now we'll setup the automatic aliases under the tab "Automated alias settings".

Open up "Blog path settings" and check the box to have the system "Bulk generate aliases".

Now open up the "Node path settings." Here we'll set up a few rules to handle paths for different node types. Use the replacement patterns (this is where the Token module comes into play) to set up appropriate paths. Make sure your URL alias scheme will produce only unique URLs! And be sure to have it "Bulk generate aliases."

Then save. Then view "List" again. You should see new aliases made for all of our existing content.

A note about URL aliases: Don't forget to delete aliases if you change your URL scheme and regenerate aliases. Deleting and recreating aliases may seem a bit scary, but the more you do it, the more confident you'll become in your URL scheme.


Shannon just informed us that she wants the site to highlight the company's recent office move. This is a good opportunity to go over blocks.

A block in Drupal is simply a 'chunk' of content, be it a list of nodes, some static HTML, a few images, or whatever. We'll set up a simple block to hold the notice about the office move.

Visit http://localhost/admin/build/block. Add a new block by using the tab "Add block".

After adding a block, you'll have to assign it to a region for display. Assign it to the left sidebar on http://localhost/admin/build/block, and don't forget to save!!!

You may also sort them with the drag handles, like menu items.

You should now see the new block displayed in the left sidebar after save.

Check user accounts

Now we're almost there. Just want to login as the users to make sure they've got the right permissions and that they can access the links to allow them to get stuff done.

Log out of the system and log back in as Shannon. Shannon is our administrator, so let's make sure she's able to create/edit all content. After logging in as Shannon, we should see a link to create content.

Go through and login as each user. Just take a look to make sure each one has the permissions and links available to get stuff done. If they don't, try going back to administer user permissions, and verify that they've been granted the correct permissions. Or also make sure you've correctly assigned roles.

Set the home page

We also need to tell Drupal to use our home page as the default home page. You can do this under http://localhost/admin/settings/site-information.

Before you change this data, though, we need to grab the node id of our home page. Visit our welcome page at http://localhost/welcome-smartmarks. Click or mouse-over the "Edit" tab; we just need the node's ID.

Our home page has a node id of 1, so we'll use that for the default home page. Visit http://localhost/admin/settings/site-information and enter some data. At the bottom, you'll see a field for the default home page. Enter "node/1". Note that we're using the node id becuase of pathauto. If we were to change the URL alias of the home page, then we won't have to change its node id, since it will remain the same. Drupal will automatically print out the correct URL alias.

10. Summary

This overview only scratches the surface of what Drupal can do. Hopefully I've given you a good overview of how to get started with the system in building this very simple CMS.


Drupal supports multiple themes, and each user can even chose their own theme.

Building a custom theme is out of the scope of this tutorial. But you can download and install some contributed themes. A good starting place is over at Theme Garden. Download and unpack themes into /webroot/sites/all/themes, then enable and configure them at http://localhost/admin/build/themes. Note that whenever you activate a new theme, you'll have to visit the blocks page to assign blocks to the theme's regions.

If you're ready to start building a theme, you might want to check out the Theme Guide.

Good luck!

Good luck in your Drupal ventures, and feel free to ask questions! Also check out for more information and helpful articles.

Dec 15 2008
Dec 15

Since Drupal 6 the Content translation, and Locale modules have been part of core allowing sites to be translated relatively easily. This is all thanks to Gabor Hojtsy, looking a his profile you can see just how much work he has done for translations whilst co-maintaining Drupal 6.

I am currently working on a trilingual site with these two modules along with Translation Overview (displays what nodes are translates into which languages in an easy table), Localization client (a jQuery pop-up translation interface), and Internationalization (builds on core features to extend them). The team of translators love it, they think it is really user friendly and works well, but I have a few issues.

There are two different types of translation, content translation (nodes) and UI translation (everything else). Content is often added by end users on a live site, where as UI additions are often added by developers on a dev site. This when raises the question, where do translators add the translations? on two separate sites? UI translations can be exported to a PO file which can be read by an app such as POedit, but this will take text out of context which can make translations harder, although it makes it more portable.

Content can be given the marker of "Language neutral" or a specific language, if marked as language neutral the content is not translatable, the original languages has to be selected first. If I were a translator I would find this a little long winded.

It would be great to hear all your views on translations in Drupal, what problems do you have? and what solutions you have found?

Dec 15 2008
Dec 15

We needed to disable all of Drupal’s CSS files from our theme. Here’s how we did it:

function THEMENAME_preprocess(&$variables) {

  // Get rid of all of Drupal's CSS files
  $css = drupal_add_css();
  foreach ($css['all']['module'] as $file => $status) {
    if (!strstr($file, 'modules/MYMODULE')) {
  $variables['styles'] = drupal_get_css($css);

We also wanted (no *real* need) to use screen.css rather than style.css, so we edited to have this:

stylesheets[all][] = reset.css
stylesheets[all][] = screen.css

… and we removed the line for style.css from it.

Finally, as the superuser we went to /admin/build/modules (or /themes, can’t remember now) to refresh the theme cache. We also had to tick to enable the theme at /admin/build/themes as although we’d been using the theme for ages quite fine, it wasn’t actually ticked before.

And hey presto, it worked. Should probably add that it took waaaay too long to do though, so though we’d add this snipped for others to read.

Share this:

Like this:

Like Loading...
Dec 15 2008
Dec 15

My last several weeks (months?) have been pretty darn hectic preparing for Do It With Drupal. Well, we've done it with Drupal - and it was awesome! It was really fun bringing the whole Lullabot team to make it happen. The speakers were awesome, the venue was great and the people rocked.

For those of you who missed it, the event was pretty well documented via the twitter backchannel and flickr photos. Thanks everyone!

I'm back home now... oh - and I moved! I'm now living in a beautiful house at St. Clair and Dufferin.

So it's time to settle in for the holiday season, finish getting unpacked and settled and enjoy a little breathing room. To kick it off, I'm heading to #hohoto tonight. Looking forward to partying with my local Toronto people!

Dec 15 2008
Dec 15

My last several weeks (months?) have been pretty darn hectic preparing for Do It With Drupal. Well, we’ve done it with Drupal - and it was awesome! It was really fun bringing the whole Lullabot team to make it happen. The speakers were awesome, the venue was great and the people rocked.

For those of you who missed it, the event was pretty well documented via the twitter backchannel and flickr photos. Thanks everyone!

I’m back home now… oh - and I moved! I’m now living in a beautiful house at St. Clair and Dufferin.

So it’s time to settle in for the holiday season, finish getting unpacked and settled and enjoy a little breathing room. To kick it off, I’m heading to #hohoto tonight. Looking forward to partying with my local Toronto people!

Dec 13 2008
Dec 13

If anyone is interested in developing, or knows of an existing one, a "bot like" theme for please make a comment.

The bot needs a bit of pizazz. (Drupal 6.x)

Dec 11 2008
Dec 11

created on Thu, 2008-12-11 15:35

Drupal CampersVancouver Drupal evangelists and ringleaders (and my Vancouver Drupal Camp co-horts) are brewing up another get together for the Vancouver League of Drupallers. Ariane and Dale have sent out a call for a Vancouver Drupal geek festive social with a purpose - code sprinting for Fearless City.

I interviewed Irwin to learn more about Fearless City's mission, audience, participants, animators, success stories, so stay tuned for more coverage. In brief, they are helping residents and artists in the disadvantaged downtown Eastside of Vancouver gain access to digital storytelling skills and tools and create ways to easily publish and share their creations.

Since, I will be sequestered on a remote island, I have no right to talk about the event, so instead will defer to Ariane's details from - Christmas Social and Fearless City Code Sprint!!!

Ok, we're a go! This has all come together very quickly, so hope lots of you can make it out!

When: 2pm, Sunday December 14th.
Where: Raincity Studios, 1 Alexander Street, Suite 400 in Gastown. (Buzz #400)

The plan is to work for a few hours at least and fix up the Fearless City website and get it all running smoothly again. If we have time, we'll add some new features as well, I'll be meeting with Scott Nelson at the end of the week to get the down low on what's wrong with the site currently, and some user feedback on additions they'd like.

If you don't know about Fearless City, check out their site, they're a great non-profit in the DTES.

We'll be doing things like cross-browser troubleshooting, module (and likely core) upgrades, theming tweaks, and some customization, so whatever your skills are come on out and we'll find something to put you to work on! If you're thinking "Oh, I'm too much of a newb to help out," put those thoughts out of your head! We'll need lots of help testing the site and new functionality, keeping things organized, etc. Plus this is also a social, so you're welcome to come and socialize too, as long as you remember the first few hours will be focused on the sprint.

Food is yet to be organized. If any lovely sponsors come out of the woodwork and want to buy us some pizzas or something, that'd be great! Otherwise, we may have to go potluck style and have everyone bring some snacks and drinks. I'm sure at least some people will head out for dinner afterwards too, and if someone wants to organize that more formally, you're more than welcome, just post the details here.

I'll try and get an outline of the work to be done posted up here a little ahead of time in case anyone wants to put dibs on some of the work.

Finally, please rsvp if you know you're coming so I can get an idea of how much wo/man power we're going to have.

Thanks and see you all soon!


Ariane torelad (at) drupal (dot) org

Drupal geeks having funIn usual Vancouver geek community manner, the Drupalists are stepping up and adding their expertise to the conversation. I talked to Raincity Studios' developer (and frequent Drupal camper) Audrey (aufumy) who mentioned how the volunteers are already preparing for the event.

Iain (iainduncan) set up an SVN and Trac (for non-devs this tool allows simultaneous work by many developers, themers etc., without overwriting files and manages file revisions and issues tickets). Ariane set up a wiki for Vancouver Drupal group members with tasks and plans.

Fearless City web crew Scott Nelson is heading up the tech tasks and Raincoaster Lorraine is on top of real-life testing for their unique requirements of serving a low-income and often transient audience. She speaks to this in her comment:

"Fearless is really looking forward to this. We're doing a users panel this Saturday to gather feedback from participants who use the site all the time. Usability is key to the success of the website, especially with a user base facing so many challenges: public computers on which they can't change settings, visual challenges due to no corrective lenses, etc. Everything needs to be as easy to use as possible.

It's great to see the Drupal community support for our project. You guys are stars!"

Check the site for potluck or other food info ... to start this important conversation Drupalist mcantelon says, "I'll bring cookies and/or some nog variant." To which i reply - Excellent news!

Photos by ArianeK on Flickr.


Dec 11 2008
Dec 11

Following on from my post yesterday about our company's sponsorship and presentations, I thought it was worth a post to highlight the sessions other people in the Drupal community have proposed that relate to the building of a geospatial web with the help of Drupal - the main reason I got involved in Drupal in the first place.

"This presentation will include an overview of the emerging Geospatial web, and the technologies, standards and communities that are driving it. We'll look at how Google Maps fall short and how to go beyond its basic approach to mapping on the web. We'll cover where Drupal fits in, ways to incorporate other mapping tools and data into your projects. Specifically, what modules extend Drupal, enable it to leverage existing tools and how to use these to do new and interesting things."

Jeff has been doing all sorts of interesting work recently with Drupal and RDF for storing geodata, and Andrew is the heavily involved in GeoCommons and Mapufacture, empowering users to share their geographic information.

"You have access to tons of information, Eric Gundersen of the online strategy shop Development Seed will talk about how interactive maps, data visualizations, and other online tools can quickly show you the bigger picture around large scale international issues. Eric will demo the new Pandemic Preparedness Mapping site built for InterAction to prevent the spread of a catastrophic disease like bird flu."

Eric, and Development Seed in general, have done a lot over recent years to build cool sites that are often centred around geospatial information. The Pandemic Preparedness Mapping site uses maps care of the Nice Map module and also a modified version of the KML module that allows people to access all the data in the site through Google Earth and many other systems that can read KML.

"This session will move from GIS concepts to Drupal GIS practice. We will talk about the principles of storing, organizing, and searching geodata, the practical usage of geodata in Drupal applications, and how geographic functionalities are implemented by existing Drupal modules."

Brandon Bergren, primary maintainer of the location module, GMap module and geo module will also be one of the presenters.

"Leveraging semantic web services such as Thompson Reuter's Calais within Drupal enables you to do amazing things that will be part of the semantic revolution. This session will cover some incredibly powerful things you can do to augment content and create powerful features once you have the semantic context and metadata of the information driving a site."

Another example of the intersection between the semantic web, Drupal and geospatial information, this talk will demo the Calais Geo service for geo-tagging and mashing up content.

There will no doubt be some BOF (birds of a feather) sessions around the growing area of geographic information in Drupal as well, but it already sounds like a great mix of presentations. If you're going, remember to vote for the sessions to make sure they all get the chance to present!

Dec 10 2008
Dec 10
  • Advisory ID: DRUPAL-SA-2008-073
  • Project: Drupal core
  • Versions: 5.x and 6.x
  • Date: 2008-December-10
  • Security risk: Moderately Critical
  • Exploitable from: Remote
  • Vulnerability: Multiple vulnerabilities


Multiple vulnerabilities and weaknesses were discovered in Drupal.

Cross site request forgery

The update system is vulnerable to Cross site request forgeries. Malicious users may cause the superuser (user 1) to execute old updates that may damage the database.

Cross site scripting

When an input format is deleted, not all existing content on a site is updated to reflect this deletion. Such content is then displayed unfiltered. This may lead to cross site scripting attacks when harmful tags are no longer stripped from 'malicious' content that was posted earlier.

Versions Affected

  • Drupal 5.x before version 5.13
  • Drupal 6.x before version 6.7


Install the latest version:

  • If you are running Drupal 5.x then upgrade to Drupal 5.13.
  • If you are running Drupal 6.x then upgrade to Drupal 6.7.

Note: the robots.txt and .htaccess files have changed and need to be replaced. The settings.php file has not been changed and can be left as it was if upgrading from the current version of Drupal.

If you are unable to upgrade immediately, you can apply a patch to secure your installation until you are able to do a proper upgrade. The patches fix security vulnerabilities, but do not contain other fixes which were released in these versions.

Reported by

Both issues were reported by David Rothstein (David_Rothstein).


The security team for Drupal can be reached at security at or via the form at

Dec 10 2008
Dec 10

OpenBand, an M.C. Dean CompanyMy employer, OpenBand, is going to be a Gold sponsor of DrupalCon DC in March 2009 and a number of our team members will be attending the conference.

We have a few presentations to give, and will be keen to see many of the other sessions that are going to be given.

In the Powering collaboration in a distributed enterprise session we'll be giving an overview of the work that we do, the collaboration platform we've been building (largely on Drupal) for our customers over the past three years or so, and some of the modules that we've contributed back to the Drupal community during that time.

Miglius Alaburda will be presenting a session titled Introducing a new File Framework about a new and powerful way of handling files in Drupal.

Darren Ferguson will be talking about Drupal with XMPP Integration and all the functionality that he has built up around the XMPP framework, allowing users of a Drupal site to use instant messaging capabilities.

With all the sessions that have been proposed by attendees, this is shaping up to be a great conference!

Updated: Added Darren's XMPP talk

Dec 09 2008
Dec 09

In this demo videocast I explain how articles from PubMed can be integrated in a Drupal site. First I focus on the end-user perspective (e.g. adding RSS feeds for specific PubMed queries). Afterwards I talk about how you can implement this on your own website.

This solution can be useful for scientists with a blog or research groups in the medical/biotechnological field that want to give easy access to some of their publications. It could also be the basis for an intranet where you want track and share comments on new developments in specific medical fields. I imagine that you could configure the site with automatic notifications when new content is aggregated and for public sites require the user to approve any new content.

The contrib Drupal modules I use are FeedAPI and the feed element mapper, 2 modules developed by DevelopmentSEED. I'm also of course using CCK and Views, to make the content types and the lists.

In the demo I'm using a PubMed feed for Myers PZ, who is a biologist and associate professor at the University of Minnesota, Morris. His blog, pharyngula was number one of the top 50 popular science blogs in 2006 at

I made this mash-up as part of the research for the PubMed module that I talked earlier about on this blog. Since then I found a student, who participates in the Drupal class which we help organize at the University of Szeged (and not a thesis student as I mention in the screencast).

This mash-up proves the feasibility of the aggregation of content from PubMed with existing Drupal modules. It also however uncovers a couple of drawbacks to this set up (e.g. manual feed creation, problems to capture the data in a structured way with existing parsers).

Dec 09 2008
Dec 09

Following on the Data Architecture Design Sprint during a cold and snowy Chicago week in February, two Drupalcon presentations, a lot of writing, and even more debating, I am really looking forward to next week's Fields in Core code sprint. Our goal is to re-organize Drupal's content APIs and data storage around Fields instead of Nodes; think of it as "CCK in core, except for the admin UI." When the dust settles, everything will continue work just as it does now, but we will have a framework in place to allow Drupal and the community to get maximum leverage from what it is best at: Adding Value to Content.

We are assembling a team of six experienced Drupal developers at the Acquia offices in Andover MA: Yves Chedemois, Károly Négyesi, Karen Stevenson, David Strauss, Moshe Weitzman, and myself, and Dries Buytaert will be on site and participating as well. We will be tracking our progress at the Fields in Core group and expect to have plenty of tasks for virtual attendees to help with.

I'd like to particularly call attention to the fact that Yves, Karen, and Moshe are donating their personal time for this sprint. Also, NowPublic, Four Kitchens, and Acquia are donating their employees' time. Since four of the attendees need to fly in and stay in hotels, we're trying to raise $7,000 to cover the costs and maybe a nice dinner out for everyone as well. That works out to $25 per hour that these developers will be working on your favorite CMS. So, please consider making a donation. :-)

Dec 08 2008
Dec 08

Version Control API ! There's no stable 5.x-2.0 release yet, and the Drupal 6 version will only be tackled after that happens (i.e. next year), but we're alive and kicking again. And yes, I'm still determined to get it to replace cvs.module on Even if it might take another year until all the odds and ends come together.

Anyways, now is the time for potential contributors to jump in and create recipes on how to set up version control integrated sites, to port the Git and Mercurial backends, create a new one for Bazaar, to make the repository viewer work on previous revisions or to improve the CVS backend so that it's browsable like the SVN backend's development version. If you're ambitious, you might also try porting's release scripts to the Version Control API so that automated releases can be made with Subversion and other version control systems.

Whatever the outcome, the era of cumbersome reinventions is over for the time being. Time to get started on features (and the D6 port, soonish) - let's push cvs.module into irrelevance and take version control integration with Drupal to the next level!

If you're passionate about version control systems, here's where you can make a difference!

Dec 08 2008
Dec 08

I recently finished, a simple Drupal 6 site for my fiancée and her handbag business. It uses CCK, Views and Panels 2 alpha, as well as ImageField, ImageCache and Lightbox2 modules. I also wrote Image Themer and Views Themer modules, which I contributed to the Themer package and plan to abstract in to re-usable solutions in my next Drupal 6 theming project which I start this week. I will also be demonstrating these modules at the Advanced Theming Techniques session (if it gets in – Go Vote!). You browse the still-very-alpha code for these modules in Drupal's CVS repository. Drupal 6 Showcase site

The site is a good example of what can be achieved with a small budget and flexible requirements. I spent no more than 30 hours total on this website including some contrib-module development, photoshop slicing and resizing and a little custom theming. The base-theme is foliage. Before commencing I spent a few hours in conversation with my fiancée (the 'client') working out what was most important sketching some paper prototypes.

Dec 08 2008
Dec 08
Now that I have been a full-time Drupal Developer for a couple of years, and a part-time Drupal developer for a year before that, I am beginning to recognize recurring patterns and problems in Drupal projects and people's experiences with Drupal. This is a report on my experiences, and a summary of learned lessons and recommendations for those entertaining the idea of a financially-driven Drupal project.

Executive Summary

  1. Don't undertake a Drupal project without, at the very least, someone on the team or available to the team, to check solutions are architected the Drupal way, monitor development for employment of good practices, look for learning opportunities for the less-experienced Drupal developers on the team, and be available in a timely manner to answer the question What would Drupal do?.
  2. Don't underestimate the cost of learning Drupal. It is almost always greater than the difference in price between experienced and inexperienced Drupal shops or developers.
  3. If you do not have an experienced Drupaler on your project's team, expect it to go several times over budget, and/or be under-delivered. Most of the time it will be cheaper to have the developers use the tool they already know.


As more and more people discover and decide to use Drupal, the more and more popular it becomes. Given the way a crowd-attracts-a-crowd, especially with free and open source software, Drupal is quite clearly set to become the dominant open source web CMS in the professional and business-oriented web-development markets – if not the dominant CMS of both open source and proprietary options. It's also likely that Drupal will dominate in the amateur and hobbyiest markets too, when usability bugs get ironed out with a little more time and a couple more Drupal versions.

Many non-Drupal web development shops are recognizing this, and are beginning to realize that it's too expensive to maintain their own proprietary CMS, or – worse – maintain skills in multiple different CMS, when one could rule them all, and even do a better job.

The Problem

Businesses and individuals seeking websites also recognize this. In fact, many clients looking for a web shop have already decided they want their website to use Drupal. Instead of shopping for a general solution provider, they often look for a Drupal developer or Drupal shop.

I have seen this many times now, always with one of the two following results;

  • They find an experienced Drupal developer, recognize the value and importance of siad Drupal developer's experience and role in the project, and get them involved.
  • They don't find (or find, but can't afford) a Drupal developer or shop, fail to recognize the importance of this, and contract web developer or web shop with little or no experience.

Unfortunately – because of the high demand for experienced Drupalers – most end up in the last category. This is understandable, given that most clients seeking someone to build their website do so because they lack the expertise to do it themselves – they are therefore not likely to understand that – even with software, including Drupal – a tool is only as useful as the skills and experience of it's user.

This always – with no exception – ends up leaving the developers running frustratedly in circles, and the client burned with an under-delivered and over-budget product.

I have seen a number of non-Drupal web development shops talked in to using Drupal for the project because it was what the client wanted. The developers or shop often tell clients that "Drupal is a PHP application, and we're a PHP shop, so we can do Drupal". Even the developers often fail to recognize that Drupal is worthless to them until they have learned "the Drupal way", have experience with Drupal, have become self-dependent Drupal learners and can confidently answer the question What would Drupal do?. For most web development shops this is a significant amount of resources to commit. In fact for most run-of-the-mill shops, which are typically small businesses of 5-15 persons, it's too-large an investment.

The Solution

And indeed it is a large investment – after working full time with Drupal for a couple of years now, I'm still learning new things about Drupal just about daily. And there is no possible way any person or even small group of people can recall, understand and know how to use even half of the almost-4000 contributed modules.

The solution is to develop mentoring relationships. Every Drupal project needs at least one person who is sufficiently experienced with Drupal such that he or she can guide other developers through the project, showing them what Drupal would do. Finding this mentor or Drupal developer is key to the success of any Drupal project with any non-trivial amount of configuration and code.

It is the responsibility of project stakeholders to find these people. It is also the responsibility of web developers to avail themselves in a mentoring capacity to less-experienced Drupal developers.

Dec 08 2008
Dec 08

Mullenweg: Scale WordPress to 20,000,000 Views per Day for $100 p/month

Posted by Aaron D. Campbell | Monday, December 8th, 2008
, , , , ,

An interesting article appeared on the front page of the website, detailing the migration of the popular “crooks and liars” blog from WordPress to Drupal. According to the developers, when the site was averaging around the “200,000 hits per day mark, we started experiencing a lot of down time from server overloads. We were utilizing the famous wp-cache plugin for WordPress, as well as hosting the database on a single master and two slaves, using the HyperDB class for WordPress to handle the replication.” After experiencing a high degree of server downtime from the massive number of comments on the site, “crooks and liars” began to consider porting the site to Drupal for performance issues.

According to the site development team, benchmark tests showed that a Drupal 5.x installation was able to serve more than 8 times the number of pages per second vs. a standard WordPress 2.3 set up:

“I setup default installations of WordPress 2.3 and Drupal 5. I only enabled the core caching mechanisms in both setups and populated them with the exact same data and display options. Both systems also used the default themes and features. After running a series of tests through JMeter, I quickly confirmed my beliefs and even exceeded them as I saw Drupal was able to handle about eight times the requests per second as WordPress, both on the front page and the same single post view with 157 comments.”

An interesting overview of the migration, and custom modules used in the development of the “crooks and liars” site can be found online here:

What is more interesting, is after the post was published, WordPress / Automattic founder Matt Mullenweg weighed in personally on the issue, by commenting on the post and listing ways to configure WordPress to scale to 20 million hits per day – at a cost of only $100 per month. He writes:

“Always sorry to see someone leave WordPress, but you ended up pretty much the other best place I could think of. Features are a great reason to switch, but scaling doesn’t need to be. We host some of the largest poltical blogs like all of CNN’s which regularly get thousands of comments per day and we do about a billion pageviews a month on, so here are some tips for future people who may come across this post (some which may be useful to the Drupal community as well):

1. Every release of WP gets faster, so upgrading can get you sometimes significant boosts depending on your bottleneck.
2. Use the memcached object cache backend.
3. If memcached is set up, use Batcache instead of wp-cache.
4. If you get a lot of comments, consider using InnoDB as your storage engine instead of MyISAM inside of MySQL.
5. Double-check that your webserver is set up properly for static requests, this is the cause of 90%+ of the problems we see.

With the above and a single $100/month server from LT you can get around 20,000,000 pageviews a day. With shared Batcache and HyperDB (which you already used, nice) it’s a lot easier to scale out both the web and database tier independently as needed. We haven’t found the upper limit of this strategy yet.”

Included are links to Quantcast’s statistics proving 1 billion page hits per month on (globally):

Link to the Memcache Plugin:

Link to the Batcache Plugin:

According to the site:

“Development testing showed a 40x reduction in page generation times: pages generated in 200ms were served from the cache in 5ms. Traffic simulations with Siege demonstrate that WordPress can handle up to twenty times more traffic with Batcache installed.”

Based on Quantcast statistics, ranks 13,298 overall while ranks #11. Global tracking statistics are not available for on the site.


Dec 08 2008
Dec 08

If you haven't tried to do video online, you'd be surprised at how difficult it is. There's a large number of formats out there, and often your source video isn't appropriate for displaying on a web page. The process of converting the source to a format and size that works online and then getting it into Drupal and delivered to your viewers turns out to be expensive and time consuming.

Many people turn to public video sites like Vimeo or for video transcoding and hosting and lie with having their video under the control of a third party. Others install ffmpeg on their web server, but that fails as soon as they have any volume. That's why we're proud to announce CDN2 -- a Drupal-native video platform that offloads video processing from your web server and gives you the delivery cost advantages of a content delivery network. It's on demand video transcoding and delivery, pre-integrated with Drupal.

CDN2 is a combination of a Drupal module and a hosted service that's designed to help you manage video with ease. The module allows you to transcode video into many different formats, from iPhone video to Flash video for the web, to high definition flash. It plugs into Drupal's permissions system, allowing you to specify user roles that are allowed to upload video, what formats they can transcode into, and who can view the different formats.

The display of your video is fully themeable and you can choose any flash video player you'd like. We've included support for FlowPlayer and DashPlayer, and adding your own is a simple matter of theming.

Unlike installing ffmpeg on your own server, this won't tie up server resources during upload and conversion, allowing you to scale your web site independently of your video services. We handle the upload, the transcoding, and even the hosting for the video files. Pricing is simple and starts at $2.50 for every GB you transcode, and $0.50 per GB for the bandwidth consumed by your video. There's no contracts to sign, just pay for what you use.

Using CDN2, you don't need to build anything to get started with video. No custom integration projects. No hardware or software to buy. No work involved in getting your video on the web. Download it and have your first video up and running in minutes.

Dec 08 2008
Dec 08

The Workhabit blog is chock full of updates to our products, videos from our crew, and discussion about our design, development, events, business strategies, and observations.

Dec 05 2008
Dec 05

Since becoming a "professional" Drupal developer earlier this year one of the hardest things I have found within my team is best practices for Drupal development. When maintaining my blog or web startup all best practices go out the window. The approach taken is to SSH into the server, get all of drupal core and contrib using wget, do all main module and theme development on localhost then FTP them to the server. All other development is done using the Drupal UI on the live site, and via SSH using vi. This is not the way it can be done in an international organisation.

Over the last few months we have not launched any sites, but have been working on a large project. This project is currently hosted on an external development environment which we use in very much the same way as I manage my own sites. Now we are looking at more development, and launches onto a live site every few weeks we needed to start planning development a bit better. So... we called on Acquia and they sent Robert Douglass. We spent two days with Robert discussing our needs, thoughts and ideas, he then fed back with his experience.

Here's what we are planning to do...

  • Store all code including core, contrib and custom modules in Subversion.
  • Regularly dump the live database and store in Subversion.
  • Maintain a local copy of the site for each developer from the latest development code and lastes live database on Subversion (refreshed weekly).
  • Create a module to update the live database using the update function.

Creating a module to update the live database using the update function seemed a very radical idea when it was mentioned. It envolves creating an update function within the install.php of a custom module to set all the database settings, it can also be used to import CCK and views settings as well as run Devel macros. This enables us to run the site setup via update.php which will keep all out development and testing environments the same, without effecting any of the existing data. So although it sounds a little long winded it will mean we have a system that is guaranteed to work from day one, with all the content, users and translation all intact.

Another big decision is what development software to use, Eclipse? Komodo? Dreamweaver? Coda? We have currently been using Eclispse but found it very hard to setup, and everyone's install seems to be inconsistant, Komodo gets very good reviews, Dreamweaver doesn't seem suited, and I love Coda (I use it at home) but it's only Mac based, which isn't good in a 99.9% Windows based office. So I quess we will stumble on with Eclipse, whilst looking into Komodo a little more.

I'm sure I have left things out, and I'm sure others have different views. It would be great to hear your comments, thoughts and feedback.

Dec 05 2008
Dec 05

We developed 4 module recommendation algorithms and tested them on And we used Google Analytics and tracked the click-through rates. The overall click-through rate was 0.263%, co-occurrences 0.097%, relevance 0.141%, recency 0.114% and uniqueness 0.138%. The relevancy algorithm appeared to have the highest click-through rate, but it was only significantly higher than the co-occurrences algorithm. Despite that, we can still say that the relevancy algorithm is the best alternative among the 4.

Now we have the baseline for future module recommendation algorithms, such as recommendations based on download statistics, or on module usage statistics. The new algorithm has to have a better click-through rate than the relevancy algorithm.

The 0.141% click-through rate, however, does not seem to be a large number. A general rule-of-thumb is that the best online ads would have 1% click-through rate. But it might be calculated using different method in different context. Therefore, I'm thinking to test the click-through rate if we put the "New forum posts" block on the module pages. Hope it can be done soon.

Dec 05 2008
Dec 05

Drupal has an option I haven't seen in any other CMS: You can set a theme for the admin section to your liking. As nice as it is, it raises serious UX problems especially for new users, if admin and frontend theme is the same (see UX study Baltimore: Where is my site?)  There has been talk and action to cure this in a simple way: get a default administration theme into core.

Having learnt that core issues require determination and endurance, I'd like to make a fresh start (apart from an existing issue about that:( by introducing some possible guidelines and candidates.


So what is this all about? Apart from seperating Front- and Backend optically, why should we want a seperate Admin theme and which requirements should it meet?

1. Clever use of Space

One thing that bugs me about Admin and settings pages in Drupal is the waste of space. Everything is rendered in a vertical manner, a lot of space is wasted because often only a third of the horizontal space is used. On the right see a typical example from the comment settings: the descriptions could easily also flow inside the red-lined area.

Though I understand the reason for this: Modules can easily insert new settings into this because everything is vertical, I hope one day we will see the use of all that horizontal space. For the time being, how to improve the use of space without having to change the forms? Well: Paddings should be small, Fontsizes can also be set to 11px for many things.

This is one main reason I never use Garland for admin section: The fonts are way too big and a lot of unnecessary paddings (that are fine for frontend) are there.

Here is an example from a theme I've done myself: The simple trick to set the font size in the blocks table to 11px makes the table much smaller and nicer, still it is very readable.

2. Optical Hierarchy

There is lots and lots of elements in Admin section. So how can you emphasize more important things and diminish less important? Not too hard to say. Use Font coloring: text can have many shades of grey, and can use color (at least the major color, which would be blue in Garland), text can be smaller and bigger. Headings can be big headings and smaller headings. Very importand messages can get an Icon, which is easy to understand for its symbolic character. See the examples from pixture for the icons. These make a lot of sense for messages which are normally very important.

3. Candidates

These first guidelines imply that a lot of work has to go into detail in an admin theme: font sizing, how to present tables and tabs. Other than a front end theme, the primary focus is not on looking nice. Well sure it should look nice. But furthermore, it must be rational and have a very good Information hierarchy, readability and so on. So far I know three themes that present themselves as Candidates, of which one is not ported for D6 and maybe never will, but is still useful as an example. These candidates so far are RootCandy, Pixture and Aquasoft (which is not ported to D6).

Realizing that this gets too long for a single blog post, it will be a series ;) So in the next issue we will have more guidelines and a look at the candidates and the skills they get onto the dancefloor.

Dec 05 2008
Dec 05

In drupal, when you go to you get redirected right away to (if 777 is your user id and if you are logged in). If you are not logged in, you see the login page.

My client wanted users to be redirected to instead. How simple, right? WRONG!

Sometimes, (or often in Drupal) the simpliest thing end up being a nightmare.

I wrote a drupal module to handle this:

function foo_menu($may_cache) {
  if ($may_cache) {
    $items[] = array(
      'path' => 'user',
      'callback' => 'drupal_goto',
      'callback arguments' => array('user/me'),
  return $items;

I cleared my cache (thanks to the devel module) and I tried going to 'user'. Nope! I ended up on user/777 again.

I ended up figuring out why I was pulling my hear out doing this rather simple change. The problem was caused by the user.module which was doing something I did not expect.

As you know, the hook_menu($may_cache) is called twice. Once when you clear the cache and once for every request. When you clear the cache this hook is being called with TRUE as the $maycache parameters. You usually put menu items that can be cached (does not change dynamically). Most menu items can be cached. Some menu item like user/123/edit must load the node at run time before allowing you to see the content. But things like 'user' can be cached... so I thoughts.

The user module actually handle this two fold.


  if ($may_cache) {
    $items[] = array('path' => 'user', 'title' => t('User account'),
      'callback' => 'drupal_get_form', 'callback arguments' => array('user_login'),
      'access' => !$user->uid, 'type' => MENU_CALLBACK);
  else {
     // ...

This is cached ($may_cached is TRUE) and is only accessible to logged out users and will present you the login form.

then you've got this which is causing my head to spin:

  if ($may_cache) {
     // ...
  else {
    if ($_GET['q'] == 'user' && $user->uid) {
      drupal_goto('user/'. $user->uid);

The "else" code is executed at every request, before the final decision is made. And this is calling drupal_goto right there right then which simply exit and stop all other menu hooks from ever being called. This is cheating!!! :)

The only way to fix that without hacking the core is to create a module with a ligther weight (change the weight column in the system table for that module) and implement a hook_menu that will run the same code as above but redirect elsewhere.

function foo_menu($may_cache) {
  if (!$may_cache) {
    if ($_GET['q'] == 'user' && $GLOBALS['user']->uid) {
  return $items;

This will only work if your custom module is executed BEFORE the user module.
More details on "How to update a module's weight":

Dec 03 2008
Dec 03

Do It With DrupalNext week marks the beginning of Do It With Drupal, the three day conference made of pure awesome held in New Orleans.

I'm really getting excited to seeing all the Drupal folk again, as well as meeting some pretty awesome people like John Resig of jQuery and Chris Pirillo from, uhhh, everywhere. It will also be great to see Ed Sussman again, and watch Nicole talk about project management in a Drupal world.

All the sessions will be amazing as well. Building Twitter/Flickr/YouTube/Amazon clones with Drupal, project managing a website being development, creating community, every session looks to be very fun and education (edutaining Drupal!). Looking forward to seeing you all there.

If you can't make it to New Orleans next week, be sure to book your ticket to DrupalCon DC 2009 next March!

Dec 02 2008
Dec 02

My first book, "Using Drupal" will be shipped December 16, 2008. I co-authored the book with several other incredible Lullabots: Angie Byron, Addi Berry, Jeff Eaton, James Walker and Jeff Robbins. I'm very, very excited about the release of this book, not only because it's the first one I've authored, but because of the subject matter covered. There are several other books on Drupal (including the excellent Pro Drupal Development book, also authored by Lullabots John VanDyk and Matt Westgate), but none of them approach Drupal with such comprehensive coverage of actually using the software to build websites. It's also the first book to extensively cover contributed modules in addition to Drupal core.

Despite having worked on the book for well over a year, it's hard to believe it's really here. Today I received a newsletter from O'Reilly containing my biography for the book. The book is already available through O'Reilly's excellent Safari service. I haven't received my physical copies yet, but I guess it's already undeniable that the book really is finished and one more life goal accomplished.

Here's my bio on O' You can pre-order Using Drupal from

Dec 02 2008
Dec 02

The Workhabit blog is chock full of updates to our products, videos from our crew, and discussion about our design, development, events, business strategies, and observations.

Dec 01 2008
Dec 01

Technological leadership

Active in product innovation and open source software services, we build lasting value for our customers and the Drupal community.

Empowering relationships

Caring about clients and the outcome of their projects, we get involved and make meaningful relationships that give our customers maximum independence.

Community engagement

Dedicated to fostering the Drupal open source community, we catalyze event and development initiatives, resulting in real change and growth.

Dec 01 2008
Dec 01

Before I got totally swamped in the preparation of Drupalcon Szeged, I was playing with a module that uses a nodeAPI implementation for extra RSS fields, similar to Ian Ward's "views rss extra maker" in the developmentSEED sandbox. This Monday I finally committed it.

The module leverages the Views 1.0 field interface to give users control over the fields that will be displayed. It needs a minor patch to views_RSS (to add the $view variable when invoking the nodeAPI) to be able to do it's thing (nested tags, only specified fields). It also supports CCK fields with multiple values.

It adds 3 new field selectors to the field interface:

  • "all_fields" that adds all fields of a node (like Ian's module)
  • "field_groups_start" that opens a tag for nested XML
  • "field_groups_end" that closes a tag for nested XML

It then adds only those node fields that you specified in the field interface and outputs them between tags derived from the field label.

In theory it should give a non-programmatic interface that allows users to adopt the information that is outputted in a feed to the disparate standards out there (it might still need some tweaking for this e.g. it doesn't support media fields). I created it however in the first place to make it possible to transfer information from CCK fields between sites using the feed element mapper module and the feedAPI.

So far my role in the company allowed me to get away without having to dive into the CVS repository. It's not all that long ago that I was saying that I probably would never be a developer. But I can't let my colleagues have all the fun ;)

So I made the plunge, but after some funky error messages with TortoiseCVS (yes I'm still on a Windows machine), that got me pretty frightened of messing up the repository, I procrastinated over committing the module. Until today I finally sat down with my colleague Kornel, who's one of our Linux guru's, to navigate the CVS oceans. So thank you Kornel and also thank you Ian Ward and colleagues at developmentSEED for their patience.

Dec 01 2008
Dec 01

If you build quality sites that attract a large number of visitors and interaction there eventually will come a point when you have to start looking for ways to offload your files and bring down your server overhead. I have been looking into the CDN issue off and on for the past 6 months. Recently I decided it was time to get something dialed in and move forward. I wanted something that required the least number of hacks and was easy and scalable. This post isn't meant to be an end all to Drupal and CDNs, but rather just some insight into the way I have tackled this issue for the time being.

There are a number of options to choose from and a lot of different ways to go about it. You could get a new server locally and load balance your stuff, you could get a new server locally and use it as a static file server, you could team up with a big time CDN like Akamai or Limelight and go that route, or you could go the less expensive CDN route with something like Amazon S3.

Note: This article doesn't attempt to explain every little detail of what's going on, but rather act as a guide for a developer to work off.

My Goals

Being somebody that is cost conscience and wanting to always try to get the most bang for my buck the idea of a CDN like Limelight didn't quite seem like an appropriate fit for me. I wanted something a little bit less serious that I could ease into. I don't care about having servers all across the world and getting content to people a few milliseconds faster than other solutions. I just want to take a huge load off my local network and put that load somewhere else. If my site is up and the users are happy, I'm happy.

I also don't care if 100% of my site files are not offloaded to the CDN. If I can take care of 95% of my load and leave 5% on my main box it really doesn't bother me. My main goal is to get rid of the majority of the overhead and keep everything scalable and dynamic with a relatively small code footprint.

Which files to offload

With these things in mind I have basically decided that a good route for me was to mainly take care of my two main sources of files: images and videos. If I really wanted to get hardcore I could also move my CSS and Javascript, but I don't see this as important as taking care of the major problems first.

Take my site for example. If you hit the homepage you will see that there are a lot of thumbnails and image requests. Each page probably has at least 20 image requests, some as much as 50. So I would rather take care of these requests first and then I can worry about the 5 or so CSS and JS requests later if I have to.

And then I have the video content which can be large in filesize and taxing on the server. This also had to go.

Local file system

Another thing to keep in mind is that I don't want to make my CDN act as my local file system. I don't want people to upload straight to this and only have this as my main system, I just see too many errors and bugs going this route. I would rather just have everything work normally and smoothly through the default local structure and just copy stuff over to the CDN, which brings up an important point.

Synching your content

Just how should you copy your content over to the CDN? Big time CDNs like Limelight allow HTTP synchronization (which Ted Serbinski talks about in his article) which basically copies your files over automatically. S3 does not offer this type of functionality so you will need to go another route.

You could simply copy them all at once programatically and call it a day. You could also maybe set up a cron and copy any new files every few minutes. But how do you know which files are new? How do you know which files get updated and which don't? You could run some PHP scripts like a cURL or file_get_contents to check the file's last modified time, but this has some big overhead (I tried). So when is the best time to copy the file and how should you do it? You most likely want to get the file over to the CDN as quick as possible, but at the same time you want to make sure if the user updates the file or something is changed your CDN reflects that.

My S3 Solution

I chose to go with a hybrid type approach. I basically send a file over to the S3 every time it is requested, if it is not already there, or if it is newer than the current file.

I have one main routing function that when called will run through the flowchart below and figure out what path to return for any given file, either:




So basically my flowchart goes something like:

The Technical

S3 Interfacing

So if any of you have messed with S3 you know that you are going to need a PHP class first to put your stuff there. I found a decent class off their forums and went with that (it requires PEAR, unfortunately). At one point I'll probably change this to something better if I find one, but it gets the job done for now.

Filetype check

This is just a quick little function that basically checks if the filetype is listed in an array of allowed filetypes that I have chosen, like: jpg, jpeg, gif, png, flv, mp3, etc.

If file exists

So this is one of the most important steps that I took to make this possible. Rather than actually checking if the file exists on S3 with one of the S3 class functions (slow) or via something like cURL or file_get_contents (slow) I went with a database table on my own server that keeps track of what is on the S3 server (fast). This table keeps track of every filepath and when it was created and changed on S3. I am able to use the changed timestamp from my table to check it against the local file's timestamp (filemtime) to know when the file needs to be updated on S3.

Queuing the file for S3

Originally I didn't queue the file at all and just tried to put the file to S3 every time it was requested - mistake. It obviously took waaaaaaay to long to render my pages with this overhead so I opted for the queue method. I created another database table that keeps track of every file that needs to be put to S3. Basically every time a file doesn't exist on S3 I return the local path for the time being and add this file to the queue.

Putting to S3

As for putting the file to S3 there are a lot of ways to do this and it probably depends a bit on your situation. You could run a cron or some type of rsync if you really wanted to dial it in, but for the time being I am going for a bit more simpler method. I simply run 1 put operation at the end of each page request by the users. This seems to work really well right now and gets the files uploaded pretty much within seconds of when they are queued. At any time I have less than 20 or so files in the queue, and obviously once most of my files are on S3 this doesn't need to run anymore. I run my put function using hook_exit and I pick 1 file each time and get it over to S3.

Routing the files with Drupal

So once you have all this ready to go how do you actually get Drupal to replace the current local paths with the S3 paths? Well, there are a number of ways to do this. If you want to replace all your images, CSS, logos and all that stuff you can patch, and (maybe more) to run through your routing function. Since I don't care too much about this stuff I skipped this part and decided just to replace imagecache and my videos (for now).


Imagecache comes with a sweet theme_imagecache function that allows you to simply over-ride it in your template.php. You basically just need to tweak the $imagecache_url to run through your routing function and decide which path to return.


If you are using Imagecache for profile pics or nodes you may need to flush the imagecache when these are updated so that your new file will run through the queue and be uploaded to S3. This can be done via some hook_form_alter or hook_nodeapi calls that run the imagecache_image_flush function.


My videos are done through a custom module so I can't really offer any help here. I just plugged my routing function into it.

So that's it!

As you can see for each file request that is going through the routing function it will always check to make sure the newest file is on S3. If it's not it just pulls the local file for the time being. As soon as the S3 file is ready it will start pulling that one. If you do an update it will pull the new local file until the new S3 file is ready again.

That's basically how I'm doing it right now and it's working really well. My server is thanking me and even with fairly high traffic the S3 costs are very reasonable. If anyone has any feedback or tips on how I could make this better lemme know!

 Filed under: Internet / Tech, Drupal, S3, File Server, CDN
Nov 29 2008
Nov 29

The third ever Drupal Ireland meet-up took place on Saturday 15th November and it was a huge success. Over 70 people attended, which is an amazing 5 times more people than there was at our last event, just a few short 6 months ago!

When in DrupalCon Szeged, Heather and I saw how active other groups were in different countries and regions and thought "wouldn't it be great if we could build a Drupal community in Ireland?" So we decided to run a day long Drupal event in Dublin to promote Drupal and help grow our community.

If nothing else, Heather and I can be proud of the fact that we did just that. Well over half the people who attended were Drupal newbies. There was a large number of university students in the audience, but we also had freelance developers, web-masters, teachers, civil servants, along with people from Google, IBM and various charities. We even had some people visit from Northern Ireland and England, and at least one Joomla developer who we successfully converted!

One of the things that I was very happy about was the gender ratio was a lot higher than the 10% we normally associate with Drupal events. I'm not sure what the reason for this was, but we couldn't help but remark on the fact that the event was organised by two females and that our main contact in DIT, where the event was held, was also female.

At this point I should really thank Deirdre Lawless in the School of Computing, DIT for all her amazing help and support in the run up to this event. Thanks to Deirdre, we were able to host the event free of charge! DIT provided us not only with free tea and coffee, but also lunch and a free venue! Also, when we decided we needed a second room in the afternoon, Deirdre was on hand to sort it out for us. We definitely hope they'll have us back for the next Drupal Ireland event!

I'd like to thank our other sponsors too, namely Indytech for providing the grand raffle prize of a year's free hosting for a Drupal site, for the Drupal training CD for the raffle, and also CivicActions for their help and support.

While overall we were really happy with the turnout and the success of the day, there are definitely some things that I would do differently next time. While the building we were in was closing an hour earlier than expected and caused some of our timing difficulties, we still didn't allow enough time to each presenter - 20 minutes was clearly too short for most presentations. In addition, we didn't allow for time needed to switch between presentations or enough time for questions and answers.

However, one of the main problems we had was that we didn't expect over 70 people to attend! At the start of the week, only 38 people had registered for the event and we weren't really expecting more than 50 on the day. While this was a fantastic turnout, it did cause some problems. For a start all the catering of tea / coffee and lunch was done with 50 people in mind. Needless to say we ran a little short, but most people didn't mind. Our main issue was the general mix of the audience. Things worked much better in the afternoon when we split the presentations into two tracks - advanced and newbies.

All in all, it was an a great event and I hope more regular monthly meet-ups will be organised in Dublin, Galway and elsewhere as a result. I'm also looking forward to the next Drupal Camp Ireland which Scor and Alan are organising in Galway for April next year. If you want to learn more about Drupal or get involved in the Drupal Ireland community, then be sure to put this in your calendar! Also don't forget to join the Drupal Ireland group where you can find out all the details on events throughout the country.

Nov 29 2008
Nov 29

By default, the range of a date element goes from the year 1900 to 2050. In some cases, we don't want users to enter a year value in the future, so we're going to have to limit the range. Click 'read more' to find out how to change the year range. By default, the range of a date element goes from the year 1900 to 2050. In some cases, we don't want users to enter a year value in the future, so we're going to have to limit the range.

1) Add the '#process' property to your date Form API element, and add a property for the start and end year (or you could hardcode this later if you don't want to make it variable)

$form['date_of_birth'] = array(
  '#type' => 'date', 
  '#title' => t('Date of birth'), 
  '#process' => array('custom_date_element'), // ADD #process property 
  '#start_year' => 1900, 
  '#end_year' => format_date(time(), 'custom', 'Y'), 

2) Open the file /includes/ and find the function expand_date().

3) Copy the function, and paste it in your own module. Change the name of the function to the value of your #process property (in our case custom_date_element)

4) Find the following code in the function:

5) Replace it by:

function custom_date_element($element) {
  case 'year':
    $start_year = isset($element['#start_year']) ? $element['#start_year'] : 1900;
    $end_year = isset($element['#end_year']) ? $element['#end_year'] : format_date(time(), 'custom', 'Y');
    $options = drupal_map_assoc(range($start_year, $end_year));

6) Now your form element should be within the range you supplied. Alternately you could also not use the #start_year and #end_year properties, but just change the range in your copied function, if you don't want to make them variable.

Nov 29 2008
Nov 29

People reported me this particular problem, and recently I experienced it myself: during the Drupal 6 installation process in the 'Database configuration' step, you might get stuck. Upon entering the right database credentials, the page reloads and shows the Database configuration form again, without any error.

After some searching around, I found what was causing this behaviour: During the installation I renamed the file /sites/default/default.settings.php to /sites/default/settings.php.

However, Drupal expects you to make a copy if this file, not rename it! So just make a copy of the default.settings.php file, and name it settings.php. When these 2 files are available, your installation should run without any problems.

Nov 26 2008
Nov 26

Ultra Light Startups, a New York-based tech entrepreneur's group, is
hosting a panel discussion on Open Source content management systems on Thursday, December 4.

I'll be speaking about Drupal along with experts from Joomla (Donna
) and WordPress (Steve Bruner). People often ask for comparisons between these projects but it's uncommon to find people who have a depth of familiarity in all three systems together in one place, so this promises to be a unique discussion. The panel will be videotaped and made available online.

In order to facilitate a valuable discussion, I've started a list of suggested discussion questions. I'd like to ask you, fellow Drupalers (and any non-Drupalers), to suggest questions that you think will help highlight the differences between these systems and add value to the discussion. Below is my list of suggested questions, starting with ones that seek introductory information to the platforms:

  • What kinds of websites/web applications have been built on your platform?
  • How large is your development community? Approximatley how many installations are there? How many modules/plugins and themes are available?
  • What license covers the code in your project?
  • What is your project's greatest asset?
  • Is your platform aimed towards developers, casual site builders, or both?
  • Making your site's content externally available via an API adds value to your product/service and is important to staying competitive. How does your platform facilitate - exposing this data?
  • What major companies have invested directly in the development of your platform?
  • Are there many service providers for your platform?
  • What has your platform done to improve scalability/performance since its last release? In general?
  • What are the key features that your project provides to improve the efficiency of developing advanced websites/web applications?
  • How does your project stay up to date on security of the platform?
  • In an open source project, it's important to carefully vet code changes. How does your project make sure that code is well maintained?
  • What organizational steps has your project taken to ensure that it is around two years from now?

Participants at Ultra Light Startups events are tech entrepreneurs (including service providers)
and investors, and Drupal community members are invited to attend. Space is limited, so for more information and tickets, visit the event page. I'll also be handing out a limited number of vouchers for a free copy of the upcoming Drupal in Action.

Nov 26 2008
Nov 26

I’m going, are you?

In case you haven’t noticed, I’ve put a Drupalcon DC banner on my site. I’m going to be there - March 4-7.

I’ve also submitted 3 session proposals: jQuery, the talk I gave last Drupalcon, at BADCamp ‘07, and as a Google TechTalk, Install profiles, an area I have expertise in but have never talked about, and Theming, a talk I gave at BADCamp ‘07 with a huge outcome (the room was over-full), but was never repeated.

If you like my proposals, please give them a vote, because I think that my session(s) will help make this Drupalcon the best one yet.

Nov 25 2008
Nov 25

A tiny bit of history...

Four years ago, a very cool musician/web guy asked me to help him do some CSS work for another musician's site he was developing, on a platform called Drupal. I didn't know Drupal very well, but I had played with it, and knew CSS, so I said Sure! The site was cool, and I recall that I was editing all kinds of CSS files in all these different places (where I shouldn't have). It all seemed very complicated with these modules having their own style sheets. I was intrigued! But I was also confused by the taxonomy, and felt it was too complicated for the little sites I was doing at the time. After that project, I returned to doing things the way I had been doing them.

It is really too bad I didn't see the real beauty of Drupal at that time, that I didn't understand it's power, flexibility, and community. They were all there four years ago, but I didn't see them. If I had, who knows what I would be doing now? I might have been smitten by the drop, like that cool musician, Robert Douglass. That was his first Drupal site as well.

A short two years ago saw me doing freelance web design, implementation, and graphic design for any customer that would take me. I didn't know anybody in my industry, didn't have much of a network outside of it, and didn't like the prospects for the future. I was not doing well, at all. At that time I was creating sites on Joomla, and implementing stores using Zen Cart or OS-Commerce.

I was finally starting to get referrals from some of my Elance and Guru customers, but like those customers, the referrals didn't seem to care as much about quality, as they did price.

That was when I made a decision. It was simple, I wasn't making enough money to live on doing freelance design, and implementing simple carts and Joomla sites, I needed to get to the next level. I chose to get back into development. I started right away getting better acquainted with PHP, MySQL, and JavaScript. I found Code Igniter, and built my own CMS and blog (who hasn't?!?) and felt mighty!

Ha! I felt so mighty that I took on more than I could chew for an old customer. Humiliation taught me a couple of awesome business lessons, it can be good (sometimes GREAT) to say "no", and know how far beyond your limits you can really strive for. (Happy ending: he deciding that the site actually didn't make sense, wouldn't make money, and so we shifted his deposit to a more profitable venture, one that was possible, one that was based on Drupal. He is still my customer today.)

At that time, I was bouncing around some "open-source" projects and looking for something that fit me. I worked with Code Igniter, and really enjoyed it, they had a great documentation page, and good people. I also worked a bunch in Magento Commerce, which is a very nice application, but because of how it is offered, seemed not "open" enough for me. Very soon after finding Magento, I began working with Drupal again, and this time, it didn't just stick, it swallowed me. I finally "got it."

This last year has been a whirlwind. I haven't done everything right, and being an actual human being, I may have even possibly done some things wrong! I have flitted from one bright shiny Drupally thing to another, most likely annoyed many Drupal luminaries that I highly respect, and in my enthusiasm have stepped on toes or hurt people's feelings. But I have also found a community of people that have renewed my faith in people, made me see that people really can selflessly come together for a common goal, that even any one person, with redoubled effort, can make an enormous difference. That's a lot to say for a software project, but Drupal has been that impactful to me.

I came here, overly eager because I finally saw possibilities, I finally had found a project that people were fervent about, and very committed to. Drupallers LOVE Drupal, they don't just work on it. These geniuses transformed code into art while I watched, yet at the same time would again and again, very patiently, and with much decorum, entertain newbish questions that I know they had answered hundreds of times before.

I thought that it was probably the pink visor effect, that after a while, I would float back down from my pink Drupal cloud, and see that these were just the same as other people, that they couldn't possibly be that different, that good.

I was once again wrong, happily so. You, Drupal, bring out the better side of the people you attract. I am proud to be a part, even if it is a nearly non-existent part, of this project and community. Thank you.

And that brings me to today, and how just this much exposure to Drupal has changed me, and how I think, and how I am changing, and how I plan to do business differently (when by the way business is going bonkers, it seems counter-intuitive to change anything). It brings me to my goal, which has been many years germinating, and has now been given the water it needs to become fully realized.

I am finding it hard to continue to think small. I have a vision of creating more. My goal that I am dedicating myself to is creating my business differently, from the inside out. I aim to find terrific people who _care_ about people, and I am going to show them Drupal.

I mean to infect these people, to put them up on my pink cloud, and see if they smile. I mean to enrich them and this community at the same time. If I can find those people, and treat my customers and the Drupal community at large, to their good spirits, my goal will be half reached. My goal will be fully reached if I can in any way influence others to understand my belief; that caring, loving, pleasant people, make for much much better business.

I am very interested to see what will happen next, and intrigued by who I will meet on the way.

Nov 24 2008
Nov 24

Styling the Drupal User Login Block – PHP Code & CSS

Posted by Jeffrey Scott -TypeHost Web Development | Monday, November 24th, 2008
, ,

This tutorial goes through the steps of one way to create a custom user login block for Drupal. Best is to disable the original login block in the admin/build/block section, start with a new block with custom code, and then style the details with CSS. The requirements for this project are a rounded corner, blue background block with two custom tabs at the top.

1. in admin/build/blocks – click on the “add new block” tab

2. enter the following code:

<?php global $user; ?>
<?php if ($user->uid) : ?>
<span class="login_text">Welcome, </span> <?php print ($user->name); ?> <br>
<?php print l("Your Account",'user/'.$user->uid); ?> |
<?php print l("Log-Out","logout"); ?>
<?php else : ?>
<div id="usertabs"> 
<span class="utabs1">Log In</span><span class="utabs2"><a href="">Sign Up!</a></span>
<div id="umain">
<form action="/user?<?php print drupal_get_destination() ?>" method="post" id="user-login-form">
<input type="text" maxlength="60" name="name" id="edit-name" size="20" value="" tabindex="1" class="form-text required" />
<input type="password" name="pass" id="edit-pass" size="20" tabindex="2" class="form-text required" />
<span class="utabs3"><a href="" title="Forgot your password?">Forgot your password?</a></span>
<span><input type="submit" name="op" id="edit-submit" value="Log In" tabindex="3" class="form-submit" />
<input type="hidden" name="form_id" id="edit-user-login" value="user_login" />
<?php endif; ?>

This code originally came from:

There are also some nice examples at:

I modified the code to add some css IDs, classes, span tags, and also the text/links for the top tabs.

3. Select PHP code for the input and save the block.

4. From the main blocks page, click on “configure” for the block you just created. I selected to show this block only for “anonymous user” because I did not need the simplified display after the user has been logged in. The code generates a block that can also be customized to show the site status for authenticated users, but usually the navigation menu does this sufficiently. Enable the block and position it where you like in the display.

5. The rest is basically CSS – setting the image as the background for the login area and the tabs, positioning the text elements and fields. This example is based on a 250px wide column with a two column layout. It includes bold text on the display and overrides the default styling of the Drupal user login form elements.

There is a vertical-alignment fix to standardize the display in IE, and a 1px addition to the lower input field so that the form will align evenly on both ends. Add the following CSS to your theme in style.css, blocks.css, or wherever fits best.

#block-block-4 {
color: #fff;
#block-block-4 a {
color: #fff;
#umain {
font-weight: bold;
height: 127px;
width: 250px;
background: transparent url(&amp;amp;amp;amp;quot;../img/login_bg.jpg&amp;amp;amp;amp;quot;) no-repeat top left;
padding-top: 20px;
vertical-align: middle;
#usertabs {
height: 23px;
width: 250px;
background: transparent url(&amp;amp;amp;amp;quot;../img/tabs1.jpg&amp;amp;amp;amp;quot;) no-repeat top left;
#usertabs a {
color: #333;
.utabs1 {
font-weight: bold;
float: left;
padding-top: 4px;
padding-left: 25px;
.utabs2 {
font-weight: bold;
float: right;
color: #333;
padding-top: 4px;
padding-right: 60px;
.utabs3 {
font-weight: bold;
float: left;
padding-left: 25px;
padding-top: 4px;
#umain #edit-name {
margin-bottom: 5px;
width: 147px;
#umain #edit-pass {
margin-bottom: 10px;
width: 148px;

Note: the “block-block-4” value will be contingent on the name of the block that was created to input the custom PHP code of the login form.


Upload to your theme’s “image” folder (in this case named ‘img’):

Tabs Background image: tabs1.jpg:



Login Background image: login_bg.jpg



7. To add a custom button, also upload and add this CSS:

#umain #edit-submit {
float: right;
margin-right: 20px;
background-color: transparent;
color: #333;
border: none;
font: 9pt/1.5em Arial, Tahoma, Verdana, &amp;amp;amp;amp;quot;Lucida Grande&amp;amp;amp;amp;quot;, sans-serif;
font-weight: bold;
background-image: url(&amp;amp;amp;amp;quot;../img/button1.jpg&amp;amp;amp;amp;quot;);
background-repeat: no-repeat;
height: 24px;
width: 58px;
cursor: pointer;








Hopefully, this will save some people a lot of time and is also a good base for doing further customization with the background images and CSS.



Nov 23 2008
Nov 23
In this episode: Drupal Docs and Drupal Dojo steal all the headlines.
Nov 20 2008
Nov 20

Look what's on the cover of the November 17, 2008 issue of Information Week! Drupal is mentioned several times throughout their series on open source.

Nov 20 2008
Nov 20

The front-end database is powered by Drupal. Includes a video demonstration.



About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web