Skip to content
Menu
Open World News Open World News
  • Privacy Policy
Open World News Open World News
PreviousNext: Creating a cards section with Layout Builder

PreviousNext: Creating a cards section with Layout Builder

Posted on May 9, 2024 by Michael G

Author:
Source

In this post, we explore building a cards section with Layout Builder.

 

by
lee.rowlands
/ 9 May 2024

The component will look something like the ‘Services’ section on our homepage*. If you’ve built websites over the last decade, you’ve probably built a component like this many times.

Screenshot of the services component on the PreviousNext website

The key aspects of the component are

  • A title
  • Some intro text
  • A series of cards. Each card has a URL, title, image and teaser text

If you’ve previously used paragraphs for modelling landing pages, you may immediately be thinking that your content model will be made up of paragraph type ‘cards’ with three fields as follows:

  • A title
  • A teaser field for the intro text
  • A multi-value cards field, which is itself another paragraph type ‘card’.

Or rather, because this is Layout Builder, you might be thinking of a block-content type called cards with those fields on it — leaning on paragraphs for the multi-value cards field.

Whilst that approach works well for paragraphs, it isn’t the best approach for Layout Builder:

  • There are some gnarly bugs with Layout Builder + Block Content + Paragraphs + Content moderation
  • It requires content-editors to fumble in the off-canvas editor to rearrange each card using drag-and-drop. We want a nice re-order experience like this:
Gif showing cards being dragged and drop with live preview

Making the most of layout plugins

Let’s instead pivot to a layout plugin for the cards component and think of it in terms of regions.

We have:

  • A layout title
  • An introduction region
  • A cards region

We probably already have a block-content type that consists of a WYSIWYG field — e.g., something like the Basic block content type in core. We can use that for the intro text.

So we need a card block content-type. But we probably want two. A lot of our cards will just point to other pages on the site — and it makes sense for the card to be built from fields on that page. If we put a teaser image and teaser text field on all our node-types, we can make use of them when creating a card for that page. We can also use these for meta-tags like the OpenGraph image. And all our node-types already have a title and URL. The second block-type is if we need to link to pages outside the site. So, the content models for those two block types are as follows:

  • For the internal card block-type, we need an entity-reference field to allow the content-editor to select the content to generate the card for
  • For the external card block-type, we need all the fields — title, image, teaser, URL

Defining layout plugins

Next, we need to define our layout plugin. We start with a layouts.yml file in our theme or module.

cards:
  label: Card grid
  category: Layouts
  template: layouts/cards
  icon_map:
    - [intro, intro, intro]
    - [c1, c2, c3]
    - [c4, c5, c6]
    - [c7, c8, c9]
    - [c10, c11, c12]
  regions:
    content:
      label: Cards
    intro:
      label: Introduction
  library: 'your_theme/card'

Note: the icon_map isn’t needed here, but it gives us a nice icon in the ‘Add section’ form.

With those pieces in place, we can use Layout builder restrictions to ensure only the right block-types can be placed in each region. The introduction region can be limited to the basic WYSIWYG block-type. The cards region can be limited to the internal and external card block-type.

This layout will use the default layout plugin, but we want a custom layout plugin with a title field in the configuration form. You can read more about creating a custom layout plugin from our previous post about creating a dynamic layout with flexible regions. This one will be much simpler. We just need a title field in the configuration form and a preprocess hook to expose that to our template. 

The first step of this is to add a ‘class’ entry to our layout definition.

cards:
  // ...
  class: Drupalyour_themeLayoutsCards
  // ...

Then, we need to create that class. 

<?php
namespace Drupalyour_themeLayouts;
use DrupalCoreFormFormStateInterface;
use DrupalCoreLayoutLayoutDefault;
/**
 * Defines a class for a layout that has a title option.
 */
class LayoutWithTitle extends LayoutDefault {
  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return parent::defaultConfiguration() + ['title' => ''];
  }
  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
    $build = parent::buildConfigurationForm($form, $form_state);
    $build['title'] = [
      '#weight' => -10,
      '#type' => 'textfield',
      '#default_value' => $this->configuration['title'],
      '#title' => $this->t('Title'),
      '#description' => $this->t('Provide an optional title for this section'),
    ];
    return $build;
  }
  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
    parent::submitConfigurationForm($form, $form_state);
    $this->configuration['title'] = $form_state->getValue('title');
  }
}

Then, in your theme you can preprocess to make this variable available to the template.

/**
 * Implements hook_preprocess_HOOK().
 */
function your_theme_preprocess_layout(array &$variables): void {
  // Add the title from LayoutWithTitle.
  $variables['title'] = $variables['content']['#settings']['title'] ?? NULL;
}

For optimum UX, we’d probably want to make Layout Builder Browser blocks, too. You can read more in our previous post about our approach to Layout Builder UX.

All that remains then is to theme the block-content types to match the design. For more on that, see our previous post on theming block-content types with Layout Builder.

As an extra enhancement, you could add integration with Layout Section Classes module to give content editors additional options like the number of cards shown across the page in the card grid.

Note: this component on our website is automated and built with Views, but there is often a need to build out curated equivalents.

Tagged

Layout Builder

Read more

Related Posts:

  • OnePlus 10T 5G Preview: Release Date, Specs, Price & More
    OnePlus 10T 5G Preview: Release Date, Specs, Price & More
  • Android 13 Beta 3 Review! Platform Stability and more
    Android 13 Beta 3 Review! Platform Stability and more
  • 15 AWESOME KDE Apps: I was WRONG about KDE applications! and more
    15 AWESOME KDE Apps: I was WRONG about KDE…
  • Apple is following Google’s lead on cleaning up iMessage reaction texts and more
    Apple is following Google's lead on cleaning up…
  • Fully Open Source M1 GPU Drivers Finally Work!! and more
    Fully Open Source M1 GPU Drivers Finally Work!! and more
  • How To Enable 64-bit Version Option in VirtualBox and more
    How To Enable 64-bit Version Option in VirtualBox and more

Recent Posts

  • [TUT] LoRa & LoRaWAN – MikroTik wAP LR8 kit mit The Things Network verbinden [4K | DE]
  • Mercado aguarda Powell e olha Trump, dados e Haddad | MINUTO TOURO DE OURO – 11/02/25
  • Dan Levy Gets Candid About Learning How To Act Differently After Schitt’s Creek: ‘It’s Physically…
  • Building a Rock Shelter & Overnight Stay in Heavy Snow 🏕️⛰️
  • Les milliardaires Elon Musk et Xavier Niel s’insultent copieusement

Categories

  • Android
  • Linux
  • News
  • Open Source
©2025 Open World News | Powered by Superb Themes
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.
Cookie SettingsAccept All
Manage consent

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
CookieDurationDescription
cookielawinfo-checkbox-analytics11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional11 monthsThe cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy11 monthsThe cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytics
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Advertisement
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
Others
Other uncategorized cookies are those that are being analyzed and have not been classified into a category as yet.
SAVE & ACCEPT