Theming the Akismet spam counter

Filed under:  Google about "Akismet" |  Google about "Drupal"

If you are happy with the job being done by Akismet, then you may wish to display a link back to the Akismet site. To do so, the Akismet module for Drupal comes with the "akismet spam counter" block and a number of options that you can use to customize how it looks. There are also some hidden features behind this block that I would like to document here. First, I would like to mention the obvious features, then I'll try to describe how is it possible to display this information exactly as you wish.

Block Options

  • You can create as many blocks as you may need from the module settings page (screenshot), should you wish to display the spam counter in different sections of your site, with different looks or layouts.

  • You can also tweak the counter itself and the format of the counting since date from the Spam counter options section of the same page (screenshot).

  • Each block has a number of parameters that offer a basic set of options (screenshot) to configure its particular look.

  • If that is not enough for you, then you may wish to theme the blocks to use your own markup, a powerful Drupal feature, and here is where the fun begins. I'll focus what follows in phptemplate based themes (phptemplate is Drupal's default template engine since 4.7).

Theming with PHP Template

  • Drupal's phptemplate engine already overrides the most common theme functions: page, node, comment, box and block. However, you can override any other theme function provided by either core or contrib modules. To do so, you need to create a file named template.php in your theme directory that may start as follows:

    <?php
    /**
     * template.php
     *
     * This file contains functions for overriding the default theme functions
     * in Drupal core and modules (look at the API documentation for more info).
     * The functions don't actually _do_ anything, except pass the variables
     * available to phptemplate for use in the *.tpl.php files.
     */

    Then you need to create, in this file, a copy of theme function that you wish to override changing the prefix of the function name from theme_ to phptemplate_. Now you can modify the contents of that function to suit your needs or replace its contents with code that will be used to invoke an external file. That is how the engine works to invoke those *.tpl.php files that exist in your theme directory. This is what we'll do next.

  • Edit your template.php file and append the following code:

    /**
     * Override theme_akismet_counter_block() from modules/akismet.module
     *
     * @param array arguments where each element is:
     *              content: String; the completely built block content.
     *              counter: Integer; the current spam counter.
     *              since   : String; the formatted 'counting since' date.
     *              text     : Array; with 2 subarrays defined as follows:
     *                             plain: Array with 2 elements ('short' and 'long').
     *                             html : Array with 2 elements ('short' and 'long').
     *              image  : String; the completely built IMG tag.
     *              block   : Array; Block settings.
     * @return string The content of the block.
     */
    function phptemplate_akismet_counter_block($args) {
      
    $variables $args;
      
    $variables['delta'] = $args['block']['delta'];
      return 
    _phptemplate_callback('akismet_counter_block'$variables);
    }

    The function _phptemplate_callback is part of the phptemplate engine and is the one who will find and load an external file (in this case, named akismet_counter_block.tpl.php) where it is much easier to work with your theme snippet.

  • Now create a file named akismet_counter_block.tpl.php and copy/paste the following code:

    <?php
    /**
     * Generate the markup for the Akismet spam counter block.
     *
     * The variables available to this block are:
     *   delta   : Integer; zero based block counter.
     *                           ie. the first spam counter block is delta = 0,
     *                           the second one is delta = 1, and so on...
     *   content: String; formatted block content (as defined by block parameters).
     *   counter: Integer; the current spam counter.
     *   since   : String; the formatted 'counting since' date.
     *   text     : Array; with 2 subarrays defined as follows:
     *                    plain: Array with 2 elements ('short' and 'long').
     *                    html : Array with 2 elements ('short' and 'long').
     *   image  : String; the IMG tag that points to the image akismet.gif
     *                           provided with the module itself.
     *   block   : Array; Block settings (see akismet.module for details).
     */
    switch ($delta) {
      case 
    0:
        print 
    '<p>'$text['html']['long'] .'</p>'$content;
        break;
      default:
        print 
    $content;
    }

    In this example, the first spam counter block (delta=0) will have a different look than any other block. The long version of the HTML text is displayed just before the block content as defined in the block configuration panel (screenshot). The result of this can be seen on the right sidebar of this site (just below the Google Ads).

Displaying the counter from other theme snippets

  • Here's another way to show the akismet spam counter information. The module provides a couple of functions that you could invoke from any code snippet: akismet_get_spam_counter() and akismet_get_counting_since()

  • As in example, here's the code snippet I'm using in the footer of this site:

    $output 'Website powered by <a href="http://drupal.org">Drupal</a>';
    $output .= ', designed by <a href="http://www.phpmix.org">phpMiX.org</a>';

    if (
    function_exists('akismet_get_spam_counter')) {
      
    $output .= t(', proudly protected by <a href="http://akismet.com">Akismet</a>, %count spam caught since %since',
        array(
          
    '%count'=> akismet_get_spam_counter(),
          
    '%since'=> akismet_get_counting_since()
        ));
    }

    echo 
    $output;

    Note the use of function_exists. This is to avoid PHP errors if the module was disabled.

That's all there is here. Check out the Drupal handbooks for more information about themes and code snippets. It might look a bit complex at first, but this is one of those things that may help to make your site a bit more different, original, unique. ;-)