If a block returns a renderable array and the array has direct attibutes they will be "stolen" from the original content and applied to the block itself.

For example a if a block returns something like this:

array(
  '#attributes' => array(
    'class' => array(
      'foo-bar'
    ),
    'data-test' => 'This is just a test'
  ),
  '#markup' => 'This is block content'
);

The rendered HTML will be:

<div id="block-foobartest" class="foo-bar" data-test="This is just a test">
  This is block content.
</div>

instead of:

<div id="block-foobartest">
  <div class="content foo-bar" data-test="This is just a test">
    This is block content.
  </div>
</div>

This is especially bad for blocks that represent forms since none of the form attributes is preserved.

Comments

ivanjaros’s picture

Issue summary: View changes
joelpittet’s picture

Component: render system » theme system
Status: Active » Closed (works as designed)
Issue tags: +Twig

This is by design. If you are using bartik theme's templates you can pass in #content_attributes like what D7 had. We decided to remove some divs.

ivanjaros’s picture

Status: Closed (works as designed) » Active

I understand the simplifying of D8's markup. but that is not what I have issue with.
My issues is that a block is providing a piece of content, which is a "unit" of content on its own, and should be immutable in a way. But the render engine will break this unit into pieces(ie. the render array) and it will steal attributes out of it and pass it to the block itself rendering the original "unit" of content improperly.

joelpittet’s picture

Ah did a bit of research and see kinda what you are trying to explain. There is a specific comment to that effect.

core/modules/block/src/BlockViewBuilder.php:212

      // Place the $content returned by the block plugin into a 'content' child
      // element, as a way to allow the plugin to have complete control of its
      // properties and rendering (e.g., its own #theme) without conflicting
      // with the properties used above, or alternate ones used by alternate
      // block rendering approaches in contrib (e.g., Panels). However, the use
      // of a child element is an implementation detail of this particular block
      // rendering approach. Semantically, the content returned by the plugin
      // "is the" block, and in particular, #attributes and #contextual_links is
      // information about the *entire* block. Therefore, we must move these
      // properties from $content and merge them into the top-level element.

I think you are write and we really should have been using #wrapper_attributes, to effect that outer element from our block plugin build() render arrary I think.

Am I following you @ivanjaros?

joelpittet’s picture

Status: Active » Needs review
FileSize
1.13 KB

Here's a quick patch to see how many test fail.

There is also a good chance this won't get into release considering it's next week. Don't want to get your hopes up @ivanjaros.

Status: Needs review » Needs work

The last submitted patch, 5: attributes_of_a_block-2486267-5-boom.patch, failed testing.

ivanjaros’s picture

Yes, usage of #wrapper_attributes makes much more sense.

joelpittet’s picture

Let's see if a framework manager can chime in here.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

effulgentsia’s picture

Version: 8.1.x-dev » 8.2.x-dev
Component: theme system » block.module
Issue tags: -Needs framework manager review +Needs subsystem maintainer review
Related issues: +#2171269: Handle block rendering's #attributes correctly (fixes in-place editing of custom blocks)
FileSize
49.58 KB

This is especially bad for blocks that represent forms since none of the form attributes is preserved.

I was curious how this affected SearchBlock, and found that most form attributes, such as method and action are ok, because they're stored as #method and #action on the render array, rather than in #attributes. However, I did find that in HEAD, $form['#attributes']['data-drupal-selector'] ends up getting moved from the <form> tag to the block's <div> wrapper, per the attached screenshot.

The code in #4 was introduced in #2171269: Handle block rendering's #attributes correctly (fixes in-place editing of custom blocks), so adding it as a related issue, and I'll post a comment there asking for people who worked on that to comment here.

Prior to giving framework manager review on this, I'd like input from block.module maintainers, so tagging for that.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.