Commit 47ff6423 authored by Jennifer Hodgdon's avatar Jennifer Hodgdon
Browse files

Issue #2015307 by thedavidmeister, meeli, Cottser: Overhaul docs for...

Issue #2015307 by thedavidmeister, meeli, Cottser: Overhaul docs for drupal_render so they actually say what the function does and what properties it uses
parent a6c63d4f
Loading
Loading
Loading
Loading
+82 −61
Changes for core/includes/common.inc: 82 added lines, 61 removed lines.
Original line number Diff line number Diff line
@@ -3658,79 +3658,100 @@ function drupal_render_page($page) {
/**
 * 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, each
 * child is itself rendered by a call to drupal_render(), and the results are
 * concatenated.
 *
 * 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., details add the required markup
 * for a details element 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().
 * 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.
 *
 * The process of rendering an element is recursive unless the element defines
 * an implemented theme hook in #theme. During each call to drupal_render(), the
 * outermost renderable array (also known as an "element") is processed using
 * the following steps:
 *   - If this element has already been printed (#printed = TRUE) or the user
 *     does not have access to it (#access = FALSE), then an empty string is
 *     returned.
 *   - If this element has #cache defined then the cached markup for this
 *     element will be returned if it exists in drupal_render()'s cache. 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.
 *       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
 *     - 'bin': Specify a cache bin to cache the element in. Default is 'cache'.
 *   - If this element has #type defined and the default attributes for this
 *     element have not already been merged in (#defaults_loaded = TRUE) then
 *     the defaults for this type of element, defined in hook_element_info(),
 *     are merged into the array. #defaults_loaded is set by functions that
 *     process render arrays and call element_info() before passing the array to
 *     drupal_render(), such as form_builder() in the Form API.
 *   - If this element has an array of #pre_render functions defined, they are
 *     called sequentially to modify the element before rendering. After all the
 *     #pre_render functions have been called, #printed is checked a second time
 *     in case a #pre_render function flags the element as printed.
 *   - The child elements of this element are sorted by weight using uasort() in
 *     element_children(). 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 an empty string.
 *   - The main render phase to produce #children for this element takes place:
 *     - If this element has #theme defined and #theme is an implemented theme
 *       hook/suggestion then theme() is called and must render both the element
 *       and its children. If #render_children is set, theme() will not be
 *       called. #render_children is usually only set internally by theme() so
 *       that we can avoid the situation where drupal_render() called from
 *       within a theme preprocess function creates an infinite loop.
 *     - If this element does not have a defined #theme, or the defined #theme
 *       hook is not implemented, or #render_children is set, then
 *       drupal_render() is called recursively on each of the child elements of
 *       this element, and the result of each is concatenated onto #children.
 *       This is skipped if #children is not empty at this point.
 *     - Once #children has been rendered for this element, if #theme is not
 *       implemented and #markup is set for this element, #markup will be
 *       prepended to #children.
 *   - If this element has #states defined then JavaScript state information is
 *     added to this element's #attached attribute by drupal_process_states().
 *   - If this element has #attached defined then any required libraries,
 *     JavaScript, CSS, or other custom data are added to the current page by
 *     drupal_process_attached().
 *   - If this element has an array of #theme_wrappers defined and
 *     #render_children is not set, #children is then re-rendered by passing the
 *     element in its current state to theme() successively for each item in
 *     #theme_wrappers.
 *   - If this element has an array of #post_render functions defined, they are
 *     called sequentially to modify the rendered #children. Unlike #pre_render
 *     functions, #post_render functions are passed both the rendered #children
 *     attribute as a string and the element itself.
 *   - If this element has #prefix and/or #suffix defined, they are concatenated
 *     to #children.
 *   - If this element has #cache defined, the rendered output of this element
 *     is saved to drupal_render()'s internal cache.
 *   - #printed is set to TRUE for this element to ensure that it is only
 *     rendered once.
 *   - The final value of #children for this element is returned as the rendered
 *     output.
 *
 * @param array $elements
 *   The structured array describing the data to be rendered.
 *
 * @return string
 *   The rendered HTML.
 *
 * @see element_info()
 * @see theme()
 * @see drupal_process_states()
 * @see drupal_process_attached()
 */
function drupal_render(&$elements) {
  // Early-return nothing if user does not have access.