3

I am using D7. I have declared a custom template facet-item.tpl.php in a module named dsfacet. My code goes as follows:

/**
 * Implements hook_theme().
 */
function dsfacet_theme($existing, $type, $theme, $path) {
  return array(
    'facet_item' => array(
      'variables' => array('facet_name' => NULL, 'facet_values' => array()),
      'template' => 'facet-item',
    ),
  );
}

This custom template is invoked from another template with the following code:

<?php foreach ($facets as $name => $values): ?>
<?php print theme('facet_item', array('facet_name' => $name, 'facet_values' => $values)); ?>
<?php endforeach; ?>

Everything works great so far, but I'd like my theme to use more specialized templates based on the facet name.

So here's what I did:

1) I declared a template suggestion based on the facet name:

/**
 * Implements template_preprocess_HOOK for facet-item.tpl.php.
 * Adds template suggestions.
 */
function template_preprocess_facet_item(&$variables) {
  $variables['theme_hook_suggestions'][] = 'facet_item__' . $variables['facet_name'];
}

2) I changed the theme invocation to take into account the facet name:

<?php print theme('facet_item__' . $name, array('facet_name' => $name, 'facet_values' => $values, 'node' => $node)); ?>

3) I created some templates based on facet names:

facet-item--address.tpl.php
facet-item--phone.tpl.php
...

I then cleared the cache but... nothing happens. Only the main template facet-item.tpl.php is used. After a few hours spent on this, I'm at my wit's end. Any ideas?

(I've tried hard-coding the facet name everywhere to make sure it wasn't a problem with my variables... I've also tried every possible permutation of singe/double dashes/underscores...)

1 Answer 1

3

It took me a bit to figure this out and what I came up with is that the issue appears to be that Drupal's Theme System will only look for dynamic templates if they are in an actual theme, not in with a module.

So, you can do one of two things, the first one obviously being to copy all of your facet-item templates into your theme directory and call it a day after clearing caches for Drupal to pick them up.

Or... you could get creative like the Views Module does and create theme registry hooks for each of the template files like so:

function dsfacet_theme($existing, $type, $theme, $path) {

  $hooks=array();
  $modulepath = drupal_get_path('module', 'dsfacet');

  $hooks['facet_item']= array(
    'variables' => array('facet_name' => NULL, 'facet_values' => array()),
    'pattern' => 'facet_item__',
    'template' => 'facet-item',
    'path' => $modulepath . '/tpl/facet-items',
  );

  $hooks += drupal_find_theme_templates($hooks, '.tpl.php', $hooks['facet_item']['path']);
  // $hooks += _views_find_module_templates($hooks, $hooks['facet_item']['path']);

  return $hooks;

}

which if you have Views installed will actually use Views' _views_find_module_templates() function to do all the work for you. (it basically goes through the directory passed to it and looks for template files and creates $hooks['facet_name__foo'] for each one it finds.) If you don't have or want Views installed, you can just copy it out of views.module and include and rename it accordingly in your own module.

ADDITION/CORRECTION: DUH; YOU CAN USE drupal_find_theme_templates() just as easily without worry about using/including Views' similiar private implementation.

And now if you have put all your facet-item templates under your module in their own directory structure (mostly so the find template function doesn't find any other templates and spin its wheels doing extra work) and cleared caches, you should now see all of your templates.

1
  • Hey Jim, thank you so much for taking the time to look into this. I've just tried your two suggestions and both work great. I like your second suggestion even better (drupal_find_theme_templates) as I find it more convenient to have the templates in the module directory. You just made my day, thanks again! Commented Feb 4, 2014 at 1:43

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.