Upgrade Your Drupal Skills

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

See Advanced Courses NAH, I know Enough
May 10 2015
May 10

After using the new gmail 'tabs' for a while, I began just ignoring anything not in the primary tab. It turns out, this included notifications from Godaddy regarding domain renewals. I neglected to renew devbee.com, and as sure as the sun rises, it got scooped up immediately by a ... person.

I've owned domains for the last twenty years, and I never thought it would happen to me :) At first I thought no big deal, I'll just use my backup devbee.net domain (which I registered a month after devbee.com and so was able to recover it before it expired). But I've been using [email protected] for my client work for about ten years now, and there's nothing that says amateur hour like bounced email.

I am in touch with the new owner of my domain, and I'll definitely be reporting back on the results of our discussion.  

Apr 07 2014
Apr 07

The first revision control system I ever used was called RCS. It was the pre-cursor to CVS and stored all revision data locally. It was nifty but very limited and not suited for group development. CVS was the first shared revisioning system I used. It was rock solid, IMHO. But it had a few big problems, like the inability to rename or move files. Everything had to be deleted and re-added. 

Since those days, I've used several other revisioning systems: Perforce, Bitkeeper, Clearcase, Subversion and GIT.

I'm tired of learning yet another system. I just want to know which horse is going to win the race for the forseeable future and go all in.

That's where Google Trends comes in very handy. It quickly reveals that I need to bet on GIT. 

I just hope I can make it through the next 5 years or more before having to learn the next greatest solution to our shared problem of tracking code revisions.

Sep 30 2012
Sep 30

I recently worked on a project which required a updated version of the jQuery library. While there is the jQuery Update module, it only allows you to upgrade Drupal 6 to jQuery 1.3. If you really know what you're doing and want to upgrade beyond that version, you can either hack core or create your own simple module to do it. While hacking core is certainly the easier approach (simply overwriting misc/jquery.js with a newer version), it is very bad practice. You do not want to get yourself in the habit of altering Drupal core unless you want to kill your upgrade path and deal with a new slew of bugs and unpredictable behavior.

Let's start by creating an admin area for configuring the version of jQuery we want to use.

/**
* Module configuration admin form.
*
*/
function mymodule_admin_form() {
 
$form['mymodule_custom_jquery'] = array(
   
'#type' => 'checkbox',
   
'#title' => t('Override Jquery'),
   
'#description' => t('Replace the version of jQuery that ships with Drupal
      (jQuery 1.2.6) with the jQuery library specified below. You will need to
      flush your cache when turning this feature on or off.'
),
   
'#default_value' => variable_get('mymodule_custom_jquery', 0),
  );
 
$form['mymodule_custom_jquery_file'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Jquery file location'),
   
'#description' => t('Specify the location of the updated jQuery library
      you would like to use. The location is relative to the docroot and
      so should probably begin with "sites/".'
),
   
'#size' => 128,
   
'#default_value' => variable_get('mymodule_custom_jquery_file', NULL),
  );

  </span>$form = system_settings_form($form);

  return </span>$form;
}
?>

Next, we're going to write a validation hook that simply makes sure the file exists.

/**
* Admin form validation callback.
*
*/
function mymodule_admin_form_validate($form, &$form_state) {
 
$file = trim($form_state['values']['mymodule_custom_jquery_file']);
 
$form_state['values']['mymodule_custom_jquery_file'] = $file;

  </span>// Only validate this value if js override is turned on
 
if (variable_get('mymodule_custom_jquery', 0)) {
    if (!
file_exists($file)) {
     
form_set_error('mymodule_custom_jquery_file', t('The file you specified does not exist: !file.', array('!file' => $file)));
    }
  }
}
?>

And lastly, we use hook_preprocess_page() to safely replace the jQuery that ships with Drupal core with our own version.

/**
* Implementation of hook_preprocess_page().
*/
function mymodule_preprocess_page(&$variables) {
  if (
variable_get('mymodule_custom_jquery', 0)) {
   
$file = variable_get('mymodule_custom_jquery_file', 0);
   
$scripts = drupal_add_js();

    </span>// remove core jquery and add our own
   
unset($scripts['core']['misc/jquery.js']);
   
$add_scripts['core'][$file] = array(
     
'cache' => TRUE,
     
'defer' => FALSE,
     
'preprocess' => TRUE,
    );
   
$scripts['core'] = array_merge($add_scripts['core'], $scripts['core']);
   
$variables['scripts'] = drupal_get_js('header', $scripts);
  }
}
?>

Make note of the line:

    $scripts['core'] = array_merge($add_scripts['core'], $scripts['core']);
?>

We are careful to add our new jQuery include at the beginning of the array (where the original jquery.js include was) in order to meet any jquery dependencies in the scripts that follow.

Sep 01 2012
Sep 01

I'm not sure how it happened, but today I noticed that Drupal's menus were behaving very oddly. After upgrading to Drupal 6 and installing several additional modules, I noticed duplicate menu entries as well as other disturbing oddities. Items I was placing into the menu were not showing up. Menu items that I moved around were apparently saved but they did not appear properly in a dropdown context. 

Looking further into it via the absolutely awesome SQLYog tool, I verified that there were dozens of duplicate entries. Some items were duplicated up to six times. It was a real mess.

The database tables involved here are menu_links and menu_router. These are two of the more mysterious tables in Drupal. I haven't had the need to spend much time with them in the past, and I know now that this is a good thing. Fortunately, you do not have to know anything about them to fix this problem. While I spent a couple hours carefully deleting items from this table, ultimately I gave up. I was able to remove all the duplicates, but the menus were still misbehaving. At this point, I just wanted to do a factory reset on the menus, but it's not so simple as flushing cache. However, that is not far from the solution.

This solution will do a 'factory reset' on your menus. You will lose any customizations you have made. However, all core and contrib module entries will be restored very nicely.

Please backup your entire database before doing any destructive database manipulation. 

Step one is to empty the corrupted tables:

In your favorite SQL client, run the following commands:

truncate menu_links;
truncate menu_router;

At this point, your site will be completely unusable. But not for long. To complete the final step, you will need to be comfortable with the Drupal admin's best friend, drush.

Simply run the following commands from your terminal (Viva tcsh!):

drush php-eval 'menu_router_build();'
drush cc menu

Now my menus are as fresh as the day they were installed.

Though I could not clearly identify the cause of this problem, I would suggest backing up your database before installing the Taxonomy Menu module

Aug 27 2012
Aug 27

I've been putting it off for a few years, but I finally decided to upgrade devbee.com to Drupal 6. 

I didn't really need to, but it bothered me that I wasn't running supported code and I figured I might learn something. And I did. Mostly obvious things that I should be familiar with already. 

Drush

I've only ever played around with this. I don't like learning new things unless they are going to be truly useful to me. Drush is definitely something I shouldn't have ignored for so long. It comes in particularly handy when doing a site upgrade as you can download and install modules, clear cache, set variables, run DB updates and a lot more all from the command line. This tool is crazy good if you're comfortable in a terminal.

Themeing didn't change much

I was able to convert my dated theme to 6 with very little effort. I created a .info file, changed the names of the region variables in my page.tpl.php file and tweaked a small amount of CSS. Took me about 20 minutes. Pretty painless. I was able to preserve my table-based layout so all you markup nazis will have an example of bad design.

Minimalism

The whole process was made much easier by the fact that I don't like using a lot of modules. I tend to go with a handful of the more popular modules such as Views, CKeditor, CCK, Pathauto, etc... Because I use only popular modules, I'm almost certainly going to have no trouble upgrading them. At least that's my experience.

Key things to remember

  1. Start with a brand new install of D6 with no contrib modules. It's tempting to try to force an upgrade on your existing site, but it's just not going to work. You must create a clean install. 
  2. Import your old database into the clean D6 database. I tried to skip this and just point D6 to my old database, but then  you end up with missing tables and a whole lot of brokenness.
  3. Run DB updates and get your core Drupal site working before worrying about contrib modules.
  4. Lastly, and this is where drush will save you time, download and enable the contrib modules you need one at a time. 

Unfortunately, the upgrade process is no longer something that can be done by the average site owner. There are going to be snags, and you're going to need to know how to interact with your database to get things up and running. I think this is the reason so many users are still on D5 and D6. I'd really like to see an upgrade path that was more accessible to non-developers, but at the same time, I'm also grateful that Drupal is upgradable and there is no need to manually migrate data for major upgrades. 

At this rate, I should be upgrading to D7 sometime around the end of the decade.

Jan 10 2012
Jan 10

The following is a guest post by Mitchel Xavier

One of the challenges of developing with Drupal is to understand Drupal’s structure. Until now, when working with the DOM structure, the DOM inspector has been the best tool for viewing the structure. A new tool has been created to make the visualization of the DOM structure much easier to interpret. It is a Firefox add-on and is called Tilt 3D. It creates 3 dimensional interactive representation of the DOM elements as a layered visual image.

A requirement to use Tilt 3D is that your browser supports WebGL. WebGL is a Javascript software library which allows for the creation of 3D graphics very quickly and without the requirement for additional plugins. Currently Firefox is the only browser to support this tool. Firefox has supported WebGL since version 4. The other requirement for Tilt 3D is that it is supported with a capable graphics card.

Tilt 3D is extremely useful for many reasons. When you click on each node, you can see the structure of each element. You can view the html and css of each node. It is great for debugging html structure issues. It also provides the option to refresh in real time during all changes made in Firebug.

Tilt 3D was created by Victor Prof and Rob Campbell, who created Firebug. One of the advantages of Tilt 3D is it’s smooth interface. It is very intuitive to use and creates a completely new way of interacting and obtaining information about your Drupal website. If you are starting work on an existing Drupal project, Tilt 3D would be a great way to understand the structure of that particular project.

[embedded content]

Mitchel Xavier is a Drupal website designer and Drupal 7 specialist.

Apr 01 2009
Apr 01

Developers are all familiar with the default behavior of the drupal menu systems "local tasks" (aka tabs). These appear throughout most Drupal sites, primarily in the administration area, but also on other pages like the user profile.

Generally, developers are pretty good about creating logical local tasks, meaning only those menu items which logically live under another menu item (like view, edit, revisions, workflow, etc... live under the node/% menu item).

But sometimes, these tabs either don't really make sense as tabs or you simply want to have the flexibility of working with the items as "normal menu items", or those menu items which appear under admin/build/menu.

I recently wanted to move some of the tabs on the user profile page (user/UID) into the main menu so that I could include them as blocks.

For some reason, developers think the user profile page is a great place to put tabs for user related pages such as friendslist, tracker, bookmarks, notifications and so on. But these types of items are less a part of the user's account information than they are resources for specific users. Personally, I would not think to look at my account information on a site to find stuff like favorites or buddies. I'd expect those items to be presented somewhere much more obvious like a navigation block.

Initially, this may seem like a trivial task. My first thought was to simply use hook_menu_alter() and change the 'type' value of the menu item from MENU_LOCAL_TASK to MENU_NORMAL_ITEM. However, for reasons I don't understand well enough to explain in detail, this does not work.

In order to achieve the desired result, you must change the path of the menu item and incorporate the '%user_uid_optional' argument, replacing the default '%user' argument.

All very confusing, I know. Let's look at an example.

The notifications module (which provides notification on changes to subscribed to content) uses the user profile page rather heavily. I don't want its links there, I want them in the sidebar where users can always see them.

/**
* Implementation of hook_menu_alter().
*/
function MODULENAME_menu_alter(&amp;$callbacks) {
 
// NOTIFICATIONS MODULE
 
$callbacks['notifications/%user_uid_optional'] = $callbacks['user/%user/notifications'];
 
$callbacks['notifications/%user_uid_optional']['type'] = MENU_NORMAL_ITEM;
  unset(
$callbacks['user/%user/notifications']);
  <
SNIP>
}
?>

So I have moved the notifications menu into my own menu, changed the type, used %user_uid_optional instead of %user, and unset the original menu item.

This works fine except for the fact that you'll lose all of the other menu items under user/%user/notifications! You need to account for all menu items in the hierarchy to properly reproduce the tabs in the main menu system, so we add the following:

    $callbacks['notifications/%user_uid_optional/thread'] = $callbacks['user/%user/notifications/thread'];
    unset(
$callbacks['user/%user/notifications/thread']);

    </span>$callbacks['notifications/%user_uid_optional/nodetype'] = $callbacks['user/%user/notifications/nodetype'];
    unset(
$callbacks['user/%user/notifications/nodetype']);

    </span>$callbacks['notifications/%user_uid_optional/author'] = $callbacks['user/%user/notifications/author'];
    unset(
$callbacks['user/%user/notifications/author']);
?>

And of course, we don't want this code executing at all if our module is not enabled, so you'd want to wrap the whole thing in:

  if (module_exists('notifications')) {
 
  <
SNIP>

  }
?>

Keep in mind that not all modules implement menu items using hook_menu(). It's becoming more and more common for developers to rely on the views module to generate menu items, and this is a wise choice. Menus generated using views (ala bookmark module) can be modified to get the desired result without any custom code.

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 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.

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.

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.

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!

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. 

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.

Pricing

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.

Installation

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.

Configuration

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 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
phpize
./configure
make
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:

zend_extension="/usr/lib/php/modules/eaccelerator.so"
eaccelerator.shm_size="32"
eaccelerator.cache_dir="/var/cache/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"
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).

Hacking

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.

Updates

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.

Functionality

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.

Communities

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.

Drupal

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.

References

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