mcpField
D
drupal-render

drupal-render

github.com/edutrulDevelopment7349 installsUpdated 21w ago
Repository

About drupal-render

A reference for Drupal developers working with Render Arrays. It explains array construction, cache metadata, markup safety, render elements, lazy builders, and programmatic rendering.

Key features

  1. 01Build render arrays
  2. 02Set cache tags and contexts
  3. 03Handle markup safely
  4. 04Use render elements and lazy builders
  5. 05Render output through the renderer

Use cases

  1. 01Configure caching for dynamic content
  2. 02Render user input safely
  3. 03Build Drupal page content in code

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/edutrul/drupal-ai --skill drupal-render

After installing, type/drupal-renderin Claude Code to confirm it loaded.

Bundled filesREADME.md

Details

From the project README

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
TagInvalidates when
node:123Node 123 is saved
node_listAny node is created/deleted
user:456User 456 is saved
taxonomy_term:789Term 789 is saved
config:my_module.settingsConfig is saved
block_content:1Block content is saved
Cache Contexts
ContextVaries by
userCurrent user identity
user.permissionsUser's permissions
user.rolesUser's roles
urlFull URL
url.pathURL path only
url.query_argsQuery string
languagesCurrent language
sessionSession data
themeActive theme

Markup Safety

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

Render Elements

// 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],
];

Lazy Builder (Uncacheable Content)

$build['dynamic'] = [
  '#lazy_builder' => [
    'my_module.service:buildDynamicContent',
    [$arg1, $arg2],
  ],
  '#create_placeholder' => TRUE,
];

Rendering Programmatically

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

Comments

Markdown supported