Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Sep 11 2008
Sep 11

Lately, I’ve had various frustrations with Drupal which have moved me away from using it for various things. I’d like to go through where I’ve moved away from Drupal, why I’ve made those changes, and my future Drupal decisions.

WordPress rather than Drupal blog

To begin with, this blog is now on WordPress rather than Drupal – and I have to say that I’m loving it… and so are my non-geeky colleagues. It ticks all the right boxes. Its *really* user friendly. Its much easier to add photos (and videos) to posts. And it’s hardly taken long at all to setup.

So where did Drupal go wrong with this? Well, I guess its the ‘kitchen sink’ approach back-firing. In trying to be something to everyone, Drupal runs the risk of being less than perfect to to any one specific task too. WordPress, on the other hand, has the ability to focus on being the very best blogging software out there, and nothing else gets in the way of that or deters it from its ultimate goal.

But also, we needed to seaparate the business end of our website (the creation of yearbooks, using tens of thousands of nodes) from the nodes and users to do with the blog, partly because around this time every year we flush out the old site and start a new. So we were either going to have a separate Drupal install for the blog or use WordPress. We chose WordPress.

Form theming frustrations

Have a look at the form here and let me know how you’d create it using FAPI (we’re on Drupal 6.4). I’m talking specifically about the theming of the form. Yes, its a very simple form. A search form. But let’s have a look at what’s going on with it and discuss the Drupal way versus the way we ended up doing it.

In FAPI, you’d probably have a ‘textfield’ element for the search box and a ‘submit’ element for the ‘Go’ button. Easy enough, one minute of code. But what about the title ‘Name of your school or group’? Probably a title for the textfield element, no? But then how do we get it centred above both the textfield and the submit button? And what about the text under the two fields? A description, right? Again… how do we get it to appear *exactly* where we want it? The look and feel of the form are to me absolutely crucial. I don’t just want a textfield’s title (with annoying colon after it), a textfield, a description, and then a Go button all one on top of the other.

The Drupal solution? Using a theme hook. We define the form in our implementation of hook_form() and then theme that form separately. The ‘programmer’ cares about the functionality of the form but not the visual design of the form. The ‘designer’ doesn’t care about the functionality and instead works on how it looks. But I’m both the programmer and the designer here, and I want my work to be as easy as possible! So, let’s say i go down this route (I tried, I really did). I need to register my theme function in hook_themes(). Okay, I know why, it saves extra code running on every page load. But its still annoying. Now I create my theme function… urgh. You’ve got to really know your FAPI stuff to get this to work. I try for a while but then I give up. It just feels so messy with some code somewhere, some in another place, and then when I ask my colleague to have a look so he can learn how to do it he’s disgusted… doesn’t know what’s going on… starts bad-mouthing Drupal. So we build our own massively simple FAPI instead in about half an hour that does just what we want it to do.

So now we’re using our own super-basic FAPI for this form. Not all forms, just the ones we want complete control over, visually. Rather than using hook_form() and defining a form array, we just hard-code the HTML for the form. Some of you may be in complete horror now thinking about this but its just by far and away the easiest way to get forms to do exactly what you want. Like a forename and surname field side by side rather than one on top of the other, sharing the title ‘Name’ which is a label for the forename field.

We’re sticking with the idea of a validate() and submit() hook though. I like that one. But we’re doing it slighly differently and more simply, so that any new coders we might hire can quickly and easily pick it up.

Going nodeless

I don’t always like nodes. I really, really don’t. I don’t need revisions, and if I did I’d do them in my own way, just the right way for me, rather than a way that kind of works for everyone but not quite perfectly for anyone in specific. I don’t like the way that as uid=1 I get all the extra bits like ‘Authoring information’ which I never touch. Node hooks and the nodeapi which I once loved are now a higgeldy-piggledy mess that’s a real pain for my new hire. I try to explain to him what’s going on when I save a node. “So this function deals with the submission. But not the core node stuff, Drupal deals with that. And if we want something used for all nodes, we put it in here instead. And we can also override this specific bit here.”… he looks on in amazement, totally baffled by what’s going on and why. It would be so much easier for him (and me) to understand if everything’s just in one place.

So what do we gain from nodes? Umm… not much really. We don’t use contributed modules any more because they never do exactly what I want and always do stuff which I don’t want them doing which just make them less efficient. We put all our code in our own one module instead. A massive, hefty module with a dozen or so include files.

We gain the ability to always do $node->nid and use node_save() and other handy things. But we don’t really need nodes, and it frustrates me having to do the extra INNER JOINs on node_revisions etc. So we’re trialing not using nodes at all for one of our content types – our customers. We just have a simple ‘id’ field now in one single table. We no longer need to INNER JOIN node and node_revisions. We haven’t had any problems so far, but the new hire is finding it much easier to code now, without the ‘baggage’ of Drupal.

The future

Our current plan is to gently migrate away from Drupal, perhaps altogether. We like the idea of building our own framework again, one that does exactly what it needs to do for our site. Its not something we can do overnight. Ours is a yearly cycle, following the academic year, and the current plan is to fork the codebase in around January/February and that would mark the beginning of our own framework if we still feel that way then.

In the meantime, we’ll continue using nodes for most of our content types (if simply because migrating away from them would be a long and arduos task with little reward) and we’ll continue to use FAPI for most our forms. But I see us using our own simple FAPI for more and more forms where we need complete control over them, and I see us extending this FAPI to help us reduce using the same code multiiple times.

I think I still like Drupal. I definitely appreciate the vibrant community. But sometimes I thoroughly hate Drupal and get massively frustrated by it. But I still like it in theory at least. One framework for all my websites. But whilst I just work on one massive website it just has so much less use to me.

You’re more than welcome to urge me to stay with Drupal. In fact, I highly hope someone can manage this. I’ve put a lot of time over the last few years into learning Drupal, and it would be a great waste and a shame to lose all that.

Share this:

Like this:

Like Loading...
Sep 01 2008
Sep 01

I eagerly awaited the videos for the Boston Drupalcon. They never seemed to appear. 

However, the videos for Szeged are already available here ! The quality is very good. Audio is good and the presentation screens are fuzzy but you can get the general idea. 

Very impressive. There are many hours of must watch video here if you were unable to attend the conference live.

Aug 26 2008
Aug 26

Recently I have upgraded a customer site from Drupal 5 to Drupal 6. The site contains a number of custom modules that required considerable work because of some changes in the Drupal API. One of the API changes is the removal of hook_info and hook_auth.

The new authentication mechanism has two advantages:

First of all, two authentication-specific hooks have been eliminated. There is no replacement hook, instead you must use hook_form_alter to replace the built-in validation functions of the user login form. This is a more general and more flexible approach and it shows the power of the current form API. You can check user_login_block and user_login_default_validators for examples.

Secondly, there is a lot more flexibility to do error reporting when authentication fails. In Drupal 5 when hook_auth returned false, Drupal would always display the error message "Sorry, unrecognized username or password. Have you forgotten your password?" even though the real problem might be something else, for example a remote server responsible for doing the actual verification of the password is not available. In Drupal 6 you can fully control which messages get displayed during an authentication failure.

Even though there is some work involved to migrate custom authentication functionality to Drupal 6, the end result is code that is much cleaner and more powerful.

Aug 22 2008
Aug 22

There is an interesting presentation by psychologist Barry Schwartz at TED called "The paradox of choice". He explains why people are not better off when there is too much choice.

He claims:

Some choice is better than none. But it doesn't follow from that, that more choice is better than some.

His explanation makes sense:

The more options there are, the easier it is to regret anything at all that is disappointing about the option that you chose.

I think he has a valid point. A point which is also true in software:

I'm not saying that there should be no choice at all but very often there is simply too much choice and investigating all possible options takes too much time. Luckily Barry Schwartz reveals how to be happy with the choices you make:

The secret to happiness is "low expectations".

You can watch the presentation below or over at TED:

Aug 09 2008
Aug 09

After over three years as an independent web developer, I've had an opportunity drop in my lap that I am going to take advantage of.

WorkHabit is in the process of opening up shop in San Diego, and I'm joining them. They've got a top-drawer team, and they don't do background checks, so it's a perfect match for me.

I've enjoyed working independently for the last several years, however, I've also learned a lot about running my own business. The primary lesson I've learned is that running a solo web development shop involves a lot more than web development chops. I've spent more time than I would have liked doing things like billing, support, follow-ups, "sales", and all the various tax and legal oriented tasks that come with working for oneself. 

I consider myself a worker bee. I love web development. All the other stuff, not so much.

WorkHabit is truly committed to contributing to the Drupal community. This is a must-have for me. I truly believe that no Drupal based shop can thrive without being directly and heavily involved in it's people and development. I've got a thing against obviously successful Drupal businesses that take but never give. It's just wrong and not too smart. WorkHabit gets it, and I'm looking forward to being able to increase my work with and contributions to the Drupal community. 

I'll be working alongside Drupal Dojo host Joel Ferris (senpai) and Michael "mad man" Murdoch (froggacuda), helping create WorkHabit's San Diego presence. 

We are going to be more heavily supporting the local San Diego DUG in the future as well.

Jul 30 2008
Jul 30

Unless the list is crazy long, like it can be for operating systems, I realized that I read software changelogs pretty closely. This site now has one, with an RSS feed. It will be a sort of commit message, listing additions and changes worth mentioning about the live site. (Can somebody remind me later on to tell you how I setup my staging environment? Yes, for a personal blog.) It will not include updates to Drupal modules run on the site unless it makes a dramatic difference. The changelog will include changes to layout or the underlying Drupal theme and addition of content sections. The first entry? That I created a changelog in the first place. You can find out which version of Drupal I'm running via the usual open secret method, though I will make a note of it when I do upgrade.

May 21 2008
May 21

Not long before my old laptop got to the end of it usable lifespan I started playing with the Zend Framework in my spare time. One of the cool things about ZF is that it wants to use friendly URLs, and a dispatcher to handle all the requests. The downside of this approach, and how ZF is organised, it works best if you use a Virtual Host per project. At first this seemed like a real pain to have to create a virtual host per project. One Saturday afternoon I worked through the Apache docs in search of a solution - then I found it! Rather than bore you with more of my views on Zend Framework, I will explain how to have a virtual host model that requires a little work up front and is very low maintenance.

It gets tedious copying and pasting virtual host config files each time you want to start a new project, so instead I let Apache do the work for me.

I added a new virtual host config file called projects to /etc/apache2/sites-available. The file contains

UseCanonicalName Off

LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon

Options FollowSymLinks
AllowOverride All

    ServerName projects

    CustomLog /var/log/apache2/access_log.projects vcommon

    VirtualDocumentRoot /home/[username]/Projects/%1/application/www
    AccessFileName     .htaccess

The important bit is the VirtualDocumentRoot directive which tells Apache to map a hostname to a path. I use an IP address from the range for the virtual host, so they aren’t accessible to the outside world and I don’t have to worry about it changing every time I check locations.

All of my projects live under ~/Projects and each one gets a directory structure that looks something like this.

  +- notes - coding notes, like grep output when refactoring etc
  +- resources - any reference material or code snippets
  +- application - the code for the project
     +- www - document root for vhost

There are usually other paths here too, but they vary from project to project.

To make this work there are few more steps. First enable the new virtual host by running sudo a2ensite projects. Don’t reload Apache yet.

Next you need to add the Apache module with sudo a2enmod vhost_alias. Now it’s time to edit your /etc/hosts file so you can find the virtual hosts. Add a line similar to this: projects phpgw-trunk.project [...] phpgw-stable.project

Now you can restart apache by calling sudo /etc/init.d/apache2 reload.

This is also handy for developing client sites - especially using drupal.

Now my /var/www/index.html is just an empty file.

I am getting a bit bored with adding entries to /etc/hosts all the time. If I get around to adding dnsmasq with wildcard hosts to the mix, I will post a follow up.

This setup is based on my current dev environment (Ubuntu Hardy), but it also works on older versions of Ubuntu. The steps should be similar for Debian and derivatives. For other distros, it should work, just how to make it work may be a little different. Feel free to post tips for others in the comments.

Mar 16 2008
Mar 16

The number of available Drupal modules is continuing to grow dramatically. Like a lot of other Drupal users, I spend a good deal of time downloading new modules and trying them out to see what they do. Unfortunately, not all contrib modules work as advertised. I may spend several hours working with a new module before realizing there's some small issue with it that prevents it from solving my problem.

Similarly, there are often modules out there that solve problems I didn't even know I had, but I'm simply not aware they exist.

What I want is a resource that leverages the experience of thousands of Drupal administrators. I want to know that I shouldn't even bother with a module because it's too buggy. I want to know what modules other users find useful in specific areas (such as multimedia, file handling, cache issues, etc.).

Other large OSS communities often solve this need for a shared knowledge base by providing user reviews. Mozilla, Thunderbird, Joomla and other modular systems provide user reviews and ratings. It is time that the Drupal community have one too.

When I first started using drupal about three years ago, it was not all that difficult to simply be aware of most modules and how effective they were because there just weren't that many. Now there are multiple new modules released on a daily basis, and I just can't keep up anymore.

Why do we, the Drupal community, not have a shared review/rating system? It's certainly not due to lack of demand. A search for "module ratings" on Drupal.org reveals a great deal of interest in this functionality.

As far as I can tell, the primary reason for not having a rating system for modules is fear. Module developers in particular are concerned with the fairness of ratings. They are concerned with "gaming" of ratings. They are concerned that inexperienced or "dumb" end users may unfairly give a bad review of a module simply because they don't understand how to use it. These are all reasonable concerns. But they are concerns shared by other OSS projects as well. Sure you will see "bad" reviews, giving a module the lowest possible rating along with some inane review such as "tis modules sukcs BEWARES" :) But who cares, it's just noise that will be drowned out by valid reviews. It works for other OSS projects, and it can work for Drupal.

John Forsythe
has released what I believe is the first site dedicated to rating and reviewing Drupal modules drupalmodules.com. No doubt this site will be a source of controversy as developers voice their concerns. But we need this resource now.

I encourage my entire audience (hi, mom!) to register at drupalmodules.com and to submit reviews for both your favorite and most hated Drupal contributions. This is a great way for non-techies to contribute to the community. The site is young, and there is naturally a shortage of ratings on the site now, but that will change as the site brings on more users.

Maybe this database will eventually make its way to Drupal.org. For now we can show our support for this type of system by helping build out the database at drupalmodules.com.

Mar 12 2008
Mar 12

Here’s a pretty basic css technique I’ve noticed myself using a lot of lately (not at all my own invention). The divs used as examples come from zen theme.

Often a design calls for putting a background (or border) on a sidebar. It should look as so:
If you haven’t been down this route before, you will probably try something like

  background: #123456;

As long as your sidebar is longer than your content you will think you have succeeded, but go to a page with long content and you will see:
short sidebar
Argh! We want the sidebar background to go all the way down the page!

You’ve learned not to overthink when you’re dealing with css, so next you might decide to give the whole page the sidebar color and then give the content section its own background on top of that. This simply gives the opposite effect:
long sidebar
Now things only look right when the content is longer than the sidebar.

The easiest way to get things straight is to just suck it up and take it to Photoshop. Make an image with a 1px height and a width the same as your sidebar. Instead of applying the image as the background to your sidebar, you’ll apply it as the background to the whole page.
bg image

#main {
  background: url(images/sidebar.png) repeat-y top right;

If you have two sidebars, make one image the full width of the page.

You had to use Photoshop.
You can’t easily change your sidebar width.
You have to load one more image per page.

You’re done!

The same principle is very useful for theming panels. Panels are made up of one or more rows which each have one or more columns. Once you put content in the columns of varying height you get one ugly panel:
panels hell
Do your panels kind of look like this too? Not good. This panel has two rows, and each row has 3 columns. Note that the second element in the second row’s first column (bottom left!) is actually a mini-panel containing two columns. Although the panel has a grid-like structure, the fact that all the content has varying heights makes it look like a mess and probably nothing like your designer’s mockup for your front page.

Adding backgrounds to the content will bring back order to the panel. But once again if you apply the background directly to columns you will end up with:
panel backgrounds
What you really want is more like:
panel heaven
This is the kind of thing that I imagine was really easy back in the days of table-based layouts. Now that the web is all about dynamic content in divs of unpredictable heights, these kinds of things are more difficult. The answer is to, as in the sidebar example, create a background image for each row and tile it vertically.

Now your panels can have the tabled look they seem to be begging for and without the embarrassment of actually using tables! Does anyone have a preferable technique?

Mar 03 2008
Mar 03

Error message

Deprecated function: The each() function is deprecated. This message will be suppressed on further calls in menu_set_active_trail() (line 2405 of /home1/markspap/public_html/kathy/includes/menu.inc). March 2, 2008

It's been a good, long while since I wrote a blog post. Between work and family, there just hasn't been time. I've been super busy for months now, but not without some benefits.

For one thing, I've been learning tons. I've been working on picking up more PHP and delving a bit more into backend Drupal work, as well as doing more accessibility and usability work and learning more about user experience design. I guess you could say I've been branching out every which way. As a reward for all that hard work, I'm going to DrupalCon in Boston. Although the conference doesn't start until tomorrow, Jon and I flew in for a long weekend to soak up some history and not a little seafood. I can now state pretty definitely that the Union Oyster House has the best clam chowder I've ever eaten, and Mike's Pastry has Boston Cream Pie to die for. Not to be missed. It might be cold here in Boston, but with good food and four whole days of Drupal learning, it's weather I'm happy to put up with.

Similar Notes

Feb 16 2008
Feb 16

The importance of project management tools is almost never fully appreciated. I am shocked at how common it is for a group of developers to go working without version control, ticket tracking, development documentation and so on. The very first thing I do when working with a new client is to make sure that they get these tools in place if they haven't already.

Those who are used to working without a complete set of project management tools never fail to appreciate the benefits of them once they are introduced. I consider it next to impossible for a team to work together without managing code and tasks in an efficient and highly organized way.[img_assist|nid=155|title=|desc=|link=none|align=right|width=250|height=156]

Hopefully you do not need to be sold on this idea and are using CVS or SVN to manage your project already. You likely have some sort of ticket system. It is a little less likely that you have both of these components integrated with each other.

When it comes to choosing a solution for project management software, a die-hard Drupal user has a dilemna. On one hand, Drupal seems as though it should be the perfect solution. It's fully customizable, has lots of nifty project management related modules and, most importantly, it's Drupal! Why would you not use it? "Eating your own dogfood" is the way to go, right? Meh...

Drupal is generally considered a content management system. Personally, I like to refer to it as a website management system. It is great at managing website related stuff like users, posts, permissions, categorization, and so on. Using contrib modules, you can customize and enhance this core functionality to almost no end. But at the end of the day, Drupal is designed to handle web content and the users that are accessing it. That's what a content management system is (and if content is king, that would make Drupal... well... God).

Managing a project, on the other hand, is a much different business from managing a website. Yes, you have many shared properties such as content and users. But the essence of project management involves things that have nothing to do with website management such as a revision controlled code base edited by multiple users, a need for efficient ticket management, and ideally full integration of everything. Essentials also include stuff like a nice repository browser, user management interface for repository access, fancy reporting for tickets, organization of tasks by milestone, date, person, severity, etc...

It's a very tall order. Yes, you can do all this in Drupal, but not very well. You can piece together something that sorta kinda resembles a project management solution, but in the end, you need to invest a relatively large amount of time to create something that is less than ideal and will require ongoing tweaking and modification. Unless your business is creating an effective project management solution in Drupal (something I dream of!), you should not be using Drupal for project management.

I'm a one man shop, and I do not have time to spare. I cannot justify spending any time at all kludging together a project management solution for a client when there are already far superior solutions available at low cost. I would much rather pay someone a few bucks a month and be done with it. Let them deal with SVN administration and enhancements; let me focus on my primary task which is building cool sites with Drupal.

While there are numerous project management related service providers out there (Fogbugz, Basecamp , Beanstalk to name a few), I want to talk about my personal favorite, Unfuddle. Unfuddle has taken obvious inspiration from the folks over at 37signals, innovators of the simple, clean, effective, it-just-works web application. Unfuddle is an instant project management solution that takes minutes to set up and costs a few dollars a month. The time you'll save in not having to set up SVN and manage SVN users alone makes it worth every penny.

[img_assist|nid=156|title=|desc=|link=none|align=left|width=250|height=221]What you get with a solution such as unfuddle is a ready-to-use repository with integrated documentation, ticketing and reporting. It takes seconds to set up a new user account with permission levels fit for everyone from a developer (gimme root!) or a suit (look but don't touch).

From a single interface, you can browse code, tickets and documentation. Every component integrates with the others. You can even resolve a ticket with an SVN commit message, saving you the trouble of having to go and edit the ticket after your commit! Users can individually subscribe to whatever level of email notificaton they would like to recieve and how often. The developer can shut off all notifications while the manager can get a nice daily summary each morning of milestone completion progress, new tickets, added documentation and so on. The project manager can glance over one of the ticket reports and group tickets into milestones for reasonable short vs long term goals.

SVN comments link back to the tickets they are related to. Tickets contain links to the changesets that resolved them. Viewing these changesets, you can see a beautiful code diff and quickly see what fixed the problem. Senior team members can quickly and easily review code changes submitted by junior staff.

With tools like this available these days, it's just not worth it spending any effort whatever on a lesser solution.

Feb 12 2008
Feb 12

The CCK ‘display fields’ settings are very useful for theming nodes by content type, but I often find myself having to get further into customizing node output field by field.

Once I decide there’s no way getting around taking finer control of my node’s fields, I create a node-{type}.tpl.php by copying my existing node.tpl.php and open up Devel’s ‘Node Render’ tab. Then I delete the $content variable from the template and start adding things like

print $node->content['field_image']['#value'];


print $node->content['body']['#value'];

The $content variable is nice for amateurs, but we need the unrendered $node->content to get good control of a node.

While this gives me complete control over the output of the node’s fields, the drawback is that now if I add a new field to the node, or if I add a module that adds something to $node->content, I have to go back to my template and add in this new element. Because I often do my theming and development in parallel, this can be rather annoying, and there is also a danger that I could overlook doing it.

Therefore I think it may be more practical to use code like this in the node template:

foreach($node->content as $key => $field) {

Instead of printing each field that is wanted in the template, I can instead unset the fields that are not wanted and then print all the fields. This is faster to write and it lets any new fields show up. After unsetting unwanted fields it looks like this:

foreach(</span>$node->content as $key => $field) {

(I found that I need to unset $node->content[‘#children’] to get this method to work correctly.)

Now if you want to control the output of specific fields individually you could add a switch:


foreach(</span>$node->content as $key => $field) {
  switch (
$key) {

'</span>. $field['#value'] .'


'</span>. $field['#value'] .'



Now I know that these template files are not supposed to get all mucked up with php, so this method is really just a hack and won’t be appreciated if you are working with a designer who dislikes php. But if you, like me, were finding yourself dissecting $node->content into crazy pieces with tons of php in your node templates already, perhaps this method could be a slight improvement.
Feb 07 2008
Feb 07

I should consider becoming a salesman for Drupal because I am always talking about how good it is. But it really is. If you are not using Drupal you have 2 options:

  1. Get Drupal
  2. Suicide

Although suicide may sound appealing you're probably better off just downloading Drupal. Once you download Drupal here are some key things that make it so powerful:

  1. User Accounts

    Being a programmer myself I can tell you that coding this type of thing is not fun. It requires a lot of form checks and admin pages. It's just not something you wanna do. But Drupal developers do (thanks Dries)!

  2. SEO

    I went from 23 visitors a day to 14,000 a day after switching to Drupal. No, not really but I can tell you that Drupal is very good for SEO. It has the internal link structure dialed in pretty well and each "keyword" goes on it's own page with a title of your choice. Google likes and I like.

  3. Theming

    The theming is broken down very nice in Drupal as it allows you to treat inside "nodes" or articles inside your site different from your "page". It also allows you to theme your comments and sidebars and all that stuff. You can also over-ride functions from modules, but that's a more advanced topic.

  4. Scalable

    Gone are the days of installing the same files over and over again on the same server. With Drupal all you need to do is slap one install up on your server and you're good to go. Any additional sites can access the same files and use the same modules. You can share databases or split a new one off for each site.

  5. Modules

    Drupal has a ton of modules that are available to download at your convenience. These modules cover pretty much anything you could ever think of except it doesn't quite offer the "Facebook Clone" module yet.

  6. Management

    Management is a breeze with Drupal. You can easily view all your posts, users and reports. You can unpublish content and comments if you don't want them to be seen. You can ban users or IPs. You can change the positioning of elements on the site in real-time and lots of other fun things.

  7. Time

    Unless you have at least 5 years of spare time on your hands to dial in your own CMS I recommend you download Drupal.

  8. FREE

    It's freaking free. I've seen companies switch from paid CMS's to Drupal cause they realized sometimes bad decisions can be remedied. I've seen people unload a full set of rounds and hit nothing but air... whoops! Drupal isn't The Matrix (yet).

Research Conclusions


(No seriously, I'm not paid to write this.)

 Filed under: Internet / Tech, CMS, Drupal
Feb 06 2008
Feb 06

I often find myself needing to get rid of some of the sections on Drupal’s ‘My Account’ page. Not every site needs it to say ‘History: Member for 1 day’ for example, and if you use a lot of contributed modules that screen can get cluttered fast. So this morning I got sick of dealing with it, found there is a perfectly good hook_profile_alter there to work with, and wrote a little module to let administrators disable these fields. Let me know how you like it: http://drupal.org/project/myaccount_alter (currently Drupal 5 only)

Feb 06 2008
Feb 06

If you work freelance like I do, you know that time is money. I’m always trying to shave a few more seconds off my development time. Here are a few tips and tricks that I constantly use:

  • Firefox Wildcard Bookmarks

    Set up some bookmarks with keywords shortcuts and wildcards. I have a bookmark for the forms api reference so that I only have to type ‘forms’ to get to it. I also used this method so that I can quickly look up api functions. I used a similar wildcard bookmark for project pages. Now if I’d like to see the views page I simply type in ‘pr views’. Not only does this save me a lot of time but it also encourages me to go check out modules I might have otherwise put off looking at since it seemed like a slight hassle previously.

  • Drupal CVS shortcut

    I check out a lot of modules from Drupal’s CVS. With Drupal you can just about build a website as fast as you can check out modules. Well, almost. I constantly had to look up the terminal command for cvs checkout until finally I got wise and set up an alias. On my Mac I did this by

    cd (go to your user home directory)
    vi .bash_profile (edit your bash profile in a unix editor I am just not quite geeky enough to have mastered. Alternatively, if you’ve set up Textmate properly you can do ‘mate .bash_profile’)
    Now add the line: alias drcvs=”cvs -d :pserver:[email protected]:/cvs/drupal checkout”

    Now when I want a module I type: drcvs -d {modulename} -r {version} contributions/modules/{modulename} . This I can actually remember.

  • Drupal navigation

    You need to get into admin_menu and/or teleport modules. I’m going to stop giving out links to every great module since by now you should have created your firefox wildcard project bookmark.

  • Parallels (Mac)

    Launching Parallels is faster than Bootcamp or getting up and turning on your old PC. Personally I believe if you’ve so much as touched your client’s css that it is now your moral imperative to recheck everything in both IE6 and 7. Bonus tip: run them both.

  • Firebug

    Firebug is the best thing that ever happened to css as I’m sure you’re aware. Make sure you check which line number of which css file you need to change and then use your text editor’s keyboard shortcut to go straight to that line. I like to use Firebug for anything I might have previously used ‘view source’ for as well. You can make sure that new css or js file you added with drupal_add_css or drupal_add_js loaded properly on your page. Find out your keyboard shortcut to go straight to inspect mode (mine is shift-command-c). I constantly use inspect mode to take a look at the relevant markup. Often if you need to find a theming function a Firebug glance at the markup will give you something to search for in your text editor. It may also give you a hint as to the form_id you’re trying to hook_form_alter.

  • Firefox search

    Go to your Firefox preferences and under General:Accessibility check off ‘search for text when I start typing’. Now you don’t need to hit command-f to search on the page. When you go to admin/build/modules to enable your new module, just start typing the first few letters and you’ll jump down to it on the page. Congratulations: you’ve just saved 200ms. Well, everything adds up.

  • Use your editor

    Mine is Textmate (Mac only) and it’s pretty great. Although you might be tempted to just type a little php in a block edit textarea or similar place, I find that this usually costs me more time than it saves because half the time I mess up a bracket somewhere. If your block is fairly complex you’ll really be glad down the road (probably three minutes from now when you want to edit it) that you took the extra minute to call hook_block in your custom module. If I really do just need to insert a little php, I still write it in my editor and then paste it in. This spares me the otherwise inevitable debugging. I think that doing things right is almost always faster than doing them fast and possibly having to debug them later.

  • Submit a patch

    This might not seem like a time-saving tip but I’ve come to believe it really is. It turns out the only difference between being a frightful Drupal hacker and an esteemed Drupal contributor is whether or not you submitted a patch. I used to always hear “don’t hack Drupal” and wonder how the hell these people thought that was possible when surely we all know there are dark corners of code where the override and hook systems never reach. Finally I realized they probably just submit a patch and call it ‘contributing’ instead of ‘hacking’. Actually I didn’t realize this until some point after I joined them.

    When you get in the habit of submitting a patch immediately after debugging or adding a new feature to a module, it will only take you a few minutes to do. The time savings comes from the fact that you now have other eyes on your work. Sometimes the module maintainer will turn around and point out to me a bug in my patch that I hadn’t yet tested for. Usually they will eventually commit my patch, which may be a time-savings for me on some future project or when upgrading the current one. Or they might give me a tip like “upgrade to my latest version you idiot because it’s actually way better” which is valuable to know. Maybe they will like my code so much that they will offer me marriage or employment, which could be side benefits on my time-saving mission.

Feb 03 2008
Feb 03

CFDV.org is the website for the The Chromatography Forum of Delaware Valley. Chromatography is a discipline of chemistry which is used to separate mixtures for analysis. For example, when your aspirin is tested to be 99.7% pure that was determined with chromatography by an analytical chemist. Likewise when your urine is tested to contain marijuana that was also determined by chromatography. Chromatography is a complex science and is used extensively in the pharmaceutical industry- an industry which has a large presence in the Delaware Valley. The Chromatography Forum is an independent organization which educates and unites scientists who are interested in this field.

I got the opportunity to build the CFDV website through my work friendships in chemistry (I was a chromatographer before learning web development). It was my first freelance project and was built in Fall ‘06 prior to my involvement with Drupal. Fortunately I convinced the forum to have me rebuild the site more recently in Drupal 5. In rebuilding the site (which previously had a homemade CMS) in Drupal, there was almost no change visible to the casual visitor but the site’s administration became streamlined and best of all the site’s potential for new functionality is extremely enhanced.

The site makes extensive use of the Date API and does some interesting things with dates and menus. When you click on ‘meetings’ it takes you to the next upcoming meeting and names it by the month it occurs. ‘Previous meetings’ uses the nice integration between date and views modules to give a very specific range and sorting of meeting nodes (the forum uses a September - June year which complicated the problem).

The site also takes reservations and payments by paypal for both meetings and courses. The meeting reservation form is just a fancy cck type. It passes the node id of a meeting as an argument to the node/add/registration page, and uses that to add relevant information and populate the meal choice. Then I used a lot of hook_form_alter and some jquery to further refine the form (it dynamically shows more fieldsets for additional guests in your party). I created a custom action to send the reservation to the CFDV administrator as well as the guest. I used lm_paypal module to integrate the site with paypal and allow the guests the option to pay online after reservation.

The course registration system is more complex than the meeting reservations, so for this I opted to create a custom multistep form using the Drupal Form API instead of relying on cck. If you’ve made it this far in this article you might already know what a hassle it is to make multistep forms in Drupal 5. You finish everything and then the client would like the form to have a back button (which I don’t think is really possible in the current API). The beauty of the course registration form is that its options are automatically created by the existing content of the course nodes on the site. All the courses and their options and prices and early-bird discounts already existed on the site as course nodes and with this wily form and my inherent fear of redundant data I made form magic come alive. (Other than being able to change the text at the top of the form, there is no maintenance required for this form at all.) I did some jquery work on the checkboxes on the form, so that only sensible combinations of box-checking can occur (checkbox wizardry). I also made the completed form save its data into an unpublished node for future reference. Then I hacked lm_paypal so that this new node’s id would be passed to paypal as an item number. Then when payment is completed and the item number is returned by paypal’s IPN, an action is fired to email the site administrator the contents of the saved node. Actually the most interesting thing about this form is that it is actually working! Next time though I might look into Simple Paypal Framework as well as lm_paypal module, to compare features.

It’s nice to work at enhancing this site and see its role with the organization evolve. There is quite a bit more use I can see the organization getting out of this site with future functionalities. Drupal sites can be much more than what you might traditionally think of as a website and also serve as software to automate things you may have been doing manually in your organization. I like the idea that a website is not one more thing an organization has to deal with updating but actually a tool that simplifies their workflow. I think that the custom forms I made for this site do exactly that, and that there is a lot of potential for this site in the future to serve as an online community for this group of scientists.

Jan 24 2008
Jan 24

One project I’m currently working on which is already live is OnlyAlummni.com.

Instead of having to build the entire site, I have a smart client who set up the site and had me work only on the trickier (fun) parts of this project. OnlyAlumni is a social networking site with about 8000 colleges, fraternities and sororities which operate as Drupal organic groups. This has been a great project for me to go much more in depth with organic groups and related modules.

The best part of the project has been getting to use Panels 2. The group homepages, user account pages, and user home page (for logged-in users) all rely on Panels 2 and made everything mind-bogglingly simple (if that’s possible) once I got my bearings with Panels 2 and its changes from alpha to beta mid-use.

The most complex part of the project so far has been the tracking of site activity. The site does something similar to Facebook’s news which lists site activity among your friends. For onlyalumni.com we are listing all site activity, the activity of your friends, and the activity in your groups. After coding all this in an insane way I wasn’t satisfied with, I found out about the activity module which seeks to do this the right way (saving activity to the database rather than trying to look it all up on the fly, and using the amazing token module to customize the output.) Because activity module is under active development and wasn’t doing everything I needed, I wrote a bunch of code for the project and redid OnlyAlumni’s activity tracking to use the module. This lucky chain of events all started in Portland where I met handsome lads Jerad Bitner and Robert Douglass who are developing activity module.

I also enjoyed using imagecache profiles module (which became an actual module around the time I was using it from its original incarnation on Nate Haug’s Lullabot article). The point of the whole thing is that it makes your user avatars all the same shape (usually square) without asking your users to do anything special, which lets you make nice little grids out of them.

If you want to get the full effect, go ahead and sign up for an account and join your college alumni group: http://onlyalumni.com

Jan 22 2008
Jan 22

I am loving this drupal 6 teleport module. Thank you ‘incidentist’. It really is quicksilver for drupal. You type in a few letters and it autocompletes paths you might want to visit- no mouse involved. For example, to post this story I pressed ctrl-T ‘stor’ enter-enter, and it took me to node/add/story.

Admin_menu: my loyalties have shifted. Our time together was pretty good, but you can’t compete with keyboard shortcuts.

Jan 14 2008
Jan 14

I just got back from Portland where I took Lullabot’s advanced drupal development course. Not only did the class take me to a wild new level of Drupalhood, but I was blown away by how great a city Portland is. It made me feel the intense masochism of the act of living in Philadelphia. Every detail was greeting me with unexpected good things, as opposed to Philly where every detail is just another slap in the face. Free fast wireless in their airport. Spotless trains coming every five minutes and asking you to pay on the honor system. I met more friendly people there in 5 days than in a year in Philly. It made me realize I’ve been living in Windows and cursing at computers in general, and then suddenly had that Mac moment where you realize all the anger is in vain.

I also had a great time catching up with my old friend Emily over beers, and meeting a lot of smart Drupal people and the Lullabots themselves. If I ever finish sorting through the mountain of email my clients sent me while I was gone, I will have a great time using my new Lullabot skills.

Also, I saw a real wild beaver swimming right next to a real submarine. In Philly all we have in the river is ‘Ride the Ducks’. I definitely need to move.

Dec 28 2007
Dec 28

Over the past year I’ve devoted myself to drupal development and a new site made in drupal has been long overdue.

This site is freshly built in Drupal 6 (currently in Release Candidate 1). It took about three hours to build (the majority of that was the design work) - Drupal 6 is even faster to set up than Drupal 5.

I plan to bring in the best of my music and comics from previous incarnations of my website, and also use this site as part random blog and part drupal-related work portfolio.

Dec 19 2007
Dec 19

Views Bulk OperationsViews bulk operations is ready for some beta testers.

It is essentially the admin nodes page on steroids. It enables you to perform node operations as well as actions from a custom view.

If you want to quickly check it out, install it, then go to the views overview page. Select 'add' for the 'admin_content' view, configure it and save it. When you first go to the view, you will be prompted to enable actions and/or operations.

For the full effect, install the actions module as well.

If you have any problems using it, please submit a bug!

Dec 17 2007
Dec 17

Drupal, Joomla and Wordpress are the 3 most popular content management systems according to Alexa and most webmasters. They all have their own blend of features and options that allow for extremely powerful and well-built web sites. With such feature rich systems it is important to understand the different aspects of each one to help with making a better choice as to which CMS fits you.

It should be noted that this chart is written from a web developers perspective and I am fairly experienced with creating sites with a CMS or without. I have used all 3 systems for developing web sites, but strictly stick to Drupal now as it allows me to built the most powerful sites the easiest.

  Drupal Joomla Wordpress Homepage http://www.drupal.org http://www.joomla.com http://www.wordpress.org Example Sites Installation Fairly easy, but requires a bit of technical stuff (will be much easier with version 6) Piece of cake A walk in the park Ease of use Not for the casual user. Drupal is usually more oriented towards developers and webmasters, although it is becoming more and more user friendly with each new version. Fairly easy and straightforward. Very easy to use. Pretty much anybody can use this. Administration Lots of control, but a bit confusing for the newbie Very graphical and intuitive! Very easy to administer the site Themes Decent, but lacking when compared to Joomla and Wordpress Good selection of themes Excellent, large theme selection! Comments Yes Yes Yes SEO
  • Fantastic! Title tags match your article title and clean URLs are easy to add.
  • Content is categorized nicely and eveything is listed as a preview and also has a permalink.
  • Requires OpenSEF or SEO extension.
  • May offer security risks due to SEO changes
Fantastic! - All content has a unique page with an SEO friendly Title and URL. Users Yes - Full user accounts and profiles can be set up. Users can log in and set preferences and settings. Yes Yes, can have multiple users Blogs A bit more cumbersome for blogging, but still has many blogging features and modules. Also, great for allowing more than 1 blog. Yes, you can create blogs easily with Joomla By far the best blogging software. Has support for many blogging features and plugins. RSS Feeds Yes, everything has a feed   Yes, made for RSS! Forums Decent, functional forum, but it doesn't have a traditional type of forum look and feel. It requires heavy theming to get it to feel right SimpleMachines integrates in very well. Yes Ecommerce Contributed ecommerce modules that are dencent, but a bit cumbersome Yes, as extensions Joomla offers ecommerce Yes, with plugins Video Full support for conventional video (.mov, .avi, .mpg) and Flash video (.flv) conversion via FFMPEG. Users can upload videos. No, unless embed YouTube videos No, unless embed YouTube videos Audio Full audio support for uploading of MP3s by users with audio module. Yes, with multimedia extensions Yes Photo Galleries Decent looking photo galleries with the use of the Image module. Gallery extensions allow for image galleries Yes Calendars Decent events and calendars, although they could definitely be improved on.   Yes Web 2.0 Yes! Pure! No, it still has the older content driven aspects and less community focus. Yes, very web 2.0! Permissions Yes, very granular permissions allow for precise control over certain features for each user Lacking Yes Scalability Great for adding new sections and elements to a site. It is very easy to build off the existing codebase. Decent Scalabily Limited scalabilty - much harder to add new sections and elements. Multisite Yes, full multisite integration out of the box! No Yes Categorization Complete control over categorization of content. Can sort and order content virtually any way. Super easy to create pages listing whatever you want. Limiting, only allows for section/category/content structure. Very good categorization via categories and tags Documentation Good documentation with lots of user submitted guides and tutorials. The forums are very friendly with helpful users. Decent, but a bit sparse on certain topics. Large community with lots of active contributors. Good documentation over all important aspects of the system. SSL Yes - SSL is all built in and pretty much transparent. Yes, requires some programming No Standards Yes sir! Close, but not exactly Full standards compliance Learning Curve By far the hardest learning curve. Easier to wrap your head around if you are a developer. Pretty easy learning curve. Lots of features, but pretty easy to follow. Fast and easy! Speed Very efficient, but page loads can take a bit longer as it can be common for many queries to happen with modules and features. Very fast with rendering pages. Can also slow down when features are added. Fast, pages render quickly and efficiently. Theming Complete control over all aspects of HTML. Hard to get used to, but fairly straight-forward once learned. Control over most aspects of the theme, although certain parts are injected in that can not be themed or tweaked. Changes on certain parts of the site may break other parts of the site and theming in general is a lot more buggy. Control over most aspects of HTML. Anti-Spam Features Lots of modules, features and captchas for removing and preventing spam Extensions that help prevent spam Lots of spam features Features Tons of features for blogging, communities, social networking, content management and everything you could ever want for a web site. A lot of good features, but lacking in social and user oriented areas. A lot of blogging features, but not many site features. My opinion My CMS of choice. Great for any type of website and very easy to build off. The Drupal community is very driven and has a great vision of where to take Drupal. Very good for brochure type sites. I guess you could say it is less powerfull than Drupal, but more powerful than Wordpress. It doesn't offer complete control on things which I don't particularily like. It is also hard to build off and is kind of more of a web 1.0 system and not web 2.0. If all I had was a blog and I wasn't too good at programming I would use this for sure. By far the best blogging software and still very good for smaller sites without a user base. Stability Rock solid, although be careful when adding modules, things can go downhill very quickly. Also avoid hacking core code. Very stable. Extremely stable. Database
  • MySQL
  • PostgresSQL
MySQL MySQL Security Great Good Great Programming Language PHP PHP PHP WYSIWYG Editor Yes, but not seamlessly integrated Yes Yes, great integration Page Caching Yes Yes   Integrated Statistics Yes Yes Yes Download Size 728kb 878kb 802kb Sitewide Search Yes Yes Yes

Overall they are all very great systems, but Drupal and Wordpress stand out to me as being at the top of their game. Wordpress is best if you are the only user and are mainly blogging or building a small site. Drupal is the best if you have multiple users and are looking to build out a full web community. Joomla kind of falls in between these as it has many features but is a bit less scalable and less customizable.

Nov 29 2007
Nov 29

Drupal books are a great way to organize content. Unfortunately, there is no way to control access to individual books by default. Like default forums, it's all or nothing.

The Book Access module adds the ability to set view, edit and delete access control for individual books and all pages therein.  

This module has no official release as it needs to be tested. The development snapshot is ready for testing though.

If you're interested in such functionality, install this module and please submit feedback and bug reports

Thanks to LifeWire for sponsoring development of this module. 

Jul 15 2007
Jul 15

Building a Drupal Web Site can be a very scary task to both beginner and experienced web designers. I have been building and theming Drupal web sites for about 2 years now and during this time I have developed my skills and picked up a few things that I would like to share.

It should also be noted, that as with any website, good design is not just entirely graphics and typography and stuff. A lot off good design is a well-planned out site with useful features, lots of content in the right places and things of this nature.

You still have to be a decent designer

If you want your site to look good you still have to be or have a decent designer handling it. That's just the way it is. Although Drupal has many exciting and cutting-edge features, these types of things do not make your site stand out as unique and powerful on their own. They need that special touch of an experienced designer to give it the direction and vision that it deserves.

Try to follow the flow of Drupal

When I first started with Drupal I didn't quite fully understand how everything really worked so I would try to force my way around theming. Rather than utilizing something as simple as comments I would try to build my own type of comments that were more "customized" and more precise to what I was looking for. As I soon realized, this became a huge problem and I started running into bugs and theme problems.

It is a much wiser move to try to understand how everything is working together and make sense of it before trying to force your own way on things. All the unique elements of Drupal offer their own set of strengths and weaknesses. Sometimes it may make sense for one and other times it may make sense for another. With a more complete understanding of all the parts of Drupal it really does help A LOT in theming and site building.

I have assembled a basic run down of some things that I usually think about when I begin theming a Drupal site. Most designers may not think this kind of thing is important and ironically this is also the reason why most Drupal sites lack the professional look that they deserve.

A quick run-down of things to consider when planning a Drupal site

User Pages

It is important to understand that all User pages have their own types of attributes. User pages are NOT nodes and do not allow for a lot of the things that nodes do allow for. If you want to have comments on your users pages you can't. You can't use CCK on your user pages either. If you want to have profiles for your users you may be limited by the default "profile" module. In fact, the default profile module can easily be replaced by CCK. For all of my sites I don't even use the user page as the user's page really. I mainly use the user page as a way to keep account information and stuff, but it makes much more sense to me to have an actual node as a user's profile. This way it is much more community oriented and allows for a lot more. As a node you can now comment on user pages, save them to favorites, search through the content on them, have the same moderation features nodes have and soooo much more. To me, this is the only way to go on a more high-end type site.


Nodes are the heart of Drupal. Pretty much any type of content on a web site should be a node. In my opinion, it is usually best to try to keep each type of content constrained to 1 node. That is, try your best not to have 2 or more pieces of content part of one node. For instance, a lot of the time I see people use CCK to attach images to a page node. This may be good in some cases and a quick fix, but it also may not. What if you want somebody to comment on your image? Since it is actually embedded as being part of your page node, it itself is not a node and does not offer any node features. What if you want to allow users to upload images for this particular node, would they be able to? What if you want to allow more than just 1 image per node? What if you want to allow many different types of attachments to this node? These are all questions that I consider and others should consider as well. In most cases I find it much more beneficial long term to allow each piece of content to be its own node type, including images, video and anything else. These items can then be referenced to other nodes using modules such as CCK's NodeReference and other type relationship modules.

It should also be noted that nodes have a huge list of contributed modules that can become super helpful for the organization, management and usability of nodes.

As I touched on earlier, nodes also allow for commenting so it is a good idea to try to keep anything that you want commented as a node.


Taxonomy is another part of Drupal which should also be understood in order to move a site to the next level. Taxonomy has a few unique features that only apply to it.

The first thing to note is that each taxonomy is basically a category that allows for the categorization of nodes. A "vocabulary" can be created that will hold different options for the user to select when creating a certain type of node. For example if you wanted to select the color for your product node you would create a vocabulary called "color" and assign it to the node type "product". You would then create the options or "terms" for this vocabulary. Such terms would include red, blue, yellow, green, etc. When a user went to create a new node they would now be presented with a Color dropdown that allowed them to select the desired color.

Everything that is part of a taxonomy term also has its own page automatically created that now lists every node that is contained in that term. So for example if you had 3 different nodes assigned to the "red" term on the color vocabulary when you go to the page mysite.com/taxonomy/term/1 (where 1 is the Red term ID) you would see 3 nodes that belong to the red term listed from newest to oldest. Mysite.com/taxonomy/term/2 (where 2 is the Blue term ID) would list all the nodes that belong to the 2 term.


Blocks are a great way to add all the cool little sidebar stuff that should be shown on either the current page or multiple pages. Blocks usually contain stuff like similar links, people also did this, subscribe to this here, top 5 images, most bookmarked and stuff like that.

When I first started out with Drupal I would try too hard to include my own types of blocks in my custom node-x.tpl files. I would create lots of cool little details about the current node in these files. I started to run into problems, however, when I wanted to quickly move this piece of text somewhere else, or even on another site as a different style. It really is important to try to keep the pieces of your site broken down as much as possible.


The tabs are a useful feature that are often overlooked by most newbies to Drupal. These tabs contain both sections and sub-sections for the current page that a user is viewing. For instance when viewing a node the user will be presented with the options for "view", "edit" and whatever else has been added here via modules. These tabs can become super useful and should not be overlooked. A lot of the times certain key features can be lost if tabs are not added to the theme.

CSS is key

Due to the nature of Drupal sites, they are usually very content and text driven. This creates great opportunities for CSS as there are many places to style headings, paragraphs and links.

Make use of the theme() feature

The theme function of Drupal is very cool. It allows any function from a module or core file that uses theme_ in front of it to be over-ridden in your template.php file. So what this means is that you can easily change the way a table, username, breadcrumb, pager or even the way comments appear. It is very handy and should be utilized when necessary. For instance, if I wanted to change the way my items listed with theme('item_list') were themed I would pull open my theme.inc file in the includes folder and search for theme_item_list. In here I would be able to over-ride this function and now add or take away from it.

Views can come in very handy

About a year or 2 ago I used to create custom modules and pages for the sole use of listing nodes of a certain type and of a certain taxonomy. With the release of view.module this is no longer necessary as view does this for you on the fly... and then some! View is very handy for creating lists of nodes with a number of parameters such as comments, node type, number of views, date of creation and so forth. Super awesome and useful!

Nodes have 2 templates, the teaser and the body

I didn't understand this concept for a while so some things were confusing to me. I didn't get why the nodes on my homepage looked different than when I was actually viewing the full node.

Nodes have both a teaser and a body element to them. This can be determined in the $page variable located in the node theme file. So if you were viewing the teaser of a node $page would be set to 0. And if you were viewing the body of a node $page would be set to 1.

So you can do a quick little php conditional on your node.tpl file to theme your teasers different than your nodes:

//theme body
//theme teaser

Use different content types for different types of content and theme them with their own node-type.tpl

If you are going to want different types of contents to look differently then you're going to want to give them their own content type. Each content type can have its own theme file so it makes sense to break up your content types accordingly.

Majority of the work can be done with page.tpl

Page.tpl is roughly about 80-90% of the site. First impressions by users will be made off the page.tpl alone. It is important to focus some effort on the page.tpl. This is where having an experienced designer could really come in handy. I usually like to treat the page.tpl just like I would any other site. I first start out in Photoshop and come up with a layout that fits the goals and intentions of the site. Once I am satisfied with everything I strategically export certain elements from Photoshop and bring them over to CSS and my page.tpl.

Avoid hacking up page.tpl.php - Use modules instead!

I would also like to warn against hacking up the page.tpl file. At times it may become appealing to write a quick if statement to maybe hide a certain part of the page for certain sections. Or it may be appealing to show a registration link for users that haven't registered. While this may be a quick fix and get the job done for the time being, I would advise against it as it will only create more and more problems as you try to keep adding more and more "hacked" features via your page.tpl. The better approach to do this which I now use is writing custom modules for these little features. If you run multiple sites it will also be much more helpful as you can easily use these similar little features between sites.

Over-ride core CSS files if you have to

Core CSS files such as system.css can be over-ridden if necessary. For instance, on my tabs I usually like to theme them differently than the default look so I usually will have my own style.css that cancels out the CSS on system.css. This way I never actually delete the file from core and I still maintain the desired look I want with my tabs.

The default user pages suck

As I hinted at earlier the default user pages are trash. They just are. They are boring and nobody cares about how long you've been a member. They want to see your content and learn about you! As of right now you pretty much will have to do some over-riding of the theme_user_profile to get around this. For more information on this you may want to check out this sweet Drupal article.

Try not to over-complicate things

Sometimes all these different things can get very cumbersome and confusing. Every once in a while you may want to step back and just go with the Drupal flow again. Drupal does have pretty much everything worked out so if you are struggling with something you may not be handling it the way Drupal wants you to. Step back for a little bit and see what other options are available to you. You'll be surprised sometimes to find that what you were looking for was just a click away!

Relax, it's not that bad!

It really isn't. Building and theming a Drupal site shouldn't be too bad with the right people and the right vision. In fact it should be 100% easier than building a site with any other system, including scratch. Drupal is the only way I build sites these days because it is just so powerful and so quick that it's the only thing that makes sense to me. I used to build sites completely from scratch with my own type of CMS and that was just retarded (and not the good kind). Drupal makes you quicker, more stable, more secure and much, much better. Drupal rocks!

 Filed under: Internet / Tech, Drupal, Design
Jun 05 2007
Jun 05

When you first get started with Drupal it can be extremely intimidating as there are many options, modules and things goin on. This guide will help show you some of the most important parts of Drupal that really make it stand above other content management systems.

How to control different parts of the page

Different parts of a page are controlled via different template files. The primary ones you will deal with are:

  • page.tpl.php - Controls the whole page view of the site. Everything that lays out the foundation of your site is done here.
  • node.tpl.php - This controls the look of the nodes, or content of your page. This will control how the text that you create as like a 'page' or 'story' looks.
  • block.tpl.php - This controls the blocks that go on your sidebars. You can style theme here.
  • comment.tpl.php - This controls how the comments look.

All you do is pretty much create a file called something like page.tpl.php and then just fill it out w/ whatever HTML you want and then you can choose from a list of variables to use, such as the page title, the navigation, etc.


It is worth mentioning node.tpl a little more as this is an important one that is used a lot in most cases. Each type of node you create can have its own theme. So you could theme your 'page' nodes to look different from your 'story' nodes. This would be done by simply naming your file node-page.tpl.php or node-story.tpl.php - you just add on -nodetype to the file and this will take precedence over the default node.tpl.php :).

You can override any function that begins with theme_ in your template.php file

I didn't really know this for a while and it is very useful information, especially for people into theming. A lot of repetitive Drupal functions use the format theme_username, or theme_table. If you go through modules you will notice they too have the theme_ format. What this does is allow any part that actually emits HTML or display-oriented parts to run through a Drupal function that first searches your template.php and overrides it with something new. This is instead of modules calling theme_username they would call theme('username'). This is basically the same thing except if called as the latter it will allow your custom template.php file to overwrite the default one.

For example, you can customize the user page by overriding the function theme_user_profile

Say you want to change how the user page looks. You could cruise around your modules and find the function that handles this. (You should be able to open up say user.module and search for 'theme_').

You will come across the function: theme_user_profile which looks like this is the one that handles that.

We would now copy this code and paste it into our template.php page:

function theme_user_profile($account, $fields) {
$output = '

$output .= theme('user_picture', $account);
foreach ($fields as $category => $items) {
if (strlen($category) > 0) {
$output .= '

'. $category .'

$output .= '';
foreach ($items as $item) {
if (isset($item['title'])) {
$output .= ''. $item['title'] .'';
$output .= ''. $item['value'] .'';
$output .= '';
$output .= '';
return $output;

We could now rename it to phptemplate_user_profile and we can tweak it however we like :)

function phptemplate_user_profile($account, $fields) {
$output = 'The profile page for '.$account->name.' is super simple but still badass';
return $output;

That's it! You will now have a custom profile page for every user. The possibilities are endless!

Use a node w/ CCK for pretty much anything you want to store data with

CCK is one of the best modules because it allows users to add any custom fields into any node type. Say you want to add a text field for a city. Boom, done. Now your node would have Title, City and Body during creation. Each one of these fields is also themable via the node.tpl file for the node. They can be accessed like $node->field_city[0]['view']. You can add as many, or as few fields as you would like for each node.

You can share multiple sites on the same Drupal install

This is somewhat advanced but not really. If you have multiple sites it makes sense to share the same modules with all of them. That way if you update core or the modules it will take effect on all the sites using that install. You can also share parts of the databases such as users and stuff, but that does a bit more advanced and isn't always necessary. I do think it is necessary to get all sites using the same Drupal install though. Otherwise you are always having to figure out which modules versions its using, make sure all the files have the current stuff uploaded and it just becomes a hassle.

Don't go through and hack up the core code or modules

When I first started using Drupal I did this. I wanted my site EXACTLY how I wanted it so I would do whatever it took to make that change. In a way this is okay, but just don't expect to have an easy upgrade when a new version of Drupal comes out with new features that you have to have. It will work you bad - it did to me. As you grow with Drupal more you will figure out ways to override certain features and use modules to pretty much do anything you want anyway.

The current system path is always sent via arg(n)

To figure out where a certain page is located it can be useful to call arg(n). For instance if you are viewing node 5 and you wanted to figure out what node you were viewing from a module or theme you would call arg(1) and it would return 5. This is because it goes through the default URL structure and splits each section between '/' up.

For instance, when viewing node 5 arg(0) would return 'node' while arg(1) would return 5. arg(2) would return nothing because there is nothing there. It pretty much takes the default Drupal path, regardless of whether there is a path or not because it is all handles internally.

So say you are editing user 3. The path in the url may look like: www.myurl.com/user/3/edit. The args would be:

  • arg(0) = 'user'
  • arg(1) = 3
  • arg(2) = 'edit'

So say you have all your nodes being re-written as just the tile of the node. So externally to users it would look ike: www.myurl.com/node-name-title-here. Internally, however, it would be:

  • arg(0) = 'node'
  • arg(1) = n (where n = whatever the nid is)

Hope that makes sense.

Hooks are awesome

Hooks are a bit more advanced and used in modules but there are still worth mentioning because they are like the heart of Drupal and its modularity. Pretty much any common or major task that is done in Drupal invokes what is called a "hook" This task could be pretty much anything. Drupal comes with a bunch of default hooks that are used, but you can also create your own.

When a user creates a new account the function hook_user is called. When a user edits a node hook_nodeapi is called. What this means is that anytime something happens in Drupal, it tells your module that it is happening and allows you to do something when this happens also. It's very cool. Say you want to also include new users in another custom table when they sign up. You would name your function something like mymodule_user and you would now be able to include these users in a custom table when they sign up :).

Recommended Modules

This tutorial wouldn't be complete without a list of some very useful modules

  1. CCK - CCK allows you to create custom fields for any node type. These fields can range from simple checkboxes, to full blown AJAX date fields.
  2. Views - Views allows you to create custom pages and blocks that list your content in tons of different ways. Say you want to have the 10 most recent story nodes listed descending by most page views. Done!
  3. Pathauto - Pathauto automatically creates a path for nodes, users and taxonomy upon creation based on settings you have control over.
  4. Webform - Webform allows you to set up any type of form that collects info. It saves the data to the database and sends an email to wherever. Very cool!


I hope this little walk-through will clear up and add some insight into the inner workings of Drupal. Drupal really is a super powerful system and it is so cool to use once you have a better understanding of it. It is the only way to build a web site in my opinion.

 Filed under: Internet / Tech, Drupal
May 27 2007
May 27

I have been using Drupal for over a year now and everyday I just love it more and more. I am mainly a designer that also has programming experience so Drupal is a great match for me as it allows me to use my design skills to tweak the front-end and then use a bit of programming to make everything hook into the back-end smoothly.

Every day I am seeing people still developing web sites from scratch and doing tons of hand-jamming on the same code over and over. There is absolutely no need to do any type of site completely from scratch these days. With systems like Drupal that handle basically all the core programming aspects for you, your time should be spent on the direction and marketing of the site and not the intricate perfection of programming details. Drupal is great for a number of reasons: it has very high quality code, it is always being updated, it has a plethora of modules, the search engines love it and it has full community involvement.

High Quality Code

The core code of Drupal is so dialed in that it’s insane. I really don’t think people fully understand just how great this type of a thing is. For over 5 years a team of very smart and experienced people have been re-working the core aspects of Drupal over and over again. Anybody that’s programmed before will know that with any application you usually don’t see the problems until after you’ve created the application. The same is true for a web site. You’ll create a piece of code and as you complete new parts you will go, “ah crap, maybe I should have done this differently.” Well yeah, that’s just how it goes, you can’t foresee all the details and bugs that will arise before hand. That is why time becomes a valuable piece of the coding puzzle. Well guess what? Drupal has been being re-worked for over 5 years now and the code is very high quality and scalable. So many details of complexity have been covered that make it a totally valuable asset when building any web site, large or small.

Updated Continuously

Drupal is updated continuously. Everyday something new is added. It is just so great to be using a system knowing that even when I am not working it is being built out stronger and stronger day by day. In the days before open source you would have to pay a team of experienced programmers every time you wanted some new feature or something fixed. With Drupal people from around the world are collaborating all day, everyday to help make Drupal the best it is. It is kind of like Apache… Yeah that’s right, you all know the open source software Apache that virtually every server runs on these days. But did you know that when it was first started there were other PAID servers being developed by people like IBM? Because of its open source nature and its team of smart, passionate developers IBM’s best programmers couldn’t even keep up with Apache. The same can be said about Drupal. A team of smart, passionate developers moves a project by leaps and bounds compared to some paid solution.

Tons of Modules

The modules is really just icing on the cake for Drupal. As if the CMS isn’t all ready badass enough, it allows for full integration of custom built modules that interact with virtually any feature of the core code (remember what I was saying about the high quality code that gets reworked over and over again). Anybody who has Drupal is able to create a module that can do any custom task they want and at the same time, update any part of the site or have anything on the site do something. Say you want a custom voting module. Done. Say you want to allow for new users to automatically be associated with something. Done. Say you want to add a new way to display your content. DONE. Modules allow you to do pretty much anything you can think up with Drupal.

Did I mention there is already about 1,000 FREE modules already submitted by the Drupal community? Yes that’s right. Chances are most things that you would need a module for already have a module. You can just cruise over to Drupal, download the module instantly and slap it on your site. Done!

Search Engines love Drupal!

I have been an SEO for a while now and I can say without trepidation that Drupal is absolutely brilliant for the search engines. Pretty much everything the search engines are looking for Drupal covers.

  1. Search engines love content web sites. Drupal sites are all about the content and they make it easy to do so. Rather than having to contact your webmaster to add a new page so you can finally get some new content up Drupal allows you to go in and insert and edit content on the fly! It almost makes you create more content just because you can. Got some spare time at the office? Go write some content and get some more rankings!
  2. The title tags and headings are perfect. I’m not going to cover any other on-page aspects of SEO basically because you have full control over every piece of code on your site. But by default, Drupal’s title system is set up perfect. You control what you name your content and Drupal uses this as your title tag and as your page heading. Brilliant I tell you!
  3. Clean URLS – I really don’t think this does much but everybody else is super in to it so hey! Drupal has clean urls. And yes, they can be generated automatically with some complex elements in them if necessary (a la pathauto module).

UM, what else? That’s pretty much all you need for SEO – good content, titles and the links is up to you!

Full community involvement

Everything in Drupal is made to be done by any user, whether it be the admin or a user from another country – it doesn’t matter at all! With a customizable degree of permissions any user can be assigned to any permission that allows for very efficient collaboration of users. Yes I know, vBulletin is a great piece of FORUM ONLY software and it doesn’t even compete with Drupal when it comes to building out a full scale community. What if you want to allow users to create articles or reviews? If you’re like any other vBulletin (or other forum software) user you’re probably sick of having users write reviews or things of this nature as an actual forum post itself. Is this really a thread? Does it belong in a forum? Why not have a REVIEWS section on the site rather than a forum (Sorry, just a pet peeve of mine). But serious, what if you want people to be allowed to comment on articles you post? Drupal says a big fat “DONE!” What about custom profile pages like MySpace? DONE. What about allowing users to upload their own content? DONE. DONE. DONE.

I hope this little write-up serves everyone well in understanding just how badass Drupal really is. There is only one thing better in life than Drupal and that ISN’T Joomla.

 Filed under: Internet / Tech, Drupal, Web, CMS
Apr 20 2007
Apr 20

I have been thinking about how to deal with releases of phpGroupWare. For me it is a technical, procedural and political question.

Over the last few months I have been playing with Drupal a fair bit. I love Drupal. It is simple to install, skin and hack. The community is great. The website is massive and has almost anything you want about Drupal. They dog food their stuff. I have quite a few clients using Drupal for their sites, they love it. There are many cool things on technical level within Druapl too - but that would take this post off on a long tangent.

Drupal was allocated 20 summer of code places by google. phpGroupWare received 1 spot, indirectly. To me this is a sign of the popularity of the project and the level of activity within the community.

I hear you thinking, but hang on, Drupal is a CMS, phpGW is a groupware suite, compare apples with apples. Well, you see I am not trying to compare apples with apples. I am looking for good ideas about how to build a quality release.

I think Drupal have it sus’d. The have the core which is released when it is ready. They also have a stack of modules which are released when the developers feel like they are ready. This provides a lot more flexibility to all developers. Developers can prepare versions for multiple versions of Drupal, but also release stuff when they think it is ready for release, not wait for the next mega tarball to be prepared.

I think that the Drupal release model may work well for phpGroupWare. We could prepare the core (probably API, admin, addressbook, calendar, email, filemanager, notes, preferences, setup, todo - the PIM apps and sync when it is ready) and release that as phpGroupWare 0.9.18. Then modules developers would be free to package there modules and release them when they were ready. Modules which were tested and stable at the time of the official releases would be listed in the release announcements. It would mean that getting our apps site working would be important as that would be the entry point for a new ecosystem. It would also mean that if someone is working on new features for an app, they could release often, while the core would be more static and stable, in order to encourage more app development.

I don’t think that we can have a release time table for the core unless we have significantly more (paid?) resources available.

I think that covers the technical and procedural issues, the political hopefully won’t be too painful either.

The decision on what is core and what is not will need to be made early. The criteria for assessment should be made publicly available. Developers should be free to ask that their app be considered core. Being a core app is not a vital thing, apps will still be promoted if they are not core.

We could look at 4 levels of apps. Core, as discussed above. Supported, apps which meet the core app standards, but are not considered core for whatever reason. Unsupported, apps which work but do not meet the project standards for some reason (coding standards, bypassing the API, lack of docs, require patches etc). Dead, apps which are no longer maintained and other developers feel should no longer be maintained. The status of the apps would be publicly listed.

Such a model as proposed above would allow us to release a 0.9.18 core with some additional supported apps (such as ged, property, messenger, tts) a lot sooner than trying to get all the 0.9.16 tarball apps ready for release.

The only technical issue to resolve in this plan would be version control as savannah’s CVS. isn’t really designed for this model of development. I have been discussing switching to SVN with the savannah hackers, they are supportive of the idea.

I do have comments open on my blog, so feel free to leave a comment, otherwise discuss it on the dev list. I will post a summary of the comments there if I feel it is warranted.

Jan 30 2007
Jan 30

Error message

Deprecated function: The each() function is deprecated. This message will be suppressed on further calls in menu_set_active_trail() (line 2405 of /home1/markspap/public_html/kathy/includes/menu.inc). January 29, 2007

Now that I've worked on a few projects with Drupal v4.7, I have to say that I'm impressed as all get-out with it. Personally, I can't think of any reason not to use it on a majority of projects. But Drupal is my personal preference, and I'm not sure it would be the best one for everyone. Movable Type and WordPress are two of the most popular blogging systems. Although they can be used for other types of sites, they were specifically designed for weblogs. Their functionality and features are limited. But what they do, they do very well. For simple sites or weblogs, MT and WP are fairly quick and easy to set up. On the other hand, Drupal is a powerful publishing platform that can be used for everything from e-commerce sites to portals to intranets. It can also be used for blogging—in fact, multiple user weblogs are a default option. I have to admit that running a one-person blog with Drupal is a bit like going after a gnat with a bazooka. But some people like that kind of firepower. For them, the complexity and difficulty of running Drupal is more than rewarded by its versatility. Indeed, for some Drupaliers, developing the necessary skills is a reward in itself. At present, MT and WP are the "point-and-click instamatics" of weblogging software—Drupal is more for those who have their own darkroom in the basement. And this is unfortunate. Drupal is far superior software, and the lure of cool new features could make developers out of a whole generation of otherwise uninitiated users. In addition, the funding that comes with popularity wouldn't hurt Drupal, either. But Drupal will never be widely used outside the development community until it becomes easy enough to install to appeal to the "point-and-click" crowd. I've heard rumors that more custom distributions like CivicSpace and DrupalED may be coming from Drupal developers. With more preconfigured distributions with very good documentation, Drupal could well give MT and WP a run for their money.

Similar Notes

Nov 16 2006
Nov 16

Until the mid 90s, spam was a non-issue. It was exciting to get email. The web was also virtually spam-free. Netizens respected one another and everything was very pleasant. Spam Those days are long gone. Fortunately, there are some pretty amazing tools out there for fighting email spam. I use a combination of SpamAssassin on the server side and Thunderbird (with its wonderful built in junkmail filters) on the desktop. I am sent thousands of spam messages a day that I never see thanks to these tools.

But approximately five years ago, a new type of spam emerged which exploited not email but the web. Among this new wave of abuse, my personal favorite, comment spam.

I love getting comments on my blog. I also like reading comments on other blogs. However, it's not practical to simply allow anyone who wants to leave a comment, as within a very short period of time, blog comments will be overrun with spam generated by scripts that exploit sites with permissive comment privileges. To prevent this, most sites require that you log in to post a comment. But this may be too much to ask of someone who just wants to post a quick comment as they pass through. I often come across blog postings which I would like to contribute to, but I simply don't bother because the site requires me to create an account (which I'd likely only use once) before posting a comment. Not worth it. Another common practice is the use of "captchas" which require a user enter some bit of information to prove they are human and not a script. This works fairly well, however, it is still a hurdle that must be jumped before a user can post a comment. And as I've personally learned, captchas, particularly those that are image based, are prone to problems which may leave users unable to post a comment at all.

As email spam grew, there were various efforts to implement similar types of protection, requiring by the sender to somehow verify he was not a spammer (typically by resending the email with some special text in the subject line). None of these solutions are around anymore because they were just plain annoying. SpamAssassin and other similar tools are now used on most mail servers. Savvy email users will typically have some sort of junkmail filter built into their email client or perhaps as part of an anti-virus package. And spam is much less a nuisance as a result.

What we need for comment spam is a similar solution. One that works without getting in the way of the commenter or causing a lot of work for the blog owner. Turn it on, and it works. I've recently come across just such a solution for blogs which also happens to have a very nice Drupal module so you can quickly and easily put this solution to work on your own Drupal site.

Enter Akismet

It's called Akismet, and it works similarly to junkmail filters. After a comment (or virtually any piece of content) has been submitted, the Akismet module passes it to a server where it is analyzed. Content labeled as potential spam is then saved for review by the site admin and not posted to the blog.


Akismet follows my absolute favorite pricing model. It's free for workaday Joes like me and costs money only if you're a large company that will be pumping lots of bits through the service. They realize that most small bloggers are not making any money on their sites, and they price their service accordingly. Very cool.


In order to use Akismet, you need to obtain a Wordpress API key. I'm not entirely sure why, but it is free and having a collection of API keys is fun. So get one if you have not already.

The Akismet Drupal module is appropriately named Akismet. It's not currently hosted on Drupal.org, but hopefully the author will eventually host it there as that is where most people find their Drupal modules. Instead, you will need to download the Akismet module from the author's own site. The installation process is standard. Unzip the contents into your site's modules directory, go to your admin/modules page and enable it. There is no need for additional Akismet code as all the spam checking is done on Akismet's servers.


After installing Akismet, I was immediately impressed at how professional the module is. There were absolutely no problems after installation. Configuration options are powerful and very well explained. The spam queue is very nice and lets you quickly mark content as "ham" (ie not spam) and delete actual spam. As you build up a level of trust with the spam detection, you can configure the module to automatically delete spam after a period of time.

Spam filtering can be enabled on a per node type basis, allowing you to turn off filtering for node types submitted by trusted users (such as bloggers) and on for others (eg forums users). Comment filtering is configured separately.

Another sweet feature is the ability to customize responses to detected spammers. In addition to being able to delay response time by a configureable number of seconds, you can also configure an alternate HTTP response to the client, such as 503 (service unavailable) or 403 (access denied). Nice touch.

One small problem

I've only been working with Akismet for several days now. And I'd previously been using captcha, which I imagine got me out of the spammers sights for a while (spammers seem to spend most of their efforts on sites where their scripts can post content successfully). So far, Akismet has detected 12 spams, 2 of which were not actually spam. These were very short comments, and I imagine Akismet takes the length of the content into consideration. I assume that as the Akismet server processes more and more pieces of content, it will become more accurate in picking out spam versus legitimate content. Each time a piece of flagged content is marked as "ham", it is sent to Akismet where it can help refine their rule sets and make the service more accurate.

Perhaps Akismet could provide an additional option that allows users to increase or decrease tolerance for spam. I would prefer to err on the side of caution and let comments through.

Nov 15 2006
Nov 15

Tailing my error log, I kept coming across annoying errors like this:

[Mon Nov 13 21:14:49 2006] [error] [client xx.xxx.xxx.xxx] PHP Warning: mysql_real_escape_string() expects parameter 1 to be string, array given in /path/to/drupal/includes/database.mysql.inc on line 350, referer: http://www.example.com/node/1234/edit

No matter how hard I tried, I couldn’t reproduce the errors locally, but somehow real users could create them on the live server. I tried to track down the bug but could only go so far – yes, it was happening when a node was edited, and it was in a database query, but which query? There were too many to look at, so I needed more information.

Because I couldn’t reproduce the bug locally, no amount of dprint_r() and such had any effect. Following some advice in #drupal I explored debug_backtrace() and added its output to a custom error log like this:

function mymodule_error($errno, $errstr, $errfile, $errline, $errcontext) {

if (in_array($errno, array(ERR_LOW, E_NOTICE, E_STRICT))) {
$level = false;
elseif (in_array($errno, array(ERR_MED, E_WARNING))) {
$level = ‘WARNING’;
elseif (in_array($errno, array(ERR_HI, E_ERROR))) {
$level = ‘FATAL’;
else $level = ‘UNKNOWN’;

if ($level) {
// don’t log unimportant errors

$functions = array();
foreach (debug_backtrace() AS $errors) {
$functions[] = $errors[‘function’] . ‘:’ . $errors[‘line’];
$trace = join(‘ < = ', $functions);

error_log($level . ' ' . $errfile . ':' . $errline . '. ' . $errstr . '. (' . $trace . ')');

I put the code in a module file, and it didn’t work… an hour of hair pulling later I found the culprit to be devel.module:

function devel_init() {

… this was undoing my error handling setting, so I had to comment out the restore_error_handler() line and my error handler took centre stage.

With the new code live, I just waited a few hours until the bug showed up again – this time, with extra backtrace information to help me debug:

[Tue Nov 14 18:13:14 2006] [error] [client xx.xxx.xxx.xxx] WARNING /path/to/drupal/includes/database.mysql.inc:350. mysql_real_escape_string() expects parameter 1 to be string, array given. (mymodule_error: < = mysql_real_escape_string:350 <= db_escape_string:152 <= _db_query_callback: <= preg_replace_callback:196 <= db_query:1040 <= my_custom_function:659 <= my_nodetype_update:297 <= node_invoke:494 <= node_save:1876 <= node_form_submit: <= call_user_func_array:206 <= drupal_submit_form:132 <= drupal_get_form:1620 <= node_form:2093 <= node_page: <= call_user_func_array:418 <= menu_execute_active_handler:15), referer: http://www.example.com/node/1234/edit

So now I knew exactly where the bug was coming from. ‘db_query’ was called on line ‘1040’ of my file, and of the several ways to get into the function in which line 1040 resides, I knew it had come form my_custom_function on line 659.

Armed with this extra information, tracking down the bug was a breeze. Stupidly, I’d forgotten to do a regular expression I was supposed to do on a variable before doing a db_query, meaning arrays which were supposed to be left alone were wandering into the query pretending to be strings.

Share this:

Like this:

Like Loading...
Nov 13 2006
Nov 13

In our effort to give something back to Drupal (the fantastic open source content management framework at the core of AllYearbooks), we’re aiming to make a physical yearbook for members of the worldwide Drupal community.

Presuming all goes to plan and enough people join, the idea is to produce physical copies of the yearbook (as well as allowing PDF downloads). These will be provided free to Dries and the top 10 Drupal contributors. It may also be possible for other interested members to buy a copy, though this book isn’t being run as a money-making venture.

If you’re a Drupal developer or involved in Drupal in some other way, join the yearbook now. It only takes a few seconds to join, and you can come back any time before printing to update your yearbook entry and upload some gallery photos for collages and other such pages.

So far 8 Drupalites have joined the yearbook. We’re hoping for at least 100 members for it to be worth printing.

If you have any suggestions, please get in touch.

Share this:

Like this:

Like Loading...
Nov 13 2006
Nov 13

PHP is an interpreted language. This means that each time a PHP generated page is requested, the server must read in the various files needed and "compile" them into something the machine can understand (opcode). A typical Drupal page requires more than a dozen of these bits of code be compiled.

Opcode cache mechanisms preserve this generated code in cache so that it need only be generated a single time to server hundreds or millions of subsequent requests.

Enabling opcode cache will reduce the time it takes to generate a page by up to 90%.

Vroom! PHP is known for its blazing speed. Why would you want to speed up your PHP applications even more? Well, first and foremost is the coolness factor. Next, you'll increase the capacity of your current server(s) many times over, thereby postponing the inevitable need to add new hardware as your site's popularity explodes. Lastly, high bandwidth, low latency visitors to your site who are currently seeing page load times in the 1-2 second range will be shocked to find your vamped up site serving up pages almost instantaneously. After enabling opcode cache on my own server, I saw page loads drop from about 1.5 seconds to as low as 300ms. Now that's good fun the whole family can enjoy.

Opcode Cache Solutions

There are a number of opcode caching solutions. For a rundown on some of them, read this article. After a bit of research and a lot of asking around, I concluded that Eaccelerator was the best choice for me. It's compatible with PHP5, is arguably the most popular of its kind, and is successfully used on sites getting far more traffic than you or I are ever likely to see.

Implementing Eaccelerator

This is the fun and exciting part. Implementing opcode cache is far easier than you might imagine. The only thing you'll need is admin (root) access to your server. If you're in a shared hosting environment, ask your service provider about implementing this feature if it is not in place already. These instructions apply to *nix environments only.

Poor Man's Benchmarking

If you would like to have some before and after numbers to show off to your friends, now is the time to get the 'before' numbers. Ideally, you will have access to a second host on the same local network as your server so that the running of the test does not affect the results. For those of us without such access, we'll just have to run the test on the actual webserver, so don't submit these results in your next whitepaper:

Apache comes with a handy benchmarking tool called "ab". This is what I use for quick and dirty testing. From the command line, simply type in the following:

ab -n 1000 -c 10 http://[YOURSITE.COM]/

Here is a portion of the results I got on my own test:

    Concurrency Level:      10
Time taken for tests:   78.976666 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      13269256 bytes
HTML transferred:       12911899 bytes
Requests per second:    12.66 [#/sec] (mean)
Time per request:       789.767 [ms] (mean)
Time per request:       78.977 [ms] (mean, across all concurrent requests)
Transfer rate:          164.07 [Kbytes/sec] received
Connection Times (ms)
min  mean[+/-sd] median   max
Connect:        0    7  51.3      0     617
Processing:    77  725 1704.4    300   21390
Waiting:        0  673 1697.5    266   21383
Total:         77  732 1706.2    307   21390
Percentage of the requests served within a certain time (ms)
50%    307
66%    468
75%    625
80%    639
90%    805
95%   3808
98%   6876
99%   8529
100%  21390 (longest request)

The single most useful number is 'Requests per second', which in my case was 12.66.

Download, Build and Install

First, download the source code.

Get it to your server and do the following (I'm assuming you have gcc on your system, if not, get it):

tar jxvf  eaccelerator-0.9.5.tar.bz2
cd eaccelerator-0.9.5
make install

Configure Apache and Restart

If you have an /etc/php.d directory, create the file /etc/php.d/eaccelerator.ini for your new settings. Alternatively, you can put them in your php.ini file. Your configuration should look something like this:

eaccelerator.log_file = "/var/log/httpd/eaccelerator_log"
; eaccelerator.allowed_admin_path = "/var/www/html/control.php"

Adjust values according to your particular distribution. For more details on configuring eaccelerator, see the settings documentation.

See Eaccelerator in Action

The value eaccelerator.allowed_admin_path, if enabled, should point to a web accessible directory with a copy of 'control.php' (which comes with the eaccelerator source code). Edit this script, changing the username and password. You can then access this control panel and see exactly what eaccelerator is caching

See the results

After enabling Eaccelerator on devbee.com, I ran my benchmark again, and here are the results:

    Concurrency Level:      10
Time taken for tests:   10.472143 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      13129000 bytes
HTML transferred:       12773000 bytes
Requests per second:    95.49 [#/sec] (mean)
Time per request:       104.721 [ms] (mean)
Time per request:       10.472 [ms] (mean, across all concurrent requests)
Transfer rate:          1224.30 [Kbytes/sec] received
Connection Times (ms)
min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       4
Processing:    20  103  52.1     96     345
Waiting:       17   92  50.1     83     342
Total:         20  103  52.1     96     345
Percentage of the requests served within a certain time (ms)
50%     96
66%    122
75%    137
80%    147
90%    176
95%    201
98%    225
99%    248
100%    345 (longest request)

We are now serving up 95.49 requests per second. That's 754% increase in server capacity. Had I been able to run the tests from another machine on the same network, I believe the numbers would be even more dramatic.

Jul 23 2006
Jul 23

The number one quality that separates Drupal from other popular CMS is its API (most often referred to as "the Drupal API).  Drupal is designed explicitly to allow for adding, altering or removing core functionality. Thanks to this API, there are hundreds of third party modules available for Drupal. Some of these modules provide very specialized features. Others provide integration with the most popular services on the web (including Google Maps, Flickr, del.icio.us, Digg and more). All take advantage of the Drupal API and none include modification of core (again, the basic code base required to run Drupal).


Enhancing software that doesn't provide an API usually involves modifying its core code directly. If software doesn't open up its functionality to developers, then developers are left to go in and manipulate the original source code to achieve their goals. In many cases, this is just how you have to do things. Drupal is not one of those cases.

To be clear, when I refer to 'hacked Drupal core', I'm referring specifically to modifications of the files that come with the standard distribution of Drupal, most importantly, the files that are in the /includes/ and /modules/ directories. All of the same concepts apply as well to third party modules, but that's not what I'll be focusing on here.

Who Cares?

Does it really make a difference whether you do things correctly as long as they work? Absolutely. While it may seem much more effective at first to edit Drupal core to add the features you want, this is a big mistake. Let's talk about some of the problems you will run into.


The first problem you'll likely run into is applying Drupal updates. The Drupal team is excellent about patching security vulnerabilities. This means that if you are steadfast in keeping your Drupal instance updated, your chances of getting 'hacked' are greatly reduced. However, if your team has modified Drupal core, applying updates becomes a painful process requiring careful scrutiny of each update and possibly an even more painful merge of those changes with your hacked core files. In my experience, rather than go through this unpleasant process, owners of sites with a hacked core tend to postpone applying patches and updates. The more the owner procrastinates, the more likely his site is to suffer an attack using a known exploit. Once your site has been exploited, there's no telling how long your site may be down or how long it will take you to recover.


The next problem you may run into is broken functionality. By altering Drupal core files, you may be inadvertently modifying functionality depended upon by other parts of the system. You are messing around inside the "black box" that Drupal as a whole depends on. While you may think it's clever to go in and modify the phptemplate engine directly, what you could be very well doing is creating bugs somewhere else in your site. By the time you come across the problem, it is unlikely that you'll immediately realize that it is caused by the changes you made to phptemplate. And, friend, you are now in for a lot of hurt as you rip apart code trying to fix it.

Maintainability and Longevity

Drupal's API is known by hundreds of developers all around the globe. The hacks introduced by your $20/hr programmer found on craigslist are known only to one developer. Should you ever need to update or extend your site, you better have that $25/hr developer on staff or you better be using the Drupal API. If you play by the rules, you can hire any experienced Drupal developer.

Bottom Line

There are legitimate reasons to modify Drupal core. If you've found an actual bug in Drupal, the best thing you can do as a developer is to fix it and submit a patch. Likewise, if you've come up with an enhancement that you feel should live in core, submit it. Aside from these two reasons, neither you nor anyone in your employ should be touching anything in that drupal .tgz file.

If you want to develop extended functionality for Drupal, use the API. If you're hiring a Drupal consultant, find one who is familiar with the Drupal API. Find a developer who's active in the Drupal community. Hiring a knowledge Drupal developer may cost more initially, but if you plan on maintaining your site for any length of time, this investment is sure to pay off down the road.

Jul 10 2006
Jul 10

A search for "blank page" of the Drupal.org domain yields about 37,000 results.

This is probably one of the more common and frustrating problems for Drupal admins.

I've had the problem dozens of times myself. For no apparent reason, pages will simply come up blank. Drupal returns nothing at all, not even a set of empty HTML tags. As a developer, I'm used to seeing broken sites and fixing them. But the typical site administrator may not have the knowledge or experience necessary to debug something like a blank page.

The first thing you want to do is gather all available debugging info. The two primary places you'll find this information is in Drupal's logs (Administer >> Logs) and in your Apache log files (/var/log/httpd on Linux systems). If you're lucky, these logs will provide obvious clues as to what's wrong. Whether or not your able to gather any clues as to the source of your problem, below is a list of the most common causes of empty server responses:

  1. Memory: In your php.ini file there is a value called memory_limit, which is set to 8 megabytes by default. If you've installed a lot of modules, you can easily exceed 8 megs on a given page request. The solution is to increase this limit (I set mine to 32 megs because I have lots of memory on my host and few domains being served on it). If you're in a shared host environment, you won't be able to modify this value. In this case, you'll need to disable modules or get a new host.
  2. Buggy Modules: If you're problem began after installing and activating a new module, move the module's directory outside of /ROOT/modules/. Experimenting with modules is probably the easiest way to "break" your site. My suggestion is to test all modules on a non-production Drupal installation. Move them to your production site only after making sure they work properly (This message approved by Captain Obvious).
  3. Incompatible Modules: Using 4.6 modules on a 4.7 site is also a great way to break stuff. Make sure you've installed the module versions that match your Drupal version.
  4. Broken Themes: A buggy theme can easily render a site unusable. My suggestion is to preview themes at the Drupal Theme Garden or on a non-production Drupal installation. If it's too late for that and you're experiencing blank pages, you should try setting the theme to a "safe", stock theme. If you cannot access your administrative pages (http://.../admin/themes), you will need to move your custom theme from your /themes/ directory to another temporary location. Alternatively, you can run this SQL command on your Drupal database: UPDATE variable SET value = 's:10:"bluemarine";' WHERE name = 'theme_default';

I don't believe I've ever seen the 'blank page' problem in a production release of Drupal core. The problem only crops up when installing and playing around with new modules. So the bottom line is be very careful when experimenting with modules. I almost always use a sandbox installation of Drupal to test modules before installing them on a production site. (updated: Thu Jul 13 14:11:27 2006)
Jun 27 2006
Jun 27

The contributions process for non-core Drupal themes and modules is in need of a revamp.

Currently the process is a very loose one that does not require adherence to any tagging conventions or release process. This makes it very difficult to know the status of the modules that make up a given site. I believe this probably results in many site admins out there just leaving their site as-is because the process of updating is somewhat confusing and tedious.

We want to fix this.

While there are existing 4.6, 4.7, etc... tags applied to contrib modules, they are not consistently used by module authors. Furthermore, tags are being applied inappropriately (4.7 tags applied to 4.6 code that is not actually upgraded).

Ultimately, I'd love to see version and update management built right into Drupal (in the same way it's built into most OSs and many software packages). Drupal might have a single page the admin can visit to check the status of his core Drupal installation as well as all modules and themes he is using. The process of upgrading to the latest versions could be a very simple matter of selecting desired updates and hitting a submit button.

That, however, is a long way off. We need to start by creating a process with which Drupal developers and contributors can "tag" their software releases and make those releases available quickly and easily.

To take part in defining this new release process, please visit "Versioning and release process for contributed projects" and leave a comment.

Jun 26 2006
Jun 26

I just returned from BarCamp San Francisco , and I'd have to say it was a success.

This was my first BarCamp, so I had no idea what to expect. It really is as simple as it sounds. A bunch of folks show up and schedule events on the spot based on who is present and what they're interested in.

It took place at Microsoft's offices on Mission and Embarcadero. While normally I'd be inclined at this point to offer one of several heartfelt opinions about Microsoft, I'll just say that it was very generous for them to allow us their location for the weekend, and it was very well suited for this great event. Thanks, Microsoft.

"Take Aways"

One of the unfortunate survivors of the dot-com bust was a vast set of obfuscated vocabulary collectively known as buzzwords, a value-add semantical meta-markup linguistic solution used to define hi-tech marketecture and other domains. Can you feel the synergy?

Yes, there was no shortage of buzzwords floating through the air, and it's hard to avoid them when they are made up largely of otherwise very usable terms such as "solution" (which now means software application), bandwidth (which now means intelligence or ability ["I don't have the bandwidth to..." actually means "I'm not smart enough to..]") and "orthogonal" (which is used in so many disparate contexts, I don't know what to make of it).

Point being that the following section may be populated with buzzwords, so watch your step.

Talent Co-op

This was probably the coolest concept I came across (read: most relevant to me). The idea of bringing together in a single (virtual) place geographically dissimilar supplies and demands is not new. Elance.com, Guru.com, blah, blah. What hasn't been done, to my knowledge, is this sort of thing without the blatant and irritating commercial aspect to it. Something just plain bothers me about relying on some corporate interloper to supply me with suitable clientèle, particularly when they have no reason to take any concern for the quality of either the supplier or the suplyee.

The internet is too obvious an answer to the problem of many people working (or wanting to work) from Location Unknown doing things they love and are good at, and other people wanting to find good worker units and not really caring where, when or how they work as long as they can do the job.

Citizen Agency is the first effort (that I'm aware of) to bring a bunch of talent together to pool talents, resources and work. The effort is only weeks old, and I believe BarCampSF was the official announcement of the effort.

Micro Formats

Here's an example of something I ignored as more buzzword blather that turned out to actually be something potentially very useful. Microformats is like XML in that it's easy to explain and difficult to completely understand. As I see it, microformats would turn any standard web page into a potential source of data objects like contacts, locations, content objects like reviews, and anything else you might normally look for in a database. Main problem, widespread adoption. Microformats probably won't blossom until these formats are managed behind the scenes by blog software, document editors, email and so on. But I can definitely see that happening, at which point you'll see all sorts of useful tools (first appearing as extended functionality to clients like browsers and email apps). Read up a bit on this so when it finally breaks out, you can say something like, yeah, I saw that coming back in 06.


No need to go into any detail here. Everyone wants to be like MySpace, Flickr, Facebook, etc... I find the subject tiresome myself. The *concept* of community has no meaning or value to me. Implementation of community oriented websites, features and so on is what interests me.


While there was a very nice showing from the Drupal camp. I got to meet Drupal luminaries jjeff, dries, drumm, roland and others. Sporting my own Drupal tag, I struck up Drupal related conversations with most of the folks I met. (I'm hereby pronouncing myself as Drupal's chief petty evangelist.) I don't think I met anyone who wasn't aware of Drupal. Most had at least some direct experience with Drupal. Most folks had a lot of questions about it. Some had the common "I installed it, now what" experience with Drupal. I think we might benefit from expanding, somehow, our efforts to help folks (hi sepeck!) install, use and love Drupal.

The BarCamp experience was better than I had anticipated. I highly recommend you attend one when it hits your town. I'm going to attempt to help organize the first BarCamp San Diego.


May 03 2006
May 03

One of the great features of Drupal is its ability to run any number of sites from one base installation, a feature generally referred to as multisites . Creating a new site is just a matter of creating a settings.php file and (optionally) a database to go with your new site. That's it. More importantly, there's no need to set up complicated Apache Virtual hosts, which are a wonderful feature of Apache, but can be very tricky and tedious, especially if you're setting up a large number of subsites.

No worries, there is a solution.

Create a new LogFormat

Copy the LogFormat of your choice, prepend the HTTP host field, and give it a name:

LogFormat "%{Host}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" vcombined 


Get the script

Next, download the attached script (split-logfile) and store it somewhere like /usr/bin (don't for get to chmod 755 that baby!)

Now, tell apache to use pipe logfiles to your script rather than writing them directly to disk:

CustomLog "| /usr/bin/split-logfile" vcombined 

Restart Apache

/etc/rc.d/init.d/httpd restart

That's it.

Naturally, you may have to modify split-logfile if you don't store your logfiles in the default location.




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