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 28 2008
Nik
Feb 28

This snippet of code gives a brief example of how to rewrite components of the $links variable to make them prettier :) Specifically, here I’m overwriting the link generated by the Forward module. You can see the result below: the little envelope icon labelled “Email”. Normally, this would just say “Forward this page”, which is a bit… well, it could be better. Obviously, it’s nice to be able to change these things to taste.

There are two ways to achieve this result: using theme code in template.php, or inside of a helper module. First, I’ll discuss the module approach.

The helper module method is what I had originally used. It’s a little neater, in that you code it once and forget about it, and it doesn’t clutter up template.php’s _phptemplate_variables function, which can easily become bloated with code.

In the module, I’ve added a function to implement Drupal’s hook_link_alter() function. Here’s the code to do it:

<?php
function mymodule_link_alter(&$node, &$links) {
  foreach (
$links as $module => $link) {   // iterate over the $links array
    //drupal_set_message(print_r($links)); // uncomment to display your $links array

    // check if this element is the forward module's link
   

if ($module == 'forward_links') {
     
$title = t('Email this page to a friend');    // change the title to suit
     
$path = path_to_theme() . '/images/email.png' // make an image path

      // now update the links array
      // set the title to some html of the image and choice of link text
     

$links[$module]['title'] = theme('image', $path, $title, $title) . ' Email'; // let's set some attributes on the link
     
$links[$module]['attributes'] = array(
       
'title' => $title,
       
'class' => 'forward-page',
       
'rel' => 'nofollow',
      );
// this must be set, so that l() interprets the image tag correctly
     
$links[$module]['html'] = TRUE;
    }
  }
}
?>

Ok so really, this ought to be done in the theme layer. Like I said, it’s perhaps not as compact and neat, but here’s the code. It’s mostly the same, but note a couple of additions and changes: firstly, we are not changing $links – this is a pre-rendered string by the time it gets to the template.php. We need to get to the original goodies! Hence, we use $vars[&#039;node&#039;]-&gt;links[module-name][field-name].

Secondly, note that because we have now altered the value of one of the original links’ values, does not mean that the node’s $links is correct. This is the bit that caught me out! We must now regenerate the $links variable using the theme_links() function, as per the last line of code below. This mimics what phptemplate.engine does in core.

<?php
function _phptemplate_variables($hook, $vars = array()) {
  switch (
$hook) {
    case
'node':
      foreach (
$vars['node']->links as $module => $link) {
        if (
$module == 'forward_links') {
         
$title = t('Email this page to a friend');
         
$path = path_to_theme() . '/images/email.png';
         
$vars['node']->links[$module]['title'] =
             
theme('image', $path, $title, $title) . ' Email';
         
$vars['node']->links[$module]['attributes'] =
              array(
'title' => $title, 'class' => 'forward-page', 'rel' => 'nofollow');
         
$vars['node']->links[$module]['html'] = TRUE;
        }
      }
     
$vars['links'] = theme('links', $vars['node']->links,
                                           array(
'class' => 'links inline'));
      break;
  }
}
?>

You can achieve this effect for anything that’s in the $links array. On this page (below), you can see the link I’ve described here, another for print-friendly pages and also a themed comment link.

Feb 27 2008
Nik
Feb 27

Currently there are three options for creating error pages in the Drupal system, that I know of. I’m going to show here which I think is the best, for reasons of usability, performance and general webmaster sanity. At the foot of this article, there’s some free code too!

The options:

Drupal’s build in error page support

Drupal provides, out of the box, two fields in the Error Reporting configuration screen. These fields can be set to any internal Drupal path. Usually, they will be set to point the user to a page created specifically for the purpose.

The downside to this is that these will now be nodes in the system, and as such they will show up in popular content lists, site searches and the like. This is clearly not desirable.

Update: I have been made aware of an outstanding issue in Drupal core with error pages. This issue means that a user without “access content” permissions cannot access 403 error pages that are created as nodes. This is true in Drupal 5.x and even 6.1, and is another weak point for this mechanism.

Search404 module

Until very recently I was using search404 but I became less than pleased with the results. To start with, I thought I was aiding usability, but as it transpires… not really. The real killer for me is that search404 often gives me empty search result sets, because the path elements just don’t relate specifically enough to the content.

For instance, the node “/blog/my-drupal-article” will almost certainly contain all the words “my drupal article”, but may not contain the word “blog”, except in the path. This means the search doesn’t catch that article, so you get no results. Given that every 404 page the module generates incurs a DB query automatically, this query is effectively just trash, but cannot be disabled.

Customerror module

Customerror module skirts round the issues of having nodes as error pages. The module makes error handling pages available as custom paths inside Drupal. These aren’t nodes, so we have no issues there.

The configuration screen offers up two textarea fields which will contain the page content to be rendered on each of the 403 and 404 page errors. The key to making this more special than just a plain text or html page is the availability of PHP processing for these fields whilst not requiring nodes for the task.

Ok, so what I’m doing here is recommending customerror as the best choice for this task. That said, let’s throw down some code and make this more useful.

To start, visit the standard Drupal error reporting page at “/admin/settings/error-reporting”. Here, set the default error page fields to “customerror/403” and “customerror/404” respectively, if you’re going to override both these pages.

Now, on the Custom Error module’s config page at “/admin/settings/customerror”, enable both checkboxes that say “Allow PHP code to be executed for 40x”. Now let’s look at handling the 404 error. I’ve added the following code for this site, in the “Description for 404” textarea, and a suitably snappy title in the other field: “404 Not Found Error: No content found at the requested URL”.

<p>Sorry, no content was found at the requested path - it's possible that you've requested this page in error.</p>

<p>Use the search form below, or go to the <a href="http://www.kinetasystems.com/">home page.</a></p>

<?php
// check that the search module exists and the user has permission to hit the form
if (module_exists('search') && user_access('search content')) {
 
// cool! - customerror doesn't trash the page request and the full path is available
 
$path = $_REQUEST['destination'];
 
// bin anything that's not alphanumeric and replace with spaces
 
$keys = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', ' ', $path));

  // retrieve the search form using the data we've pull from the request
  // note that we can override the label for the search terms field here too
 
print drupal_get_form('search_form', NULL, $keys, 'node', 'Search terms');
}
?>

In the 403 error fields, we adopt a similar technique. I’ve used “403 Forbidden Error: Access to this page is denied” for the title. Here we display different content depending on whether or not the user is logged in. If you’re running a site with lots of members, you can uncomment the user login line towards the bottom and the login form will be rendered on the 403 page!

<?php global $user; ?>
<?php if ($user->uid): ?> 
  <p>Sorry <?php print $user->name; ?>, you don't have permission to view the page you've just tried to access.</p>
  <p>If you feel that you have received this message in error, please
    <a href="http://www.kinetasystems.com/blog/creating-custom-error-pages-in-drupal/contact">contact us</a> with specific details so that we may review your access to this web site.</p>
  <p>Thanks</p>
<?php else: ?>
  <p>This page may be available to clients and registered users only. Please select from one of the other options available to you below.</p>
  <ul>
    <li><a href="http://www.kinetasystems.com/user/login?<?php print drupal_get_destination(); ?>">Login</a> to view this page</li>
    <li>Use the <a href="http://www.kinetasystems.com/blog/creating-custom-error-pages-in-drupal/search">search</a> facility</li>
    <li>Go to the <a href="http://www.kinetasystems.com/">home page</a></li>
    <li>Go to the <a href="http://www.kinetasystems.com/blog/creating-custom-error-pages-in-drupal/sitemap">site map</a></li>
  </ul>
<?php //print drupal_get_form('user_login'); ?>
<?php endif; ?>

Now we’ve got friendly, usable error pages that are helpful and don’t scare off visitors!

Updated 24th April 2008

Feb 07 2008
Nik
Feb 07

Recently released – a Javascript aggregator module for Drupal 5. This function is included in core in Drupal 6, but users of 5.x are left hanging on. Enter, the Javascript Aggregator module.

I put this onto my own site straight away to test it out, as I’m using shared hosting at the moment, and I want to reduce page load times as much as I can. It seems to work just fine. The module requires no core patches, and also includes an interface for file exceptions, as TinyMCE (natch) causes the module to fail.

Theming purists should maybe note the issue I filed here, which clears up a problem with having to add unnecessary PHP into the page.tpl.php file. It looks like this will get sorted and patched fairly soon, though [Edit: that’s fixed]. This is another great way to speed up Drupal page load times!

Posted by Nik - February 7th, 2008 at 11:58am

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

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