D8 Render Arrays - pierregermain/MyDrupal GitHub Wiki

Drupalizeme

Two Main Parts:

  1. Render arrays:
    • Render elements
    • Render caching
  2. Render pipeline

Render Element Properties:

  • #markup for simple HTML
  • #theme for using a template file
  • #type encapsulates complexity and will be tranformed to #markup or #theme automatically.

Value Properties:

  • #prefix, #title, #weight

Callable Properties:

  • #pre_render, #post_render

Examples

For a link you will use:

$output = array(
  '#type' => 'link',
  '#title' => 'About',
  '#url' => 'about',
);

For using a #item_list this implementation is defined in the drupal_common_theme()

'item_list' => array(
  'variables' => array(
    'items' => array(),
    'title' => '',
    'list_type' => 'ul',
    'wrapper_attributes' => array(),
    'attributes' => array(),
    'empty' => NULL,
    'context' => array()
  ),
),

So, to define instanciate an item_list we would do

$list = array(
  '#theme' = 'item_list',
  '#title' => Drupal::t('A list of items'),
  '#items' => array(
    array('value' => Drupal::t('Item one')),
    array('value' => Drupal::t('Item two'), 'attributes' => array('class' => 'blue')),
  ),
  '#attributes' => array('class' => array('my-item-list')),
);

Render Elements

They are shortcuts to render elements. Ex.) Links and Forms.

We use the #type to render predefined elements.

api

Output content with template files

Example:

From the controller

$build['marquee'] = [
  '#theme' => 'render_example_marquee',
  '#content' => $this->t('Hello world!'),
  '#attributes' => [
    'class' => ['my-marquee-element'],
    'direction' => 'right',
  ],
];

From the theme hook

/**
 * Implements hook_theme().
 */
function render_example_theme() {
  return [
    'render_example_marquee' => [
      'variables' => [
        'content' => '',
        'attributes' => array(),
      ],
    ],
  ];
}

From the twig file

{#
/**
 * @file
 * Default theme implementation for the marquee render element.
 *
 * Available variables:
 * - attributes: Attributes for the marquee tag.
 * - content: The text to display within the marquee tag.
 *
 * @ingroup themeable
 * @ingroup render_example
 */
#}
<marquee{{ attributes }}>{{ content }}</marquee>

From the theme preprocess

/**
 * Implements hook_preprocess_HOOK().
 */
function template_preprocess_render_example_marquee(&$variables) {
  // The $variables array contains the same keys as in the hook_theme() implementation
  // by default. Any new values added will be new variables available in the
  // template file.
  $variables['direction'] = $variables['attributes']['direction'];
  // Convert attributes to a proper \Drupal\Core\Template\Attribute object.
  $variables['attributes'] = new Attribute($variables['attributes']);
}

where:

  • "template" is the name of the template or module
  • "render_example_marquee" is the name of the theme

Big example


  /**
   * Examples of defining content using renderable arrays.
   *
   * Methods on a controller that are the target of a route should return a
   * renderable array which contains any content to display for that route.
   */
  public function testArrays($grouped) {

    $build = [];

    // Simple markup example.
    $build['simple'] = [
      '#markup' => '<p>' . t('markup of simple markup') . '</p>',
      '#description' => t('Example of using #markup'),
    ];

    // Example of using prefix and suffix.
    $build['simple_extras'] = [
      '#description' => t('Example of using #prefix and #suffix'),
      // Note the addition of '#type' => 'markup' in this example compared to
      // the one above. Because #markup is such a commonly used element type you
      // can exclude the '#type' => 'markup' line and it will be assumed
      // automatically if the '#markup' property is present.
      '#type' => 'markup',
      '#markup' => '<p>' . t('This one adds a prefix and suffix, which put a blockqoute tag around the item.') . '</p>',
      '#prefix' => '<blockquote>',
      '#suffix' => '</blockquote>',
    ];

    // Example of using theme hook.
    $build['theme_element'] = [
      // The '#theme' property can be set to any valid theme hook. For more
      // information about theme hooks, and to discover available theme hooks
      // that you can use when creating render arrays see the documentation for
      // hook_theme().
      //
      // Many of the most commonly used theme hooks are defined in
      // drupal_common_theme().
      '#theme' => 'item_list',
      '#title' => t('Example of using #theme'),
      // The #items property is specific to the 'item_list' theme hook, and
      // corresponds to the variable {{ items }} in the item-list.twig.html
      // template file.
      '#items' => [
        t('This is an item in the list'),
        t('This is some more text that we need in the list'),
      ],
    ];

    // Render arrays can be nested any level deep. This allows you to group
    // like things together. A great example of this is the $page array used in
    // conjunction with the page.html.twig template. The top level contains all
    // the regions, each of which contain the blocks placed in that region,
    // which in turn contain their own content. In fact, when this array is
    // ultimately displayed on a page it will be as part of the $page array.
    $build['nested_example'] = [
      '#description' => t('Example of nesting elements'),
      '#markup' => '<p>' . t('markup of nested_example') . '</p>',
      'nested_child_element' => [
        // An un-ordered list of links.
        // See /core/modules/system/templates/item-list.html.twig.
        '#theme' => 'item_list',
        '#title' => t('Links'),
        '#list_type' => 'ol',
        '#items' => [
          'one', 'two',
        ],
      ],
    ];

    // Example of adding a link to a nested array
    $build['nested_example']['another_nested_child'] = [
      // See \Drupal\Core\Render\Element\Link.
      '#type' => 'link',
      '#title' => t('A link to example.com'),
      '#url' => 'https://example.com',
    ];

    $output = [];
    // We are going to create a new output render array that pairs each
    // example with a set of helper render arrays. These are used to display
    // the description as a title and the unrendered content alongside the
    // examples.
    foreach (Element::children($build) as $key) {
      if (isset($build[$key])) {
        $output[$key] = [
          '#theme' => 'render_array',
          'description' => [
            '#type' => 'markup',
            '#markup' => isset($build[$key]['#description']) ? $build[$key]['#description'] : '',
          ],
          'rendered' => $build[$key],
          'unrendered' => [
            '#type' => 'markup',
            '#markup' => htmlentities(Variable::export($build[$key])),
          ],
        ];
      }
    }

    foreach (Element::properties($build) as $key) {
      $output[$key] = $build[$key];
    }

    $rendered = \Drupal::service('renderer')->render($output);

    var_dump($rendered);die;
    return $rendered;

  }
⚠️ **GitHub.com Fallback** ⚠️