Change record status: 
Project: 
Introduced in branch: 
8.0.x
Introduced in version: 
8.0-BETA3
Description: 

#2118703: Introduce #post_render_cache callback to allow for personalization without breaking the render cache introduced #post_render_cache (but #2478483: Introduce placeholders (#lazy_builder) to replace #post_render_cache simplified it into the concept of "placeholders") and added a second parameter to drupal_render(): $is_recursive_call, defaulting to FALSE.

In hindsight, that was very much the WRONG default, since most calls to drupal_render() in fact are recursive. But, that's not what happened. So, that API change effectively required most drupal_render() calls to be updated.

Of course, that's not great. And it's a relatively big undertaking to update all existing calls. And it's a definite DX/TX regression.

That's why we instead chose to invert the meaning of the parameter: $is_recursive_call = FALSE -> $is_root_call = FALSE. And finally, to make it more clear, more distinguishable, more discoverable when to set the $is_root_call parameter to TRUE, we introduced drupal_render_root(), which just calls drupal_render() with $is_root_call = TRUE (unlike the default, which is $is_root_call = FALSE). And we documented it very clearly:

/**
 * Renders final HTML given a structured array tree.
 *
 * Calls drupal_render() in such a way that placeholders are replaced.
 *
 * Should therefore only be used in occasions where the final rendering is
 * happening, just before sending a Response:
 * - system internals that are responsible for rendering the final HTML
 * - render arrays for non-HTML responses, such as feeds
 *
 * @param array $elements
 *   The structured array describing the data to be rendered.
 *
 * @return string
 *   The rendered HTML.
 *
 * @see drupal_render()
 */
function drupal_render_root(&$elements) {
  return drupal_render($elements, TRUE);
}

In conclusion:

  1. Relative to Drupal 7, we made the DX/TX of drupal_render() exactly the same again
  2. But in the <1% use case of doing the "final" rendering (i.e. when you want placeholders to be replaced), you must now use drupal_render_root() instead
Impacts: 
Module developers
Themers