20 Jan 2026
Drupal.org aggregator
Specbee: Understanding Entity Reference Revisions in Drupal
Losing track of revisions after repeated edits in Drupal? Learn how Entity Reference Revisions preserves content integrity by ensuring safe edits, accurate history, and reliable workflows.
20 Jan 2026 5:44am GMT
19 Jan 2026
Drupal.org aggregator
Aten Design Group: Simplified Drupal Views Styling with Custom Style Plugins
Simplified Drupal Views Styling with Custom Style Plugins

Drupal's shift to component based styling has been a much welcome change to how we plan out and organize a Drupal theme. While this has gone a long way in helping reduce duplication within our styles, figuring out the best way to apply the component styles to Drupal structures can sometimes be a challenge. Modules like SDC: Display are beginning to bridge this gap, but this doesn't address every use case. One such scenario is applying component styles to a Views list.
No One Size Fits All
Let's imagine that we have a simple grid component in our design system. This simple component accepts props for the items and column_count. This simple grid is going to be used all throughout the project and specifically across multiple View displays. There are a couple of common approaches to tackle this.
Apply the Styles Globally
One option is to make the grid styles globally available, then use something like the HTML List plugin provided by Views to add the classes we need through the UI. While it keeps all of the config in Drupal's UI where other developers might first look to replicate and make changes, we've made styles global that we likely don't need on every page. It also requires detailed knowledge of the design system to know which CSS classes to apply and where to apply them to accomplish the desired styles.
Override View Twig Templates
Another option is to move all of the styling to the Twig templates for those View displays. For example, on a list of blog posts we could create a template like views-view-unformatted-blog-posts.html.twig. Once we have that template, we call our grid component:
{{ include('my_theme:grid', { items: rows|map(row => row.content), column_count: '4', }, with_context = false) }}
Now anytime we want to apply this to a new View, all we have to do is copy/paste this into a template for that View and update any needed props. The drawback here is that the Views UI won't reflect where the styles are coming from, or how to recreate them, and a front-end developer familiar with the theme would have to do the copy/pasting.
Moving Back into the UI
Creating a custom Views style plugin gives us the best of both worlds. We still can leverage all the benefits of SDC, but expose all the options to site builders to apply to Views keeping the UI intact with the output. Let's walk through the steps to get it done.
To start, in a custom module, create a new style plugin within \Drupal\my_module\Plugin\views\style. This plugin should extend \Drupal\views\Plugin\views\style\StylePluginBase. At its simplest, all a style plugin needs is:
<?php declare(strict_types=1); namespace Drupal\my_module\Plugin\views\style; use Drupal\views\Plugin\views\style\StylePluginBase; /** * Style plugin to render results in a grid. * * @ingroup views_style_plugins * * @ViewsStyle( * id = "my_module_grid", * title = @Translation("Custom Grid"), * help = @Translation("Render results in a grid layout."), * theme = "views_view_my_module_grid", * display_types = { "normal" } * ) */ class MyModuleGrid extends StylePluginBase { }
This will provide a new option when configuring a View style called "Custom Grid" without extra configuration. It will output the View rows through a new Twig template defined in the theme option within the annotation. In our case: views-view-my-module-grid.html.twig.
Before getting into the markup, we need to align our new template with other View style plugin templates:
/** * Implements template_preprocess_HOOK(). */ function my_module_preprocess_views_view_my_module_grid(&$variables) { template_preprocess_views_view_unformatted($variables); }
From there you can customize your new template as you would a standard views-view-my-unformatted.html.twig. template.
Adding Configuration to the Plugin
Currently the way our style plugin is set up assumes we want it to work the same everywhere. However most front-end systems like SDC allow components to be modified by passing props into them. For a grid component, allowing for the number of columns to be configured would give this component more flexibility. We can easily choose which props are exposed in Views to site builders.
First, we modify our plugin class:
class MyModuleGrid extends StylePluginBase { /** * {@inheritdoc} */ protected function defineOptions(): array { return parent::defineOptions() + [ 'column_count' => ['default' => '3'], ]; } /** * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $form['column_count'] = [ '#type' => 'select', '#title' => $this->t('Column Count'), '#description' => $this->t('The number of columns for the grid to use on desktop.'), '#default_value' => $this->options['column_count'], '#options' => [ '3' => $this->t('Three Columns'), '4' => $this->t('Four Columns'), ], ]; } }
The ::defineOptions() method here provides the default settings for what our form will control. In this case, setting the column_count to 3. ::buildOptionsForm() does exactly what it sounds like: it creates the form that site builders will interact with.
Next, we need to make these options available to our Twig file. To do this, we update our preprocess function from earlier:
function my_module_preprocess_views_view_my_module_grid(&$variables) { $options = $variables['view']->style_plugin->options; $variables['options'] = $options; template_preprocess_views_view_unformatted($variables); }
Finally, we update our Twig template to use the new options:
{{ include('my_theme:grid', { items: rows|map(row => row.content), column_count: options.column_count, }, with_context = false) }}
Scratching the Surface
With all this in place, we can now update our Views to use this new Style plugin. And anyone with a basic understanding of Drupal views can recreate these styles when setting up new Views. There's a lot more that can be done with Views style plugins. What other Views style plugins functionality do you want us to demonstrate? Let us know in the comments.

19 Jan 2026 8:23pm GMT
Talking Drupal: Talking Drupal #536 - Composer Patches 2.0
Today we are talking about Patching Drupal, Composer, and Composer Patches 2.0 with guest Cameron Eagans. We'll also cover Configuration Development as our module of the week.
For show notes visit: https://www.talkingDrupal.com/536
Topics
- What is Composer Patches 2.0
- Exploring Community Dynamics in Composer Patches
- The Genesis of Composer Patches
- The Decision to Use GitHub
- Broadening Composer Patches Beyond Drupal
- The Evolution to Composer Patches 2.0
- Understanding Workflow Complexities
- Refining User Experience in 2.0
- New Features and Enhancements in 2.0
- Navigating Controversial Changes in 2.0
- The Role of Dependency Patches
- Introducing patches.lock.json
- Best Practices for Patch Management
- Transitioning to Git Patching
- Exploring New APIs in Composer Patches 2.0
- Understanding Capabilities and Events
- Transitioning to Composer Patches 2.0
- Future of Composer Patches and Community Contributions
Resources
Guests
Cameron Eagans - cweagans.net cweagans
Hosts
Nic Laflin - nLighteneddevelopment.com nicxvan John Picozzi - epam.com johnpicozzi Andy Giles - dripyard.com andyg5000
MOTW Correspondent
Martin Anderson-Clutz - mandclu.com mandclu
- Brief description:
- Do you maintain modules that provide configuration files? There's a module that can help manage them.
- Module name/project name:
- Brief history
- How old: created in Apr 2014 by chx, though recent releases are by Joachim Noreiko (joachim)
- Versions available: 8.x-1.11, which works with Drupal 9.3, 10, and 11
- Maintainership
- Actively maintained
- Security coverage
- Test coverage
- Number of open issues: 36 open issues, 7 of which are bugs
- Usage stats:
- 2,391 sites
- Module features and usage
- The module really provides three useful features. First, it can ensure specific configuration files are automatically imported on every request, as though the contents were pasted into the core "single import" form
- Second, it can automatically export specific configuration objects into files whenever the object is updated. You provide a list of filenames and the module will derive the objects that need to be exported.
- Finally, it provides a drush command that can be used to generate all the necessary configuration files for a specific project. You put a list of the files into the project's info.yml file, and then with a single command a fresh copy of all the specified files will be generated and placed directly into the project's configuration folder.
- For obvious reasons this is not something you should ever have enabled in production, so definitely a best practice to pull this in using the require-dev composer command
19 Jan 2026 7:00pm GMT
Symfony Blog
SymfonyLive Paris 2026: “Édition simultanée : Facile avec Symfony UX“
SymfonyLive Paris 2026, conference in French language only, will take place from March 26 to 27! The schedule is currently being revealed as we go along. More details are available here. 🎤 Nouvelle talk annoncé à SymfonyLive Paris 2026 ! Avec…
19 Jan 2026 11:00am GMT
18 Jan 2026
Symfony Blog
A Week of Symfony #994 (January 12–18, 2026)
This week, Symfony development activity focused on improving the HTTP Cache attribute and making some changes to controller event attributes. Meanwhile, we published more information about the upcoming SymfonyLive Paris 2026 conference. Lastly, we introduced…
18 Jan 2026 8:18am GMT
14 Jan 2026
Symfony Blog
Introducing the Symfony 8 Certification
Symfony 8 was released at the end of November 2025, alongside Symfony 7.4. Both versions share the exact same features, but Symfony 8.0 removes all deprecated features and requires PHP 8.4 or higher. Today, we're introducing the new certification exam for…
14 Jan 2026 9:27am GMT