Removing a reusable block (in Gutenberg) clears the content of the reusable block

Created on 3 February 2023, over 1 year ago
Updated 5 June 2024, 21 days ago

Problem/Motivation

Imagine the following use case.

  1. I have created a node (A) with a reusable content block
  2. I create a new node (B), that is using the reusable content block
  3. I delete the Gutenberg block (not the reusable block) in the Gutenberg editor on node B

This currently clears the content of the reusable block, means the removal of the reusable block in node B will destroy the reusable content block and all its usages.

The reason is, that the ReusableBlocksController save functions checks for the content to be NOT NULL. But when you debug the request, you will see that the content is an empty string, therefore the condition matches and the block body will be set to empty.

This could lead to unexpected data loss for the Drupal user, because he does not necessarily understands the block structure and tend to delete the content of the reusable block (especially if it's a group or a single block) rather than the reusable block as itself, because that sometimes is the one that would be selected when clicking in the Gutenberg editor.

Steps to reproduce

Proposed resolution

Check for empty instead

if (!empty($content)) {

Remaining tasks

User interface changes

API changes

Data model changes

Feature request
Status

Fixed

Version

3.0

Component

Code

Created by

🇩🇪Germany szeidler Berlin

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @szeidler
  • 🇩🇪Germany szeidler Berlin

    Here's a patch that solves this. I'm not marking it as "Needs review", because it might be a desired behavior and just an end user issue with selecting the wrong block.

  • Status changed to Needs review 11 months ago
  • Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update 11 months ago
    Waiting for branch to pass
  • 🇨🇦Canada joseph.olstad

    Our editors have noticed blocks vanishing, somewhere along the way gutenberg behavior changed and introduced this bug.

    Marking this as critical as it implicates data loss.

  • Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update 10 months ago
    Waiting for branch to pass
  • 🇨🇦Canada joseph.olstad

    New patch.

    This patch improves the UI /DX/UX , editors will now know when they're editing a reusable block.

    Added to the original patch.

    To make this patch localized one would have to add an style to the head that inserts a translated content attribute.

    I'll add a screenshot of what it looks like in my environment with french text instead of english.

  • 🇵🇹Portugal marcofernandes

    For 3.x, the reusable block (now called synced pattern) selection is much clearer.

  • 🇨🇦Canada joseph.olstad

    is it expected to be a smooth "upgrade" from 2.x to 3.x?

  • 🇨🇦Canada joseph.olstad

    @marcofernandes
    Thanks for this.

  • Pipeline finished with Success
    about 1 month ago
    Total: 306s
    #176609
  • Status changed to Fixed about 1 month ago
  • 🇵🇹Portugal marcofernandes

    I just added szeidler's patch. To add a visual indicator I suggest creating a feature request and it should be done via block hook filters using wp.hooks.addFilter(). By using only CSS would be difficult to add translations.

  • Pipeline finished with Success
    about 1 month ago
    Total: 254s
    #176617
  • 🇨🇦Canada joseph.olstad

    Implementing a css solution with a tiny bit of php isn't that hard.

    Here is what needs to be done:

    /**
     * Implémente hook_preprocess_HOOK() pour les pages.
     */
    function gutenberg_preprocess_page(&$variables) {
      // Add the CSS file
      $variables['#attached']['library'][] = 'gutenberg/gutenberg_custom_styles';
    
      // Generate the localized content.
      $localized_content = t('Reusable block editing, changes have global impact.');
    
      // Add the attribute "data-warning-content" to a specific element.
      // For example we add an element with the class "gutenberg-block"
      $variables['page']['#attached']['html_head'][] = [
        [
          '#tag' => 'script',
          '#value' => "
            document.addEventListener('DOMContentLoaded', function() {
              var elements = document.querySelectorAll('.gutenberg-block');
              elements.forEach(function(element) {
                element.setAttribute('data-warning-content', '" . $localized_content . "');
              });
            });
          ",
          '#attributes' => [],
        ],
        'gutenberg_warning_message',
      ];
    }
    
    /**
     * Implémente hook_library_info_build().
     */
    function gutenberg_library_info_build() {
      $libraries['gutenberg_custom_styles'] = [
        'css' => [
          'theme' => [
            'css/gutenberg_custom.css' => [],
          ],
        ],
      ];
      return $libraries;
    }
    
    

    Now for the css:

    .node-form div.block-library-block__reusable-block-container div.block-editor-block-list__block.has-child-selected {
      position: relative;
    }
    .node-form div.block-library-block__reusable-block-container div.block-editor-block-list__block.has-child-selected div.block-editor-block-list__block.is-selected::before,
    .node-form div.block-library-block__reusable-block-container div.block-editor-block-list__block.has-child-selected:first-child > div.wp-block-group__inner-container.block-editor-block-list__layout:first-child::before,
    .node-form div.block-library-block__reusable-block-container > div.block-editor-block-list__layout > .is-selected::before {
      position: absolute;
      content: attr(data-warning-content);
      font-size: 18px;
      font-weight: normal;
      color: red;
      width: 100%;
      top: -120px;
      left: 74px;
      border: 1px solid #cca379;
      border-radius: 5px;
      background-color: linen;
      padding: 10px;
      padding-right: 10px;
      padding-right: 0;
    }
    .node-form div.block-library-block__reusable-block-container div.block-editor-block-list__block.has-child-selected div.block-editor-block-list__block.is-selected::after,
    .node-form div.block-library-block__reusable-block-container div.block-editor-block-list__block.has-child-selected:first-child > div.wp-block-group__inner-container.block-editor-block-list__layout:first-child::after,
    .node-form div.block-library-block__reusable-block-container > div.block-editor-block-list__layout > .is-selected::after {
      position: absolute;
      top:-77px;
      left: 123px;
      width: 0;
      height: 0;
      border-left: 20px solid transparent;
      border-right: 20px solid transparent;
      border-top: 20px solid #cca379;
    }
    
    

    scss now:

     .node-form {
      div.block-library-block__reusable-block-container div.block-editor-block-list__block.has-child-selected {
        position: relative;
      }
      div.block-library-block__reusable-block-container div.block-editor-block-list__block.has-child-selected div.block-editor-block-list__block.is-selected::before,
      div.block-library-block__reusable-block-container div.block-editor-block-list__block.has-child-selected:first-child > div.wp-block-group__inner-container.block-editor-block-list__layout:first-child::before,
      div.block-library-block__reusable-block-container > div.block-editor-block-list__layout > .is-selected::before {
        position: absolute;
        content: attr(data-warning-content);
        font-size: 18px;
        font-weight: normal;
        color: red;
        width: 100%;
        top: -120px;
        left: 74px;
        border: 1px solid #cca379;
        border-radius: 5px;
        background-color: linen;
        padding: 10px;
        padding-right: 10px;
        padding-right: 0;
      }
      div.block-library-block__reusable-block-container div.block-editor-block-list__block.has-child-selected div.block-editor-block-list__block.is-selected::after,
      div.block-library-block__reusable-block-container div.block-editor-block-list__block.has-child-selected:first-child > div.wp-block-group__inner-container.block-editor-block-list__layout:first-child::after,
      div.block-library-block__reusable-block-container > div.block-editor-block-list__layout > .is-selected::after {
        position: absolute;
        top:-77px;
        left: 123px;
        width: 0;
        height: 0;
        border-left: 20px solid transparent;
        border-right: 20px solid transparent;
        border-top: 20px solid #cca379;
      }
     }
    
  • 🇨🇦Canada joseph.olstad

    This imho, is not fixed until the UI solution is implemented.

  • 🇨🇦Canada joseph.olstad

    When it's working, expect it to look something like this screenshot:

    This is important as the UI improvement helps prevent mistakes and provides important information to the editor.

  • Status changed to Needs review about 1 month ago
  • 🇨🇦Canada joseph.olstad

    This isn't fixed IMHO until the GUI gets the improvement. Otherwise very confusing for any editor scratching their heads.

    I have not tested this latest merge request.

  • Pipeline finished with Success
    about 1 month ago
    Total: 216s
    #177339
  • Pipeline finished with Success
    about 1 month ago
    Total: 218s
    #177343
  • Pipeline finished with Success
    about 1 month ago
    Total: 218s
    #177348
  • 🇨🇦Canada joseph.olstad

    Needs review/testing

  • Pipeline finished with Canceled
    about 1 month ago
    Total: 258s
    #177349
  • Pipeline finished with Canceled
    about 1 month ago
    Total: 159s
    #177357
  • 🇨🇦Canada joseph.olstad

    Sorry I'm unable to test this but hopeful that it works for the 3.0.x branch.

  • Pipeline finished with Success
    about 1 month ago
    Total: 305s
    #177360
  • 🇨🇦Canada joseph.olstad

    joseph.olstad changed the visibility of the branch 3338959- to hidden.

  • 🇨🇦Canada joseph.olstad

    joseph.olstad changed the visibility of the branch 3338959- to hidden.

  • 🇵🇹Portugal marcofernandes

    Sorry 😬, but I think we shouldn't go for that approach. Gutenberg hook filters should definitely be used here.

    And I'm not really convinced that we should adopted this behaviour for 3.x since now the editor needs to select the reusable block (synced pattern) in order to edit it. And when selecting a synced pattern, its color is different (magenta). So, I believe, they will be aware they are editing the pattern. 🤔

    Here's how it works in 3.x:
    https://www.drupal.org/files/issues/2024-05-20/Screen%20Recording%202024...

    But for 2.x probably makes sense since we don't have almost any visual indication.

    • marcofernandes committed 4aaa53a2 on 3338959-reusable-blocks-message
      Issue #3338959 by joseph.olstad, marcofernandes, szeidler: Add warning...
  • 🇵🇹Portugal marcofernandes

    @joseph.olstad I added this MR https://git.drupalcode.org/project/gutenberg/-/merge_requests/136 for 2.x

    But I'm still thinking if this should go to 3.x 😄

    • marcofernandes committed c9ed7262 on 3338959-reusable-blocks-message
      Issue #3338959 by marcofernandes: Revert unwanted change
      
  • 🇵🇹Portugal marcofernandes

    Btw, I'm changing this issue classification because it's not a bug nor critical. It is, after all, a user behaviour. It's bad UX, for sure.

    • marcofernandes committed c6a24018 on 3338959-reusable-blocks-message
      Issue #3338959 by marcofernandes: Tweak style and message
      
  • 🇨🇦Canada joseph.olstad

    Nicely done, thanks!

  • Status changed to Fixed about 1 month ago
  • Pipeline finished with Failed
    22 days ago
    Total: 260s
    #190203
  • Pipeline finished with Success
    22 days ago
    Total: 154s
    #190217
  • Pipeline finished with Success
    22 days ago
    Total: 158s
    #190221
  • Automatically closed - issue fixed for 2 weeks with no activity.

  • Pipeline finished with Success
    12 days ago
    #198926
  • Pipeline finished with Failed
    1 day ago
    Total: 408s
    #206663
  • Pipeline finished with Failed
    1 day ago
    Total: 210s
    #206676
  • Pipeline finished with Success
    1 day ago
    #206679
Production build 0.69.0 2024