Community Documentation

drupal_render

5 common.inc drupal_render(&$elements)
6 common.inc drupal_render(&$elements)
7 common.inc drupal_render(&$elements)
8 common.inc drupal_render(&$elements)

Renders HTML given a structured array tree.

Recursively iterates over each of the array elements, generating HTML code.

Renderable arrays have two kinds of key/value pairs: properties and children. Properties have keys starting with '#' and their values influence how the array will be rendered. Children are all elements whose keys do 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.

HTML generation for a renderable array, and the treatment of any children, is controlled by two properties containing theme functions, #theme and #theme_wrappers.

#theme is the theme function called first. If it is set and the element has any children, it is the responsibility of the theme function to render these children. For elements that are not allowed to have any children, e.g. buttons or textfields, the theme function can be used to render the element itself. If #theme is not present and the element has children, they are rendered and concatenated into a string by drupal_render_children().

The #theme_wrappers property contains an array of theme functions which will be called, in order, after #theme has run. These can be used to add further markup around the rendered children; e.g., fieldsets add the required markup for a fieldset around their rendered child elements. All wrapper theme functions have to include the element's #children property in their output, as it contains the output of the previous theme functions and the rendered children.

For example, for the form element type, by default only the #theme_wrappers property is set, which adds the form markup around the rendered child elements of the form. This allows you to set the #theme property on a specific form to a custom theme function, giving you complete control over the placement of the form's children while not at all having to deal with the form markup itself.

drupal_render() can optionally cache the rendered output of elements to improve performance. To use drupal_render() caching, set the element's #cache property to an associative array with one or several of the following keys:

  • 'keys': An array of one or more keys that identify the element. If 'keys' is set, the cache ID is created automatically from these keys. See drupal_render_cid_create().
  • 'granularity' (optional): Define the cache granularity using binary combinations of the cache granularity constants, e.g. DRUPAL_CACHE_PER_USER to cache for each user separately or DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE to cache separately for each page and role. If not specified the element is cached globally for each theme and language.
  • 'cid': Specify the cache ID directly. Either 'keys' or 'cid' is required. If 'cid' is set, 'keys' and 'granularity' are ignored. Use only if you have special requirements.
  • 'expire': Set to one of the cache lifetime constants.
  • 'bin': Specify a cache bin to cache the element in. Defaults to 'cache'.

This function is usually called from within another function, like drupal_get_form() or a theme function. Elements are sorted internally using uasort(). Since this is expensive, when passing already sorted elements to drupal_render(), for example from a database query, set $elements['#sorted'] = TRUE to avoid sorting them a second time.

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 and prevents them from being rendered more than once on subsequent calls to drupal_render() (e.g., as 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.

Parameters

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

Return value

The rendered HTML.

▾ 87 functions call drupal_render()

ajax_prepare_response in includes/ajax.inc
Converts the return value of a page callback into an Ajax commands array.
bartik_field__taxonomy_term_reference in themes/bartik/template.php
Implements theme_field__field_type().
book_children in modules/book/book.module
Format the menu links for the child pages of the current page.
book_node_export in modules/book/book.module
Generates printer-friendly HTML for a node.
comment_node_update_index in modules/comment/comment.module
Implements hook_node_update_index().
comment_unpublish_by_keyword_action in modules/comment/comment.module
Unpublishes a comment if it contains certain keywords.
dashboard_show_block_content in modules/dashboard/dashboard.module
Ajax callback to display the rendered contents of a specific block.
DrupalRenderTestCase::assertRenderedElement in modules/simpletest/tests/common.test
DrupalRenderTestCase::testDrupalRenderCache in modules/simpletest/tests/common.test
Tests caching of an empty render item.
DrupalRenderTestCase::testDrupalRenderChildrenAttached in modules/simpletest/tests/common.test
Test #attached functionality in children elements.
DrupalRenderTestCase::testDrupalRenderSorting in modules/simpletest/tests/common.test
Test sorting by weight.
DrupalRenderTestCase::testDrupalRenderThemeArguments in modules/simpletest/tests/common.test
Test passing arguments to the theme function.
drupal_get_css in includes/common.inc
Returns a themed representation of all stylesheets to attach to the page.
drupal_get_html_head in includes/common.inc
Retrieves output to be displayed in the HEAD tag of the HTML page.
drupal_render in includes/common.inc
Renders HTML given a structured array tree.
drupal_render_children in includes/common.inc
Renders children of an element and concatenates them.
drupal_render_page in includes/common.inc
Renders the page, including all theming.
FieldAttachOtherTestCase::testFieldAttachView in modules/field/tests/field.test
Test field_attach_view() and field_attach_prepare_view().
FieldDisplayAPITestCase::testFieldViewField in modules/field/tests/field.test
Test the field_view_field() function.
FieldDisplayAPITestCase::testFieldViewValue in modules/field/tests/field.test
Test the field_view_value() function.
FieldUIManageDisplayTestCase::assertNodeViewTextHelper in modules/field_ui/field_ui.test
Asserts that a string is (not) found in the rendered nodein a view mode.
file_ajax_upload in modules/file/file.module
Menu callback; Shared Ajax callback for file uploads and deletions.
FormCheckboxTestCase::testFormCheckbox in modules/simpletest/tests/form.test
FormsTestCase::testRequiredFields in modules/simpletest/tests/form.test
Check several empty values for required forms elements.
hook_search_execute in modules/search/search.api.php
Execute a search for a set of key words.
hook_tokens_alter in modules/system/system.api.php
Alter replacement values for placeholder tokens.
hook_update_index in modules/search/search.api.php
Update the search index for this module.
install_run_task in includes/install.core.inc
Runs an individual installation task.
install_select_locale in includes/install.core.inc
Installation task; select which locale to use for the current profile.
install_select_profile in includes/install.core.inc
Installation task; select which profile to install.
JavaScriptTestCase::testAttachedLibrary in modules/simpletest/tests/common.test
Tests the addition of libraries through the #attached['library'] property.
locale_translate_export_screen in modules/locale/locale.admin.inc
User interface for the translation export screen.
locale_translate_seek_screen in modules/locale/locale.admin.inc
String search screen.
node_feed in modules/node/node.module
Generates and prints an RSS feed.
node_search_execute in modules/node/node.module
Implements hook_search_execute().
node_unpublish_by_keyword_action in modules/node/node.module
Unpublishes a node containing certain keywords.
openid_redirect in modules/openid/openid.inc
Creates a js auto-submit redirect for (for the 2.x protocol)
render in includes/common.inc
Renders an element.
search_embedded_form_preprocess_search_result in modules/search/tests/search_embedded_form.module
Adds the test form to search results.
system_themes_page in modules/system/system.admin.inc
Menu callback; displays a listing of all themes.
TaxonomyTermFieldTestCase::testTaxonomyTermFieldWidgets in modules/taxonomy/taxonomy.test
Test widgets.
template_preprocess_block_admin_display_form in modules/block/block.admin.inc
Processes variables for block-admin-display-form.tpl.php.
template_preprocess_poll_results in modules/poll/poll.module
Preprocess the poll_results theme hook.
template_preprocess_poll_vote in modules/poll/poll.module
Themes the voting form for a poll.
template_preprocess_search_block_form in modules/search/search.module
Process variables for search-block-form.tpl.php.
template_process_html in includes/theme.inc
Process variables for html.tpl.php
TextFieldTestCase::_testTextfieldWidgets in modules/field/modules/text/text.test
Helper function for testTextfieldWidgets().
TextFieldTestCase::_testTextfieldWidgetsFormatted in modules/field/modules/text/text.test
Helper function for testTextfieldWidgetsFormatted().
ThemeLinksTest::testDrupalPreRenderLinks in modules/simpletest/tests/theme.test
Test the use of drupal_pre_render_links() on a nested array of links.
theme_aggregator_categorize_items in modules/aggregator/aggregator.pages.inc
Returns HTML for the aggregator page list form for assigning categories.
theme_book_admin_table in modules/book/book.admin.inc
Returns HTML for a book administration form.
theme_color_scheme_form in modules/color/color.module
Returns HTML for a theme's color form.
theme_exposed_filters in modules/system/system.module
Returns HTML for an exposed filter form.
theme_field in modules/field/field.module
Returns HTML for a field.
theme_field_multiple_value_form in modules/field/field.form.inc
Returns HTML for an individual form element.
theme_field_ui_table in modules/field_ui/field_ui.admin.inc
Returns HTML for Field UI overview tables.
theme_file_widget_multiple in modules/file/file.field.inc
Returns HTML for a group of file upload widgets.
theme_filter_admin_format_filter_order in modules/filter/filter.admin.inc
Returns HTML for a text format's filter order form.
theme_filter_admin_overview in modules/filter/filter.admin.inc
Returns HTML for the text format administration overview form.
theme_image_anchor in modules/image/image.admin.inc
Returns HTML for a 3x3 grid of checkboxes for image anchors.
theme_image_style_effects in modules/image/image.admin.inc
Returns HTML for a listing of the effects within a specific image style.
theme_image_widget in modules/image/image.field.inc
Returns HTML for an image field widget.
theme_locale_date_format_form in modules/locale/locale.admin.inc
Returns HTML for a locale date format form.
theme_locale_languages_configure_form in modules/locale/locale.admin.inc
Returns HTML for a language configuration form.
theme_locale_languages_overview_form in modules/locale/locale.admin.inc
Returns HTML for the language overview form.
theme_menu_link in includes/menu.inc
Returns HTML for a menu link and submenu.
theme_menu_local_tasks in includes/menu.inc
Returns HTML for primary and secondary local tasks.
theme_menu_overview_form in modules/menu/menu.admin.inc
Returns HTML for the menu overview form into a table.
theme_node_preview in modules/node/node.pages.inc
Returns HTML for a node preview for display during node creation and editing.
theme_node_search_admin in modules/node/node.module
Returns HTML for the content ranking part of the search settings admin page.
theme_overlay_disable_message in modules/overlay/overlay.module
Returns the HTML for the message about how to disable the overlay.
theme_poll_choices in modules/poll/poll.module
Returns HTML for an admin poll form for choices.
theme_profile_admin_overview in modules/profile/profile.admin.inc
Returns HTML for the profile field overview form into a drag and drop enabled table.
theme_shortcut_set_customize in modules/shortcut/shortcut.admin.inc
Returns HTML for a shortcut set customization form.
theme_simpletest_test_table in modules/simpletest/simpletest.pages.inc
Returns HTML for a test list generated by simpletest_test_form() into a table.
theme_system_date_time_settings in modules/system/system.admin.inc
Returns HTML for the date settings form.
theme_system_modules_fieldset in modules/system/system.admin.inc
Returns HTML for the modules form.
theme_system_modules_uninstall in modules/system/system.admin.inc
Returns HTML for a table of currently disabled modules.
theme_tableselect in includes/form.inc
Returns HTML for a table with radio buttons or checkboxes.
theme_taxonomy_overview_terms in modules/taxonomy/taxonomy.admin.inc
Returns HTML for a terms overview form as a sortable list of terms.
theme_taxonomy_overview_vocabularies in modules/taxonomy/taxonomy.admin.inc
Returns HTML for the vocabulary overview form as a sortable list of vocabularies.
theme_user_admin_permissions in modules/user/user.admin.inc
Returns HTML for the administer permissions page.
theme_user_admin_roles in modules/user/user.admin.inc
Returns HTML for the role order and new role form.
update_selection_page in ./update.php
UpgradePathTaxonomyTestCase::testTaxonomyUpgrade in modules/simpletest/tests/upgrade/upgrade.taxonomy.test
Basic tests for the taxonomy upgrade.
_node_index_node in modules/node/node.module
Index a single node.
_theme_table_cell in includes/theme.inc
Returns HTML output for a single table cell for theme_table().

File

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

Code

<?php
function drupal_render(&$elements) {
  // Early-return nothing if user does not have access.
  if (empty($elements) || (isset($elements['#access']) && !$elements['#access'])) {
    return;
  }

  // Do not print elements twice.
  if (!empty($elements['#printed'])) {
    return;
  }

  // Try to fetch the element's markup from cache and return.
  if (isset($elements['#cache'])) {
    $cached_output = drupal_render_cache_get($elements);
    if ($cached_output !== FALSE) {
      return $cached_output;
    }
  }

  // If #markup is set, ensure #type is set. This allows to specify just #markup
  // on an element without setting #type.
  if (isset($elements['#markup']) && !isset($elements['#type'])) {
    $elements['#type'] = 'markup';
  }

  // If the default values for this element have not been loaded yet, populate
  // them.
  if (isset($elements['#type']) && empty($elements['#defaults_loaded'])) {
    $elements += element_info($elements['#type']);
  }

  // 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);
      }
    }
  }

  // Allow #pre_render to abort rendering.
  if (!empty($elements['#printed'])) {
    return;
  }

  // Get the children of the element, sorted by weight.
  $children = element_children($elements, TRUE);

  // Initialize this element's #children, unless a #pre_render callback already
  // preset #children.
  if (!isset($elements['#children'])) {
    $elements['#children'] = '';
  }
  // Call the element's #theme function if it is set. Then any children of the
  // element have to be rendered there.
  if (isset($elements['#theme'])) {
    $elements['#children'] = theme($elements['#theme'], $elements);
  }
  // If #theme was not set and the element has children, render them now.
  // This is the same process as drupal_render_children() but is inlined
  // for speed.
  if ($elements['#children'] == '') {
    foreach ($children as $key) {
      $elements['#children'] .= drupal_render($elements[$key]);
    }
  }

  // Let the theme functions in #theme_wrappers add markup around the rendered
  // children.
  if (isset($elements['#theme_wrappers'])) {
    foreach ($elements['#theme_wrappers'] as $theme_wrapper) {
      $elements['#children'] = theme($theme_wrapper, $elements);
    }
  }

  // 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)) {
        $elements['#children'] = $function($elements['#children'], $elements);
      }
    }
  }

  // Add any JavaScript state information associated with the element.
  if (!empty($elements['#states'])) {
    drupal_process_states($elements);
  }

  // Add additional libraries, CSS, JavaScript an other custom
  // attached data associated with this element.
  if (!empty($elements['#attached'])) {
    drupal_process_attached($elements);
  }

  $prefix = isset($elements['#prefix']) ? $elements['#prefix'] : '';
  $suffix = isset($elements['#suffix']) ? $elements['#suffix'] : '';
  $output = $prefix . $elements['#children'] . $suffix;

  // Cache the processed element if #cache is set.
  if (isset($elements['#cache'])) {
    drupal_render_cache_set($output, $elements);
  }

  $elements['#printed'] = TRUE;
  return $output;
}
?>

Comments

Some more

Some more information:

Fixed link for Page render

Fixed link for Page render drill down in Drupal 7:
http://sf2010.drupal.org/conference/sessions/page-render-drill-down-drup...

drupal_render() is not

drupal_render() is not working well with ajax. I'm not sure why or maybe my code is wrong. but when I create a loop with form elements and render is using drupal render then put it again in array so that my table will now have a textfields in rows. when I view source I've noticed that the ajax on class is gone.

<?php
  $options
= array();
  for (
$i = 0; $i < $total_parts; $i++) {
   
/** FOR ITEM CODE **/
   
$form['code'.$i] = array(
     
'#id' => 'code'.$i,
     
'#type' => 'textfield',
     
'#title' => NULL,
     
'#name' => 'code'.$i,
     
'#size' => 10,
    );
   
   
/** FOR DESCRIPTION **/
   
$form['description'.$i] = array(
     
'#type' => 'select',
     
'#title' => NULL,
     
'#id' => 'description'.$i,
     
'#name' => 'description'.$i,
     
'#options' => scheduler_get_parts_per_task($taskID),
     
'#attributes' => array('style' => 'width: 100%',),
    );

   
/** FOR UNITS **/
   
$form['units'.$i] = array(
     
'#id' => 'units'.$i,
     
'#type' => 'textfield',
     
'#title' => NULL,
     
'#name' => 'units'.$i,
     
'#size' => 5,
    );
 
   
/** FOR QTY **/
   
$form['qty'.$i] = array(
     
'#id' => 'qty'.$i,
     
'#type' => 'textfield',
     
'#title' => NULL,
     
'#name' => 'qty'.$i,
     
'#size' => 5,
    );

   
/** FOR PRICE **/
   
$form['price'.$i] = array(
     
'#id' => 'price'.$i,
     
'#type' => 'textfield',
     
'#title' => NULL,
     
'#name' => 'price'.$i,
     
'#size' => 10,
     
'#ajax' => array(
       
'callback' => 'ajax_multifield_callback',
       
'wrapper' => 'subtotal_wrapper-' . $i,
      ),
    );
   
   
/** FOR SUBTOTAL **/
   
$form['total_price'.$i] = array(
     
'#id' => 'subtotal'.$i,
     
'#type' => 'textfield',
     
'#title' => NULL,
     
'#name' => 'subtotal'.$i,
     
'#size' => 10,
     
'#prefix' => '<div id="subtotal_wrapper-' . $i . '">',
     
'#suffix' => '</div>',
    );

    if (!empty(
$form_state['values']['price'.$i])) {
     
$form['total_price'.$i]['#default_value'] = $form_state['values']['price'.$i];
     
$form['total_price'.$i]['#value'] = $form_state['values']['price'.$i];
    }
      
   
$options[$i] = array(
     
drupal_render($form['code'.$i]),
     
drupal_render($form['description'.$i]),
     
drupal_render($form['units'.$i]),
     
drupal_render($form['qty'.$i]),
     
drupal_render($form['price'.$i]),
     
drupal_render($form['total_price'.$i]),
    );
  }
 
 
$header = array(
     
'CODE' => array('data' => t('CODE'), 'width'=> '15%'),
     
'DESCRIPTION' => array('data' => t('DESCRIPTION'),'width'=> '50%'),
     
'UNITS' => array('data' => t('UNITS'), 'width'=> '10%'),
     
'QTY' => array('data' => t('QTY'), 'width'=> '10%'),
     
'PRICE' => array('data' => t('PRICE'), 'width'=> '15%'),
     
'SUBTOTAL' => array('data' => t('SUBTOTAL'), 'width'=> '15%'),
     
  );
   
 
$form['list']['bom_details'] = array(
   
'#theme' => 'table',
   
'#rows' => $options,
   
'#header' => $header,
   
'#empty' => t('You did not add parts to this task.'),
  );
?>

drupal_render and #ajax

I've come across exactly the same problem. I am trying to place a submit button with an ajax callback inside a table. If i use

$rows[] = array(
$form['my_submit'],
);

Then the form element (button in this case) is drawn outside the table and the ajax callback is working correctly

If instead I use:

$rows[] = array(
drupal_render($form['my_submit']),
);

Then the button is inside the table but the ajax callback is not called at all.

Using firebug I confirmed that "ajax processed" is missing in the second case.
So is something wrong with my approach or drupal_render can't handle #ajax that way?

Login or register to post comments