Hi there

I'm trying to add page template suggestions to Drupal 7 so I can do things like have page__type--blog.tpl.php to modify the page layout of all blog posts. Here's what I have so far in template.php:

function mytheme_preprocess_page(&$vars, $hook) {
// Add template suggestions based on content type 
	if (isset($vars['node'])) {  
       $vars['theme_hook_suggestions'][] = "page--type--" . $vars['node']->type;
  }
}    

Devel themer shows the suggestion should be working (and predeed the other templates), but, no matter how many times I flush the theme cache, my page--type--blog.tpl.php file doesn't get loaded.

Any ideas? D7 documentation is pretty weak

Thanks

Comments

Kirk’s picture

Unless I totally miss what you're trying to do, you should be using node--blog.tpl.php for your template file for "blog" nodes. You shouldn't even have to write a preprocess function.

Though if you are trying to actually override the default page.tpl.php file for blog nodes, I'm not certain on what you need to be doing. but based on what you have said above could it be just a typo? "page__type--blog.tpl.php" is not "page--type--blog.tpl.php"

occupant’s picture

No, I'm trying to modify elements contained within the page.tpl.php file when accessing a node of a particular type - not the node.tpl.php. I need a preprocess function so I can create a page.tpl.php specific to the content type. I had the same thing working in D6 using:

function mytheme_preprocess_page(&$vars, $hook) {
  if ($vars['node']->type != "") {
    $vars['template_files'][] = "page-type-" . $vars['node']->type;
  }
}  

I use it to theme the overall page outside the node (I want my blog posts to have a different structure). I know this could be done with css, but I'd rather use a template file.

The underscore typo was just in the post. No luck there. Thanks for the suggestions though.

bitradiator’s picture

The file name for your template should be of the format page--content_type.tpl.php ie. For blogs page--blog.tpl.php, for articles page--article.tpl.php etc. No preprocess function is necessary.

occupant’s picture

Yes, that's what I thought originally, however I have a page--blog.tpl.php file and it only changes the main Blog page (with the teasers and read more links). The pages that contain the full posts are using page.tpl.php. I've double-checked in Garland to see if it was something funky with my theme and it still won't use page--blog.tpl.php.

bitradiator’s picture

in my modified Bartik theme I used:

function mytheme_process_page(&$variables) {
  $variables['theme_hook_suggestions'][] = 'page__'. $variables['node']->type;
}

My template is now mytheme/templates/page--blog.tpl.php

occupant’s picture

Awesome, thanks bitradiator. That did it. It seems the problem was $vars instead of $variables. Changing it has made it all work. I now have:

function mytheme_preprocess_page(&$variables, $hook) {
   //some other stuff
	if (isset($variables['node'])) {  
    $variables['theme_hook_suggestions'][] = 'page__type__'. $variables['node']->type;
    $variables['theme_hook_suggestions'][] = "page__node__" . $variables['node']->nid;
  }
}

And, counter-intuitively, the template file is named with dashes instead of underscores. ie: page--type--blog.tpl.php or page--node--2.tpl.php

Hope this helps out someone else.

Thanks again!

vitok-dupe’s picture

Yes it's! Thx!

petersmeekens’s picture

Great indeed! Thanks!

mourad-zitouni’s picture

thanks! it was helpful :)

leanderl’s picture

Thanks! It helped me out greatly!

---

catrina’s picture

Note - when I swapped "MYTHEME" with my actual theme name, I got thrown an error - apparently, I'd already been using the preprocess page function. So I moved the snippet into the function block and now it works:

//updated template.php code

  function MYTHEME_preprocess_page(&$variables) { //already existed in template.php
    //...some other code...//

    if (isset($variables['node'])) {  
      $variables['theme_hook_suggestions'][] = 'page__'. $variables['node']->type;
    }

    //...some other code...//
  }

My new page--petition.tpl.php is working great as an alternative to page.tpl.php for the custom "petition" content type. Thanks again.

jwa’s picture

Thanks heaps

drtrueblue’s picture

This was so valuable. It worked perfectly with just the if statement and 'page__'. Thank you for taking the effort.

Cellar Door’s picture

Worked like a charm!

cossovich’s picture

I got caught on this, underscores in for the strings that get added to theme_hook_suggestions, but hyphens in the template file name. +1

amphioxus’s picture

Hurray, I finally got it to work because of this piece of code. Cheers!

Buckminster_Bond’s picture

Worked great for me - many many thanks.

<?php
function mytheme_preprocess_page(&$variables, $hook) {
   //some other stuff
	if (isset($variables['node'])) {  
    $variables['theme_hook_suggestions'][] = 'page__node__'. $variables['node']->type;
}
}

But,

Is it possible to make the "edit" page ignore the instruction above, or at least look at it's own template?

I've added a template named page--node--edit--mycontenttype.tpl.php and have tried every combination of $variables['node-edit'] and 'page__node__edit' that I can think of using _ __ -- and - ,my usual coding approach doesn't seem to be bearing any fruit!

Any help appreciated!

nielsvoo’s picture

Dear Bitradiator,

your trick worked for me but i now get this error...

Notice: Undefined index: node in templatename_process_page() (regel 100 van /srv/www/htdocs/site/themes/touch/template.php).
Notice: Trying to get property of non-object in templatename_process_page() (regel 100 van /srv/www/htdocs/site/themes/touch/template.php).

is there a solution for this?

Nielsvoo

hayskelly’s picture

That is happening because the page that you are trying to render doesn't have a node type associated with it (like the front page, or a veiw) and as such, is undefined. If you put in an if statement, then it will skip over the test of the node variable and should not give you an errors. I was having the same issue, this is what I used to fix the problem.

<?php
  function hive_preprocess_page(&$variables, $hook) {
    if (isset($variables['node']->type)) {
      $variables['theme_hook_suggestions'][] = 'page__' . $variables['node']->type;
    } 
  }
?>
jmatuska’s picture

duplicate post. sorry...

trentharlem’s picture

Your page-front.tpl.php from D6 becomes page--front.tpl.php in D7 and node-blog.tpl.php becomes node--blog.tpl.php

Devel was no help for me (shows html.tpl.php on my Bartik mod); I relied on the Documentation. After renaming my page.tpl.php to page--front.tpl.php I was able to see my changes but html.tpl.php still shows in devel_themer.

Source: http://drupal.org/update/themes/6/7

Search for "Specific template overrides" to read the whole section.

occupant’s picture

That's currently what I have; page--blog.tpl.php works fine to theme the page elements on the page that shows the teasers, but has no effect on the page elements when viewing the full node (the blog post in it's entirety). When viewing the full blog node, the page elements are pulled in from page.tpl.php instead of page--blog.tpl.php.

What I'm trying to do is something like: http://drupal.org/update/modules/6/7#theme_hook_suggestions_2
but for the page rather than the node. I assumed that was the correct way to go about it.

bobtimms’s picture

I'm having similar issues in that I need to create a custom page.tpl.php for a content type I created - 'lab'. I've tried all of the possible derivatives of page--lab.tpl.php, page--node--lab.php, page--lab--%.tpl.php etc without success. I've also added code snippets which my searches indicated was needed to add a preprocess function to template.php to create custom page templates including this thread to no avail. Since this operation is essentially point & click in other cms' like joomla I'm beginning to think its a bug in D7. Hopefully someone can come up with a solution.

trentharlem’s picture

Just shooting from the hip here..... have you tried node--blog.tpl.php

occupant’s picture

Actually I've got it working (above) but no, I hadn't tried node--blog.tpl.php because I wanted to modify the page template, not the node template. Different things.

Edit: (oops, not sure if you were replying to me. At any rate...)

Anonymous’s picture

I need a layout variant for my contact page so I can add Google map scripts & content w/o having to read in the script on every page on the site. I created a page with the url http://_mysitename.com_/contact.

Then I made a copy of my page.tpl.php, renamed page--contact.tpl.php, and made a single change to see if it would be picked up:

<?php print render($page['content']); ?><?php print render($page['content_bottom']); ?>

becomes:

<?php print render($page['content']); ?><?php print '<h1>Foobar!</h1>'; ?><?php print render($page['content_bottom']); ?>.

Also updated the page id info to reflect the new template name.

Then I flushed the cache & held my breath. No change. Am I missing something?

occupant’s picture

Could you post your preprocess function? Hard to know without seeing that.

Anonymous’s picture

Not sure where to find that in D7. Are you wanting my theme-settings.php? or my template.php? or something else?

Would it be simpler to use the method described here? or is that specifically for Webform?

bitradiator’s picture

http://drupal.org/node/1035656#comment-3996684
or:
http://drupal.org/node/1035656#comment-3997484

The code goes in your template.php file. Be sure to replace mytheme_ with the name of your theme. The link you gave is on how to add javascript to a page and is unrelated to this issue.

Anonymous’s picture

Whoops, yeah I missed that bit about adding some code to the pre-process area of template.php in the earlier discussion. It works now; I had to change the existing “function mytheme_preprocess_page(&$vars)” to “function mytheme_preprocess_page(&$variables, $hook)” as shown in the example.

Come to think of it, I did have to do something similar in D6 to achieve this type of results. But that was months ago & I had forgotten this crucial 1st step.

So how would one modify this to use a path instead of a NID?

robmalon’s picture

I've modified it to use a path. Outlined all the details here:

Drupal 7.0 Preprocess Page Templates – theme_hook_suggestions

Another thing to be careful of... I'm using array_splice to insert my template suggestions appropriately. The order in which theme_hook_suggestions keys are placed will determine which template's get overridden when presenting new options into the mix. For example, I found it more intuitive to always place page--node--nid last.

ajeancharles’s picture

Can this be done in a module?
And will a suggestion in a module have preponderance over the active theme.

nguyentran’s picture

Hello, i am creating a module, using template suggestion, i want to ask a question that can i put the suggestion file in my module not in template folder. thank you for helping me.

spovlot’s picture

I found this link http://www.metachunk.com/blog/adding-module-path-drupal-7-theme-registry under "Drupal 7 Theme Hook Suggestions" - http://drupal.org/node/1089656

Hope this helps.