8.3.x common.inc drupal_render(&$elements, $is_recursive_call = FALSE)
8.0.x common.inc drupal_render(&$elements, $is_recursive_call = FALSE)
8.1.x common.inc drupal_render(&$elements, $is_recursive_call = FALSE)
8.2.x common.inc drupal_render(&$elements, $is_recursive_call = FALSE)
8.4.x common.inc drupal_render(&$elements, $is_recursive_call = FALSE)
5.x common.inc drupal_render(&$elements)
6.x common.inc drupal_render(&$elements)
7.x common.inc drupal_render(&$elements)

Renders HTML given a structured array tree.

Recursively iterates over each of the array elements, generating HTML code. This function is usually called from within another function, like drupal_get_form() or node_view().

drupal_render() flags each element with a '#printed' status to indicate that the element has been rendered, which allows individual elements of a given array to be rendered independently. This prevents elements from being rendered more than once on subsequent calls to drupal_render() if, for example, they are part of a larger array. If the same array or array element is passed more than once to drupal_render(), it simply returns a NULL value.


$elements: The structured array describing the data to be rendered.

Return value

The rendered HTML.

47 calls to drupal_render()
book_form_update in modules/book/book.pages.inc
Renders a new parent page select element when the book selection changes.
book_node_export in modules/book/book.module
Generates printer-friendly HTML for a node.
drupal_render_form in includes/form.inc
Renders a structured form array into themed HTML.
hook_search in developer/hooks/core.php
Define a custom search routine.
node_feed in modules/node/node.module
A generic function for generating RSS feeds from a set of nodes.

... See full list


includes/common.inc, line 2999
Common functions that many Drupal modules will need to reference.


function drupal_render(&$elements) {
  if (!isset($elements) || (isset($elements['#access']) && !$elements['#access'])) {
    return NULL;

  // If the default values for this element haven't been loaded yet, populate
  // them.
  if (!isset($elements['#defaults_loaded']) || !$elements['#defaults_loaded']) {
    if ((!empty($elements['#type'])) && ($info = _element_info($elements['#type']))) {
      $elements += $info;

  // Make any final changes to the element before it is rendered. This means
  // that the $element or the children can be altered or corrected before the
  // element is rendered into the final text.
  if (isset($elements['#pre_render'])) {
    foreach ($elements['#pre_render'] as $function) {
      if (function_exists($function)) {
        $elements = $function($elements);

  $content = '';
  // Either the elements did not go through form_builder or one of the children
  // has a #weight.
  if (!isset($elements['#sorted'])) {
    uasort($elements, "element_sort");
  $elements += array('#title' => NULL, '#description' => NULL);
  if (!isset($elements['#children'])) {
    $children = element_children($elements);
    // Render all the children that use a theme function.
    if (isset($elements['#theme']) && empty($elements['#theme_used'])) {
      $elements['#theme_used'] = TRUE;

      $previous = array();
      foreach (array('#value', '#type', '#prefix', '#suffix') as $key) {
        $previous[$key] = isset($elements[$key]) ? $elements[$key] : NULL;
      // If we rendered a single element, then we will skip the renderer.
      if (empty($children)) {
        $elements['#printed'] = TRUE;
      else {
        $elements['#value'] = '';
      $elements['#type'] = 'markup';

      unset($elements['#prefix'], $elements['#suffix']);
      $content = theme($elements['#theme'], $elements);

      foreach (array('#value', '#type', '#prefix', '#suffix') as $key) {
        $elements[$key] = isset($previous[$key]) ? $previous[$key] : NULL;
    // Render each of the children using drupal_render and concatenate them.
    if (!isset($content) || $content === '') {
      foreach ($children as $key) {
        $content .= drupal_render($elements[$key]);
  if (isset($content) && $content !== '') {
    $elements['#children'] = $content;

  // Until now, we rendered the children, here we render the element itself
  if (!isset($elements['#printed'])) {
    $content = theme(!empty($elements['#type']) ? $elements['#type'] : 'markup', $elements);
    $elements['#printed'] = TRUE;

  if (isset($content) && $content !== '') {
    // Filter the outputted content and make any last changes before the
    // content is sent to the browser. The changes are made on $content
    // which allows the output'ed text to be filtered.
    if (isset($elements['#post_render'])) {
      foreach ($elements['#post_render'] as $function) {
        if (function_exists($function)) {
          $content = $function($content, $elements);
    $prefix = isset($elements['#prefix']) ? $elements['#prefix'] : '';
    $suffix = isset($elements['#suffix']) ? $elements['#suffix'] : '';
    return $prefix . $content . $suffix;


drupalshrek’s picture

The following is an example of using this function as found in the link module.

Basically this theming function takes a normal radio button option and changes it into being a radio button with a textfield next to it.

 * Theme the settings form for the link field.
function theme_link_field_settings($form) {
  $title_value = drupal_render($form['title_value']);
  $title_checkbox = drupal_render($form['title']['value']);

  // Set Static Title radio option to include the title_value textfield.
  $form['title']['value'] = array('#value' => '
'. $title_checkbox . $title_value .'
'); // Reprint the title radio options with the included textfield. return drupal_render($form); }