You are hereBlogs / moshe weitzman's blog / Drupal 7 rendering. Roles and responsibilities

Drupal 7 rendering. Roles and responsibilities

By moshe weitzman - Posted on 15 July 2009

I have lots to say about the awesome new page rendering in Drupal 7. For now, I want to clarify the design. The meaning of some familiar features has changed:

  • Regions. Regions are promises made by a theme: “I will print whatever you put into these part of the $page array.”
  • Hook_block(). A modules uses this to make pre-packaged hunks of content available to the CMS
  • Block module. An optional UI where admin populates regions with blocks
  • $page array. See graphic below. $page gets built up during a page request. At the top level of the array we find each region. Within each region we find renderable arrays that often correspond to blocks. After page building is complete, core calls drupal_render($page). We theme each element of the array until we finally get to page.tpl.php
  • Hook_page_alter(). A chance for the site builder to change almost anything about the $page before it is rendered. Populating regions is perfectly reasonable here (e.g. toolbar module). Thats what block.module does.
  • Preprocess layer. A useful place to make minor tweaks to variables before they are printed in templates. Core should not call drupal_render() here. Core should strive to remove all drupal_render() calls from Drupal except drupal_render_page() and render() in templates (e.g. node.tpl.php).

Here is the $page array from current HEAD:


Thank you for championing this and doing so much of the work.

I'd like to clarify in the very last point regarding removing drupal_render() from Drupal code (so prior to rendering everything is available to be modified with hook_page_alter) that "except ... render() in templates (e.g. node.tpl.php)" does not mean no render() calls in preprocessing for templates. Having render() in THEME_node_preprocess() creating variables for printing in the node template is considered by many to be best practice, and is no different from the perspective of removing drupal_render functions as having render() in a .tpl.php.

Very good point. I love the studio theme approach too. I've updated the post so that my statements only apply to core.

Question: are the blocks data arrays when my module gets the page? Can I do things like disable or alter blocks in my contrib module? I've been considering mounting a drupal_alter($block) campaign in block_list() for this purpose. Maybe I don't need to?

Yes, your module can change blocks hook_page_alter. And what you see is unthemed data, as opposed to a string. Your module just needs a higher weight than block.module which is not hard since we thoughtfully weighted block at -5.

Agreed. Should that overview live in a PHPdoc / API documentation section somewhere in core? It could be very helpful ...

I will definately contribute an expanded writeup closer code freeze. We're still a bit volatile for documentation. Glad you agree.

Thanks Moshe for documenting this so simply, and for getting this awesome feature in Drupal 7! Remind me to get you a beer in Paris ;)

Block module. An optional UI where admin populates regions with blocks

When I initially read this, I thought awesome! It’s like the views_ui module. But then I realized its not. Block module is also responsible for putting the blocks data into the region arrays with a call to hook_page_alter(). Which means if you disable the block module, no blocks will appear on your page. This, unfortunately, includes the content block.

The thinking there is that a site builder will only disable block module when he has another solution in mind for populating the regions, including content region. it might be panels module or something else. i agree that we need a confirm screen or some other safety net. thats a ux issue, and making block required is too heavy handed a solution for that, IMO.