Drupal Front End Development
Overview
Enable expert-level Drupal front end development capabilities. Provide comprehensive guidance for theme development, Twig templating, preprocessing, responsive design, and asset management for Drupal 8, 9, 10, and 11+.
When to Use This Skill
Invoke this skill when working with:
- •Theme development: Creating or customizing Drupal themes
- •Twig templates: Writing or modifying .twig template files
- •Preprocessing: Implementing preprocess functions for templates
- •Template suggestions: Adding custom template naming patterns
- •CSS/JS libraries: Managing theme assets and dependencies
- •Responsive design: Implementing breakpoints and mobile-first design
- •Rendering system: Understanding Drupal's rendering pipeline
- •Theme hooks: Implementing theme-related hooks and alterations
Core Capabilities
1. Theme Development
Build complete, standards-compliant Drupal themes with proper structure:
Quick start workflow:
- •Use theme template from
assets/theme-template/as starting point - •Replace
THEMENAMEwith your theme's machine name - •Replace
THEMELABELwith human-readable name - •Customize templates, CSS, JS, and libraries
- •Enable theme and configure via Appearance UI
Theme components:
- •
.info.yml- Theme metadata and configuration - •
.libraries.yml- CSS/JS library definitions - •
.theme- Preprocess functions and theme logic - •
.breakpoints.yml- Responsive breakpoints - •
templates/- Twig template files - •
css/- Stylesheets - •
js/- JavaScript files
Reference documentation:
- •
references/theming.md- Complete theming guide with examples
2. Twig Template System
Master Twig syntax and Drupal-specific extensions:
Twig fundamentals:
- •
{{ variable }}- Print variables - •
{% if/for/set %}- Control structures and logic - •
{# comment #}- Comments and documentation - •
{{ var|filter }}- Apply filters to variables - •
{% extends %}- Template inheritance - •
{% block %}- Define overridable sections
Drupal-specific Twig:
- •
{{ 'Text'|t }}- Translate strings - •
{{ attach_library('theme/library') }}- Load CSS/JS - •
{{ url('route.name') }}- Generate URLs - •
{{ path('route.name') }}- Generate paths - •
{{ file_url('public://image.jpg') }}- File URLs - •
{{ content|without('field') }}- Exclude fields
Common templates:
- •
page.html.twig- Page layout structure - •
node.html.twig- Node display - •
block.html.twig- Block rendering - •
field.html.twig- Field output - •
views-view.html.twig- Views output
3. Preprocessing Functions
Modify template variables before rendering:
Preprocess pattern:
function THEMENAME_preprocess_HOOK(&$variables) {
// Add or modify variables
// Access entities, services, configuration
// Prepare data for templates
}
Common preprocess hooks:
- •
hook_preprocess_page()- Page-level variables - •
hook_preprocess_node()- Node-specific data - •
hook_preprocess_block()- Block modifications - •
hook_preprocess_field()- Field alterations - •
hook_preprocess_html()- HTML document
Best practices:
- •Keep logic in preprocess, markup in templates
- •Use dependency injection when possible
- •Cache properly with cache contexts/tags
- •Document complex preprocessing
4. Template Suggestions
Provide specific templates for different contexts:
Suggestion patterns:
page--front.html.twig # Homepage
page--node--{nid}.html.twig # Specific node
page--node--{type}.html.twig # Content type
node--{type}--{viewmode}.html.twig # Type + view mode
block--{plugin-id}.html.twig # Specific block
field--{entity}--{field}.html.twig # Specific field
Adding suggestions:
function THEMENAME_theme_suggestions_HOOK_alter(array &$suggestions, array $variables) {
// Add custom suggestions
$suggestions[] = 'custom__suggestion';
}
5. CSS & JavaScript Management
Organize and load theme assets efficiently:
Library definition:
# THEMENAME.libraries.yml
global-styling:
version: 1.0
css:
base:
css/base/reset.css: {}
theme:
css/theme/styles.css: {}
js:
js/custom.js: {}
dependencies:
- core/drupal
Loading libraries:
- •Global: Define in
.info.yml - •Conditional: Use
attach_library()in templates - •Preprocessed: Attach in preprocess functions
Best practices:
- •Separate CSS into layers (base, layout, component, theme)
- •Use CSS aggregation in production
- •Minimize JavaScript dependencies
- •Leverage Drupal's asset library system
6. Responsive Design
Implement mobile-first, accessible designs:
Breakpoints definition:
# THEMENAME.breakpoints.yml THEMENAME.mobile: label: Mobile mediaQuery: 'screen and (min-width: 0px)' weight: 0 THEMENAME.tablet: label: Tablet mediaQuery: 'screen and (min-width: 768px)' weight: 1 THEMENAME.desktop: label: Desktop mediaQuery: 'screen and (min-width: 1024px)' weight: 2
Mobile-first approach:
- •Design for smallest screens first
- •Enhance for larger viewports
- •Use responsive images
- •Test across devices
- •Follow accessibility standards (WCAG)
Development Workflow
Creating a New Theme
- •
Scaffold the theme:
bashcp -r assets/theme-template/ /path/to/drupal/themes/custom/mytheme/ cd /path/to/drupal/themes/custom/mytheme/ # Rename files mv THEMENAME.info.yml mytheme.info.yml mv THEMENAME.libraries.yml mytheme.libraries.yml mv THEMENAME.theme mytheme.theme
- •
Update theme configuration:
- •Edit
mytheme.info.yml- Set name, regions, base theme - •Edit
mytheme.libraries.yml- Define CSS/JS libraries - •Replace
THEMENAMEwith your machine name - •Replace
THEMELABELwith your label
- •Edit
- •
Enable the theme:
bashddev drush cr # Enable via UI at /admin/appearance or: ddev drush config:set system.theme default mytheme -y
- •
Enable Twig debugging:
- •Copy
sites/default/default.services.ymltosites/default/services.yml - •Set
twig.config.debug: true - •Set
twig.config.auto_reload: true - •Set
twig.config.cache: false - •Run
ddev drush cr
- •Copy
- •
Develop and iterate:
- •Modify templates in
templates/ - •Update CSS in
css/ - •Clear cache frequently:
ddev drush cr - •Check browser console for errors
- •Modify templates in
Standard Development Workflow
- •Enable development settings (Twig debug, disable CSS/JS aggregation)
- •Create/modify templates based on suggestions from Twig debug
- •Implement preprocessing in
.themefile for complex data manipulation - •Add CSS/JS via libraries system
- •Test across browsers and devices
- •Clear cache after changes:
ddev drush cr
Finding Template Names
With Twig debugging enabled, inspect HTML source:
<!-- FILE NAME SUGGESTIONS: * page--node--123.html.twig * page--node--article.html.twig * page--node.html.twig x page.html.twig -->
The x indicates the active template. Others are suggestions you can create.
Common Patterns
Adding Custom Variables in Preprocess
function mytheme_preprocess_page(&$variables) {
// Add site slogan
$variables['site_slogan'] = \Drupal::config('system.site')->get('slogan');
// Add current user
$variables['is_logged_in'] = \Drupal::currentUser()->isAuthenticated();
// Add custom class
$variables['attributes']['class'][] = 'custom-page-class';
}
Template Inheritance
{# templates/page--article.html.twig #}
{% extends "page.html.twig" %}
{% block content %}
<div class="article-wrapper">
{{ parent() }}
</div>
{% endblock %}
Conditional Library Loading
function mytheme_preprocess_node(&$variables) {
if ($variables['node']->bundle() == 'article') {
$variables['#attached']['library'][] = 'mytheme/article-styles';
}
}
Accessing Field Values in Twig
{# Get field value #}
{{ node.field_custom.value }}
{# Check if field has value #}
{% if node.field_image|render %}
{{ content.field_image }}
{% endif %}
{# Loop through multi-value field #}
{% for item in node.field_tags %}
{{ item.entity.label }}
{% endfor %}
Best Practices
Theme Development
- •Base theme: Choose appropriate base (Olivero, Claro, or none)
- •Structure: Organize CSS logically (base, layout, components, theme)
- •Naming: Use BEM or similar CSS methodology
- •Comments: Document complex Twig logic and preprocessing
- •Performance: Optimize images, minimize CSS/JS, lazy load when possible
Twig Templates
- •Logic: Keep complex logic in preprocess, not templates
- •Filters: Use appropriate filters (|t, |clean_class, |safe_join)
- •Whitespace: Use {% spaceless %} to control output
- •Debugging: Enable Twig debugging during development only
- •Suggestions: Use specific templates only when needed
Preprocessing
- •Services: Use dependency injection in theme service subscribers
- •Caching: Add proper cache contexts and tags
- •Performance: Avoid heavy operations in frequently-called preprocessors
- •Organization: Group related preprocessing logically
CSS & JavaScript
- •Libraries: Group related assets into logical libraries
- •Dependencies: Declare all library dependencies
- •Loading: Load globally only when necessary
- •Aggregation: Enable in production for performance
Accessibility
- •Semantic HTML: Use proper elements (header, nav, main, etc.)
- •ARIA: Add labels and roles when needed
- •Keyboard: Ensure keyboard navigation works
- •Contrast: Meet WCAG color contrast requirements
- •Alt text: Provide for all images
Responsive Design
- •Mobile-first: Design for small screens, enhance for large
- •Breakpoints: Define logical breakpoints
- •Images: Use responsive image styles
- •Testing: Test across devices and screen sizes
- •Performance: Optimize for mobile networks
Troubleshooting
Template Changes Not Showing
- •Clear cache:
ddev drush cr - •Verify file location and naming
- •Check Twig debug for active template
- •Ensure library is properly defined
CSS/JS Not Loading
- •Check library definition in
.libraries.yml - •Verify file paths are correct
- •Ensure library is attached (globally or conditionally)
- •Clear cache and check browser console
Variables Not Available in Template
- •Check preprocess function naming
- •Verify variables are being set correctly
- •Use Twig debugging:
{{ dump() }} - •Clear cache after preprocessing changes
Twig Debugging Not Working
- •Verify
sites/default/services.ymlexists - •Check
twig.config.debug: trueis set - •Clear cache:
ddev drush cr - •Check file permissions
Resources
Reference Documentation
- •
references/theming.md- Comprehensive theming guide- •Twig syntax and filters
- •Template suggestions
- •Preprocessing patterns
- •Library management
- •Responsive design
- •Best practices
Asset Templates
- •
assets/theme-template/- Complete theme scaffold- •
.info.ymlwith regions and configuration - •
.libraries.ymlwith CSS/JS examples - •
.themewith preprocess examples - •Page template
- •CSS and JS starter files
- •
Searching References
# Find specific Twig filter grep -r "clean_class" references/ # Find preprocessing examples grep -r "preprocess_node" references/ # Find library patterns grep -r "libraries.yml" references/
Version Compatibility
Drupal 8 vs 9 vs 10 vs 11
- •Twig syntax: Consistent across all versions
- •Base themes: Some legacy themes removed in 10+
- •Libraries: Same structure across versions
- •jQuery: Drupal 9+ doesn't load jQuery by default
- •Claro: Admin theme standard in 9+
- •Olivero: Frontend theme standard in 10+
Migration Notes
- •When upgrading, check for deprecated base themes
- •Review jQuery dependencies
- •Test with current Twig version
- •Check for removed core templates
See Also
- •drupal-backend - Module development, hooks, APIs
- •drupal-tooling - DDEV and Drush development tools
- •Drupal Theming Guide - Official documentation
- •Twig Documentation - Twig syntax reference