ワンクリックで
drupal-render
Drupal render arrays — structure, cache metadata (tags, contexts, max-age), render elements, and markup safety.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Drupal render arrays — structure, cache metadata (tags, contexts, max-age), render elements, and markup safety.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
HTMX in Drupal 11.3+ core — the Htmx PHP fluent builder, dynamic forms with swapOob, partial routes with _htmx_route, response headers, and Drupal.behaviors integration. Use when building interactive UI without full-page reloads using Drupal's native HTMX support.
DDEV local development expertise. Use when working with DDEV projects, containers, configuration, or troubleshooting DDEV environments.
Custom Docker Compose local development patterns. Use when working with Docker-based local environments, container configuration, or troubleshooting Docker setups.
Drupal access control — permissions.yml, access callbacks, AccessResult, custom access checkers, and entity access.
Drupal Cache API — cache tags, contexts, max-age, cache bins, invalidation, and adding cache metadata to render arrays.
Drupal Composer management — requiring modules, updates, patches via composer-patches, and version constraints.
| name | drupal-render |
| description | Drupal render arrays — structure, cache metadata (tags, contexts, max-age), render elements, and markup safety. |
$build = [
'#type' => 'container',
'#attributes' => ['class' => ['my-wrapper']],
'content' => [
'#markup' => $this->t('Hello world'),
],
];
$build['content'] = [
'#markup' => $output,
'#cache' => [
'tags' => ['node:' . $node->id(), 'node_list'],
'contexts' => ['user.permissions', 'url.query_args'],
'max-age' => 3600,
],
];
| 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 |
| 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 |
// Plain text — always safe
$build['#plain_text'] = $user_input;
// Trusted markup — use Markup class
use Drupal\Core\Render\Markup;
$build['#markup'] = Markup::create('<strong>Safe</strong>');
// User input in markup — filter first
use Drupal\Component\Utility\Xss;
$build['#markup'] = Markup::create(Xss::filter($user_input));
// Admin-level markup — allows more tags
$build['#markup'] = Markup::create(Xss::filterAdmin($html));
// HTML tag
$build['heading'] = [
'#type' => 'html_tag',
'#tag' => 'h2',
'#value' => $this->t('Title'),
'#attributes' => ['class' => ['my-heading']],
];
// Link
$build['link'] = [
'#type' => 'link',
'#title' => $this->t('Go'),
'#url' => Url::fromRoute('entity.node.canonical', ['node' => $nid]),
'#attributes' => ['class' => ['button']],
];
// Entity view
$build['node'] = $this->entityTypeManager
->getViewBuilder('node')
->view($node, 'teaser');
// Inline template
$build['inline'] = [
'#type' => 'inline_template',
'#template' => '<div class="{{ class }}">{{ content }}</div>',
'#context' => ['class' => 'my-class', 'content' => $content],
];
$build['dynamic'] = [
'#lazy_builder' => [
'my_module.service:buildDynamicContent',
[$arg1, $arg2],
],
'#create_placeholder' => TRUE,
];
// Inject renderer service
public function __construct(
private readonly RendererInterface $renderer,
) {}
// Render to string
$html = $this->renderer->render($build);
// Render in isolated context (doesn't bubble cache)
$html = $this->renderer->renderInIsolation($build);