4

I've a piece of code what is rendering a custom table (see var_dump below) what is shown on for specific states of the node. The data of the table is for both states the same.

array(1) {
  [0]=>
  array(5) {
    ["#theme"]=>
    string(5) "table"
    ["#header"]=>
    array(2) {
      [0]=>
      string(4) "test"
      [1]=>
      string(9) "geen test"
    }
    ["#rows"]=>
    array(2) {
      [0]=>
      array(2) {
        [1]=>
        string(6) "e1a1r1"
        [2]=>
        string(6) "e1a2r1"
      }
      [1]=>
      array(2) {
        [1]=>
        string(6) "e1a1r2"
        [2]=>
        string(6) "e1a2r2"
      }
    }
    ["#prefix"]=>
    string(38) "<h3>Table</h3>"
    ["#attributes"]=>
    array(1) {
      ["class"]=>
      array(1) {
        [0]=>
        string(15) "previous-scheme"
      }
    }
  }
}

The custom states of the node are determined by a condition what prints one of the following gathered variables.

For the variable at the line below works with both drupal_render and render.

$kickoff_deadline .= '<h2>Between kickoff and deadline</h2>'.drupal_render($table);

For the variable at the line below only works with render, without it wont show anything.

$after_deadline .= '<h2>After the deadline</h2>'.render($table);

So what is happening? Why doesn't drupal_render work for a similar printed variable what does work?

7

Once you've done this:

$kickoff_deadline .= '<h2>Between kickoff and deadline</h2>'.drupal_render($table);

The render array is marked as #printed, and won't be rendered again. So this

$after_deadline .= '<h2>After the deadline</h2>' . drupal_render($table);

Will do nothing.

If you take a look at the code for render():

function render(&$element) {
  if (is_array($element)) {
    show($element);
    return drupal_render($element);
  }
  else {
    // Safe-guard for inappropriate use of render() on flat variables: return
    // the variable as-is.
    return $element;
  }
}

You can see it runs show($element);, making it available for rendering again. Which is why this works:

$after_deadline .= '<h2>After the deadline</h2>'.render($table);
  • 1
    So performance related it would be the best solution to use one of the two function, right? This is how that can be done with drupal_render. By storing the render action into a variable $rendered_table=drupal_render($table); and than.. $kickoff_deadline='...'.$rendered_table; $after_deadline='...'.$rendered_table;` – Fleuv Nov 5 '14 at 10:29
  • 1
    Correct @Fleuv - you'll save processing time and a bit of memory by caching the result in a local var – Clive Nov 5 '14 at 10:30
3

If you look at the documentation for those functions there are hints to this.

drupal_render() will only render the element if it has not already been printed and has not been hidden using hide().

render() on the other hand will always render the element because it calls show() on the element before then calling drupal_render() on it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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