Render arrays

Last updated on
4 July 2017

"Render Arrays" or "Renderable Arrays" are the building blocks of a Drupal page. A render array is an associative array which conforms to the standards and data structures used in Drupal's Render API. The Render API is also integrated with the Theme API.

In many cases, the data used to build a page (and all parts of it) is kept as structured arrays until the final stage of generating a response. This provides enormous flexibility in extending, slightly altering or completely overriding parts of the page.

Render arrays are nested and thus form a tree. Consider them Drupal's "render tree" — Drupal's equivalent of the DOM.

Note: While render arrays and arrays used by the Form API share elements, properties and structure, many properties on form elements only have meaning for the Form API, not for the Render API. Form API arrays are transformed into render arrays by FormBuilder. Passing an unprocessed Form API array to the Render API may yield unexpected results.

What is "rendering"?

Rendering in the Drupal world means turning structured "render" arrays into HTML. See The HTML main content renderer in the Drupal 8 render pipeline documentation.

What is a render array?

A render array is a structured array that provides data (probably nested) along with hints as to how it should be rendered (properties, like #type). A page array might look like this:

$page = [
  '#type' => 'page',
  'content' => [
    'system_main' => […],
    'another_block' => […],
    '#sorted' => TRUE,
  ],
  'sidebar_first' => [
    …
  ],
];

Why?

Before Drupal 7, forms could be altered (with hook_form_alter()), but so many other things that needed to be altered by a module or a theme had already been rendered into HTML before any rational thing could be done with them.

In Drupal 8, a module or a theme can alter a block's render array (hook_block_view_alter()), an entity's render array (hook_entity_view_alter()), and so on.

How are render arrays related to element types?

Modules have the capability of defining "element types", which are essentially prepackaged default render arrays. To define a new element type, create a new RenderElement plugin, which implements ElementInterface.

Render array properties

Many, many properties can be applied in a given render array, and they can be created as needed. This will attempt to cover some of the most common.

(Note that the default render element properties are documented on the RenderElement API page linked above.)

Property Description
#type The element type. If this array is an element, this will cause the default element properties to be loaded, so in many ways this is shorthand for a set of predefined properties which will have been arranged through a RenderElement plugin.
#cache Mark the array as cacheable and determine its expiration time, etc. Once the given render array has been rendered, it will not be rendered again until the cache expires or is invalidated. Uses the Cache API. This property accepts the following subproperties:
  • 'keys'
  • 'contexts'
  • 'tags'
  • 'max-age'
  • 'bin'

See Cacheability to learn more. It's very important to set #cache correctly!

#markup Specifies that the array provides HTML markup directly. Unless the markup is very simple, such as an explanation in a paragraph tag, it is normally preferable to use #theme or #type instead, so that the theme can customize the markup. Note that the value is passed through \Drupal\Component\Utility\Xss::filterAdmin(), which strips known XSS vectors while allowing a permissive list of HTML tags that are not XSS vectors. (I.e, <script> and <style> are not allowed.)
#plain_text Specifies that the array provides text that needs to be escaped. This value takes precedence over #markup if present.
#prefix/#suffix A string to be prefixed or suffixed to the element being rendered
#pre_render An array of functions which may alter the actual render array before it is rendered. They can rearrange, remove parts, set #printed = TRUE to prevent further rendering, etc.
#post_render An array of functions which may operate on the rendered HTML after rendering. A #post_render function receives both the rendered HTML and the render array from which it was rendered, and can use those to change the rendered HTML (it could add to it, etc.). This is in many ways the same as #theme_wrappers except that the theming subsystem is not used.
#theme A single theme function/template which will take full responsibility for rendering this array element, including its children. It has predetermined knowledge of the structure of the element.
#theme_wrappers An array of theme hooks which will get the chance to add to the rendering after children have been rendered and placed into #children. This is typically used to add HTML wrappers around rendered children, and is commonly used when the children are being rendered recursively using their own theming information. It is rare to use it with #theme.

Since every element type can declare its own properties (that make sense for that element type), there are many more. These element type specific properties can be found in the document for the specific element. A list of which can be found at https://api.drupal.org/api/drupal/elements.