| name | drupal-render |
| description | Drupal render arrays — structure, cache metadata (tags, contexts, max-age), render elements, and markup safety. |
Drupal Render Arrays
Basic Structure
$build = [
'#type' => 'container',
'#attributes' => ['class' => ['my-wrapper']],
'content' => [
'#markup' => $this->t('Hello world'),
],
];
Cache Metadata (Always Required)
$build['content'] = [
'#markup' => $output,
'#cache' => [
'tags' => ['node:' . $node->id(), 'node_list'],
'contexts' => ['user.permissions', 'url.query_args'],
'max-age' => 3600,
],
];
Cache Tag Conventions
| Tag | Invalidates when |
|---|
node:123 | Node 123 is saved |
node_list | Any node is created/deleted |
user:456 | User 456 is saved |
taxonomy_term:789 | Term 789 is saved |
config:my_module.settings | Config is saved |
block_content:1 | Block content is saved |
Cache Contexts
| Context | Varies by |
|---|
user | Current user identity |
user.permissions | User's permissions |
user.roles | User's roles |
url | Full URL |
url.path | URL path only |
url.query_args | Query string |
languages | Current language |
session | Session data |
theme | Active theme |
Markup Safety
$build['#plain_text'] = $user_input;
use Drupal\Core\Render\Markup;
$build['#markup'] = Markup::create('<strong>Safe</strong>');
use Drupal\Component\Utility\Xss;
$build['#markup'] = Markup::create(Xss::filter($user_input));
$build['#markup'] = Markup::create(Xss::filterAdmin($html));
Render Elements
$build['heading'] = [
'#type' => 'html_tag',
'#tag' => 'h2',
'#value' => $this->t('Title'),
'#attributes' => ['class' => ['my-heading']],
];
$build['link'] = [
'#type' => 'link',
'#title' => $this->t('Go'),
'#url' => Url::fromRoute('entity.node.canonical', ['node' => $nid]),
'#attributes' => ['class' => ['button']],
];
$build['node'] = $this->entityTypeManager
->getViewBuilder('node')
->view($node, 'teaser');
$build['inline'] = [
'#type' => 'inline_template',
'#template' => '<div class="{{ class }}">{{ content }}</div>',
'#context' => ['class' => 'my-class', 'content' => $content],
];
Lazy Builder (Uncacheable Content)
$build['dynamic'] = [
'#lazy_builder' => [
'my_module.service:buildDynamicContent',
[$arg1, $arg2],
],
'#create_placeholder' => TRUE,
];
Rendering Programmatically
public function __construct(
private readonly RendererInterface $renderer,
) {}
$html = $this->renderer->render($build);
$html = $this->renderer->renderInIsolation($build);