Upgrade Your Drupal Skills

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

See Advanced Courses NAH, I know Enough
Feb 06 2012
Feb 06

This isn't so much a technical guide as it is a workflow overview. Sometimes the philosophic part of a website can be just as important as, or even more important than, the technical. So here is a collection of some things worth considering if you are developing sites with Drupal. This is more focused towards a designer or developer who builds and manages their own sites.

Separate Databases / Separate Files / Use Same Web Server

Installation / Prefixing

When it comes to each new website I always put them on their own install now. With Drupal it is possible to share things like nodes and users between multiple sites but this usually isn't as good of an idea as it sounds. Just because you can do something doesn't mean you should. Most sites are hardly tied together and most sites don't need to share data. So when it comes to setting up new sites I recommend putting them on their own install. You can put them all on the same database, but I would advise against sharing tables. I usually prefix each site accordingly. So site 1 would be site1_ and site two would be site2_ in the settings.php and so on. They can share the same database, but they don't share the same tables.

For my sites I have a Drupal database for each main version. So I have a drupal7 database that has each Drupal 7 site in that database prefixed accordingly. For some of my old Drupal 6 sites I have a drupal6 database that holds these sites. When Drupal 8 is rolled out I will have a drupal8 database for all these. This makes it easy to backup 1 big database versus lots of individual ones.

Custom Database Tables

Which brings me to my next point. I am also not a big fan of creating new tables for sites. Say you want to store some custom data for a module that you wrote? I really don't like the idea of having to install a new table simply to store the data. It is tricky because it is hard to make sure other sites that will be using this module stay up to date. What happens when you make a change on your table structure? Now you have to make it so all the sites with this table get updated too. The better approach, IMO, would be to have a table that works for ALL your domains.

So rather than having a custom table for each install, I would recommend having a global table that all the sites share. This could even be on a separate global DB. So I recommend having your individual core installation and then all your custom extensions handled on a separate "global" database. In your module you can simply switch to your global connection that you define in your settings.php. So your db query would be like:

db_select('custom_table', 'c')->fields('c')->condition('domain', 'domain.com')->condition('more', 'stuff')->execute();

Then all you need to do is add a column in your table to have some unique identifier like the domain name. This way every time you do a query you just check to make sure the domain matches the current domain they are on so that you know you are pulling the right data. This type of setup has made my life way easier than trying to have a separate custom table for each install. It's just not necessary in most cases.


I also recommend having files separate. I usually have a separate folder that contains the files for each Drupal install. This one isn't as big of a deal, but I think from an organizational standpoint it is kind of weird to store everything in one folder. What if you want to move the site to another server? What happens if you want to move a site over to a CDN? Do you write a script to sort out all the files for that site? What happens if there are shared files? Do you just copy all the files over and deal with having extras? It's not a super big deal, but I just have had more problems in this scenario.

Web Server

As for the actual core Drupal files and web server itself I highly recommend sharing this. Sharing the core files and modules makes it very simple to update all your sites at once. Putting everything on the same web server doesn't really have any negatives. Everything is centralized and organized and it is much more simple to only have 1 directory with all your Drupal stuff.

If you do plan on having multiple servers then I would recommend using something like rSync to copy files from one Drupal web server to the other Drupal web server. This way you still only have 1 main web server to worry about and all the others are simply remote clients that receive their data from the main one. This is how I structure my servers and it works great. You can have an rSync script set up as a cron task or you can just run it manually whenever you want. Just make sure that you don't copy things over that you don't need to like individual site files.

Avoid lots of modules / Use core

I really think most modules should be avoided. There are really only a few modules that I could see being needed, where everything else just doesn't seem as necessary. The only 2 modules I really use on every site I have is pathauto/token and captcha. Most of the things you need are probably already handled in core. Obviously something like ecommerce will need a module and a few other things might, but for the most part you don't need many modules.

Another module that is fairly popular is views, but I don't use this one myself. I've found that views is something that needs to be set up for each site individually and is hard to scale quickly on multiple sites. Which brings me to my next point...

Have one global module that extends Drupal for all your sites

I have one main module that I use on every one of my websites. This way I know that anything I want on all my sites will always be there. I want forms to look a certain way on all my sites. So in that Global module I have custom CSS code that makes all my sites look a certain way. I want all my sites to track things like searches and page load times. So I have a global module that captures all this data and stores it centrally in one global database. If at any point there is something that I want all my sites to do I can easily roll it out to all my sites just by updating my main global module. I want all my sites to have a contact form that sends data to my CRM. So I have a global module that puts this page on a site by default. I have a privacy policy that I want on every site. My global module handles all this. I have certain spam checks I want on every site. My global module handles all this. You get the idea. Having one big module that handles all the custom stuff you want to have on all your sites is a good idea.

My global module is kinda like my mini-CMS that runs off Drupal. I have Drupal as my main CMS, but I have global.module as my own CMS for all the stuff that I want.

Share as many aspects as possible between sites

It is usually a good idea to share as much stuff as possible between sites. It takes a lot of time to customize things for each site and it usually isn't as important as we think. I have probably 3 or 4 main themes that I use between all my sites depending on the type of site it is. Corporate sites have a certain theme, community sites have a certain theme, and sales sites have a certain theme. I really don't need to have more themes than this. Within each theme there may be a few custom things I can do for each site, but this can all be done by changing a header background image for each site. That's really all that needs to be changed for each site. Each site has its own logo and a few other things, but other than that it doesn't need to be different. All sites probably should have a white background and blue links for text. There really isn't any reason to go crazy with theming.

If you look at all the top websites they almost all have very basic themes. Most of the top websites have things like, black or grey text, blue links, white backgrounds, very few images and not a lot of confusing stuff. They're simple and basic. So there really isn't that much of a need to make each site unique. The thing that should be unique should be the content, not as much the theme.

So I try to share as much stuff as possible between sites. I try to find as many things that all my sites should do the same and then I group all these similar things into core modules. Anything that needs to be unique for each site I make unique for each site. Anything that doesn't need to be unique is centralized.

Shift to core trends (images, fields, etc)

It is important to keep up with core trends and shift to these trends as possible. For Drupal 5 and Drupal 6 I had individual Image nodes that would handle my images. With Drupal 7 I have now finally made the shift to the fields API. I now upload images as a field rather than as an individual node. Since fields (CCK) are now a core part of Drupal it is a pretty safe bet to start framing your modules around this.

It's important to pay attention to where Drupal is heading and see how it will affect you into the future. The way you are doing things right now may not be the best way to do things into the future. There may come a point where you need to shift from doing something with modules to doing it with core. There may come a point where you need to shift from doing something with core to doing it with modules. But as often as possible I would recommend using core since you don't need to worry about sorting out all the bugs and problems. Which brings me to my next point...

Extend using core

Core is almost always going to be more dialed in than custom solutions -- so use core as much as possible. Sometimes you can save a week of coding just by using core instead. Drupal should be seen as a framework and should be used as that. If you have data chances are it can be stored through Drupal. You don't always have to use custom tables in a database to store data from a custom form. Why not just use a node? You don't always have to create custom fields in a table to collect data for customers. Why not just use fields? You don't always have to create custom tables to organize things. Why not create a new vocabulary and organize it with taxonomy? Many of the data and organizational things you need to do can already be done through core. I use nodes all the time to store data. I use taxonomy all the time to organize things. You don't always have to write something custom and mess with custom tables if you can do it with core.

Use blocks for a lot of stuff

Block come in really handy. I use them all the time for shared pieces between sites like contact forms and recent content pulls. But blocks can also be nice for individual site "hacks". Like say you want something to not show up on a certain site. Rather than write some 4 hour piece of code to allow certain options for each site it may be better just to throw some CSS in a block that hides a div on a certain page. Blocks are nice because they can show only on certain pages if you want. So if you want something to only happen on certain pages use a block.

Sometimes a block can also be your main content. For example, on a landing page you may not really have a lot of text content. Your landing page may be mostly an image or a form or something really graphical and custom like that. So rather than try to do this all with a node, I would recommend using a block. Just have a blank node or page, and then have a block that is your content. Make your landing page a block that only shows on your homepage, for example. Your main content may only be 500px wide and you may be limited by using a node or a page through a module. Your best bet would be having a part in your theme that allows you to use the full width of your page. This way you can then have a big header that takes up 900px of space and really uses the most space possible. Blocks are handy for stuff that you want to have happen on only specific pages. In many ways, blocks can be pages.

Sometimes quick custom code is better than pre-written excessive code

There are lots of modules out there. You can probably find a module for just about everything that you want done. But sometimes it may be better just to write your own code. Most modules almost always come with stuff you don't want and don't need. Most modules come with tons of options and many install tables in your database. A lot of modules also are hard to scale and update with. What happens if you want to now move to Drupal 8 but the module you are using isn't ready? You may only be using 1 feature out of the 20 features it does. Do you update the whole module yourself? The better thing to do may be just writing that 1 thing yourself, this way you don't have to drag around all the slop that you don't need.

It may just be me, but I just think most custom modules have waaaaaay too much stuff that isn't needed. Most modules have tons of options and settings that just aren't needed. I don't think most people care about settings. I think most people want a module that does exactly what it should do, is slim and is always up to date and working.

It also is a pain when modules have dependencies and need other modules to work. One module can quickly turn into 5 other modules that you don't need -- all for just 1 feature you want. I am very careful with new modules and usually avoid them if I can. Most of the stuff you need from a module can usually be done with 100 lines of code or less.

Keep it simple

With all this said, the underlying theme is keep is simple. The main thing people care about on a website is content. Focus your site around your content. You don't need 10,000 modules. You don't need some eye catching theme. What you need is eye catching content. What you need is eye catching value. Keep your network of websites easy to manage and easy to scale. Keep your network of websites doing what people want. Make sure your sites load fast and are always live. All the extra features can be decided once you have the basics done first.

These are my thoughts on Drupal and how I approach building my sites. Hopefully this helps a few people.

 Filed under: Internet / Tech, Drupal, Theming, Development
Dec 01 2008
Dec 01

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

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

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

My Goals

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

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

Which files to offload

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

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

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

Local file system

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

Synching your content

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

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

My S3 Solution

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

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

Local: http://www.domain.com/files/full/path/myfile.jpg


S3: http://s3domain.com/files/full/path/myfile.jpg

So basically my flowchart goes something like:

The Technical

S3 Interfacing

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

Filetype check

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

If file exists

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

Queuing the file for S3

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

Putting to S3

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

Routing the files with Drupal

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


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


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


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

So that's it!

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

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

 Filed under: Internet / Tech, Drupal, S3, File Server, CDN
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
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.

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

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