An important feature of Drupal 7 is the clean separation between the structure of elements created by modules and the rendering of those elements by themes. One cool thing is that a module can provide suggestions for the theme hook which should render an element. This gives theme writers an opportunity to override the theme for very specific elements in a module, and provides for more generic fallback themes otherwise.

The theme hook suggestions are lists of increasingly specific keys separated by a double underscore, for example node__mymodule__block5. The first entry, node here, is a top level hook defined by a hook_theme function. When the theme function is called, the theme system will try the most specific hook first, in this example node__mymodule__block5. If that doesn’t exist, it will try the next hook, node__mymodule, and so on until it gets to the top level hook. Themes that implement these specific hooks with template files will replace the underscores with hyphens, so node__mymodule__block5 would be rendered by node--mymodule--block5.tpl.php.

Module developers can set a theme hook suggestion for an element by using the #theme key of a render array. The keys of the render array will have to include any parameters that the top level hook requires. These parameters are defined when the hook is declared. Hooks in Drupal core have their parameters in the Drupal API, and hooks from custom Drupal modules should be documented in the module. Here is a nice list of default theme hooks in Drupal core

Here is an example that creates a list using a theme suggestion derived from the Drupal core hook item_list, getting the elements from some function get_items.


function mymodule_block_view($delta = "")
{
    $block = array();
    $block["subject"] = t("My Awesome List");
    $block["content"] = array(
        // item_list is the Drupal core theme hook for unordered or ordered lists
        "#theme" => "item_list__mymodule__awesome_list",
        // #type and #items are parameters for the item_list theme
        "#type" => "ul",
        "#items" => get_items(),
    );

    return $block;
}