Take the 2-minute tour ×
Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

I've created a theme and have my template files in this structure

  • /templates/page/page.tpl.php
  • /templates/page/page--node-type.tpl.php

I've created a custom page template but for some reason it's not being picked up by Drupal. I've cleared my cache and also tried adding this preprocessor function in the theme template.php file but it's still not working.

if (isset($vars['node'])) 
  {
    // If the node type is "blog" the template suggestion will be "page--blog.tpl.php".
    $vars['theme_hook_suggestions'][] = 'page__'. str_replace('_', '--', $vars['node']->type);
  }

Any help would be appreciated.

share|improve this question
    
/templates/page/page--node-type.tpl.php should that not be page--blog.tpl.php? –  Jeremy French Mar 28 '11 at 15:03
add comment

3 Answers 3

up vote 11 down vote accepted

As reported in Drupal 7 Template Suggestions, the template suggestion used by default from Drupal 7 for pages is page--[front|internal/path].tpl.php.

For a page visible at http://www.example.com/node/1/edit, Drupal would look for the following template files:

  • page--node--edit.tpl.php
  • page--node--1.tpl.php
  • page--node.tpl.php
  • page.tpl.php

To add extra suggestions, your theme should implement template_preprocess_page() and add new suggestions in $variables['theme_hook_suggestions'] ($variables is the variable passed by reference to the function).

If you did that, then the only reason the suggested template file is not being used is because the file is not correctly named: in the case the page shows a book page, for example, the template file should be page--book.tpl.php. You could change the code for your theme, and let it use the page--node-type.tpl.php template, if it doesn't find a template like page--book.tpl.php.

To notice also that, in theme_get_suggestions() (which is the function called by template_preprocess_page()) hyphens are replaced by _, and not vice versa. The reason that is done is explained in a comment reported in the function code.

// When we discover templates in drupal_find_theme_templates(),
// hyphens (-) are converted to underscores (_) before the theme hook
// is registered. We do this because the hyphens used for delimiters
// in hook suggestions cannot be used in the function names of the
// associated preprocess functions. Any page templates designed to be used
// on paths that contain a hyphen are also registered with these hyphens
// converted to underscores so here we must convert any hyphens in path
// arguments to underscores here before fetching theme hook suggestions
// to ensure the templates are appropriately recognized.
$arg = str_replace(array("/", "\\", "\0", '-'), array('', '', '', '_'), $arg);
share|improve this answer
add comment

I'm using Drupal 7.4, and I had the same problem and the only thing that helped was this post: How to add a custom page.tpl based on content types

From the post:

<?php
/**
* Variables preprocess function for the "page" theming hook.
*/
function THEME_NAME_preprocess_page(&$vars) {

  // Do we have a node?
  if (isset($vars['node'])) {

    // Ref suggestions cuz it's stupid long.
    $suggests = &$vars['theme_hook_suggestions'];

    // Get path arguments.
    $args = arg();
    // Remove first argument of "node".
    unset($args[0]);

    // Set type.
    $type = "page__type_{$vars['node']->type}";

    // Bring it all together.
    $suggests = array_merge(
      $suggests,
      array($type),
      theme_get_suggestions($args, $type)
    );

    // if the url is: 'http://domain.com/node/123/edit'
    // and node type is 'blog'..
    //
    // This will be the suggestions:
    //
    // - page__node
    // - page__node__%
    // - page__node__123
    // - page__node__edit
    // - page__type_blog
    // - page__type_blog__%
    // - page__type_blog__123
    // - page__type_blog__edit
    //
    // Which connects to these templates:
    //
    // - page--node.tpl.php
    // - page--node--%.tpl.php
    // - page--node--123.tpl.php
    // - page--node--edit.tpl.php
    // - page--type-blog.tpl.php          << this is what you want.
    // - page--type-blog--%.tpl.php
    // - page--type-blog--123.tpl.php
    // - page--type-blog--edit.tpl.php
    //
    // Latter items take precedence.
  }
}
?>
share|improve this answer
    
Thanks so much...showing the relation between the suggestion and template name really really helped. Thanks again :) –  SGhosh Mar 23 '13 at 10:01
add comment

I have spent too long trying to follow the example above using string replace in Drupal 7.22. This does not seem to work for me. Interestingly some content types seem to be suggested automatically, while others do not. This is the code that worked for me in the end.

if (isset($variables['node'])) {
   // $variables['theme_hook_suggestions'][] = 'page__'. str_replace('_', '--', $variables['node']->type);
   //cannot get above working for some reason?
     $variables['theme_hook_suggestions'][] = 'page__' . $variables['node']->type;
  }

so the template suggestion for a front_page content type this would then be:

page--front_cover.tpl.php

Interestingly the code template suggestion for 'issue' content type comes through for as page--issue.tpl.php without any need for a preprocessor script!? This for my purposes seems to override the view template that uses a similar path.

i.e.

view path = /issue/# template suggestion based on content type i.e. /issue/#/front_cover

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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