Render arrays

Last updated on
1 February 2023

"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 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' is a property.
  '#type' => 'page',
  // 'content' is a nested render array, or child element.
  'content' => [
    'system_main' => […],
    'another_block' => […],
    '#sorted' => TRUE,
  ],
  'sidebar_first' => [
    …
  ],
];

Render arrays consist of two types of key/value pairs: properties and child elements.

Any key starting with a # is a property, these are like settings for the renderer, and influence the generated HTML. In the above example the #type property indicates the array represents a \Drupal\Core\Render\Element\Page render element. And the Page class should be used to handle rendering. Additional properties at this level in the array are essentially arguments for that code.

Elements are all keys whose name does not start with a #. Their values should be renderable arrays themselves, which will be rendered during the rendering of the parent array. The markup provided by the children is typically inserted into the markup generated by the parent array. In the above example content is an element that contains the blocks in the content region, its children are block elements, which are render arrays themselves. When rendering happens the block elements will be rendered to HTML, and the resulting string will be inserted into the page element as appropriate. A list of the allowed elements can be found in the Form and render elements API documentation page.

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, 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

A lot of 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 that 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.
See hook_theme and Theme system overview.
#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.
#sorted TRUE if the elements of this render array have been sorted by weight. You can set this to FALSE to force Drupal to re-sort the elements in the array. This is useful when adding a new element to a render array in a preprocess hook.

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.

Help improve this page

Page status: No known problems

You can: