Transitioning to Layout Builder in Drupal 8

Submitted on Oct 01, 2019, 6:11 p.m.

The Drupal 8 team have done a brilliant job of getting Layout Builder stable in core. Here's a tip on how you can transition to a layout builder-based theme while keeping your existing region-based and global block-based theme active for as long as needed.

The key is to create new template suggestions for your theme based on whether the current node type has Layout Builder enabled or not. If we can detect whether Layout Builder is enabled, then we can add new page, and node-level twig templates that will allow a completely different structure for the site - in this case, based on Layout Builder layouts.

Here are the page and node hooks called in a .theme file that add the additional template suggestions...

/**
* Implements hook_theme_suggestions_HOOK_alter() for page templates.
* @param array $suggestions
* @param array $variables
*/
function infonomic_theme_suggestions_page_alter(array &$suggestions, array $variables) {
if ($node = \Drupal::request()->attributes->get('node')) {
if(!empty($node) && $node instanceof \Drupal\node\NodeInterface) {
$type = $node->getType();
// Add content type suggestions.
array_splice($suggestions, 1, 0, 'page__' . $type);
// Add layout builder enabled template suggestions
try {
$entityTypeManager = \Drupal::service('entity_type.manager');
$storage = $entityTypeManager->getStorage('entity_view_display');
$view_display = $storage->load('node.' . $type . '.default');
if (!is_null($view_display)) {
$layout_builder_enabled = $view_display->getThirdPartySetting('layout_builder', 'enabled');
if($layout_builder_enabled) {
array_splice($suggestions, 1, 0, 'page__node__layout__' . $type);
array_splice($suggestions, 1, 0, 'page__node__layout');
}
}
} catch (Exception $e) {
\Drupal::logger('type')->error('Error in infonomic.theme infonomic_theme_suggestions_page_alter' . $e->getMessage());
}
}
}
}

 

/**
* Implements hook_theme_suggestions_HOOK_alter() for node templates.
* @param array $suggestions
* @param array $variables
*/
function infonomic_theme_suggestions_node_alter(array &$suggestions, array $variables) {
$node = $variables['elements']['#node'];
$view_mode = $variables['elements']['#view_mode'];
if(!empty($node) && $node instanceof \Drupal\node\NodeInterface) {
$type = $node->getType();
try {
$entityTypeManager = \Drupal::service('entity_type.manager');
$storage = $entityTypeManager->getStorage('entity_view_display');
$view_display = $storage->load('node.' . $type . '.default');
if (!is_null($view_display)) {
$layout_builder_enabled = $view_display->getThirdPartySetting('layout_builder', 'enabled');
if($layout_builder_enabled) {
array_splice($suggestions, 1, 0, 'node__layout__' . $type);
array_splice($suggestions, 1, 0, 'node__layout');
if($view_mode === "full") {
array_splice($suggestions, 1, 0, 'node__layout__full__' . $type);
array_splice($suggestions, 1, 0, 'node__layout__full');
}
}
}
} catch (Exception $e) {
\Drupal::logger('type')->error('Error in infonomic.theme infonomic_theme_suggestions_node_alter' . $e->getMessage());
}
}
}

Then add one or more of the following twig templates to your theme, for Layout Builder-specific layouts.

node--layout.html.twig
node--layout--<type>.html.twig
node--layout--full.html.twig
node--layout--full--<type>.html.twig
page--node--layout.html.twig
page--node--layout--<type>.html.twig