This seems like a very simple one and yet I can't find the answer on google.

Say I want to make my own implementation of theme_table so that all tables all over the site will show my table.

To do this in a theme is very easy

function MYTHEME_table(){}

but how do I do this with a module?
hook_theme_registry_alter()? - this looks a bit hackish to me..
Does drupal have some kind of function-naming convention for this?

thanks

Comments

tce’s picture

I would say using hook_theme_registry_alter() is fine. I've read plenty articles in the past that recommend doing it that way.

jamesbenison’s picture

Theme hooks should be able to be overridden. Unfortunately it appears that there is some uber secret code recipe for doing it. I've just wasted hours on a similar time toilet.

For instance, it should be possible to take:

$vars['items'][$delta] = array(
  '#theme' => 'image_formatter',
  '#item' => $item,
  '#image_style' => $image_style,
);

And instead use:

$vars['items'][$delta] = array(
  '#theme' => 'image_formatter__MYMODULE',
  '#item' => $item,
  '#image_style' => $image_style,
);

However, example above and declaring:

function theme_image_formatter__MYMODULE($variables) {
  /* my custom code */
}

Does not work. No variation of declaring a theme function seems to work either. And yes I am rebuilding the theme registry.

This is not the first time I have run into this kind of problem. It's the type of thing that leads to ugly code hacks going into modules to make them work.

Does anyone have an answer to what should be this simple and well documented question?

Web Assistant’s picture

Hi jamesbenison, though your question is not exactly related to the OP question (as they are wanting all tables overriding), what I would try is the following.

<?php
$vars['items'][$delta] = array(
  '#theme' => 'image_formatter__SOMENAME',
  '#item' => $item,
  '#image_style' => $image_style,
);
?>
<?php
function MYTHEME_image_formatter__SOMENAME($variables) {
  /* my custom code */
}
?>

I don't think it matters what name you add to the end of the callback (though using your module name keeps things tidy, as you'll know already!), just as long as the hook name is MYTHEME rather than THEME, eg:

<?php
function bartik_image_formatter__SOMENAME($variables) {
  /* my custom code */
}
?>

Also, the OP is asking for theme functions to be overridden by the module rather than the theme, hence the answer they got to use hook_theme_register_alter, unless you know if this has changed in D7?

jamesbenison’s picture

I am talking about overriding core theme functions in modules, not themes.

For an example of what I'm talking about, please refer to page 99 in the book Drupal 7 Module Development if you have it.

I'm simply trying to override these functions correctly within my modules only, not throughout the entire site or in a particular theme. Yet the recommended ways simply do not seem to work, or I'm not doing it right. Perhaps I have been overlooking something obvious, 'cause this problem has been causing me grief for quite some time.

jamesbenison’s picture

I completely forgot about this module: http://drupal.org/project/examples

Very handy resource...Absolute treasure trove.

Web Assistant’s picture

I've got the book you mention, I can't see the actual function theme_item_list__single_blog, or anything similar. I wonder if I can download any files that accompany the book? Perhaps see the full module code.

Also, did you find an example of what you were looking for in the example module? I couldn't see it.

Web Assistant’s picture

I've looked the files that came with the book (http://www.packtpub.com/code_download/6196). I can't see anywhere suggesting they meant to override in the module itself. On an unrelated note, www.packtpub.com is a Drupal site, didn't know that!

jamesbenison’s picture

But I'd be okay with crazy if it meant getting to a solution.

It should be possible to declare a theme function in a render array and have it used. That does not work.

My attempts to duplicate the examples modules have also been no joy so far.

Hasn't anyone else ever wondered why soooo much ugly html is in the preprocess functions and tpl files of drupal modules?

Web Assistant’s picture

I don't think it's possible to override theme functions using suggestions without using the theme hook. If you look at drupal_render(), it calls theme(),

<?php
  if (isset($elements['#theme'])) {
    $elements['#children'] = theme($elements['#theme'], $elements);
  }
?>

In theme(), it calls theme_get_registry() to fetch info about the theme function (which uses the ThemeRegistry class). So that tells me you have to either use the theme name as the hook OR use hook_theme_registry_alter() to override the name first.

Can't you just make your own theme from scratch in the module and use that instead?

pelach’s picture

@jamesbenison
in hook_theme()?
that should work for you.

But, I'm looking for a way to override an existing theme function and not creating a new one.
As I said in my question - overriding with a theme is no problem but what about module overriding?!

Web Assistant’s picture

@pelach, I mentioned creating a new theme function because jamesbenison said he needs to override a single output, whereas you said you want to override throughout the site (so two different cases here). My opinion is that to do what your asking, you can only use hook_theme_registry_alter(), and I don't feel it's a hack. But, this is just my opinion... someone else have a better idea.

jamesbenison’s picture

That was basically what I ended up doing. I gave up on the book example.

It seems like "theme" functions absolutely must get registered using hook theme. Only then it becomes possible to use preprocess, process, render, etc functions that apply to that theme function. However, from what I can see the example from the book above does not work.

And as stated above, to override a theme function thoughout the site hook_theme_registry_alter() is the answer.

KalleJ’s picture

I have been going mad for the same reason, the irritating page 99 example. If you ever got any further please let me know.

liquidcms’s picture

yes, super simple.. use hook_theme_registry_alter.

function MYMODULE_theme_registry_alter(&$theme_registry) {
  $theme_registry['table']['function'] = '_MYMODULE_my_table_theme';
} 

function _MYMODULE_my_table_theme($variables) {
 .
 .
 .
}