I have overridden the theme_breadcrumb function by using mytheme_breadcrumb() in my template.php file. However I want to move this function to a module. But when I put it in a module and changed it to mymodule_breadcrumb() it wasn't called. So how do I override theme functions from a module?

Comments

maxferrario’s picture

Overriding themable output says:

The "Drupal Way" is to do an override. This involves four basic steps:
1. Locate the module responsible for the markup
2. Do one of the following:
* If the module provides a template (tpl.php file), copy the template to your theme directory. See Core Templates and Suggestions for a list of core templates. OR...
* In the module code, identify the theme or preprocess function that is generating the markup you want to change and copy the function to your theme's template.php file. You will need to change the "theme_" or "template_" prefix to match the name of your theme. For example, "theme_breadcrumb" would become "mythemename_breadcrumb"; "template_preprocess_page" would become "mythemename_preprocess_page".
3. Within the copied function or template, change the HTML code to suit your needs.
4. Refresh the theme cache.

And take a look to Beginners guide to overriding themable output too!

In short, I think the answer to your question is no... but please note that I just had a quick look to both pages!

ltwinner’s picture

That is for overriding theme functions in template.php. I am looking to override theme functions in a module. How do I override theme_breadcrumb in mymodule.module?

maxferrario’s picture

As I'm not a Drupal guru, I might well be mistaken.
But if you think about it, bradcrumbs (and all theme_ stuff) is a display thing, so overriding if in a theme looks like the perfect way to do it!

ltwinner’s picture

Yeah, there is no problem overriding it in template.php. I want to override it a module though because I want to split up my code -
All the main theme functions such as page, node, comment, etc... in template.php and the rest of them in mymodule.module. It's just for usability sake.

ltwinner’s picture

I have just run into the exact same problem again now that I am theming the pager. Does anyone here know how to override a theme function in a module?

ltwinner’s picture

I have a module called mymodule.

How do I override theme_pager in this module? I presume the function has to be registered by hook_theme()...Can someone give me a code example of how to override theme_pager in mymodule.module. Surely someone must know how to do this?

Here's what I've done and it doesn't work obviously -

<?php
function mymodule_theme(){
  return array(
    'pager' => array(
      'arguments' => array($tags => array(), $limit => 10, $element => 0, $parameters => array(), $quantity => 9),
    ),
  );
}

function mymodule_pager($tags = array(), $limit = 10, $element = 0, $parameters = array(), $quantity = 9) {
...
...
...
}

?>

I've flushed the theme registry. mymodule_pager() is not getting called, what is going wrong with this code?

joshuautley’s picture

You helped me! (=

Josh Utley, President & CEO
Intrepid Network Inc. | Multimedia Services & Business Solutions

"Our mission is to provide a more personable multimedia service along with the highest quality business solutions."

dubs’s picture

I don't know if you're still interested, but here's a very useful article about this: -

http://shellmultimedia.com/articles/hookthemeregistryalter-advanced-temp...

If you implement the code in these examples, it should achieve exactly what you require. It worked for me.

fietserwin’s picture

I managed to do this, using just the hook_theme instead of using the hook_theme_registry_alter. The example that follows overrides the way a term page is rendered (taxonomy/term/%):

/**
 * Implementation of hook_theme().
 */
function mytaxonomy_theme() {
  return array(
    // override default implementation from taxonomy:
    // show a term with its additional fields, children, and teasers from nodes tagged with this term
    'taxonomy_term_page' => array(
      'file' => 'mytaxonomy.pages.inc',
      'function' => 'mytaxonomy_theme_taxonomy_term_page',
      'arguments' => array('tids' => array(), 'result' => null),
    ),
    // ... other themeing functions
  );
}

Note: to avoid function name clashes with the original theme function from taxoniomy.pages.inc, I had to rename my theme function, and thus pass in the 'function' parameter. The 'file' parameter ensures that the file where in the function is defined is included.

After cleaning the cache registry, it worked fine.

abaddon’s picture

i think your way depends on module run priorities (name, weights in the system table).. i think hook_theme_registry_alter is the proper way to replace a theme function from a module

[edit] heres the link, i knew i read this somewhere: http://www.lullabot.com/articles/overriding-theme-functions-in-modules

dnewkerk’s picture

Fantastic! Works great in Drupal 7. Finally I can remove a ton of "heavy lifting" PHP from my template.php (and easily share it among my sites and other themes). I've never been a fan of how much complex PHP tends to end up at the theme layer, often with the goal of altering Drupal's HTML output, adding classes, etc. I prefer to keep the theme layer light.

Thanks for the link :)

Gik000’s picture

I managed to do this via theme_registry_alter

In your module implement the hook like this

/**
 * Implements hook_theme_registry_alter().
 */
function MYMODULE_theme_registry_alter(&$theme_registry) {
  $theme_registry['menu_local_action']['function'] = 'MY_NEW_FUNCTION';
  $theme_registry['menu_local_action']['includes'] = array();
  $theme_registry['menu_local_action']['theme path'] = drupal_get_path('MYMODULE','umnw_local_task');
}

The function should be a copy of theme_menu_local_action

function MY_NEW_FUNCTION($variables) {
  $link = $variables ['element']['#link'];

  $output = '<li>';
  if (isset($link ['href'])) {
    $output .= l($link ['title'], $link ['href'], isset($link ['localized_options']) ? $link ['localized_options'] : array());
  }
  elseif (!empty($link ['localized_options']['html'])) {
    $output .= $link ['title'];
  }
  else {
    $output .= check_plain($link ['title']);
  }
  $output .= "</li>\n";

  return $output;
}

Anyway I'm not able to pass "options" to MENU_LOCAL_TASK ... and I'm still finding a solution.

I know that documentation states:

Note that the "options" parameter has no effect on MENU_LOCAL_TASK, MENU_DEFAULT_LOCAL_TASK, and MENU_LOCAL_ACTION items.

but I need this behavior!