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.

<?php
/**
* 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),
  );
$form = system_settings_form($form);

  return

$form;
}
?>

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

<?php
/**
* 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; // 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.

<?php
/**
* 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(); // 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:

<?php
    $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.

<?php
/**
* 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:

<?php
    $callbacks
['notifications/%user_uid_optional/thread'] = $callbacks['user/%user/notifications/thread'];
    unset(
$callbacks['user/%user/notifications/thread']); $callbacks['notifications/%user_uid_optional/nodetype'] = $callbacks['user/%user/notifications/nodetype'];
    unset(
$callbacks['user/%user/notifications/nodetype']); $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:

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

May 24 2007
May 24

SWF Charts is a API wrapper for PHP/SWF Charts.

I have just finished the basic module and want to get feedback and see if there's any interest in such a module. The primary reason there may not be interest in this module is that PHP/SWF Charts is not GPL'd, and that's generally a major turnoff for most (including me). But I'm not aware of any other method of generating high quality charts and graphs while not introducing unnecessary server load and not requiring fancy PHP Graphing libraries.

Right now the module relies on a moderately complex data structure as input. I did not want to try to create an abstraction layer initially as that inevitably results in "hiding" functionality, though it would make the module much easier to use.

The following sample charts are based on those from the PHP/SWF Charts Gallery page. The first sample graph consists of the following code saved as a PHP node:

<?php
$config
['height'] = 300;
$config['width'] = 400;
$config['bgcolor'] = '#FE8F01';$chart[ 'axis_category' ] = array ( 'font'=>"arial", 'bold'=>true, 'size'=>16, 'color'=>"000000", 'alpha'=>60, 'skip'=>0 ,'orientation'=>"vertical_up" );
$chart[ 'axis_ticks' ] = array ( 'value_ticks'=>false, 'category_ticks'=>false, 'major_thickness'=>2, 'minor_thickness'=>1, 'minor_count'=>1, 'major_color'=>"222222", 'minor_color'=>"222222" ,'position'=>"centered" );
$chart[ 'axis_value' ] = array ( 'font'=>"arial", 'bold'=>true, 'size'=>10, 'color'=>"ffffff", 'alpha'=>50, 'steps'=>6, 'prefix'=>"", 'suffix'=>"", 'decimals'=>0, 'separator'=>"", 'show_min'=>true );$chart[ 'chart_border' ] = array ( 'color'=>"000000", 'top_thickness'=>0, 'bottom_thickness'=>0, 'left_thickness'=>5, 'right_thickness'=>0 );
$chart[ 'chart_data' ] = array ( array ("", "2007", "2006", "2005" ), array ( "Drupal", 100, 45, 25), array ( "Joomla", 80, 65, 35 ), array ( "Wordpress", 55, 30, 10 ) );
$chart[ 'chart_grid_h' ] = array ( 'alpha'=>10, 'color'=>"000000", 'thickness'=>0 );
$chart[ 'chart_grid_v' ] = array ( 'alpha'=>10, 'color'=>"000000", 'thickness'=>20 );
$chart[ 'chart_rect' ] = array ( 'x'=>50, 'y'=>50, 'width'=>320, 'height'=>200, 'positive_color'=>"ffffff", 'positive_alpha'=>30, 'negative_color'=>"ff0000"'negative_alpha'=>10 );
$chart[ 'chart_type' ] = "stacked bar";
$chart[ 'chart_value' ] = array ( 'prefix'=>"", 'suffix'=>"", 'decimals'=>0, 'separator'=>"", 'position'=>"cursor", 'hide_zero'=>true, 'as_percentage'=>false, 'font'=>"arial", 'bold'=>true, 'size'=>12, 'color'=>"ff8888", 'alpha'=>100 );$chart[ 'draw' ] = array ( array ( 'type'=>"text", 'color'=>"000033", 'alpha'=>25, 'font'=>"arial", 'rotation'=>0, 'bold'=>true, 'size'=>30, 'x'=>0, 'y'=>0, 'width'=>380, 'height'=>295, 'text'=>"CMS Progress Report", 'h_align'=>"right", 'v_align'=>"bottom" ) );$chart[ 'legend_label' ] = array ( 'layout'=>"horizontal", 'font'=>"arial", 'bold'=>true, 'size'=>13, 'color'=>"ffffff", 'alpha'=>50 );
$chart[ 'legend_rect' ] = array ( 'x'=>25, 'y'=>15, 'width'=>350, 'height'=>5, 'margin'=>3, 'fill_color'=>"ffffff", 'fill_alpha'=>10, 'line_color'=>"000000", 'line_alpha'=>0, 'line_thickness'=>0 ); $chart[ 'series_color' ] = array ( "3b5743", "303d3d", "4c5e6f", "564546", "784e3a", "677b75" );print module_invoke('swfcharts', 'chart', $chart, $config);
?>

Now go see the pretty sample charts.

Nov 25 2006
Nov 25
Nostradamus

I began the Devbee website back in March as a way to help others by way of documenting what I have learned about Drupal and also to drum up a little bit of business for myself. The content of this site is extremely targeted, and I don't ever expect to see more than a few hundred visits a day. This definitely does not reflect the expectations, or at least hopes, of most website owners. It's typically all about bringing in as many visitors as possible to generate money through advertising or purchases. Sites interested in bringing in large numbers of visitors typically do this by spending a lot of time focusing on "search engine optimization" (SEO). Absolutely nothing can drive traffic to a site like a top placement in the search results on one of the major search engines.

Back in the day (way back during the last millennium), all one needed to do was have a simple HTML page containing relevant words or phrases and he was fairly likely to make a decent showing in results pages. In fact, this is exactly how I shifted from studying literature to building websites. I built my first homepage (don't laugh!) for fun. It was found by an employer, and I got a cool job at a major search engine. Today, it is not so simple.

Fortunately for us, as Drupal users, we have a secret weapon, Drupal itself. Drupal SEO does not require any witchcraft or elaborate HTML trickery. It's simple, and in this article, I'm going to explain how I get consistent premium search placement with very little effort.

Stumbling upon Drupal SEO

Today I discovered that an article I wrote recently is the top result for the query "opcode cache" on Google. I almost feel guilty about it. There are countless pages out there with much more information on the topic than my article, yet I'm at the top. I guess I'll just have to deal with it.

This is not unusual. I find myself on "the first page" of many searches for terms relevant to my site. And when I'm not seeing a premium placement (top-ten), it's either because the search term is very broad (e.g. "Drupal") or there are simply much more relevant pages pushing my placement down. Just like the old days.

And more than half of my very modest traffic comes through these search results.

What's the Secret?

Now comes the mysterious part. I make no claims of expertise in the area of SEO. It's mostly voodoo as far as I'm concerned. The search engines are necessarily very secretive about their methods, trying to stay ahead of search engine spammers. And what works today may be detrimental tomorrow. What I'm going to describe below is entirely based on my own, very subjective, experience with various techniques and modules. These are the things that I believe are resulting in my accidental SEO success.

Drupal SEO

Drupal itself is well-known for its search-engine friendliness. Its markup is clean and standards-compliant. It creates all the tags the engines are looking for. And unlike so many other CMSs, Drupal creates search engine friendly URLs. Using Drupal is the first step in this process, but presumably you're already doing this, so let's move on.

The Right Path

Here's an example of the URL to a Joomla forum topic: http://forum.joomla.org/index.php/topic,65.0.html

And here's an example of a URL to a Drupal forum topic: http://drupal.org/drupal-5.0-beta1

Do you notice a difference? Can you tell me anything about the Joomla article without going to the page? In fact you can, sort of: you might conclude that the page covers a topic, a fact of dubious value. The URL really provides no useful information to you. Nor does it provide anything useful to a search engine. This is key. Unless you're searching for "index topic 65.0 html", this URL isn't going to help you find the information on this page.

Looking at the Drupal URL is another story. Based on that URL, one can assume that it has something to do with "drupal 5.0 beta1", and so can a search engine. If that's what you're looking for, this page will come up #1.

Most SEO "experts" agree that the search-engine-friendly URLs are critical to a page's search ranking.

Drupal allows you complete control of the path of any page. Creating short, clean and informative paths will improve your rankings. And the Pathauto module automates the process of generating relevant paths. But be extremely careful when experimenting with Pathauto, particularly on sites with existing content. Using Pathauto without first understanding how to use it properly can result in all of the URLs on your site changing, and thereby breaking existing links to your content. If you are going to introduce Pathauto on an existing site, play it safe and enable the Create a new alias in addition to the old alias option in Pathauto's settings. But keep in mind that having multiple URLs pointing to the same page on your site may result in a search engine penalty for "duplicate content".

Sitemaps

Sitemaps are an easy way for webmasters to inform search engines about pages on their sites that are available for crawling. In its simplest form, a Sitemap is an XML file that lists URLs for a site along with additional meta data about each URL (when it was last updated, how often it usually changes, and how important it is, relative to other URLs in the site) so that search engines can more intelligently crawl the site.

I've seen no solid evidence that implementing a sitemap will directly improve search rankings. However, even if search engines do not use your sitemap to to adjust the ranking of your pages (which I doubt), it does help them more efficiently index your site, thereby increasing the likelihood of your pages being included in search results. This one's a no-brainer.

Sitemaps would be virtually impossible to maintain by hand. And this is where the excellent XML Sitemap (formerly Google sitmeap) module comes in. Installing this module is simple and comes with reasonable default settings that don't require changing unless you want to fine tune your sitemap. After you've installed and enabled this module, you'll need to tell search engines about your sitemap. At this point, I'm only familiar with Google Sitemaps, Though other major companies are beginning to adopt this concept as an new open standard.

Leaving Comments

Another common method used by search engines to determine the importance of your pages is the number of other sites that link to them. A simple way to continually promote your site while helping improve your search rankings is to make regular comments on other sites like Drupal.org. Take the time to create an account on sites similar to yours and complete your public profile. Then leave useful comments where appropriate. Do not post comments simply to include a link back to your site. This is in very poor taste and may get you blocked. Instead, post comments where you have something to contribute to the topic being discussed. If you have nothing useful to add, don't post a comment. I'm a regular participant over at Drupal.org, and I'm confident this helps the "relevance" of my own site.

Page Title

By default, Drupal will use the title of your node as the page HTML title (the bit that appears in the <title></title> tags of the HTML and shows up in the title bar of your browser). This is very reasonable behavior. However, if you want to give your page that extra SEO boost, you may want to allow for two different page titles, one that appears at the top of the page in <h1> tags and the other that appears in the head of the HTML document in the <title> tag. the <h1> and <title> tags are both pieces that search engines will consider when reviewing your page. If they are identical, you're missing out on an opportunity to further promote the page!

So how do you manage to control the <title> tag contents if Drupal automatically sets it based on the node title? The Page Title module does this. Install and enable this module, and you will see an additional field on the node edit form called "page title". Use this field to configure the phrase that you think will most likely attract users to the page. Use something eye catching and alluring, something the user will feel he has to read. If you're writing about an article you found on another site, don't title the page "cool link!", instead, something more enticing: "Fascinating study of the Indonesian spotted tadpole". Follow that up with a relevant <h1> title: "National Geographic looks at one of nature's most mis-understood wonders".

The Prophecy

Search result placement was not a top concern of mine when I built this site. But it has become a bit of an obsession now. I have no need to drive thousands of visitors seeking information on opcode caching to my site, but hitting that number one position for a query is a bit of a rush! Thanks Drupal!

Lastly, I asked myself a question as I wrote this article: Is there anything at all to what I'm saying? Well, I think there is, and I'm willing to make a bold prediction based on this belief. Within three days of posting this article, I believe it will appear in the top-ten search results for "Drupal SEO" on Google. If I'm right, that should serve as some pretty solid evidence that there's something to all this. There are currently 1,090,000 pages competing for placement in this results page. The odds of making it into the top-ten by shear luck are 1 in 109000.

And if I'm wrong, well, I can always come back and edit out this prediction to save face %^)

The Revelation

Update: Mon Nov 27 23:19:42 2006

A search for "Drupal SEO" now shows this article as the second result out of 1,080,000 pages. I come in just below an article on Drupal.org.

So as you now see, there is not a lot of work involved in getting premium search placement if you are using Drupal. Of course, the broader your topic, the more difficult it will be to hit the top-ten. While you can almost certainly hit number one for surfers searching for a certain rare antiquity, your less likely to see much success attracting surfers hunting for the term "sex".

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

 

 

Apr 21 2006
Apr 21

This article explains a practical implementation of a technique outlined in the article "Sharing Drupal tables between databases using MySQL5 Views".

Problem

You have multiple (multisite) Drupal sites and you would like to manage the content for all of these sites through a single interface. Depending on the nature of a given piece of content, you may want the content published on one, several or all of your subsites, but you do not want to have to create copies of the same content for each site.

Solution

Taxonomy plus MySQL5 views. (NOTE: this solution will not work with versions of MySQL prior to 5.)

Assumming you have your subsites properly set up and running, the first step is to create a special vocabulary which you will use to target content.

Go to [your site's baseurl]/admin/taxonomy/add/vocabulary and create a vocabulary. We'll call it simply "sites".

Next, go back to your taxonomy page (/admin/taxonomy) and select "edit vocabulary" for the "sites" vocabulary.

Add a name for each of the subsites you would like to manage. For our example, we'll have two subsites, "foo" and "bar", and one master site, "master".

Now add at least three pieces of test content. Target one piece of content for each of foo, bar and both.

Next, we're going to create a node view for each of our subsites that we'll use to replace the actual node table.

The SQL is as follows:

CREATE VIEW [subsite, eg. "foo"]_node AS SELECT n.* FROM node n, term_data td, term_node tn, vocabulary v WHERE v.name = '[vocabulary name, eg. "sites"]' AND td.vid = v.vid AND td.name = '[subsite vocab term, eg. "foo"]' AND td.tid = tn.tid AND n.nid = tn.nid ;

Because the terms that serve as our subsite labels may very well exist within other vocabularies, we also need to join on the vocabulary table to ensure our solution works reliabley.

Finally, we need to have our subsites use the views we have created instead of our master nodes table, which only the "master" site will have access to directly.

In your drupal's sites directory, you should have directories that correspond to each of your drupal sites (both master and subsites). Edit the settings.php file for each of your subsites, and use the db_prefix variable to point the site to your view. So sites/foo.example.com/settings.php would contain the following:

$db_prefix = array( 'node' => 'foo_', );

At this point, you'll want to disable creation of content from within each of your subsites. You can do this in the from the admin/access page. If you attempt to create content from within the subsites, you'll likely get a 'duplicate key' error.

I hope that explanation is clear. These articles are written rather hastily. If you questions or suggestions regarding this solution, please leave a comment.

Apr 11 2006
Apr 11

Drupal is an open-source Content Management System (CMS), which is particularly suited to customization through use of blocks, themes and modules. Drupal's innovative use of taxonomy and its unique menu system allow for effective management of content as a site grows or evolves.

Driving the ongoing development of Drupal is the desire for a simple and powerful framework which developers can work within to create custom web applications without having to build the pieces that nearly all websites have as a foundation (user authentication, content creation interface, layout managment).

And unlike other similar CMSs, Drupal takes its role as a framework very seriously. Take a look at the database structure of any other CMS that has been around for a while, and you'll almost certainly find a labyrinth of tables with mysterious names and seemingly redundant purposes. Drupal's database design is clean and constantly being re-factored. Tables that have outlived their purpose are removed from the schema and the code. Table design is very generic, allowing different types of content and modules to share the same table space.

Drupal also has an actual API. It too is refactored on a regular basis as the web and user needs change. Drupal 4.7, for example, has a completely redesigned Forms API which now allows developers a much broader reach into the entire Drupal framework, allowing her to tweak parts of Drupal that were previously pretty much set in stone.

From a webmaster's point of view, Drupal may not have the most eye-candy or largest feature set when compared to other CMSs. However, there's virtually nothing that can't be built into Drupal, making it the most flexible CMS out there.

Go with Drupal, and you will have no regrets.

Mar 25 2006
Mar 25

Ok, ok, maybe there actually is something to this Web2.0 business. A lot of the Web2.0 hype stems from the maturation of blogging, the software that helps people blog and RSS. All of these are good and bad things. Good in that there's more information available to more people today than ever before. Bad because there's more information available to more people today than ever before. Even before the term "blog" was coined, people were publishing personal journals, ramblings and general rants on the web. It was as true ten years ago as it is now, most of this content is... well... not very interesting to most people. Maybe it's poorly written blather about why someone hasn't posted poorly written blather recently. Or maybe it's well written content on a very specialized topic that is only relevant to a small number of people.

Good, bad, relevant, meaningless, it's all out there somewhere. The key to finding it is RSS. I used to subscribe to the Los Angeles Times. I'd poke through it every day and read a sentence or two and then tossed it in the recycling bin. The fact is, my interest in polotics, world affairs, sports, gardening, real estate and used cars is pretty limited, and that's all you're going to read about in most newspapers. My interests are elsewhere. Software programming, guns, literature, skiing, and so on. The best way to feed my desire for information is to turn to the web. But turning to the web for information is like visiting Niagra Falls for a sip of water. It's just too much. You need something like Google, Yahoo or now RSS to filter the information for you.

Will Web2.0 ever mean anything? Absolutely. I believe Web2.0 will eventually become something even grandma can understand. Presentation will be fast and flexible (AJAX, DHTML). Content will be tightly filtered with RSS. Folks can easily take advantage of all this stuff now with sites such as Bloglines, Feedster (update: now dead) and Feedburner. And all of this falls under the annoying label of Web2.0. This site is dedicated to Drupal. One of the things I wanted to provide was an aggregate feed of the most relevant Drupal news available. So using Drupal's aggregator module, I began creating the Drupal news page. You'd think that would be a simple task, but it isn't. With so many feeds, and so many feeds of feeds, and so much information available, pulling down just the right content is still very hard, and I still don't have the desired page I want. But the fact that it is even possible is something I'm very excited about. Here's a link to the story I was going to originally write about before my ADHD kicked in: The bottom line on blogging.

Mar 24 2006
Mar 24

Problem:

You have a "master" database that contains data from multiple Drupal sites and you want to share it among them. Normally, you could use table prefixing to allow each of your sites to point to a single table. But what if you do not want content from one site to "bleed" across to the other sites? Let's say you have a network of Drupal sites sharing a user database. You want to share that user's information across your entire network of sites, but only make the information visible from those sites to which the user has subscribed. Or maybe you want to populate baz.com with users who meet some arbitrary criteria. There are lots of possibilities here, but nobody's paying me to write this, so let's get on with it.

Solution:

Use MySQL5 Views. For our example, we'll use the users table. Our "master" users table (the table that contains all users for all of our sites) resides in a database called "master". The database of the our example site that will have restricted access to our masters users table is called "banana". Assuming you're starting with a fresh instance of the Drupal schema in your database "banana", do this:

use banana;
drop table users;
CREATE VIEW users AS
SELECT *
FROM master.users
WHERE uid IN (
SELECT uid
FROM somedatabase.sometable
WHERE uid = 0
OR label = 'foo'
)

Drupal will use banana.users just as it would a normal users table. No other modifications are necessary. Now only "foo" users will be included in the users table for your banana website. Note: Drupal has a dependency that is not really documented. Every users table must have an entry that contains uid=0. It's a "stub" entry that Drupal needs to function properly when a user is anonymous. A workaround for this dependency is to include "user 0" in the results set that defines your view. See, wasn't that easy? Please post questions here, and I'll update these instructions as needed.

Mar 15 2006
Mar 15

Today, the folks over at Performancing.com announced the realease of Performancing Metrics, a free new service for tracking statistics for Blogs. Best of all, it's all in Drupal. OK, I'll come clean, I was involved in this project. My primary role was integrating Performancing's existing website with the Metrics tool. The entire toolset runs behind a single Drupal module that acts as a wrapper for what are essentially standalone PHP scripts.

Disclosure out of the way, I've also been using this tool for some of my own websites for the last month or so. When Google Analytics launched, I was able to get an account before they blocked new subscribers due to load issues. I've been monitoring my sites with Google Analytics for about four months. It seems to be a very powerful tool, but to be honest, I don't understand how to use it. There are just too many views and parameters and summaries. Using it, I feel like I did when I first used Vim or MS Word or Paint Shop Pro, overwhelmed and confused. Hey, I just want to write a letter to Mom, and I'm staring what looks like the cockpit of a 747. Similarly, when I look at website stats, I just want to see how many folks are visiting, where they come from, how long they stay, what they like, whether they bothered to leave comments, etc... I don't need a pivot table detailing gross ROI per visitor vectored over a decreasing granular matrix margin. Eeeek! Just show me the big pic and let me get on with my day.

If you're like me, you'll appreciate this new tool. It's light on eye-candy and heavy on simplicity and quick access to what you want to know. It's also somewhat addictive.

To use it, you'll need to sign up over at Performancing.com. Then all you have to do is paste a bit of javascript into your Blogs pages (via templates or footer configuration).

What distinguishes this tool from others is that it's focused on Blogs. The javascript you use will vary depending on which blogging software you're using. This way the javascript is able to glean information from your site that other trackers simply can't. Author names, Comments, Posts, etc...

We're working on making this embedded javascript tracking more effective and specific to the various blog systems, but even this beta version of Performancing Metrics is worth the effort of signing up.

You'll also find lots of cool articles regarding professional blogging. Even if this isn't how you make your living, there is some excellent information that non-professionals can use. Stuff like how to bring more people to your site and how to "monetize" your website more effectively.

Check it out.

Mar 14 2006
Mar 14

Web2.0 is now, and it's here. If you're not Web2.0, you're out like 2005. If you have to ask, you wouldn't understand.

Well, I have to admit, I need to ask. In fact, I have several questions about all this Web2.0 fanfare.

Why should I upgrade? How much will it cost me? How come nobody has it in stock when I try to buy it?

I've been making my living doing web stuff since 1996, and I never got my copy of Web1.0. I didn't even realize it had been released. Now I just sit and nod in meetings where people talk about "synergistic solutions", or throw in a "user comprehensible value prop" in such a way that you just scratch your head and think it must mean something. "This needs to be Web2.0" is a favorite of mine. Whatever Web2.0 is, obviously it's critical to the success of new projects. (I need to remember to remember that for my next project.)

Who owns Web2.0? For now, I guess the safe assumption is that Google does. That would explain both all the ballyhoo as well as the mystery surrounding this next generation breakthrough. Ask someone at work what Web2.0 is and you'll likely get the curly brows and a loud "Pffft!", in which case you just give them a, "... I guess some of the folks in this meeting haven't gotten the Web2.1 pre-release yet ..." and give them the reverse curly brows and a subtle sigh.

Look around for Web2.0 and you will no doubt find everyone talking about it, but you're not likely to actually find an example of it. I found no screenshots on Google Images. No info on where to order it or how to install it. However, I do think I'll be able to recognize it once I find it. I know it will have an "API". I know it will also be very clean because it requires Ajax. It will probably involve pastels contrasted with ridiculously bright primary colors.

It will also have a very fancy look to it. I imagine the email icon above probably isn't very Web2.0. (though I'm not claiming to be a Web2.0 authority, of course.

And I'm sure all the experts would agree that this RSS icon is definitely Web2.0.. However, my failure to convert the white background to transparent is probably more web 1.1 or so.

If you know as little about Web2.0 as I do, I wouldn't worry about it too much. If there's anything to it, I'm sure we'll all be getting 3000 free hours of it in the mail from AOL real soon.

Mar 10 2006
Mar 10

Rumor is spreading of some sort of new analytics tool from the blogging experts over at Performancing. This tool utilizes Drupal and is designed specifically for bloggers. It's a tool similar to others like Google Analytics and Sitemeter. What makes it different is that it is designed to track blogs specifically. Read more about it at Performancing, Problogger and Code Professor.

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