2

I can't figure out how to correctly implement the theme mechanism in my module. The hook just doesn't get called, after flushing registry ofc.

My mymodule.module contains a function (this function gets called, no problem, I give it just for illustration):

function mymodule_node_view($node, $view_mode) {
  ...
  $node->content['mymodule_tocteasers'] = array(
    '#markup' => theme('tocteasers', array('tocteasers' =>  "whatever")),
  );
}

As I understand the theme mechanism, in order to render tocteasers hook, the module should implement it. Here is my module's implementation, which is not called at all, ever:

function template_preprocess_tocteasers(&$variables) {
  $variables['content'] = "something!!!";
  dsm($variables); print "hello";
}

^^I also tried function mymodule_preprocess_tocteasers(&$variables) without success

In addition, I have a file named tocteasers.tpl.php in my module directory, containing:

<div>
  <?php print "!!"; ?>
  <?php print $content; ?>
</div>

This also does not get printed or called.

Can someone plese advise me, how to make this implementation so that the tocteasers.tpl.php file is used and gets the $content variable as intended?

  • 1
    Can you show the code for your hook_theme() implementation? – Clive Mar 20 '12 at 10:04
  • I didn't implement it! (it's the first time I use this kind of theme in a module) Now all is working after implementing hook_theme. Thanks and please make an answer so I can accept. – camcam Mar 20 '12 at 11:29
  • No problem...I think @kiamlaluno has it pretty much covered though, I'd accept that one if I were you :) – Clive Mar 20 '12 at 11:48
4

What you don't report in your question is the hook_theme() implementation, which is necessary for Drupal to know the theme functions a module implements. In your case, the array returned from hook_theme() should be something similar to the following (supposing that your module defines just a theme function).

  return array(
    'tocteasers' => array(
      'variables' => array('content' => 'the default value'),
      'template' => 'tocteasers',

      // Use it only if the template is not in the same directory the module is located.                         
      // This path should be relative to the Drupal root directory.
      'path' => 'the directory where the template file is located',
    )
  );

Notice that:

  • You call the theme function with theme('tocteasers', array('tocteasers' => "whatever")), but the template file is not using $tocteasers.
  • The template filename must be the same used for the theme name; in your case as the theme function is tocteasers, the reported template filename must be "tocteasers". The extension ".tpl.php" is not used, as it is automatically added by Drupal when it looks for the template file. The only allowed difference between the theme name and the template filename is that the template filename can use "-" where the theme name uses underscores. This is because the "-" character is not allowed in a theme name, which must use the same characters used in a PHP function name. (This means it cannot start with a number, for example.)
  • If you are altering the code of an existing, enabled module, Drupal caches the data returned from hook_theme(); the result is that you had a theme function that was not using a template file, and that has been modified to use it, Drupal will not use the template file because it still referring to the old definition. hook_theme() is called in some specific cases, such as when a module is disabled, enabled, or updated. To force Drupal to update its cached data, you should disable and re-enable the module from the administration interface.
  • dsm($variables) could not show anything, if it is called too late, i.e. when the messages set with drupal_set_message() (the function used from dsm()) are already rendered. For those type of debug messages it's better to use watchdog(), which saves the message in a database table. Drupal allows to see those messages in admin/reports/dblog, and defines WATCHDOG_DEBUG for this very purpose.
  • Both template_preprocess_tocteasers() and hook_preprocess_tocteasers() are used, the difference is that template_preprocess_tocteasers() is defined from the module implementing the theme function, and it is called before hook_preprocess_tocteasers(). The purpose of the preprocess functions is not printing anything, but altering the variables passed to the template file, or the theme function. As consequence, the following code doesn't work as expected (i.e. "hello" is not in the output of the theme function).

    function template_preprocess_tocteasers(&$variables) {
      $variables['content'] = "something!!!";
      print "hello";
    }
    
  • THanks for detailed answer and interesting point is about the hook_theme caching, that's probably why it is necessary to flush all caches in order to make Drupal notice it. Flushing only theme registry is not enough from my observations. – camcam Mar 20 '12 at 12:03
  • When you disable, and enable a module, Drupal clears many of the caches it uses, not just the theme registry cache. Actually, the function called by system_modules_submit() is drupal_flush_all_caches() – kiamlaluno Mar 20 '12 at 12:50
0

Definitely hook_theme() should be implemented by your module instead of the preprocess.

To use preprocess_tocteasers(), you would have to call it yourself in hook_preprocess().

  • hook_theme() needs to be implemented in any cases, not instead of the preprocess function. The preprocess function could still be used, even if hook_theme() is implemented; one doesn't exclude the other. – kiamlaluno Mar 20 '12 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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