n How to register custom layout with annotations in Drupal 8 & 9 | CodimTh

Please Disable Your Browser Adblock Extension for our site and Refresh This Page!

our ads are user friendly, we do not serve popup ads. We serve responsible ads!

Refresh Page
Skip to main content
On . By CodimTh
Category:

How to register custom layout with annotations in Drupal 8 & 9

 

The layout builder lets users change the way their content is presented. There was some projects in Drupal 7 which were similar to layout builder, but it was never as effective, or as user friendly like the Layout API. The layout, when set up, can affect a content type globally, or user can change layout per node.

The layout builder can be used in two ways. You can use it to create a layout for each content type on your site and you can also use it to create a layout for each individual piece of content.

Read this tuto If you want to read how to create custom layout in Drupal 8 & 9.

After you create custom layout it's possible to use a custom 'class' for a layout! This can be useful if, for example, you want your layout to have custom settings so that users can change the way the layout is rendered.

Here's an example layout class which provides a settings form to add classes to custom layout:

 

<?php

namespace Drupal\mymodule\Plugin\Layout;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Layout\LayoutDefault;
use Drupal\Core\Plugin\PluginFormInterface;

class MyLayoutClass extends LayoutDefault implements PluginFormInterface
{

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration()
  {
    return parent::defaultConfiguration() + [
        'layout_classes' => 'layout',
        'region_classes' => 'region',
      ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state)
  {
    $configuration = $this->getConfiguration();
    $form['layout_classes'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Layout classes'),
      '#default_value' => $configuration['layout_classes'],
    ];

    $form['region_classes'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Region classes'),
      '#default_value' => $configuration['region_classes'],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state)
  {
// any additional form validation that is required
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state)
  {
    $this->configuration['layout_classes'] = $form_state->getValue('layout_classes');
    $this->configuration['region_classes'] = $form_state->getValue('region_classes');
  }

}

 

Then your *.layouts.yml could look like:

custom_layout_2:
  label: Custom Layout 2
  category: Custom
  class: '\Drupal\mymodule\Plugin\Layout\MyLayoutClass'
  path: layouts/custom-layout-2
  template: custom-layout-2
  library: mymodule/custom-layout-2-library
  regions:
    main:
      label: Main content

 

And in your Twig template, you now have access to the {{ settings.layout_classes }} and {{ settings.region_classes }} variables. So, your layouts/custom-layout-2/custom-layout-2.html.twig could look like:

{#
/**
 * @file
 * Default theme implementation to display a one plus four grid layout.
 *
 * Available variables:
 * - content: The content for this layout.
 * - attributes: HTML attributes for the layout <div>.
 *
 * @ingroup themeable
 */
#}

<div class="custom-layout-2 {{ settings.layout_classes }}">
  <div class="main-region {{ settings.region_classes }} ">
    {{ content.main }}
  </div>
</div>

 

The form settings is like this:

custom layout classes

 

 

and after you submit the form your classes are added to twig file like this:

custom layout classes twig

 

 

How to register custom layout with annotations in Drupal 8 & 9

 

If you have a one-off layout that uses a custom class, it can be easier register it in PHP with annotations.

To do this, you put a @Layout annotation above the layout class using the same keys as in the *.layouts.yml. Here's a simple example:

 

<?php

namespace Drupal\mymodule\Plugin\Layout;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Layout\LayoutDefault;
use Drupal\Core\Plugin\PluginFormInterface;

/**
 * Custom Layout.
 *
 * @Layout(
 *   id = "custom_layout_2",
 *   label = @Translation("Custom Layout 2"),
 *   category = @Translation("Custom"),
 *   path = "layouts/custom-layout-2",
 *   template = "custom-layout-2",
 *   library = "mymodule/custom-layout-2-library",
 *   regions = {
 *     "main" = {
 *       "label" = @Translation("Main content"),
 *     }
 *   }
 * )
 */
class MyLayoutClass extends LayoutDefault implements PluginFormInterface
{

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration()
  {
    return parent::defaultConfiguration() + [
        'layout_classes' => 'layout',
        'region_classes' => 'region',
      ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state)
  {
    $configuration = $this->getConfiguration();
    $form['layout_classes'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Layout classes'),
      '#default_value' => $configuration['layout_classes'],
    ];

    $form['region_classes'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Region classes'),
      '#default_value' => $configuration['region_classes'],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state)
  {
// any additional form validation that is required
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state)
  {
    $this->configuration['layout_classes'] = $form_state->getValue('layout_classes');
    $this->configuration['region_classes'] = $form_state->getValue('region_classes');
  }

}

 

Each layout definition must have the following keys:

label
The human-readable name of the layout.
category
The human-readable category to which the layout belongs.
regions
Array of regions in the layout. The keys are the regions' machine names and the
values are sub-arrays containing the following elements:
  • label (required): The human-readable name of the region.
theme_hook
If specified, the theme hook which will be used to render this layout. It's
expected that the module or theme which registers the layout will also register this
theme hook. If you use this key, you cannot use template.
template
If specified, the template to use to render the layout, relative to the given
path, without the .html.twig extension. If given, the template will be
automagically registered with the theme system. If you use this key, you cannot use
theme_hook.

Each layout definition can also have the following optional keys:

default_region
Machine-readable name of the default region.
icon_map
YML structure to describe the icon used in the layout builder interface
description
Optional description of the layout.
path
Path (relative to the module or theme) to resources like icon or template.
library
The asset library to load for this layout. If given, it's expected that the module
or theme which registers the layout has also registered the library in its
*.libraries.yml file. If you use this key, you cannot use css

Riadh Rahmi

Senior Web Developer PHP/Drupal & Laravel

I am a senior web developer, I have experience in planning and developing large scale dynamic web solutions especially in Drupal & Laravel.

Web Posts

Search

Page Facebook