The Definitive Guide to Drupal 7

Introducing render(), hide(), and show()

One of the best new theming features of Drupal 7 is the ability to selectively render bits of content in templates. As detailed in the previous sections, the content of some variables (render arrays) is sent to templates as structured arrays instead of chunks of HTML. This is really awesome news for the theme layer.

To understand just how awesome this is, you need to look into the past. In prior versions of Drupal, theming complex nodes with fields wasn’t the easiest task. Fields were lumped into the $content variable, and while they could be printed and manipulated individually, there were issues. You had to be very careful to properly sanitize variables, and once you decided to break up the content variable, you needed to rebuild it entirely. This was not future-proof, as the addition of new fields would often require going back to the template file and printing the new field.

In Drupal 7, those problems have been solved quite gracefully. You now have the ability to very easily render individual pieces of content, such as fields, with three new functions called render(), hide(), and show(). They can be used inside theme functions and templates files as well as preprocess and process functions. All three of these functions take a single argument, which is the element (or child) you wish to target.

hide()

Hides a render element or part of a render element by tricking drupal_render() into thinking it has already been printed. Example usage:

  1. <?php hide($element['something']); ?>
show()

Does the opposite of hide(). It can be useful to revert a previously applied hide() status. Example usage:

  1. <?php show($element['something']); ?>
render()

Converts a render array to HTML markup. It returns HTML, so it should be used along with print in templates. Example usage:

  1. <?php print render($element); ?>

To demonstrate these functions in action, look at node.tpl.php (see Listing 16–21).

Listing 16–21. Excerpt from the default node.tpl.php template
  1. <div id="node-<?php print $node->nid; ?>" class="<?php print $classes; ?> clearfix"<?php print $attributes; ?>>
  2. <?php print $user_picture; ?>
  3. <?php print render($title_prefix); ?>
  4. <?php if (!$page): ?>
  5. <h2<?php print $title_attributes; ?>><a href="<?php print $node_url; ?>"><?php print $title; ?></a></h2>
  6. <?php endif; ?>
  7. <?php print render($title_suffix); ?>
  8. <?php if ($display_submitted): ?>
  9. <div class="submitted">
  10. <?php print $submitted; ?>
  11. </div>
  12. <?php endif; ?>
  13. <div class="content"<?php print $content_attributes; ?>>
  14. <?php
  15. // Hide the comments and links now so they can be rendered later.
  16. hide($content['comments']);
  17. hide($content['links']);
  18. print render($content);
  19. ?>
  20. </div>
  21. <?php print render($content['links']); ?>
  22. <?php print render($content['comments']); ?>
  23. </div>

As you can see in Listing 16–21, this template is already making use of both render() and hide() functions out of the box. There are three render arrays in this node template: $title_prefix, $title_suffix, and $content. Inside the <div class="content"> wrapper, both $content['links'] and $content['comments'] are hidden using hide(), and then $content is rendered directly underneath.

The reason that the comments and links are hidden is to break them out of the $content variable and allow them to be placed outside of the <div class="content"> wrapper. Both of the items are then rendered afterward using render() individually.

Of course, the fun doesn’t have to stop at top-level variables. These functions work as deep into the array as you can go. As long as you pass in a proper render element (see the “Render API” section), you’ll be able to manipulate it with these functions.

As an example, say you wanted to hide the “Add new comment” link when viewing a node that has a comment form on the page you’re viewing. You can simply check to see if the form exists in your array, and then hide that specific link group (comment). The code in Listing 16–22 demonstrates how to do this.

Listing 16–22. Hiding the “Add new comment” link when the comment form is present
  1. <?php
  2. // Hide the "Add new comment" link when the comment form is present.
  3. if (!empty($vars['content']['comments']['comment_form'])) {
  4. hide($vars['content']['links']['comment']);
  5. }
  6. // Print the rendered links afterward.
  7. print render($content['links']);

Because the show() function resets the print status but does not print anything, it can be helpful to revert a previously applied hide(). In most cases, you’ll likely just use render() because it will allow you to print the element as many times as you need, as shown in Listing 16–23.

Listing 16–23. Hiding the “Add new comment” link when the comment form Is present, but showing it again if some other condition is met
  1. <?php
  2. // Hide the "Add new comment" link when the comment form is present.
  3. if (!empty($content['comments']['comment_form'])) {
  4. hide($content['links']['comment']);
  5. if ($some_exception) {
  6. show($content['links']['comment']);
  7. }
  8. }
  9. // Print the rendered links afterward.
  10. print render($content['links']);

You are reading content from two chapters on Theme Development from The Definitive Guide to Drupal 7, written by Jacine Luisi and published by Apress on July 19, 2011. All rights reserved.