Problem/Motivation

See #2884601: Add a Layout Builder to core

To test:
Go to the "Manage Display" page for any bundle.
For example, /admin/structure/types/manage/article/display
Check the box for "Allow each content item to have its layout customized."
On an entity page, like /node/1, click the "Layout" tab (or go to /node/1/layout).

Proposed resolution

This issue solves the ability for individual fieldable entities to define their own layout and is step 1 in our larger layout solution documented by #2884601: Add a Layout Builder to core

Remaining tasks

  • Framework Manager Review/Signoff
  • Release Manager Review/Signoff

Blockers:
NONE

Followup roadmap (EclipseGc's suggested priorities)

User interface changes

Adds a opt-in Layout Builder UI

API changes

N/A

Data model changes

N/A

CommentFileSizeAuthor
#117 2905922-117.patch169.38 KBtedbow
#99 2905922-layout_builder-99.patch186.68 KBtim.plunkett
#99 2905922-layout_builder-99-interdiff.txt6.04 KBtim.plunkett
#97 2905922-layout_builder-97.patch185.59 KBtim.plunkett
#97 2905922-layout_builder-97-interdiff.txt1.57 KBtim.plunkett
#92 2905922-layout_builder-91.patch185.59 KBtim.plunkett
#92 2905922-layout_builder-91-interdiff.txt6.16 KBtim.plunkett
#87 2905922-layout_builder-87.patch179.43 KBtim.plunkett
#87 2905922-layout_builder-87-interdiff.txt5.13 KBtim.plunkett
#84 2905922-layout_builder-84-interdiff.txt974 bytestim.plunkett
#84 2905922-layout_builder-84.patch180.45 KBtim.plunkett
#82 2905922-layout_builder-82-interdiff.txt7.87 KBtim.plunkett
#82 2905922-layout_builder-82.patch180.24 KBtim.plunkett
#75 2905922-layout_builder-75.patch179.66 KBtim.plunkett
#71 2905922-layout_builder-71.patch203.6 KBtim.plunkett
#71 2905922-layout_builder-71-interdiff.txt4.56 KBtim.plunkett
#70 2905922-layout_builder-70.patch195.82 KBtim.plunkett
#70 2905922-layout_builder-70-interdiff.txt7.19 KBtim.plunkett
#68 2905922-layout_builder-68.patch194.61 KBtim.plunkett
#68 2905922-layout_builder-68-interdiff.txt11.55 KBtim.plunkett
#67 Backend_Editor.png12.08 KBEclipseGc
#62 icons_in_tray.png20.35 KBxjm
#62 am_I_sure_of_what.png13.94 KBxjm
#58 2905922-layout_builder-58.patch188.9 KBtim.plunkett
#58 2905922-layout_builder-58-interdiff.txt19.02 KBtim.plunkett
#57 2905922-layout_builder-57.patch189.66 KBtim.plunkett
#57 2905922-layout_builder-57-interdiff.txt7.65 KBtim.plunkett
#53 2905922-layout_builder-53.patch187.84 KBtim.plunkett
#53 2905922-layout_builder-53-interdiff.txt17.69 KBtim.plunkett
#51 2905922-layout_builder-51.patch183.73 KBtim.plunkett
#51 2905922-layout_builder-51-interdiff.txt15.32 KBtim.plunkett
#50 2905922-layout_builder-50.patch175.75 KBtim.plunkett
#50 2905922-layout_builder-50-interdiff.txt50.48 KBtim.plunkett
#36 Screen Shot 2017-10-19 at 12.22.54 PM.png56.31 KBwebchick
#32 2905922-layout_builder-32-do-not-test.patch152.77 KBtim.plunkett
#31 2905922-layout_builder-31.patch169.47 KBtim.plunkett
#30 2905922-layout_builder-30-interdiff.txt21 KBtim.plunkett
#30 2905922-layout_builder-30.patch173.7 KBtim.plunkett
#25 2905922-25.png177.56 KBvijaycs85
#23 2905922-layout_builder-23.patch170.28 KBtim.plunkett
#23 2905922-layout_builder-23-interdiff.txt23.31 KBtim.plunkett
#21 2905922-layout_builder-21.patch163.77 KBtim.plunkett
#21 2905922-layout_builder-21-interdiff.txt2.72 KBtim.plunkett
#17 2905922-layout_builder-17.patch164.6 KBtim.plunkett
#17 2905922-layout_builder-17-interdiff.txt37.9 KBtim.plunkett
#16 2905922-layout_builder-16.patch160.55 KBtim.plunkett
#16 2905922-layout_builder-16-interdiff.txt25.89 KBtim.plunkett
#14 2905922-layout_builder-14.patch159.16 KBtim.plunkett
#14 2905922-layout_builder-14-interdiff.txt1.58 KBtim.plunkett
#11 2905922-layout_builder-11.patch142.06 KBtim.plunkett
#11 2905922-layout_builder-11-interdiff.txt53.08 KBtim.plunkett
#10 2905922-layout_builder-10-interdiff.txt508 bytestim.plunkett
#10 2905922-layout_builder-10.patch142.21 KBtim.plunkett
#8 2905922-layout_builder-8.patch142.18 KBtim.plunkett
#8 2905922-layout_builder-8-interdiff.txt33.96 KBtim.plunkett
#7 2905922-layout_builder-7.patch126.71 KBtim.plunkett
#7 2905922-layout_builder-7-interdiff.txt11.12 KBtim.plunkett
#2 2905922-layout_builder-2.patch127.09 KBtim.plunkett
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tim.plunkett created an issue. See original summary.

tim.plunkett’s picture

tim.plunkett’s picture

Issue summary: View changes
Chi’s picture

You may find this interesting. The recent version of Snippet manager can work as a layout builder (requires Layout discovery to be enabled).

tim.plunkett’s picture

This is the implementation issue for a larger core initiative. Thanks!

GrandmaGlassesRopeMan’s picture

Issue tags: +JavaScript
  1. +++ b/core/misc/ajax.es6.js
    @@ -269,6 +251,28 @@ function loadAjaxBehavior(base) {
    +    $element.find('.use-ajax').once('ajax').each(function () {
    

    Arrow function.

  2. +++ b/core/misc/ajax.es6.js
    @@ -269,6 +251,28 @@ function loadAjaxBehavior(base) {
    +      // For anchor tags, these will go to the target of the anchor rather
    

    Multiline comment format.

  3. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +(function ($, Drupal) {
    

    Arrow function, and destructure Drupal.

  4. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +
    

    Needs docs.

  5. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +    attach: function (context) {
    

    Object property shortcut syntax.

  6. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +        update: function (event, ui) {
    

    Object property shortcut syntax.

  7. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +          let data = {
    

    Can be `const`

  8. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +            region_to: $(this).data('region'),
    

    I'd expect these to not have underscores, but I also understand that PHP is expecting them.

  9. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +          if (this === ui.item.parent()[0]) {
    

    Maybe document why this is needed.

  10. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +            let url = ui.item.closest('[data-layout-update-url]').data('layout-update-url');
    

    Probably don't need this.

  11. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +            let ajax = Drupal.ajax({
    ...
    +            ajax.execute();
    

    Don't assign to variable.

  12. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +              url: url,
    

    Drupal.ajax({url, submit: data}), maybe?

  13. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,40 @@
    +            ajax.execute();
    

    Append .exectue() directly to Drupal.ajax().

tim.plunkett’s picture

b1955f7 Remove extra whitespace from CSS selectors.
02ab9c7 Add @todo to info.yml about removing Settings Tray.
f7240c1 Remove obsolete layout_builder_contextual_links_view_alter().
cc387a3 Fix _has_layout_selection/_has_layout_section typo.
0ac7f71 Improve comments in layout_builder.module.
9898c43 Update the JS per drpal's review.
e8c3f0d Remove obsolete hardcoded ID.
65f6f00 Make the field type code more understandable.

tim.plunkett’s picture

27a0312 Add support for configurable layouts.
c7ce41c Simplify URL construction in LayoutRebuildConfirmFormBase.
d1baeb7 Provide a proper API for adding sections.
d0c6ad0 Add namespaced CSS classes for use in the Layout Builder.

#2660124: Dynamically build layout icons based on well formed config is now the only remaining issue needed for MVP.

Status: Needs review » Needs work

The last submitted patch, 8: 2905922-layout_builder-8.patch, failed testing. View results

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
142.21 KB
508 bytes

Added @group to the new test.

tim.plunkett’s picture

f9cae45 Nest the block information down a level within each section to allow for future additions.
60a2182 Refactor Layout Builder routing.
70bdf11 Streamline LayoutBuilderController::layout().

Status: Needs review » Needs work

The last submitted patch, 11: 2905922-layout_builder-11.patch, failed testing. View results

tim.plunkett’s picture

Assigned: Unassigned » tim.plunkett

Pushed up a fix for that last mistake:

diff --git a/core/modules/layout_builder/src/Controller/LayoutBuilderController.php b/core/modules/layout_builder/src/Controller/LayoutBuilderController.php
index a7d13f5..7af8a35 100644
--- a/core/modules/layout_builder/src/Controller/LayoutBuilderController.php
+++ b/core/modules/layout_builder/src/Controller/LayoutBuilderController.php
@@ -180,8 +180,8 @@ protected function buildAddSectionLink($entity_type_id, $entity_id, $delta) {
    */
   protected function buildAdministrativeSection(LayoutSectionItemInterface $item, EntityInterface $entity, $delta) {
     $layout_id = $item->layout;
-    $layout_settings = $item->layout_settings;
-    $section = $item->section;
+    $layout_settings = $item->layout_settings ?: [];
+    $section = $item->section ?: [];
     $entity_type_id = $entity->getEntityTypeId();
     $entity_id = $entity->id();
 

Code is at https://github.com/timplunkett/d8-layouts/tree/2905922-layout_builder

tim.plunkett’s picture

tim.plunkett’s picture

Priority: Normal » Major
Status: Needs work » Needs review
tim.plunkett’s picture

07c6b4f Resolve outstanding @todos.
0de5226 Simplify the JS.
506e5c2 Add stricter type checking to LayoutSectionBuilder.
c7aeeb2 Refactor section building.
273dfba Add links for @todos.

tim.plunkett’s picture

62ff345 Add test coverage for non-refresh AJAX updates.
6c6a5a3 Ensure bypassing the dialog still results in a functional UI.
2c65119 Refactor AJAX/dialog code.

#2905676: ajax.js overwrites WRAPPER_FORMAT when already specified is no longer a blocker! Yay.

Unrelatedly, #2909782: Provide the ability for JS functional tests to track whether the page has been reloaded is now a soft blocker.

Status: Needs review » Needs work

The last submitted patch, 17: 2905922-layout_builder-17.patch, failed testing. View results

Bojhan’s picture

@tim Should we create a separate UI issue?

tim.plunkett’s picture

Status: Needs work » Needs review

This *is* the UI issue. The "implementation" in the title is just because this one is in the core queue, not the Ideas queue.
Also that last test is missing a assertWaitOnAjaxRequest(), not wasting a testbot cycle for now.

tim.plunkett’s picture

EclipseGc’s picture

Status: Needs review » Needs work

Overall, I'm really happy with this patch. I didn't review the tests yet because I wanted to get the functional parts reviewed first to clear the path for work that could potentially happen at Drupalcon Vienna.

Eclipse

  1. +++ b/core/modules/layout_builder/css/layout-builder.css
    @@ -0,0 +1,59 @@
    +  transition: visually-hidden 2s ease-out, height 2s ease-in;
    

    I was reviewing our demo and didn't notice where this bit was applying. Is this applying? how do I see it?

  2. +++ b/core/modules/layout_builder/js/layout-builder.js
    @@ -0,0 +1,39 @@
    \ No newline at end of file
    

    twice now I've seen .js files w/o newlines. Is this a thing?

  3. +++ b/core/modules/layout_builder/layout_builder.module
    @@ -0,0 +1,145 @@
    +      $output .= '<p>' . t('Layout Builder provides layout building utility, surprisingly.') . '</p>';
    

    We should probably remove the snark?

  4. +++ b/core/modules/layout_builder/layout_builder.module
    @@ -0,0 +1,145 @@
    +function layout_builder_form_entity_view_display_edit_submit(&$form, FormStateInterface $form_state) {
    +  /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
    +  $display = $form_state->getFormObject()->getEntity();
    +
    +  $original_value = $display->getThirdPartySetting('layout_builder', 'allow_custom', FALSE);
    +  $allow_custom = $form_state->getValue(['layout', 'allow_custom'], FALSE);
    +
    +  // Only continue if the value has changed.
    +  if ($original_value !== $allow_custom) {
    +    $display->setThirdPartySetting('layout_builder', 'allow_custom', $allow_custom);
    +    $entity_type_id = $display->getTargetEntityTypeId();
    +    $bundle = $display->getTargetBundle();
    +
    +    if ($allow_custom) {
    +      layout_builder_add_layout_section_field($entity_type_id, $bundle);
    +    }
    +    elseif ($field = FieldConfig::loadByName($entity_type_id, $bundle, 'layout_builder__layout')) {
    +      $field->delete();
    +    }
    +  }
    +}
    

    Ok, so this function deletes a field in some cases which probably means we need to confirm that the user wants to proceed with this action when it would result with data loss.

  5. +++ b/core/modules/layout_builder/layout_builder.permissions.yml
    @@ -0,0 +1,3 @@
    +configure any layout:
    +  title: 'Configure any layout'
    +  restrict access: true
    

    Seems like we might want to expand our permissions to include per entity (per bundle?) layout configuration and also ownership configuration?

  6. +++ b/core/modules/layout_builder/layout_builder.routing.yml
    @@ -0,0 +1,122 @@
    +    _permission: 'configure any layout'
    ...
    +    _permission: 'configure any layout'
    ...
    +    _permission: 'configure any layout'
    ...
    +    _permission: 'configure any layout'
    ...
    +    _permission: 'configure any layout'
    ...
    +    _permission: 'configure any layout'
    ...
    +    _permission: 'configure any layout'
    ...
    +    _permission: 'configure any layout'
    ...
    +    _permission: 'configure any layout'
    

    Per my permissions point, we should probably include a custom access handler here for more nuanced access control.

  7. +++ b/core/modules/layout_builder/layout_builder.routing.yml
    @@ -0,0 +1,122 @@
    +    plugin_id: null
    

    I don't recall why we needed to do this. Is this truly needed or left-over cruft?

  8. +++ b/core/modules/layout_builder/src/Access/LayoutSectionAccessCheck.php
    @@ -0,0 +1,63 @@
    +      $access = AccessResult::allowedIf($account->hasPermission('configure any layout'));
    

    If we change permissions, we'll need to do something more complex here.

  9. +++ b/core/modules/layout_builder/src/Controller/AddSectionController.php
    @@ -0,0 +1,89 @@
    +/**
    + * Returns responses for Layout Builder routes.
    + */
    

    We used to have all the controllers in one class, and I think this docblock might be left over from that time. It doesn't seem accurate to the controller we're looking at.

  10. +++ b/core/modules/layout_builder/src/Controller/AddSectionController.php
    @@ -0,0 +1,89 @@
    +class AddSectionController implements ContainerInjectionInterface {
    
    +++ b/core/modules/layout_builder/src/Controller/ChooseBlockController.php
    @@ -0,0 +1,98 @@
    +class ChooseBlockController implements ContainerInjectionInterface {
    
    +++ b/core/modules/layout_builder/src/Controller/ChooseSectionController.php
    @@ -0,0 +1,117 @@
    +class ChooseSectionController implements ContainerInjectionInterface {
    
    +++ b/core/modules/layout_builder/src/Controller/LayoutBuilderController.php
    @@ -0,0 +1,306 @@
    +class LayoutBuilderController implements ContainerInjectionInterface {
    
    +++ b/core/modules/layout_builder/src/Controller/MoveBlockController.php
    @@ -0,0 +1,101 @@
    +class MoveBlockController implements ContainerInjectionInterface {
    

    Is there a reason we're not just extending ControllerBase?

  11. +++ b/core/modules/layout_builder/src/Controller/AddSectionController.php
    @@ -0,0 +1,89 @@
    +    $this->classResolver = $class_resolver;
    +    $this->layoutTempstoreRepository = $layout_tempstore_repository;
    

    Super nit-picky, but maybe it'd be nice if these were in the same order as the passed parameters.

  12. +++ b/core/modules/layout_builder/src/Controller/AddSectionController.php
    @@ -0,0 +1,89 @@
    +    $field_list = $entity->layout_builder__layout;
    

    So we used to pass the field name to these controllers. When we decided to hard code a field we stopped doing that. I know there's a lot of nuance to that particular problem, but I can't help feeling like it might have been better if we'd hard coded to field name into the route definition's defaults rather than into the code because then contrib routes could potentially "do stuff" w/o being forced to use our field or subclass our controllers... granted the problem is I don't know what "do stuff" means at this moment, so feel free to dismiss this concern. I'm probably just being overly paranoid.

  13. +++ b/core/modules/layout_builder/src/Controller/AjaxHelperTrait.php
    @@ -0,0 +1,34 @@
    +namespace Drupal\layout_builder\Controller;
    +
    +use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
    +
    +/**
    + * Provides a helper to determine if the current request is via AJAX.
    + */
    +trait AjaxHelperTrait {
    

    Is this specific to our module? or more broadly useful? Seems like this could be somewhere in Drupal\Core.

  14. +++ b/core/modules/layout_builder/src/Controller/ChooseBlockController.php
    @@ -0,0 +1,98 @@
    +/**
    + * Returns responses for Layout Builder routes.
    + */
    

    Same as on AddSectionController.

  15. +++ b/core/modules/layout_builder/src/Controller/ChooseSectionController.php
    @@ -0,0 +1,117 @@
    +/**
    + * Returns responses for Layout Builder routes.
    + */
    

    Needs better doc.

  16. +++ b/core/modules/layout_builder/src/Controller/ChooseSectionController.php
    @@ -0,0 +1,117 @@
    +      '#title' => $this->t('Basic Layouts'),
    

    This seems like it could be word smithed a bit to be more accurate to what we're doing.

  17. +++ b/core/modules/layout_builder/src/Controller/LayoutBuilderController.php
    @@ -0,0 +1,306 @@
    +/**
    + * Returns responses for Layout Builder routes.
    + */
    

    again, need to update the comment.

  18. +++ b/core/modules/layout_builder/src/Controller/LayoutBuilderController.php
    @@ -0,0 +1,306 @@
    +    $entity_id = $entity->id();
    +    $entity_type_id = $entity->getEntityTypeId();
    

    So after watching the errors that popped up in the demo at Drupalcon, this immediately looked suspect to me. Maybe you've moved something around into a route enhancer or something, but this used to extract the entity from a tempstore if it existed there before trying to do anything here. This code might also be completely ok for reasons I enumerate above, but just saying.

  19. +++ b/core/modules/layout_builder/src/Controller/MoveBlockController.php
    @@ -0,0 +1,101 @@
    +/**
    + * Returns responses for Layout Builder routes.
    + */
    

    docs

  20. +++ b/core/modules/layout_builder/src/Controller/MoveBlockController.php
    @@ -0,0 +1,101 @@
    +    $data = $request->request->all();
    

    We have a lot of $_GET expectations in thsi method, perhaps we should be throwing some sort of exception if we don't get everything we expect?

  21. +++ b/core/modules/layout_builder/src/Form/ConfigureBlockForm.php
    @@ -0,0 +1,252 @@
    +    $this->entity = $entity;
    +    $this->delta = $delta;
    +    $this->region = $region;
    

    Should we be throwing exceptions if we don't get all the expected parameters?

  22. +++ b/core/modules/layout_builder/src/Form/ConfigureSectionForm.php
    @@ -0,0 +1,175 @@
    +    $form['layout_settings'] = $this->layout->buildConfigurationForm($form['layout_settings'], $subform_state);
    

    Should we be delegating to the PluginFormManager for this?

  23. +++ b/core/modules/layout_builder/src/LayoutSectionBuilder.php
    @@ -0,0 +1,199 @@
    +    if ($access->isAllowed()) {
    +      $block_output = [
    +        '#theme' => 'block',
    +        '#configuration' => $block->getConfiguration(),
    +        '#plugin_id' => $block->getPluginId(),
    +        '#base_plugin_id' => $block->getBaseId(),
    +        '#derivative_plugin_id' => $block->getDerivativeId(),
    +        'content' => $block->build(),
    +      ];
    +      $cacheability->addCacheableDependency($block);
    

    Do we need to be adding the access object as a cacheable dependency just in case dependencies were added to it?

  24. +++ b/core/modules/layout_builder/src/LayoutSectionItemInterface.php
    @@ -0,0 +1,16 @@
    +interface LayoutSectionItemInterface extends FieldItemInterface {
    +
    +}
    

    Is this just for type-hinting purposes? I forget the reason we added it.

  25. +++ b/core/modules/layout_builder/src/LayoutTempstoreRepository.php
    @@ -0,0 +1,98 @@
    +    if (!empty($tempstore['entity'])) {
    

    being full on pedantic here this should probably read:

    if (!empty($tempstore['entity']) && $tempstore['entity'] instanceof EntityInterface) {

  26. +++ b/core/modules/layout_builder/src/Plugin/Field/FieldFormatter/LayoutSectionFormatter.php
    @@ -0,0 +1,87 @@
    +  public function viewElements(FieldItemListInterface $items, $langcode) {
    +    $elements = [];
    +
    +    /** @var \Drupal\layout_builder\LayoutSectionItemInterface[] $items */
    +    foreach ($items as $delta => $item) {
    +      $elements[$delta] = $this->builder->buildSection($item->layout, $item->layout_settings, $item->section);
    +    }
    +
    +    return $elements;
    +  }
    

    I love how simple this is despite the complexities of what we're doing. Just saying. :-D

  27. +++ b/core/modules/layout_builder/src/Plugin/Field/FieldType/LayoutSectionItem.php
    @@ -0,0 +1,111 @@
    +          'serialize' => TRUE,
    ...
    +          'serialize' => TRUE,
    

    Ok, so... can we even do this? Or is it ok for experimental code in a pre-alpha state and we just need to convert to json or something before release?

  28. +++ b/core/modules/layout_builder/src/Plugin/Field/FieldType/LayoutSectionItem.php
    @@ -0,0 +1,111 @@
    +    $values['section'] = [];
    

    So when i wrote this I was in a hurry during the sprint or something. I think we should actually generate a block in there. Generating entities that have sample values would mean that we should probably introspect the entity in question and place field blocks (not yet in core) for each of the fields of the entity type in question. So we can totally punt on this comment, I just want to put it out there for the moment.

  29. +++ b/core/modules/layout_builder/src/Plugin/Menu/LayoutBuilderLocalTask.php
    @@ -0,0 +1,23 @@
    +    $parameters['entity'] = $route_match->getParameter('entity');
    

    This looks too optimistic to my eyes. Probably something like hasParameter && instanceof EntityInterface.

  30. +++ b/core/modules/layout_builder/src/Routing/LayoutBuilderRouteEnhancer.php
    @@ -0,0 +1,31 @@
    +    $defaults['entity'] = &$defaults[$defaults['entity_type_id']];
    

    So this initially looks too optimistic as well, but looking at how we're generating routes, this could only fail if someone did something really stupid. Is it worth insulating that? Or should we just let it blow up in that case?

  31. +++ b/core/modules/layout_builder/src/Routing/LayoutBuilderRoutes.php
    @@ -0,0 +1,148 @@
    +    $templates = ['canonical', 'edit_form', 'delete_form'];
    

    So, nitpicky here, but this hard-codes our tasks to only work when on the task itself OR one of these templates. I get the reasoning behind that, but any additional tasks at this level would (if I recall these very old brain cells correctly) not display the "layout" task inline with the others. This is in part due to shortcomings of the task/action menu system, but we'd essentially need to do a lookup against all tasks to get ours to render properly because we have to alter all those routes which is REALLY heavy handed. Again I'm fine with this going in as is, I just want to document the weirdness that's sitting here.

  32. +++ b/core/modules/layout_discovery/layout_discovery.layouts.yml
    @@ -56,6 +68,10 @@ layout_threecol_25_50_25:
    +    - [first, second, second, third]
    

    OK, I realize this is a patch we're including for the sake of showing the whole patch working, but this means a 1/3|2/3 icon map for a layout would be [first, second, second]?? TOTALLY weird lol.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
23.31 KB
170.28 KB

1) From my understanding, this doesn't actually do anything because visually-hidden is not a CSS property but another drupal CSS class, and height is not used by the selector. Will check with @dyannenova before removing.

2) *.js files are generated from *.es6.js files, apparently there might be a Babel configuration change we could make globally to add a newline. Could open a generic issue about that

3) Eeeek I forgot that made it into the patch! Yes, though we should have the discussion about module naming before expanding/fixing the hook_help

4) Hm. We're piggybacking on the "Manage Display" form here, which does not have a confirmation step. I'm not sure of another place where we have a confirmation step but only for certain submitted values. This needs UX guidance before code, I'll add an @todo for now

5) Yes, we did discuss permissions for our MVP. Wasn't sure if they would be in this first patch or not. I'll add an @todo for now, and am not going to mention each following review point about permissions.

7) This is still needed, I added a comment. The flow around this is still a little odd, and confusing when compared to blocks. This could be cleaned up a bit.

9) Well spotted :)

10) ControllerBase is full of legacy and deprecated code, and wouldn't add any real benefit here.

11) Quite the nitpick, but I totally agree :)

12) I feel very paranoid about that change also. I like the route idea, will look into it.

13) This trait has gotten smaller and smaller over time. It should be addressed in #2896535: Create a helper trait for Forms in ajax dialogs, added an @todo.

16) I think the whole details element can go away, but I will check with @dyannenova first. Added an @todo.

18) This is now controlled by the route definition (specifically the parameters option), the same was as the Views UI. See \Drupal\layout_builder\Routing\LayoutTempstoreParamConverter and the layout_builder_tempstore string.

20/21) I don't really understand why this approach is preferred to URL parameters, any reason not to switch to those instead? Added an @todo for now.

22) Definitely! Done.

23) That's two lines above the snippet you posted: $cacheability->addCacheableDependency($access);

24) I believe the was more code here at one point. But yes, for the @property definitions

25) Good idea to be more defensive. Added an exception instead.

26) <3

27) Uhhhhh didn't you write this part? I assumed it was okay, but now I'm remembering that it might not be... Added an @todo!

28) There's not enough dreditor context to know what this is referring to, I'm guessing generateSampleValue? This I'd like to punt to a follow-up, opened #2912331: Improve LayoutSectionItem::generateSampleValue()

29) I just went down a pretty long rabbit hole and ended with #2912363: LocalTaskDefault/LocalActionDefault ignore parameters when raw parameters are not present.?
There are issues with raw parameters that are not in the path as {slugs}, so this is all a mess. Adding an @todo for now.

30) This is easy enough to protect against.

31) Okay this code has always bothered me. After digging into the local task stuff more in point 29, I was able to completely remove this. It takes a bit uglier change to LayoutSectionAccessCheck

32) Yep! That's the logic from #2660124: Dynamically build layout icons based on well formed config anyway.

EclipseGc’s picture

1, 2, 10, 11, 16, 18, 21, 22, 25, 30, 32: Great

3: Yup, I think module naming is a topic we should all prioritize at this point. Maybe next scotch meeting.

4: Yeah, I recognize this is a unique-ish issue.

5 & co: Fair enough. The todo actually satisfies me here if committers are fine with it, I just wanted to call out that we needed more nuance in this area.

7: I was just thinking the controller could do an = NULL in the method, but I'm fine with this solution too.

9, 14, 15, 17, 19: todos++

12: Ok, if we're both paranoid about this, that makes me feel better. :-D

20: The MoveController specifically is called via some JS, so I think I was just working with what it naturally did. I have no problem with cleaning this up in the way you suggest, just justifying why it is how it is.

23: How did I miss that?

27: I did write about half of that and I think you copied it for the other half (layout configuration). Point being yeah... I think for security purposes we need to be doing json here instead of PHP serialization since this is field values on an entity. It's unfortunate that the serialize blog stuff doesn't just support a format so that we don't have to manually intervene to make json happen.

28: Sorry, yes that's what I was referring to. And also yes, let's do a follow up for it. We need to get a few other things committed before we could even entertain what I'm asking for, so definitely follow up material.

29: Yeah things are a mess. Subscribed.

31: Ok, I need to apply this patch and play with that. If you could remove all this with that one change I'm SUPER ++.

Again, I want to reiterate, I'm super happy with where this patch is going, so I think we just need to enumerate which of the remaining issues we are going to address for our MVP before commit. Things like 27 could probably be handled in a follow up if we're ok with HEAD having a known security issue in an experimental module. I just don't know what the standard we're attempting to achieve here is and I think that's my main ask at this point.

Awesome stuff!

Eclipse

vijaycs85’s picture

FileSize
177.56 KB

Saw this in DrupalCon Vienna 2017 and gave it a try and here is my findings:
It's so nice to see both in-place editing and system tray work very well with layouts. It also seamlessly adds panes/blocks without page reload. Here is few minor UI issues(IMO):
1. The drag-and-drop option is hidden as the cursor doesn't change (stays as pointer)
2. Position of add block link (refer attached screenshot)
3. Not sure about the purpose and design of save and cancel layout links.

EclipseGc’s picture

1.) Dyannenova has been iterating on the css. We're aware of and agree that this (as well as drop placement indication) are problems.
2.) Yeah, I've not looked into what's going on with that yet, but it is annoying. Probably a css issue as well.
3.) So this one actually deserves some justification. If we've not done that elsewhere, I'll do it here.

Collectively, we'd like to use the administrative toolbar for our buttons (example screenshots are here #2884601: Add a Layout Builder to core), however the code for doing that was UGLY. We punted on this as the toolbar needs a lot of love right now, and that is certainly a separate effort from our own. Understanding that, we needed a different place for our save/cancel buttons. It's been suggested multiple times that we should put them in the settings tray forms, however those forms change regularly (block placement, layout placement, etc) and worse still, the settings tray can be closed. In order to satisfy our need, we placed the save/cancel links as sub-tabs of the layout tab because it will always be available to the user. True, they're not actual "buttons" but the links suffice just fine for our needs and are always available to the user while working on these screens.

Ultimately, we'd like to migrate this back to the toolbar per the screenshots I referenced earlier, but until such time as the toolbar can support what we need, this seemed the best compromise.

Eclipse

vijaycs85’s picture

Thanks for your time to address those items and good to hear from you @EclipseGc as always.
1. Great! thanks for the details
2. On someone's list. That's good :)
3. I am not a UI person, not going to suggest anything other than just point out, admin toolbar could get crowded once we start moving more items (like Workspace) there. Probably we have to have some rules/standards around what can be part of admin toolbar. Should it be side wide or page level etc. Another way of looking at it is to find a common UI for things like this. I don't know, if views UI or block placement UI fall under this category, but either a) we take one of those existing pages as common b) we come up with a new UI that works for all?

tim.plunkett’s picture

I've fixed the add block link placement in the repo.

EclipseGc’s picture

awesome! I was not looking forward to that. :-D

tim.plunkett’s picture

tim.plunkett’s picture

The contextual links issue went into 8.5.x!
Rerolled. And then there was one!

tim.plunkett’s picture

EclipseGc’s picture

Adding myself to commit credit since I helped write a lot of this code.

Eclipse

vijaycs85’s picture

i wouldn't mind taking myself out of commit credit as it was just a single review(with a screenshot file). Considering the amount of work done by @tim.plunkett and @EclipseGc, it's negligible.

tim.plunkett’s picture

Issue summary: View changes

@EclipseGc only a committer's changes to that section are persisted :)

Added the list of people to include to the IS for the committers

webchick’s picture

We reviewed this at today's product management meeting. You can see the recording here: https://www.youtube.com/watch?v=fAGQToEOgTQ

No blockers for committing this patch as an experimental module from our team's POV. The patch looks and works great. It's a very exciting, significant user-facing change, and a huge "selling point" for 8.5.

For stable:

Primary/secondary tabs

- We need to work a bit on the "save/cancel" button placement. They're currently in secondary tabs, which we know are hard to see, and they're not styled like buttons, which compounds the issue. (Emilie has mocks for moving these to the toolbar, needs a sub-issue for design exploration... the issue about the general problem with toolbar is at #2877853: Make toolbar items first class menu citizens) (must-have)
- Dries pointed out that adding Yet Another Tab™ here is an anti-pattern as well. Better would be to combine this with edit mode, else it's confusing how "edit" only edits content, yet "layout" (which doesn't mention editing) is for editing layout. Needs a follow-up for design exploration. (must-have)
- Because the list of blocks in the sidebar is just a set of links, there's going to be a lot of "pogo-sticking" with this UI: clicking a link to add the block, seeing how it looks, realizing it's not the right one, deleting it, repeating. Would be great if there were some means of getting a visual representation of the block you're about to place before hand. Needs a sub-issue for design exploration. (should-have, since it doesn't make the existing situation worse, though it's very important given this is a more user-facing screen vs. an admin-facing screen.)

The accessibility team should also review this before committing to get their take on commit-blockers vs. stable-blockers. We noted some things like there's no selection in the sidebar for weight / region. Not sure if tabbing works throughout, etc. Tagging "needs accessibility review."

The question of upgrade paths also came up, it sounds like the Panelizer team is committing to writing an upgrade path between that module and core, so the official recommendation should be "build with Panelizer."

AMAZING work, all! We are SO excited for this!! :D

EclipseGc’s picture

So first, can I just say "YAAY!". That conversation was enlightening in a bunch of ways and was really good to hear. I'm glad the product manager review went this direction.

To speak to some of the issue brought up here (and add additional color).

36.1 & 36.2) Agreed all around. I would love to get these buttons back into the toolbar. It feels like the right place for this, and building an expandable pattern of administrative tools there would be really great in my opinion. That being said, Wim's comment on #2877853: Make toolbar items first class menu citizens is sort of disheartening (and he's totally correct) so I worry that that effort might be greater than this one has been. Bojhan mentioned a "3rd option" that never seemed to be expounded upon. I'd love to hear what he's thinking.

36.3) Also agreed, having block previews would be awesome. panopoly_magic module did this in D7. There have been a number of discussions on this topic over the last few years now as it pertains to 8. This is a pretty nuanced topic and will likely require its own efforts at some later date. My biggest worry here is that the UI will likely need some significant love to make it visually grok-able and not a cluttered mess.

36.4) Accessibility has been a concern since the beginning, but we've worked pretty fast and furious through this whole effort and haven't had the time to really allot to it. FWIW I was envisioning a separate "move" contextual action that would be visually hidden. That UI would parse the layout field for deltas, regions and block placement and represent that data in a simple form with select lists. As Tim mentioned, "weight" isn't even a concept in this UI because blocks are placed within the array at the appropriate point for rendering. Weight was introduced to Block entities for use within core's normal block rendering pipeline, but these are separate things (despite the overlap of the word "block" in both places hehe). I'll of course wait for the accessibility review, but I wanted to at least document what had been in my head in terms of solving this problem (or initial steps toward solving it).

36.5) I'll also point out that the Lightning team is also incentivized from an "upgrade" front. Panelizer makes the most sense in terms of where the effort should happen. I didn't realize Jakob was that degree of committed to writing the upgrade path there but cool.

Thanks so much again for this review. And again "YAAY!"

Eclipse

webchick’s picture

I believe the "third option" that @Bojhan alluded to is hinging it off the "Preview bar" pattern:

Node preview bar

@Bojhan was going to open an issue tomorrow though that deals less with the specific solution but more around the general problem space of "where to stick these buttons." But this approach theoretically seems like it would nicely avoid the implementation challenges around Toolbar.

EDIT: Looks like this is what panopoly_magic does: a pop-up screen that previews the block and allows you to set settings prior to doing the placement. Interesting.

Panopoly Magic

And right, "weight" in this context is a short-hand for "make sure there's a way to reorder blocks within a section and a way to move blocks up/down to different sections that doesn't involve a mouse." :) @EclipseGc and I were discussing at BADCamp and seems like this would be useful for mobile as well. Drag and drop is often a disaster when you can't see the full page. ;)

dsnopek’s picture

panopoly_magic does what webchick is showing there (you can change the block settings on the left, and they are reflected immediately in the preview on the right via AJAX). But, also, on the screen before that screen, where you're picking which block to add, it shows the blocks rendered so you can see what it looks like before even selecting which block you want.

We've gone through a couple iterations of both those "screens" based on users' experience with them over the years, and a couple of them are still available via configuration options (because we didn't want to change existing sites too much as stuff evolved), in case anyone is curious.

xjm credited DyanneNova.

xjm credited japerry.

xjm credited phenaproxima.

xjm credited tedbow.

xjm’s picture

Adding issue credits.

Bojhan’s picture

tim.plunkett’s picture

Linking that issue to the meta, since this one will be closed after commit and we won't see the followups

xjm’s picture

+++ b/core/modules/layout_builder/tests/src/Functional/LayoutSectionTest.php
@@ -0,0 +1,351 @@
+  public function providerTestLayoutSectionFormatter() {

So, I recently proposed that a different issue use a data provider for a BTB test, and got pushback because it apparently adds multiple minutes of test run time to install Drupal over and over. I wanted to overrule and say it was worth it for maintainability (the alternative being the mother-of-all-nested-foreach-loops), but OTOH slow test run time is also a contribution barrier, so we should at least consider this before committing a data provider with this many dimensions.

Patch looks great overall.

larowlan’s picture

Code review, no manual test yet.
This looks really good, great job.
The follow-ups look good.

Re @xjm's question about the setup cost of a data provider, I think its worth it for the long-term maintenance sake.

Code review observations.

  1. +++ b/core/modules/layout_builder/js/layout-builder.es6.js
    @@ -0,0 +1,37 @@
    +      $(context).find('.layout-builder--layout__region').sortable({
    

    do we need a .once here?

  2. +++ b/core/modules/layout_builder/layout_builder.module
    @@ -0,0 +1,147 @@
    +  array_unshift($form['actions']['submit']['#submit'], 'layout_builder_form_entity_view_display_edit_submit');
    

    Should this use an #entity_builder instead? That would allow it to 'run before the entity is saved by the form'

  3. +++ b/core/modules/layout_builder/src/Controller/AddSectionController.php
    @@ -0,0 +1,91 @@
    +      $url = Url::fromRoute("entity.{$entity->getEntityTypeId()}.layout", [$entity->getEntityTypeId() => $entity->id()]);
    

    If we altered the entity to add a 'layout' link template, we could use $entity->toUrl('layout') here. Would be more convenient elsewhere too.

  4. +++ b/core/modules/layout_builder/src/Controller/AjaxHelperTrait.php
    @@ -0,0 +1,38 @@
    +      'drupal_ajax',
    +      'drupal_dialog',
    +      'drupal_dialog.off_canvas',
    +      'drupal_modal',
    

    There are more wrapper formats in contrib and client projects than listed here. Perhaps in a follow up this could be a container parameter.

  5. +++ b/core/modules/layout_builder/src/Controller/LayoutBuilderController.php
    @@ -0,0 +1,309 @@
    +            'attributes' => [
    +              'class' => ['use-ajax'],
    +              'data-dialog-type' => 'dialog',
    +              'data-dialog-renderer' => 'off_canvas',
    +            ],
    ...
    +        '#attributes' => [
    +          'class' => ['use-ajax', 'configure-section'],
    +          'data-dialog-type' => 'dialog',
    +          'data-dialog-renderer' => 'off_canvas',
    ...
    +        '#attributes' => [
    +          'class' => ['use-ajax', 'remove-section'],
    +          'data-dialog-type' => 'dialog',
    +          'data-dialog-renderer' => 'off_canvas',
    

    there are a few instance of this pattern - worth a helper method? buildAjaxLinkAttributes($additionalClass = [])

  6. +++ b/core/modules/layout_builder/src/Controller/LayoutRebuildTrait.php
    @@ -0,0 +1,58 @@
    +    $layout_controller = $this->classResolver->getInstanceFromDefinition(LayoutBuilderController::class);
    +    $layout = $layout_controller->layout($entity);
    

    nice

  7. +++ b/core/modules/layout_builder/src/Controller/MoveBlockController.php
    @@ -0,0 +1,107 @@
    +      if (empty($values[$region_to])) {
    +        $values[$region_to] = [];
    +      }
    +      $values[$region_to] = array_merge([$block_uuid => $configuration], $values[$region_to]);
    

    minor: could do $values = $values + [$region_to => []]; and save some lines?

  8. +++ b/core/modules/layout_builder/src/Form/ConfigureBlockForm.php
    @@ -0,0 +1,254 @@
    +      $plugin_id = $field->section[$region][$uuid]['block']['id'];
    +      $configuration = $field->section[$region][$uuid]['block'];
    

    Are there instances where these keys may not exist? Should we be more defensive?

  9. +++ b/core/modules/layout_builder/src/Form/ConfigureBlockForm.php
    @@ -0,0 +1,254 @@
    +    $form_state->set('block_theme', $this->config('system.theme')->get('default'));
    

    bugger

  10. +++ b/core/modules/layout_builder/src/Form/ConfigureSectionForm.php
    @@ -0,0 +1,213 @@
    +  /**
    +   * {@inheritdoc}
    +   */
    +  public function buildForm(array $form, FormStateInterface $form_state, EntityInterface $entity = NULL, $delta = NULL, $plugin_id = NULL) {
    

    We should document the additional parameters here - especially the instances in which they can be NULL. Took me a while to understand that plugin_id is only passed for new items, at first I thought the $this->isUpdate = is_null($plugin_id) was back-to-front.

  11. +++ b/core/modules/layout_builder/src/Form/ConfigureSectionForm.php
    @@ -0,0 +1,213 @@
    +    $this->delta = $delta;
    ...
    +      $field = $field_list->get($this->delta);
    ...
    +      $field_list->addItem($this->delta, [
    

    $delta can be NULL according to signature - should we validate that? I realize it has to have the = NULL to satisfy the interface, but should we enforce it isn't NULL in the body?

  12. +++ b/core/modules/layout_builder/src/Form/ConfigureSectionForm.php
    @@ -0,0 +1,213 @@
    +      $field = $this->entity->layout_builder__layout->get($this->delta);
    

    Same for the entity?

  13. +++ b/core/modules/layout_builder/src/LayoutSectionBuilder.php
    @@ -0,0 +1,199 @@
    +    $cacheability->applyTo($result);
    

    offtopic: we should open an issue to have applyTo return the render array as well, so we could return $cacheability->applyTo($result);

  14. +++ b/core/modules/layout_builder/src/LayoutSectionItemInterface.php
    @@ -0,0 +1,16 @@
    +interface LayoutSectionItemInterface extends FieldItemInterface {
    

    Should this be marked @internal?

  15. +++ b/core/modules/layout_builder/src/LayoutTempstoreRepository.php
    @@ -0,0 +1,102 @@
    +class LayoutTempstoreRepository implements LayoutTempstoreRepositoryInterface {
    
    +++ b/core/modules/layout_builder/src/LayoutTempstoreRepositoryInterface.php
    @@ -0,0 +1,60 @@
    +interface LayoutTempstoreRepositoryInterface {
    

    Should these be internal too?

  16. +++ b/core/modules/layout_builder/src/LayoutTempstoreRepository.php
    @@ -0,0 +1,102 @@
    +   *   An array containing the collection name and the tempstore ID.
    ...
    +  protected function generateTempstoreId(EntityInterface $entity) {
    ...
    +    return [$collection, $id];
    

    I am not a fan of this pattern, but a value object seems like overkill.

    However, if we had a method getTempstoreCollection and kept the generation of the collection name internal to that, we could do away with this and have it solely return the ID. Outside of the exception, we don't use the collection other than to get the tempstore. Does it add that much value to the Exception? We could just use the entity type ID.

  17. +++ b/core/modules/layout_builder/src/Plugin/Field/FieldFormatter/LayoutSectionFormatter.php
    @@ -0,0 +1,87 @@
    +      $elements[$delta] = $this->builder->buildSection($item->layout, $item->layout_settings, $item->section);
    

    nice and clean <3

  18. +++ b/core/modules/layout_builder/src/Routing/LayoutBuilderRoutes.php
    @@ -0,0 +1,124 @@
    +      $route = (new Route("$template/layout"))
    

    As mentioned above, I think we should add an entity type alter hook to add a link template for this too?

  19. +++ b/core/modules/layout_builder/src/Routing/LayoutBuilderRoutes.php
    @@ -0,0 +1,124 @@
    +          $entity_type_id => '\d+',
    

    Not all content entities have numeric IDs. This is done conditionally in other places in core, see the entity route builder handlers.

larowlan’s picture

+++ b/core/modules/layout_builder/src/Controller/MoveBlockController.php
@@ -0,0 +1,107 @@
+    $configuration = $values[$region_from][$block_uuid];
+    unset($values[$region_from][$block_uuid]);
+    $field->section = array_filter($values);
+
+    /** @var \Drupal\layout_builder\LayoutSectionItemInterface $field */
+    $field = $entity->layout_builder__layout->get($delta_to);
+    $values = $field->section;
+
+    if (isset($preceding_block_uuid)) {
+      if (!isset($values[$region_to])) {
+        throw new \InvalidArgumentException('Invalid region');
+      }
+
+      $slice_id = array_search($preceding_block_uuid, array_keys($values[$region_to]));
+      if ($slice_id === FALSE) {
+        throw new \InvalidArgumentException('Invalid preceeding block UUID');
+      }
+
+      $before = array_slice($values[$region_to], 0, $slice_id + 1);
+      $after = array_slice($values[$region_to], $slice_id + 1);
+      $values[$region_to] = array_merge($before, [$block_uuid => $configuration], $after);
+    }
+    else {
+      if (empty($values[$region_to])) {
+        $values[$region_to] = [];
+      }
+      $values[$region_to] = array_merge([$block_uuid => $configuration], $values[$region_to]);

One final thing, one of the consequences of Drupal's consistent use of arrays is we end up with lots of scattered logic. Having had to manually update a lot of panelizer config in an update hook before, I've found dealing with these big structured arrays difficult in the past.

Given this is just getting serialized, we could introduce a domain object here. And move all of the logic that is currently in controllers into that domain object.

e.g.
$section->moveBlock()

$section->removeBlock()

$section->insertBlock()

At the present all of this logic is in the controller, and if someone finds themself having to update a lot of them in bulk (e.g. in an update hook), we have to drop back to replicating this logic.

Yes, I realise this is how panelizer has done it since D7.

But I think it would be worth the pain.

The net result would be the controllers would be far thinner and we'd have domain logic we could test without a functional test.

tim.plunkett’s picture

#47
I disagree, especially since we're dealing with a test concerning caching. I'd feel much safer with a clean Drupal.

#48
Glad you agree on the data provider.

1) I double checked and we do not. .sortable() handles this for us, it functions very similarly and adds a .ui-sortable class, and subsequent calls do not reprocess it.

2) We could do this, but would have to work around #2799637: Document that #entity_builders and overrides of EntityForm::copyFormValuesToEntity() must be idempotent by adding a check for $form_state->isSubmitted() to ensure it doesn't run twice. The second run is at the correct time though.

3) Good idea

4) That whole trait is temporary, and the trait docs link to #2896535: Create a helper trait for Forms in ajax dialogs as an @todo. Agreed this is not enough.

5) I started in on this, but halfway through decided it should be a more generic bit of code provided by Off Canvas. We have this spread through PHP and also in layout_builder.links.contextual.yml...
@todo open a followup

6) Thanks :)

7) Fair enough

8) Fixed

9) Clarified that this is a workaround

10) Updated the docs.

11/12) We usually don't babysit these sort of things. If we could use PHP 7, we'd typehint it int and it would catch that for us.

13) Not a bad idea!

14/15) Yes

16) Fixed. That had been bothering me too.

17) Thanks! That's my favorite part.

18) Done!

19) Ugh good catch. Fixed

Ran out of time for #49, but I will definitely be looking into that.


60d5aa8ace Checkboxes use int instead of bool, cast both values here to be explicit.
d4c8953cdf Switch from #submit to #entity_builder for altering the entity view display form.
f61f233289 Clean up MoveBlockController::build().
4360c8888b Use a link template for /layout.
a7dd1dc06c Use the link template within tests.
367a30f929 Mark everything else @internal
7824776319 Return the ID and not an array from getTempstoreId().
aa9073d35a Check to see if an entity type uses integer IDs.
dd50c20fc4 Move LayoutSectionItemInterface into Field.
9e69bc5fa4 Improve the confusion around ConfigureBlockForm

Pushed to https://github.com/timplunkett/d8-layouts/tree/2905922-layout_builder

tim.plunkett’s picture

This is intended to address #49. It's not as clean as I hoped, but I like the direction.

d3f2c72b4b Introduce a Section domain object.
Pushed to https://github.com/timplunkett/d8-layouts/tree/2905922-layout_builder

Status: Needs review » Needs work

The last submitted patch, 51: 2905922-layout_builder-51.patch, failed testing. View results

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
17.69 KB
187.84 KB

&getBlock was a bad idea anyway. Being more explicit is good!

Status: Needs review » Needs work

The last submitted patch, 53: 2905922-layout_builder-53.patch, failed testing. View results

larowlan’s picture

Yeah, this is looking really nice

@tim.plunkett++

yoroy’s picture

I just watched last week review (https://www.youtube.com/watch?v=fAGQToEOgTQ). It's all looking pretty damn smooth already and the main points for followups have been identified. I'm in favor of committing this sooner rather than later.

To get to Stable status it would be nice if we tested this with non-core developers as well. You know, to validate that we've built the right thing and for identifying where to focus further refinements and/or extend the capabilities.

Super great work team!

tim.plunkett’s picture

tim.plunkett’s picture

Adjusted the AjaxTrait to be more reusable, with #2896535: Create a helper trait for Forms in ajax dialogs in mind.
Still waiting on IconGenerator, and the framework manager signoff.
Going to seek out a11y review next.

Status: Needs review » Needs work

The last submitted patch, 58: 2905922-layout_builder-58.patch, failed testing. View results

tim.plunkett’s picture

Status: Needs work » Needs review
xjm’s picture

I don't have a clear enough sense yet of what is blocking vs. followup for this because I wasn't able to test the patch fully (something is broken). I checked and the summary of #2884601: Add a Layout Builder to core doesn't have a list yet of what's scoped to followup issues vs. remaining tasks for this patch, nor does this summary. I think it would be good to start enumerating things and sorting them between those two categories (plus listing things that haven't been sorted one way or another yet), to avoid a repeat of the Great Outside In Issue Comment Review Struggle of 2016 and to avoid reviewers like me repeating feedback that's already been given or scoped to followups. I'd propose something like:

Remaining tasks

Blockers

  • #49.3: Pretend larowlan said something blocking here' that's not addressed
  • #61.4: Figure out why xjm gets no layouts. Regression?

Followup roadmap (to be prioritized later)

Unaddressed feedback

  • #61 (all points)

Wontfix


And so, miscellaneous things from testing.

  1. I think there might be some missing cache invalidation or something. First of all, it took me forever to find the "Layout options" fieldset on /admin/structure/types/manage/article/display. But even after I did, and checked and enabled it, the layout tab didn't show up and so I could not for the life of me figure out how to use the patch. I would not have been able to get anywhere without @webchick's video. :) The tab appeared after a cache clear.
  2. I assume that the long-term plan will be to convert both the field UI and the block library to the same interaction pattern; is that correct? Because having three different interaction patterns for laying out the page is very confusing and overwhelming.
  3. I think the content layout needs to default to a single layout with the main content area. Otherwise, someone could find and check the custom layout box like I did, never discover the layout tab, and never understand why content they input into Drupal never shows up. Seems like a serious UX issue.
  4. I, um. I also set up a whole layout (with an impressive array of breadcrumb, menu, help, and search blocks) but it never seems to be applied after I save the layout. The "View" tab remains forever empty, no matter how many times I log in/out, clear the cache, etc.
  5. Does a layout in progress go into a tempstore like Views? Seems like the kind of thing where it would really suck to lose your work when leaving the page. I couldn't tell whether it did or not when playing with it.
  6. On that note, would be good to have a message like "You have unsaved changes" like Views does. Otherwise I can get lost in the page and not know if I actually changed something or not.
  7. IANAD (I am not a designer) but it seems like it would be good to have visual feedback on when a layout is saved or not.
  8. It's also kind of hard to see the difference between sections and regions. The gray vs. blue dotted borders are very subtle. Do they pass a contrast ratio with each other?

Can't really review more until it works. :P

xjm’s picture

FileSize
13.94 KB
20.35 KB

Oh I had a couple more things:

  1. Can't read what I'm confirming:
  2. This point removed; feedback was duplicated across two issues.
xjm’s picture

On #61.4, I had hacked up the patch to test with the latest icon generator, and using the actual patch from #58 did actually make the layouts show up. So maybe I just made a mistake that introduced the regression. Assume that point can be disregarded for now. No this is actually broken; see below.

xjm’s picture

Another thing that I found confusing. Removing a whole section has a visible x button, but removing a block from the layout requires using the contextual links that you can only see when hovering over the block, and there's very little feedback as you move the cursor over the page as to where the block is and isn't. Because there aren't any boundaries around the block separating it from the rest of the region, which includes both other blocks in the region and whitespace.

I wonder if the Settings Tray hover interaction would be a good model?

xjm’s picture

Oh! It wasn't because of me hacking up the patch after all. If you have Field Layout enabled, the Layout Builder's layouts are ignored and the content appears empty forever (not even displaying the main content). That seems like a critical issue to me.

xjm’s picture

It was also hard to tell when a section is added; at first, I didn't understand what was happening with the sections. The sections end up sort of below the fold, and when you have multiple sections, there's no visual feedback as to where the new one goes. It seems like a final version, maybe not the MVP, would do the thing where the new section is highlighted when it appears and then fades in to the normal colors.

EclipseGc’s picture

Issue summary: View changes
FileSize
12.08 KB

xjm

61.0: Yeah I'll see if I can devote some time tomorrow or Monday to fixing up the IS on this issue. Generally speaking the only thing we consider a blocker currently is #2660124: Dynamically build layout icons based on well formed config. Obviously pending the various reviews we have that could change, but as far as external blockers, that's the only one we are blocked on.

61.1: Confirmed, I've seen this too.

61.2: Field UI for certain. That's on our immediate todo list after this is committed. So much so, we'd favor pulling this code out of 8.5 if we can't convert the field UI to this mechanism as well. We don't want a generation of Drupal sites that use this code w/o sane default options for content layout. That would be a nightmare.

With regard to your question about core's Block Layout, I've been turning some of my attention toward that problem mentally, but we have not discussed it as a group at all. Having Entity view modes and individual entities themselves properly laid out with this tool is a complete enough state that I think we are all exclusively focussed on that idea for the time being. It's functionally "panelizer in core" which hits the 80% use case for certain. Don't get me wrong, I'd like to do "all the things" but there are no plans of any sort yet in place for such a future.

61.3: I'm not sure I follow what you were trying to say in this point. Maybe elaborate a bit more? It sounds like you were discussing having some sort of sane default? If not I apologize for the following response.

Our next goal is to get entity view_modes working with layout. Part of that would be to copy in the full view_mode's layout into the entity specific layouts as a "starting point" for doing a custom override. That way, if there was just some small change to be made, it'd not require the content author/site builder to rebuild the default layout from scratch for each override. Again, if this was tangential to what you were saying, I apologize. Just try again and hopefully I get it this time :-D

61.4: Weird, I've never had that problem... do you have field_layout installed at the same time? Might be the modules are stepping on each others toes? I've also not tried the newest new patch, but tests should be failing if this were the case. I'll apply it and try it this weekend.

61.5: yes, we use tempstore extensively

61.6: Fair point. Do you feel that needs to be addressed now? or would a follow up issue be sufficient?

61.7: So again, fair point. Counter point to that is that when you save it you're immediately dropped back onto the entity's canonical link, so I guess I felt that communicated "hey it's saved" pretty clearly since you were seeing it in action after you hit the save button. That said, I guess I'd prefer to let DyanneNova address whether or not that's a concern. I'm just expressing my experience with the system (which again... since I coded a fair bit of it, my expectations could be TOTALLY wrong cause I know what happens when you click that link hehe).

61.8: 100% agree. I think we all do. FWIW I think we're all contemplating something more like this for the next big iteration of css changes:

62: Yeah, we're aware. I question whether or not this isn't an issue for the settings tray elements themselves (as opposed to layout builder). Sort of feels like we're just exposing an existing shortfall of that toolset. That being said, we could certain consider using modals in this case. I kind of like having it in the sidebar though. Again, I defer to DyanneNova on this.

64: So, in answer to this, I think I'd point back to the screenshot I included for 61.8. I think we'd like to have a bit of administrative UI attached to the regions (and I'd like to do similar with the blocks). Kind of unify the "stuff you can do" at each of these levels while bringing some visual clarity to the UI at the same time. As usual, I defer to DyanneNova on this, I'm just documenting some of what we've passed around in back-channels on this topic. Again I'd ask, is this in "follow up" territory in your opinion? or should we be addressing it in this patch?

65: Is this what you were saying in 61.4? I read all your comments before responding, so I assume that's where I got the idea. :-D

66: Yeah, again referring to 61.8 here but I like the idea of maybe scrolling to the newly added section and temporarily highlighting it somehow. I think it'll be less confusing once the sections and the "add section" elements don't have the same visual authority on the screen, but I'm open to anything that helps communicate to the user how to use the tool, and what effects their actions are having.

Again, I'll try to get to the IS tomorrow or Monday. Thanks for the review, this is all good stuff. Sorry it and field_layout don't like each other yet. I don't think any of us have tested with both of them on (not that I know of). We should put a disclaimer somewhere for the time being. heh.

Eclipse

tim.plunkett’s picture

#61

1) Added coverage for this (which failed), and then fixed it.
2) Yes
3) We can do that in the short term, sure. Long term you would override what was set up for the bundle already
4) Added code to prevent LB from being installed at the same time as Field Layout
5) Yes
6&7) I will open a follow-up for this, as the UX team signed off on what we have as an MVP
8) The contrast will be part of the a11y review. The CSS is rudimentary, and we have a follow-up for that, see below

#62

1) Needs a Settings Tray issue, I guess.

#64/66) #2916877: Update Layout Builder CSS to match updated mockups

@EclipseGc is working on the IS
I will open a follow-up for more designs around the Tempstore/Saving part
I will open a follow-up for starting with a default section


747027e972 Prevent field layout and layout builder from being installed together.
1d82d6a449 Add link assertions before clicking.
da4b98de78 Cache the local tasks by the layout builder status.
2e3b30dac2 Improve workaround for contextual links.

Pushed to https://github.com/timplunkett/d8-layouts/tree/2905922-layout_builder

Status: Needs review » Needs work

The last submitted patch, 68: 2905922-layout_builder-68.patch, failed testing. View results

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
7.19 KB
195.82 KB

Needed to decouple the field creation from the UI code.

tim.plunkett’s picture

Opened:

#2919795: Add visual hints that Layout Builder work is in tempstore and will not be lost, or take effect until saved
#2919811: Write Layout Builder handbook documentation
#2919813: Until per-bundle defaults exist, consider starting per-entity overrides with a single one-column section

Also fixed a bug where allowing overrides for that bundle took over the output for all entities of that bundle, regardless of whether they had been overridden.

Moving the a11y tag from this MVP-only issue to the parent issue, as that blocks stable commit.

Status: Needs review » Needs work

The last submitted patch, 71: 2905922-layout_builder-71.patch, failed testing. View results

mgifford’s picture

Just a list of a few accessibility issues as part of a quick review:

1) the "Choose a layout" panel that popus up after clicking on "Add Section" has no focus or hover states. It is very difficult to find out where you are and how to close the window. Some simple CSS should fix this.

2) Any time content is being changed via JavaScript, we need to alert screen reader users that the page is no longer the same. Adding the layout should come with a call to Drupal.announce() so that a blind user is alerted in a semantic fashion.

3) After adding a new layout, the focus should go to the new layout that has been added rather than simply landing at the top of the page. The first thing a person should tab to after adding a new layout is the new layout they have added.

4) When adding a block to a layout there is the same problem with lack of focus/hover that is mentioned in #1. It actually might be there but it is very faint and there is a bit of a delay so hard to notice.

5) As Tim pointed out in slack, there are some color contrast issues. #46a0f5 on #222222 doesn't pass.

6) As with #2 Any time content is being changed via JavaScript, we need to alert screen reader needs to be alerted with Drupal.announce() so that a blind user is alerted to the new content.

I'm happy to have a look later on this.

mgifford’s picture

In Slack, Tim let me know that some of the issues in #73 probably should be dealt with in other components.

An area I didn't discuss in much detail was the drag/drop functionality. I wanted to remind folks that this is how we dealt with it in Drupal 7 because we didn't have access to a stable version of WAI-ARIA - #448292: Drag and Drop for table rows is not accessible to screen-reader users

Some possible code to consider

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
179.66 KB

https://bugs.jqueryui.com/ticket/9633 is a really bad sign, since that's what we used for the drag-and-drop part.
Thanks for all the links, we'll have to explore one of those instead.

There's an unrelated known issue with composer right now, so this will continue to fail.
But #2660124: Dynamically build layout icons based on well formed config went in, so I'm rerolling this.
There are now no known hard blockers for this issue!

andrewmacpherson’s picture

Re: #73

5) As Tim pointed out in slack, there are some color contrast issues. #46a0f5 on #222222 doesn't pass.

This colour combination has a contrast ration of 5.8:1, so it does pass... but which element are you talking about? I can't find #222222 anywhere.

andrewmacpherson’s picture

After adding a section or block in the settings tray, focus is lost (it returns to the start of the document). It would be better if it returned to the same "add section" or "add block" button that the user operated to reach the settings tray.

andrewmacpherson’s picture

At the moment you have to be sighted to get an understanding of the layout. There's no human-readable content in the div#layout-builder which describes the layout; all the layout information is in class, data-*, and href attributes, which are really only developer-readable.

We'll have to find a human-readable way to describe the layout (and your current position inside it...) to assistive tech users. This isn't going to be easy! Two obvious semantic structures spring to mind:

  • HTML tables. Screen readers and other assistive tech can already understand these, and many screen readers have advanced tools for interrogating the structure. For instance a user can press key-combos to announce the current cell coordinates, or speak the row/column headers.
    Pros: in theory we get a lot for free, between the HTML semantics and screen reader tools.
    Cons: the grids here are likely to be quite complicated and irregular, so even using the screen reader tools, a user may easily become lost. There's a likelihood we would end up using nested tables. There's also a slight semantic mismatch; tables are containers for content; the cells aren't usually expected to move around!
  • An ARIA grid pattern, such as the ones described in the WAI-ARIA Authoring Practices working draft. Instead of HTML semantics, ARIA roles and properties provide the semantics (role, aria-labelledby, aria-describedby, and possible the new aria-roledescription).
    Pros: they're not tables, so there are fewer assumptions about how they work. We may achieve it with simpler markup, as there's less expectation of a uniform grid.
    Cons: We get less for free, we have to define all semantics carefully. ARIA 1.0 core is a full rec, but the authoring practices is still a working draft.

Whichever approach we take, we'll likely need a lot of visually hidden text, and manage IDREFs for aria-labeledby & aria-describedby, and some custom drupal.announce() messages too.

I have no idea how to build this. I've not inspected many layout builders like this in the wild, let alone found an accessible one. AFAIK there isn't yet a tried and tested best practice for this, a11y-wise. The ARIA grid pattern only gets us so far. It doesn't cover parts like telling a user what has changed as a result of their actions.

We can ask around the a11y community to see if anyone has built something like this.

The closest thing to this that we've built is the CKEditor toolbar configuration UI. Note that doesn't use ARIA grid, but it does have a lot of custom announcements for screen readers. We also have had some feedback from screen reader users who are confused by it (#2349309: Improve CKEditor toolbar configuration usability).

andrewmacpherson’s picture

Patch in #75:

+      $build[$category]['links'] = [
+        '#type' => 'table',
+      ];

We're generating tables with just a single cell per row. Wouldn't a UL be simpler?

andrewmacpherson’s picture

Via @webaxe on Twitter, we've learned of DragonDrop (demo) which has a nice(-ish) keyboard and screen reader experience.

Here's an initial review of the DragonDrop demo:

  • It only has examples of draggable rows, not 2-dimensional movement.
  • The first example has clear grab-buttons with a clear icon, text fallback, and focus styles.
  • The grab behaviour isn't as discoverable in the second example.
  • The grab-button is a <button> so we'd expect enter and spacebar to both activate it. However enter and spacebar have two different behaviours:
    • Enter toggles the grab state. To move it you either press enter (grab), arrows keys, enter (ungrab).
    • Spacebar acts more like a shift key, so it's grabbed while spacebar is held down. To move it, press spacebar + arrow keys together.

    This different behaviour is a bit hard to discover. I initially pressed + released spacebar, then used arrows. My first impression was that it was broken.

  • Escape cancels the re-ordering, and leaves things where they were before you tried dragging. Nice, assuming you discover it.
  • aria-live announcements say what the new position is.
  • The DragonDrop has it's own aria-live region, i.e. we wouldn't use drupal.announce(). This is fine, in fact it's already the case that our autocomplete widgets have their own aria-live region.
  • The aria-live messages tend to queue up, so you can sometimes hear a long sequence of grabbed/ungrabbed messages. Meh, needs a throttle.
  • The grab-buttons are all aria-describedby a piece of visible help text. This gets announced after every movement, which is very verbose and repetitive. It will likely respect the verbosity settings of different screen readers, but they don't all offer this. I didn't like this part.
  • The DragonDrop demo does not use HTML tables or ARIA grid semantics. It's just draggable rows, so it gets away with an ordered list. For our layout builder, I still think we'll need ARIA grid.

I think we should start a separate issue to explore accessible drag & drop grid patterns.

andrewmacpherson’s picture

Added #2920006: Research accessibility of drag-and-drop grid interfaces.. I'll copy most of my previous comment over to there, as the first library reviewed.

tim.plunkett’s picture

@mgifford, @andrewmacpherson: thanks so much for the accessibility review.
There's a lot to take in there! Good to see the issues being marked as related to the parent issue, since this will be closed once the MVP is added to core at alpha stability.

#61.3:
Overriding the layout now begins with a single section.
Currently, removing the override is done by removing all the sections (not intuitive!)
But we now have tests for this, which can be adapted once a better flow is determined.

#65:
#2920394: Field Layout should not alter fields placed into regions it doesn't know about is a blocker for fixing the clash between Field Layout and Layout Builder. I split it out for now, but it could easily be included here if desired.
I have a branch locally incorporating that issue and removing the hook_requirements() workarounds.

Status: Needs review » Needs work

The last submitted patch, 82: 2905922-layout_builder-82.patch, failed testing. View results

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
180.45 KB
974 bytes

Missed a spot in the tests.

xjm’s picture

So um. The latest patches seem broken. When I click "Add section" something burps and the sidebar does not open.

droplet’s picture

tim.plunkett’s picture

#2920394: Field Layout should not alter fields placed into regions it doesn't know about went in, so with a small change to LB we can remove the hook_requirements hack!
This may have also fixed #85? Not sure if you tested it on top of the other issue or not.

I also fixed #86, that was a complete oversight.


6d491fcc2d Make layout builder compatible with field layout.
d332376a11 Hide the layout field on manage display and manage form display.
Pushed to https://github.com/timplunkett/d8-layouts/tree/2905922-layout_builder

The last submitted patch, 84: 2905922-layout_builder-84.patch, failed testing. View results

EclipseGc’s picture

Issue summary: View changes
EclipseGc’s picture

Issue summary: View changes
droplet’s picture

I think this issue focus on CODE (main features) more than UX/UI. But I also drop my comments here. It's an MVP and some issues might be discussed already and I think the contributors able to pick my suggestions to right channels.

Add Section
- Provide a way to add single row column rather than a whole layout. eg. 2 column row (better UX actually)

Add Block
- Core: Page title
If you add it without "Display title", it's nothing. It's a bug to a regular user. (bad UX)

- Core: Tabs
Tabs has no visible UI

- Forms: User login
It needs an API to hide these empty blocks I think.

- CSS BEM naming issues

====================================================================================

I suggest to change the way to add a new block:

I'm a long time WordPress user also. They have many 3rd party layout plugins already. It's a very traditional way to add things (Add Section -> Select Block). It's horrible and painful I can tell from my experiences.

My idea is similar to https://snack.expo.io/

LEFT SIDE:
Design the Layout

1. Click "Add Section"
2. Show a menu (popover/megamenu) below the "Add Section" button
3. Select a Layout
4. Hide menu
5. Insert new added Layout.

RIGHT SIDE:
1. A fixed panel on the landing page:
- 1.1: With Floating / Pin feature (WHY? Do not affect the display area WIDTH, no RWD)
- 1.2: Able to collapse into a small icon
- 1.3: A checkbox for turn on/off default config for all dragged block
- 1.4: With keywords filters

2. Loaded a list of block on the Panel
3. Drag a block from list to LEFT section
- 3.1: If we checked 1.3 to default config, then that's all.
- 3.2: If we unchecked 1.3, then show a Detail Config Panel

Why is this better?
`For end users, we always want to PREVIEW the result!!!`

This way we knowing what blocks we have on hand first. We design the layout on the left quickly and then drag the block into different sections (This is the 2nd time to design our Layout). Usually, it's like a prototype process more than one-step to final. For most users, they don't know how it works and can't imagine the whole pictures of final results.

It even able to introduce a CONFIG MODE for batch config editing. (Saving few more clicks)

tim.plunkett’s picture

I wrote a test to ensure Layout Builder and Field Layout play nice.
Thanks for the IS update @EclipseGc!

tim.plunkett’s picture

@droplet from what I can see, none of that is in scope. Please create targeted follow-ups. Thanks!

EclipseGc’s picture

Status: Needs review » Reviewed & tested by the community

I think we're basically at our MVP barring review from Framework and Release Managers to the contrary. Marking RTBC.

Eclipse

larowlan’s picture

Issue tags: +DrupalSouth 2017

tagging for sprint next week

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
  1. +++ b/core/modules/layout_builder/layout_builder.module
    @@ -0,0 +1,200 @@
    +  unset($form['fields']['layout_builder__layout']);
    +  $key = array_search('layout_builder__layout', $form['#fields']);
    +  if ($key !== FALSE) {
    +    unset($form['#fields'][$key]);
    +  }
    ...
    +  _layout_builder_hide_layout_field($form);
    

    If only we had a ->setDisplayConfigurable for config fields

  2. +++ b/core/modules/layout_builder/layout_builder.module
    @@ -0,0 +1,200 @@
    +  if ($original_value != $new_value) {
    

    nit this could be !==?

  3. +++ b/core/modules/layout_builder/src/Access/LayoutSectionAccessCheck.php
    @@ -0,0 +1,68 @@
    +      $access = AccessResult::allowedIf($account->hasPermission('configure any layout'));
    

    Should this use ::allowedIfHasPermission() so that the permissions cacheability metadata is added?

I'm happy with the architecture, but as discussed with Tim via irc/slack - would be keen to see what the data model will look like for #2922033: Use the Layout Builder for EntityViewDisplays

tim.plunkett’s picture

1) That would have been great!

2)

+++ b/core/modules/layout_builder/layout_builder.module
@@ -0,0 +1,200 @@
+  $new_value = (bool) $form_state->getValue(['layout', 'allow_custom'], FALSE);

Originally we needed the loose comparison, but I did add a cast here. Everything else should be safe.

3)
I... had no idea that existed, whoops. Thanks!

The internal data model should be the same. Layout ID, Layout Settings, Sections

The tricky part will be doing from within an experimental module.

Status: Needs review » Needs work

The last submitted patch, 97: 2905922-layout_builder-97.patch, failed testing. View results

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
6.04 KB
186.68 KB

Random failure in the JS test.
I think the issue was around overly generic assertWaitOnAjaxRequest() calls.
I went through the existing calls and replaced them with something more targeted.
This includes the line wait() call before the random fail.

EclipseGc’s picture

Status: Needs review » Reviewed & tested by the community

moving back to rtbc

Eclipse

xjm’s picture

It's great to see this RTBC.

@catch and I agreed that release managers don't need to totally sign off on adding this as alpha now that we only ship beta+ modules, unless we have concerns with the maintainability of adding them at all. Layout Builder obviously belongs in core so we're comfortable with this going in as alpha. Untagging for release manager review for that reason.

The release manager will want to do a thorough review before the module is tagged as beta (and therefore kept in a release). That also means we might make updates to the roadmaps based on our reviews.

Tim and I discussed a couple things in person yesterday:

  1. I think the task to make this same interaction for laying out the templates for an entity display (the replacement for field layout) needs to be a must-have on the roadmap. If it's already there, please retitle it to be clearer; if it isn't, please add it because Tim said he agreed it was a must-have. :)
     
  2. Emilie's designs show content in the blocks when you place them. This patch doesn't do that. I don't think it's required for a stable version unless the product team says so, but it's definitely the thing that makes the designs look "wow" and that will make the feature more intuitive for people. Can we make sure there's a roadmap issue specifically for that, or title the existing issue that will do that more clearly?
     
  3. Similarly, there's some design issues with the borders of the section and the padding that I know Tim scoped to a followup issue but I don't see it in the summary yet.
     
  4. #91 sounds really interesting actually -- one of the things that slowed me down when testing was block selection -- so I'd love to see a followup for that too. It wouldn't block this initiative, I don't think. @droplet, can you file an issue and link it here?
     
  5. On the whole, I'd really appreciate incorporating my suggestion of adding unaddressed points of feedback to the IS (even if they're descoped) in the summary would have been helpful. Until we do that, I feel pressure to read the entire issue and understand whether increasingly outdated feedback will be addressed now, later, or never. E.g. #62 which it looks like Tim considers a Settings Tray issue, but I see no followup for it in the summary. Part of what committers do when reviewing an issue is confirm that others' feedback has been addressed so it would be really helpful if that could happen each time the initiative team processes the feedback.
     

I'm also untagging for Framework Manager review because @larowlan has signed off in #96!

I'm happy with the architecture, but as discussed with Tim via irc/slack - would be keen to see what the data model will look like for #2922033: Use the Layout Builder for entity view_modes

Really looking to reviewing this more when some of the must-have followps around the interactions are in.

xjm’s picture

Sorry, forgot a few things after I noticed #62 seemed to be missing and got distracted by the unaddressed feedback question.

  1. I would suggest that the Layout Builder start with only the main content block in a single-column layout. This really would have made a difference for me in terms of understanding what to do on the page. This also can be a followup; I'd say it's a should-have unless the product and UX teams say it's a must have.
     
  2. I think we need an issue to discuss how to make it clear to users how they can get rid of the sidebar and header areas when they're laying out the whole page with Layout Builder. This could be something like a theme with just one single-column region, and a form for Layout Builder that says "Layout Builder can be used to arrange the main content region of your site on the page. For the Layout Builder to control the whole page, you can enable the Layout Builder theme. (This will hide any blocks that were already placed outside the main content area.) This is way out of scope and will need discussion about what exactly we should do, but I think we should put it on the roadmap since it's frustrating to only be able to lay out the white square of the page and to not be able to get rid of the dumb search block on the side or to rearrange things WRT the page top.
alphawebgroup’s picture

Hi Guys
I've played a little bit with Layout Builder today, especially replayed a case with custom blocks
probably you know some plugins like blocks use "third_party_settings", what is pretty useful for implementing additional behavior or data handling for blocks (and for other plugins also).

For example, many site owners use Block Class module to have an opportunity to add extra classes to their blocks according to different front-end rules coming from different frameworks like Bootstrap.

Block Class (probably like other extenders) use "third_party_settings" array as a part of config form of the block
What do you think, would be useful to include "third_party_settings" handling for blocks in Layout Builder?
or should it be an additional/standalone issue about that?

tim.plunkett’s picture

@alphawebgroup

Block plugins (\Drupal\Core\Block\BlockPluginInterface) DO NOT support third party settings. These are used here.

Block entities (\Drupal\block\BlockInterface, a config entity) DO support third party settings. These are only used by the block module, and are unrelated to this effort.

That said, it definitely seems worth exploring. Please open a new issue to discuss, thanks!


Working on responding to #101/102 now

tim.plunkett’s picture

#101

1) #2922033: Use the Layout Builder for EntityViewDisplays is the issue, it might need retitling.
It is linked in #2884601: Add a Layout Builder to core and https://www.drupal.org/core/roadmap#layouts

2) Opened #2924051: Show live previews of content within Layout Builder

3) #2916877: Update Layout Builder CSS to match updated mockups

5) Opened #2924052: Off Canvas dialog cuts off longer titles, I will read back through and make sure similar issues

#102

1) Main Content block does not do what you think it does. Additionally, what SHOULD happen is that the sections that were set as defaults are copied to the override. But for this to be possible, we first must have defaults. Since we have decided NOT to ship without that part of the code, I do not think an intermediate step is needed.

2) Opened #2924058: Discuss using Layout Builder to control full site layout and replace Block UI

tim.plunkett’s picture

larowlan’s picture

Adding review credits for those who helped shape the final patches

Discussed change record with tim on slack

larowlan’s picture

Issue tags: -Needs change record

cross post

  • larowlan committed 88a22dd on 8.5.x
    Issue #2905922 by tim.plunkett, xjm, EclipseGc, vijaycs85, webchick,...
larowlan’s picture

Status: Reviewed & tested by the community » Fixed

Committed 88a22dd and pushed to 8.5.x.

On with the next steps!

Un-postponing all the follow ups and publishing the change record.

Wim Leers’s picture

EXCITING 🎉

webchick’s picture

HELL yes. :D

almaudoh’s picture

Wow!!! Great job here!!

anavarre’s picture

Do we have specific issues for Messages, User login, Tabs, Primary admin actions blocks failing to be added via the layout builder?

  • xjm committed 08d676a on 8.5.x
    Revert "Issue #2905922 by tim.plunkett, xjm, EclipseGc, vijaycs85,...
xjm’s picture

Status: Fixed » Needs work

Had to revert this due to #2924201: Resolve random failure in LayoutBuilderTest so that it can be added to HEAD which is unfortunately too serious a disruption to leave in HEAD. It's worth considering a patch without the failing part of the test since this is an experimental module, and just adding the test in #2924201: Resolve random failure in LayoutBuilderTest so that it can be added to HEAD once we fix it.

tedbow’s picture

Assigned: tim.plunkett » Unassigned
Status: Needs work » Needs review
FileSize
169.38 KB

I think since this is an experimental module we can commit it with the test without the random failure. There is already a follow up to fix this #2924201: Resolve random failure in LayoutBuilderTest so that it can be added to HEAD

This patch removes Drupal\Tests\layout_builder\FunctionalJavascript\LayoutBuilderTest and Drupal\Tests\layout_builder\FunctionalJavascript\ PageReloadHelperTrait

EclipseGc’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me!

Eclipse

  • xjm committed f7c9dd9 on 8.5.x
    Issue #2905922 by tim.plunkett, tedbow, xjm, EclipseGc, webchick,...
xjm’s picture

Status: Reviewed & tested by the community » Fixed

Alright, recommitted after reading the diffstat. Thanks @tedbow and @EclipseGc!

xjm’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

andrewmacpherson’s picture

Where do we track progress towards marking layout-builder as stable?

xjm’s picture

@andrewmacpherson, on this issue I believe: #2884601: Add a Layout Builder to core

tim.plunkett’s picture

Component: layout.module » layout_builder.module