Problem/Motivation

At times, sections in a layout will need to be grouped by an HTML wrapper, such as <div> or <section>. Following are two such scenarios:

Problem 1

Themer needs a background texture or image to underlay several layout sections.

Problem 2

Themer needs flexibility to set differing container widths for different sections of the page. See sketch below.

Illustration of need to be able to wrap sections in an HTML wrapper

Proposed resolution

  • As the Field Group module wraps groups of fields with an HTML wrapper, so layout builder should be able to wrap one, several, or all layout sections with an HTML wrapper.
  • In addition, layout builder users should be able to add settings to the wrapper via the settings tray, such as selecting the wrapper's HTML tag or adding classes to the wrapper.

Based on comment #10:

  1. Create a "Group sections" link at the top of the layout builder.
  2. That link should open in the off-canvas dialog and use a form to select sections to be group together, excluding any already grouped sections. Only sections next to each other should be groupable.
  3. Also in that form, add whatever properties for the group.

Remaining tasks

User interface changes

Yes.

API changes

Data model changes

Release notes snippet

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Adrian83 created an issue. See original summary.

AaronMcHale’s picture

I can definatly agree with adding this, either as another button next to "Add Section" e.g. "Add Section Wrapper", or as a option in the Choose Layout UI.

tedbow’s picture

This could be done in contrib.

Override core/modules/layout_discovery/templates/layout.html.twig
Add "Wrap sections" link at the top of the form
Open up Settings Tray to select sections to wrap(or allow selecting via clicking sections)

I think it would be easier if core/modules/layout_discovery/templates/layout.html.twig didn't also render the

for the regions and that was in another template. Right now if you override layout.html.twig the theme could not separately override the region markup.
Adrian83’s picture

@tedbow Thank you for your explanation. It seems like some words are missing in your last paragraph, and I'm not sure if I'm understanding it.

AaronMcHale’s picture

Personally I don't see a reason we shouldn't do this in the core Layout Builder, a lot of uses of Layout Builder in practice will be for building things like home pages, showcase pages, product pages, etc, where you want to have greater control over the styling and make them look pretty, so I think a lot of people would find this useful.

bkosborne’s picture

+1 for this. An alternative (much less flexible) would be to define custom layouts that have all possible combinations of rows/columns that you may need. You could have custom settings for that layout like adding CSS classes. If we had a way to group sections together and apply settings to the group as a whole that would great.

I'm not quite sure I understand how this can be done in contrib based on #3. Maybe it can be expanded on?

AaronMcHale’s picture

I haven't checked if this already exists but the idea occurred to me, in addition to this possibly adding theme hook suggestions for individual sections and section wrappers, so you could do some custom theming using template files for individual sections.

If it doesn't already exist I imagine it wouldn't be too hard to implement and could be a first step for this idea.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jian he’s picture

Just like what Block Style Plugins doing for block and section component, what we need is just a "Section style plugins" to configure CSS classes for section.

tedbow’s picture

Ok I am not sure about description in #3 it was a while ago and things have changed in the module.

Now that #3027938: Abstract the contents of LayoutBuilderController into a render element and #2942661: Sections should have third-party settings have been committed this should actually be easier in contrib.

Since layout builder now uses a render element you can take advantage for #pre_render callbacks like this

/**
 * Implements hook_element_info_alter().
 */
function tester_element_info_alter(array &$info) {
  if (isset($info['layout_builder'])) {
    $info['layout_builder']['#pre_render'][] = '_tester_prerender_layout_builder';
  }
}

/**
 * Prerender callback for layout builder element.
 */
function _tester_prerender_layout_builder($element) {
  $element['layout_builder']['your_stuff'] = [
    '#markup' => 'your stuff here',
    '#weight' => -100000,
  ];
  return $element;
}

So something like

  1. Use the above to create a link at the top of the layout builder that says "Group sections"
  2. that link should open in the off-canvas dialog
  3. The link opens a form to select sections to be group together(exclude any already grouped sections and only sections next to each to be grouped)
  4. also in that form add whatever properties for the group
  5. You would probably want to save your setting with this #2942661: Sections should have third-party settings. Though would have to choose a section to store info about grouping somehow and maybe others just say they belong to group
  6. I am pretty sure on the rendering you would have to use hook_entity_view_alter to actually do the wrapping of sections.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

tim.plunkett’s picture

Issue summary: View changes
Issue tags: +Needs issue summary update

Site builder isn't a gendered role :)

bkosborne’s picture

Ted's proposal in #10 seems viable. I just worked thru something similar yesterday to prove it could work. The biggest hurdle I ran into is that the render array that's built for the layout element is pretty large and complex. I wanted to insert a link above each section, alongside the existing "delete" and "configure" links. In my own pre_render function, I ended up with something like this, which seems a bit brittle.

function _layout_builder_styles_pre_render($element) {
  // Find all sections, and add a link before the section for assigning a style
  // to the section.
  /** @var \Drupal\layout_builder\SectionStorageInterface $sectionStorage */
  $sectionStorage = $element['#section_storage'];
  foreach (Element::children($element['layout_builder']) as $key) {
    // Check if this render element is for a section by checking if includes the section array.
    if (isset($element['layout_builder'][$key]['layout-builder__section'])) {
      // Extract the section delta from this attribute. This seems to be the only place we can get to it.
      $delta = $element['layout_builder'][$key]['layout-builder__section']['#attributes']['data-layout-delta'];

      // Add a new link for configuring styles for this section.
      // No easy way to control the position of this link so that it appears after the other links, but before the
      // the section div. Probably need to splice the array rather then manipulate #weight
      $element['layout_builder'][$key]['layout_builder_styles'] = [
        '#type' => 'link',
        '#title' => t('Configure styles for section <span class="visually-hidden">@section</span>', ['@section' => $delta + 1]),
        '#url' => Url::fromRoute('layout_builder_styles.configure_section_style', [
          'section_storage_type' => $sectionStorage->getStorageType(),
          'section_storage' => $sectionStorage->getStorageId(),
          'delta' => $delta,
        ]),
        '#attributes' => [
          'class' => [
            'use-ajax',
            'layout-builder__link',
            'layout-builder__link--styles',
          ],
          'data-dialog-type' => 'dialog',
          'data-dialog-renderer' => 'off_canvas',
        ],
      ];
    }
  }
  return $element;
}
Adrian83’s picture

Issue summary: View changes
FileSize
42.65 KB

Updated IS Problem and Resolution sections. Did not remove tag because Remaining tasks need to be scoped yet.

Adrian83’s picture

Brainstorming after reading #10:
Speaking only about the UI of the off-canvas dialog (not considering technical challenges), is there a reason to not use classic Drupal tabledrag to nest layout builder sections within their wrapper group in the same way that Field Group module does for fields? Here is a screenshot of Field Groups in action:
fields grouped with tabledrag

Thinking out loud about the ramifications:

  1. A tabledrag form also allows the user to change the order of layout builder sections overall and within groups. Is there something in progress around this idea anyway, perhaps Provide a Layout Overview dialog that allows performing all actions in a text/form based method? Should section grouping be a part of that UI?
  2. With tabledrag, Field Groups allows multiple levels of nesting, so that several groups could themselves be wrapped into a group. See image below. Is this desirable behavior?

groups nested within groups

Adrian83’s picture

Could the issue Allow layout builder sections to be nested negate the need for section wrappers?

andrewmacpherson’s picture

Issue tags: +Accessibility

Some thoughts on how this relates to accessibility, and the (in-progress) accessibility plan.

So far there have been some discussion about the UI for configuring section wrappers. A dedicated dialog, and the overview UI have both been suggested. What hasn't been considered yet is that we need to convey the mere presence of section wrappers to assistive tech users. You need to understand the layout you are starting from, before diving into dialogs to make changes :-)

One challenging aspect is that the section wrappers proposed here are optional - is that right? As things stand, the other levels are all mandatory; every block is in a region, and every region is in a section. So we know there are exactly 3 layers of hierarchy to each layout, and the current accessibility plan is working on that assumption. But if we introduce section layers as an optional aspect, then the hierarchy will sometimes be 4 levels, and sometimes be 3 levels. That complicates things, especially as the current accessibility plan involves heading levels for section/region/block.

Re. #15.1: the overview UI could indeed be a good place for this. However the overview UI needs more work. Last time I looked at it, there wasn't enough context available. Basically it needs more columns, so each thing's type (wrapper, section, region, block) can be explicitly stated. Tables work by cross-referencing row and column names. I'll try to get around to updating the overview-UI issue.

#15.2: nesting section wrappers will complicate the level hierarchy even more, so we end up having to convey a tree of unlimited depth. We already do this for tabledrag in the Menu UI, but FWIW I don't think the current Menu UI is easy to understand in a non-visual way. In any case, we'd also need a way to convey the nested section wrappers outside of the tabledrag dialogs. At least all the items in Menu UI are the same type (they're all links). Nesting section wrappers means we'd have a hierarchy involving different types: wrapper > wrapper > ... > section > region > block.

#16: Nesting layout sections is the same problem, but more extreme. Now we'd have a tree of unlimited depth, with the additional semantics of levels which alternate in type (i.e. section > region > section > region > ... > block). I've never seen an accessible pattern to convey that to assistive technology. All bets are off :-(

Luke_Nuke’s picture

#3075939: Allow layouts to provide dynamic regions I'm bringing this proposition to your attention. It's much less invasive, and contrib modules then could easily implement configurable sublayouts/subsections which would be simply a part of section's configuration. It could solve this and other use cases, without messing with anything else, and is even BC.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Falco010’s picture

I agree with Luke_Nuke that adding the functionality to have nested regions that it is better than having a "Section wrapper"

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Wim Leers’s picture

Could a Layout Builder maintainer clarify how this relates to #3053145: Allow layout builder sections to be nested.? 🙏