I'm about to start theming a Drupal 7 website for the first time. I've watched Moshe's video, Lia Clark's introduction to theme overrides using context naming, and Franz's talk at Drupalcon Chicago. These are all great, but like everything else in Drupal there must be a thousand different ways to theme now.

What is are the best techniques and practices to theme now in Drupal 7? More specifically, how do I best use hook_page_alter($page)? I'm imagining that after I move all the parts of the page around it will be huge and unwieldy. Are there ways to add a region to a node template?


Here is an example of moving a page region that is populated with the Context module while the block module is disabled completely. It was the first way of doing this that came to my mind. Why someone would want to put a region between the links and comments, I don't know. Still it's cool to be able to put stuff there.

In template.php:

function hook_page_alter(&$page){

  $main_content_display = &drupal_static('system_main_content_added', FALSE);

  // Need to beat common.inc drupal_render_page() line 5485 to this
  if (!$main_content_display) {
    $page['content']['system_main'] = drupal_set_page_content();

  if ($node = menu_get_object()) {
    $region_to_embed = $page['sidebar_first'];
      $page['content']['system_main']['nodes'][$node->nid]['#node']->region = $region_to_embed;

And in node.tpl.php:

  <?php print render($content['links']); ?>
  <?php if ($node->region): ?>
    <?php print render($node->region); ?>
  <?php endif; ?>
  <?php print render($content['comments']); ?>
  • If you are really using hook_page_alter() as function name, then you are using the wrong function name.
    – avpaderno
    Commented May 10, 2011 at 5:39

1 Answer 1


Kind of a "big"/multiple question(s), that is hard to answer. Try to ask more specific, single questions in the future.

About hook_page_alter(). In a theme, you should customize the output by overriding default templates. IMHO, that hook is more meant if modules want to alter the output of other modules, especially if they return render arrays instead of arbitrary strings.

Speaking of render arrays, that is one of the main things I do with my modules now, instead of arbitrary templates. I've already replaced quite a few specific "page callback templates" by building and returning a so called render array. The advantage is that, if you for example want to change the order of the table rows, or add/hide a table row, you can do that without duplicating a template with maybe 100 lines of code. And, multiple modules can add/change things.

Two examples:


And for your last question: Regions in "Theme-speak" are places where blocks can be placed. Regions are defined in the .info file of a theme. The node template itself is more or less a block (The "Content" block, which is the output of the executed page callback). Since it is not possible to nest regions within regions/blocks you can also not place regions in a node template.

That said, you can make your node template as complex as you want, and split the content up into "visual regions" for example.

  • I understand the module development strategy to use '#theme' => 'table' rendered array instead of the old $output .= theme('table'). From a themer point of view where is the best place to hook into building of the page array to start moving comments into side blocks, regions inside of node templates....... oh, I just realized the answer. Use hook_page_alter(), hide the region with hide($region) and add it to the node array. Then add print render($region) in the node template file. I just wish there was a unified theory of moving stuff around.
    – Adam S
    Commented May 9, 2011 at 20:51
  • response to edit: Sure you can put regions inside of regions in Drupal 7. Take the example of an online newspaper article with a block that has similar content -- this block's context is created in a View. If I want this with the article text wrapping around it, the block, View, or region needs to be printed in the node template. Because drupal_render() is recursive concatenating and returning an HTML string at the end of every branch in the entire $page array, there is no reason not to leverage the Context module UI to manage these contextual blocks embedded in a node template.
    – Adam S
    Commented May 9, 2011 at 21:21
  • 1
    @Adam I'm not a themer, but regions defined in the .info file available as variables only for page.tpl.php according to drupal.org/node/171224. But yes, you can define a region and then manualy load the blocks of that region (example for D6 can be found here: zyxware.com/articles/1188/…).
    – Berdir
    Commented May 9, 2011 at 22:06
  • I've used the example you have given. However, in Drupal 6 it was impossible to move comments around. Now comments can be placed any where in the $page array. The original question is what are the different possibilities like these and the best way to accomplish them?
    – Adam S
    Commented May 9, 2011 at 23:57

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.