7

Drupal provides hook_theme(). But is there a hook_theme_alter()? I'm looking for something like hook_menu_link_alter(), which overrides hook menu entries, but for the theme. I want to modify a view hook theme entry so I can specify where to look for one of my custom templates. I am not interested in specifying it through the Views interface, since it look for the theme template inside the theme folder, and I want my template in a feature module.

I found hook_theme_registry_alter() and _theme_process_registry(). You can answer which one is the best to use and why.

Which of these keys should I modify in order to make the view pickup the template from the module?

If I put views-data-export-xml-header--richard-feeds-nokia-movies--views-data-export-1 in the feature, the View defaults to pick up views-data-export-xml-header.tpl.php. If I put that template in the theme layer, the view picks it up (even with the registry alter hook in place).

2 Answers 2

13

Your feature should implement hook_theme_registry_alter(). The use case you describe is exactly what that hook is for. The example code linked on the API page should get you started. The basic idea is to target the entry that corresponds to the entry that views_theme() is inserting into the registry, and change the template to match the one in your feature.

3
  • 1
    jhedstrom is right: the equivalent of hook_menu_link_alter() for hook_theme() is hook_theme_registry_alter(); _theme_process_registry() is a private function that should never be used from third-party modules.
    – avpaderno
    Commented Mar 23, 2011 at 20:18
  • It sounds logical, but it actually did not work. Refer to drupal.org/node/939462#comment-3758480. Commented Mar 24, 2011 at 0:44
  • 2
    @kiamlaluno UPDATE: Pairing hook_theme_registry_alter() with a _theme_process_registry($registry, 'phptemplate', 'theme_engine', 'mymodulename', $path); like suggested here did the trick. This issue queue has some interesting information as well. Might want to add that information to the answer. Thanks! Commented Mar 24, 2011 at 1:22
1

This is the code I use to declare a view template stored in the template folder of a custom module.

/**
 * Implements hook_theme_registry_alter().
 */
function custom_module_theme_registry_alter(&$theme_registry) {
  $extension   = '.tpl.php';
  $module_path = drupal_get_path('module', 'custom_module');
  $files       = file_scan_directory($module_path . '/templates', '/' . preg_quote($extension) . '$/');

  foreach ($files as $file) {
    $template = drupal_basename($file->filename, $extension);
    $theme    = str_replace('-', '_', $template);
    list($base_theme, $specific) = explode('__', $theme, 2);

    // Don't override base theme.
    if (!empty($specific) && isset($theme_registry[$base_theme])) {
      $theme_info = array(
        'template'   => $template,
        'path'       => drupal_dirname($file->uri),
        'variables'  => $theme_registry[$base_theme]['variables'],
        'base hook'  => $base_theme,
        // Other available value: theme_engine.
        'type'       => 'module',
        'theme path' => $module_path,
      );

      $theme_registry[$theme] = $theme_info;
    }
  }
}

You should be easily able to fork it override an existing theme instead of adding a new one. Hope it helps someone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.