"Components in Drupal can be defined as re-usable chunks of mark-up serving the atomic design principles"
There are many terms used for a component-based design that includes pattern library, design program, living style guide, and atomic composition. No matter what you call it, the idea is the same, breaking the page structure into smaller parts. On their own, these can be quite simple, but when these components are put together they form something meaningful and useful.
Why Component-Based Theming?
A good reason to use this method is maintenance. The frontend developer can create a content-based component, and submit it to another developer with little knowledge of the site (or Drupal) and it will make sense immediately. If an engineer needs to fix something on the footer there is a folder on items that contain everything related to the footer. It's the same for headers, pagers, and so on. This also allows these same components to be used in JavaScript and mobile apps.
Another reason is the trend toward style guides. If you are already using style guides as part of your design process then you are structuring your files in this way. Combining your style guide and your Drupal theme files in this way provides “a single source of truth.” Making a change to the style guide means that change will be reflected in the site itself and vice versa.
In short:
- One single component can be used by several types of content
- Any update to its template/style would automatically reflect this change across all those content types, pages or blocks as well
Component-based theming has become a popular topic in recent years, especially in the Drupal community. Thanks to the Twig architecture engine, Drupal 8/9 allows us to build them in a standard operation, and then use them as required for the Drupal templates. This is great news for those of us who want to create pre-systems that use patterns (e.g., atomic structure or molecule structure) and can call the style guide (always up to date) on a regular basis.
Component-Based Development in Drupal 8
Now, if we have to focus our attention on the component-based UI approach in relation to Drupal 8/9 web development, here are the key aspects:
Prerequisites
- Know basic site-building.
- Know how to set up a custom module/theme in Drupal 8.
- Know some basic twig.
- With the Twig engine in Drupal 8, you’re free to “joggle with” extensible templates; once you’ve defined a Twig template in one place, we get to reuse it across the whole Drupal website/app.
- The Component Libraries module allows you to set up template files (storing all their needed JS and CS), assign a namespace for them, and place them pretty much anywhere on your Drupal filespace (not just in your themes’ “templates” directory)
Using UI Patterns module in a component-based Drupal 8 theme
A great new Drupal 8 module, UI Patterns by Nuvole, has just been released. UI Patterns can expose stand-alone theme components (patterns) to Drupal and enables them to be used with the core Views module and well-known contrib modules like Field Group, Display Suite, and Panels. Getting started(example)
Install and enable the UI Patterns module just like you install modules in Drupal 8. Also, enable the UI Patterns Library module which shows a list of all patterns on a single page at your-site/patterns
. You can use this page to preview your patterns during development.
Top 6 Key Benefits of the Component-Based UI Design
- It Accelerates the method of Turning our Visual style of designing into a User Interface (UI). By using a component-driven UI approach translating a visual design into a user interface gets much easier.
- It confirms UX Consistency Across all of our Drupal-8 Websites.
- It Streamlines the complete Development method. e.g the already existing ones can always get further extended there's no need for new components to be designed which means saving both time and money.
- It Reduces the Time Spent on Setting Up the Functionality e.g Change made in one file reflects changes in all the components used in the drupal-8 website.
- It Enables us to Systematically Reuse our predefined Components on our site and also we can use these components in another drupal-8 website too.
- It Integrates Seamlessly into the Development Process, which means we would also gain better control over the whole development cycle.
Step 1: Defining patterns
To use a pattern, we need to define it first! Pattern definitions contain metadata about the pattern. Let’s create a pattern called basic_card. Start by creating the following file:
Note: Any changes to this YML file will only take effect after clearing Drupal’s cache.
THEME/patterns/basic_card/basic_card.patterns.yml
basic_card:
label: 'Basic Card'
description: Basic Card Example.
variants:
default:
label: Default card
description: Default basic card example.
highlighted:
label: Highlighted basic card
description: Highlighted Basic Card.
fields:
title:
type: text
label: Card Title
description: Basic Card title .
preview: 'Basic Card Title'
body:
type: text
label: Card Body
preview: This is description of basic card body.
image:
type: image
label: card Image
description: Image of the Basic Card.
preview: <img src="https://mdbootstrap.com/img/Photos/Others/images/43.jpg"/>
author:
type: text
label: Author By
description: Basic Card Author
preview: Admin
date:
type: date
label: Author On
description: Publish date and time
preview: 18 may
url:
type: url
label: link
description: link to content
libraries:
-
basic_card:
css:
component:
css/basic-card.css: {}
Here’s a description of some of the noteworthy elements of the definition.
Fields
Definition of fields supported by this pattern, keyed by field IDs. Each field must have:
- label: A human-readable label.
- description: A description.
- type: The type of data expected by the field. Example:
text|numeric|uri|boolean|collection|mixed
. - preview: A string or a Drupal renderable array. This is used to generate previews on the pattern library page
your-site/patterns.
Libraries
Define Drupal libraries for your pattern. This makes your UI pattern self-contained as these libraries are automatically loaded whenever you use the associated pattern.
Loading UI pattern libraries globally
What if we want to have the CSS / JS for the blockquote on all pages, even the ones where the pattern is not used? You can do this by referring to the pattern’s library from your THEME.libraries.yml
as follows:
global-styling:
# ...
dependencies:
- ui_patterns/basic_card.basic_card
# ...
In this way, you can style all block basic-card on the site without repeating the CSS elsewhere.
Variants
The UI Patterns also support component variants. Variants are different versions of the same UI pattern. Say, we want to have 2 types of block quotes:
1. Default version
2. Highlighted version
You can do this by including the variants key in your pattern definition as follows:
variants:
default:
label: Default card
description: Default basic card example.
highlighted:
label: Highlighted basic card
description: Highlighted Basic Card.
Step 1: Pattern templates
Once you’ve defined the pattern, create a basic_card.html.twig in your pattern’s directory. This will contain a template for the blockquote.
<div class="card" style="width: 18rem;">
{{ image }}
{% if author or date %}
<div class="pl-4 pt-1">
<span class="pr-5"><i class="fa fa-user"></i>
{{ author}}</span>
<span class="pr-5"><i class="fas fa-calendar- alt"></i>
{{ date }}</span>
</div>
{% endif %}
<div class="card-body">
<div class="">
</div>
<h5 class="card-title">{{ title }}</h5>
{% if body %}
<p class="card-text">{{ body }}</p>
{% endif %}
{% if url %}
<a href="{{ url|striptags }}" class="btn btn-primary">
Read more..</a>
{% endif %}
</div>
</div>
Here is the preview of the basic card on /patterns page
Step 2: Organizing patterns
It is quite possible to dump all the patterns in a single directory. However, once you start creating a bunch of patterns, it is highly recommended that you organize them nicely. One such approach is to organize them into directories as per Atomic Design principles.
As per atomic design principles, we can arrange the patterns as follows:
- Atoms: Basic building-blocks or the smallest of patterns. Example: A title, an image, a button.
- Molecules: Patterns that use one or more atoms. Example: A hero that comprises of a title, an image, and a button.
- Organisms: Patterns that use a combination of one or more molecules. Example: The page header comprising of a logo, a navbar, and a hero.
- Templates: Groups of organisms and smaller patterns, stitched together to form pages. Example: A standard page that has a header and a footer.
- Pages : Are “specific instances of templates” and they are “the most tangible”. Example: The home page or the contact page.
I like this school of thought and I use it in my projects like many other developers. However, you can organize your templates as per your team’s preferences.
Using UI Patterns with Views
Most Drupal sites need to provide pages with lists of content, for example, a blog page, a search results page, etc. With the UI Patterns Views module, you can render the items of these list pages consistently as UI patterns.
First, choose the row style as Pattern, then click on Settings to map the views fields to pattern fields.
To render Views rows as UI patterns, do the following:
Edit the View and in the Show field under the format section, choose Pattern.
Now, in the row style options dialog, choose a pattern — each row in the View will be rendered using this pattern.
Next, add some fields to the View — these fields will provide data to the UI pattern.
When all required fields are added to the view, click the Settings link for the Show field and map the View fields to the correct UI pattern fields.
Now, when you save the View and visit the page containing the View, each row will appear as a UI pattern.
Thanks.
Ishfaq Ahmad
Sr. Drupal site Builder/ Drupal Themer/Drupal Module Developer