About drupal-twig
A reference skill for Drupal Twig templates, aimed at developers building themes and rendering Drupal content. It covers translation, library attachment, safe markup, debugging, and component usage.
Key features
- 01Twig auto-escaping guidance
- 02Translatable strings with `{% trans %}`
- 03Attach CSS and JS libraries
- 04Safe content and field rendering
- 05Debugging with `dump()`
- 06Drupal SDC component examples
Use cases
- 01Reviewing Twig templates for safe output
- 02Adding translated strings to templates
- 03Attaching theme libraries to markup
- 04Rendering fields and SDC components
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ edutrul/ drupal-ai --skill drupal-twigAfter installing, type/drupal-twigin Claude Code to confirm it loaded.
Bundled filesREADME.md
Details
From the project READMEDrupal Twig Best Practices
Core Rules
- Variables are auto-escaped — never use
|escapeunless you know the source - Use
{% trans %}for all user-facing strings - Use
{{ attach_library() }}for CSS/JS — never inline - Never access services or run queries in Twig
Translation
{# Simple string #}
{% trans %}Hello world{% endtrans %}
{# With variable #}
{% trans %}Hello {{ name }}{% endtrans %}
{# Plural #}
{% trans %}
@count item
{% plural count %}
@count items
{% endtrans %}
Attaching Libraries
{{ attach_library('my_module/my-library') }}
{{ attach_library('mytheme/component-name') }}
Safe Markup
{# Already sanitized by Drupal — safe to use |raw #}
{{ content.body }}
{{ content|raw }}
{# Render a single field #}
{{ content.field_image }}
{# Render with a specific view mode #}
{{ node|view('teaser') }}
Debugging
{# Dump variables (requires Twig debug enabled) #}
{{ dump(content) }}
{{ dump(node) }}
{{ dump(_context|keys) }}
Common Variables
{# Node template #}
{{ node.title.value }}
{{ node.bundle() }}
{{ node.id() }}
{{ node.isPublished() }}
{# Check if field is set #}
{% if content.field_image|render %}
{{ content.field_image }}
{% endif %}
{# Field items loop #}
{% for item in node.field_tags %}
{{ item.entity.name.value }}
{% endfor %}
SDC Components (Drupal 10.3+)
{# Use a component #}
{% include 'mytheme:button' with {
label: 'Click me',
url: path('entity.node.canonical', {node: node.id()}),
variant: 'primary',
} %}
Template Suggestions Hook
#[Hook('theme_suggestions_node_alter')]
public function themeSuggestionsNodeAlter(array &$suggestions, array $variables): void {
$node = $variables['elements']['#node'];
$view_mode = $variables['elements']['#view_mode'];
$suggestions[] = 'node__' . $node->bundle() . '__' . $view_mode;
}
Comments
Markdown supported