It seems like while this issue was raised couple of times before, it was sidelined due to more pressing concerns. So lets decide this here once and for all. I'll try to list pros and cons of retaining the wrapper div from my understanding and others are welcome to add to the list:

PROS:
* In case of a failure, user could still see the wrapper and any placeholder text which might have been used in between. This behavior is kinda similar to alt text for an image. (Can be a con as well, in certain cases)
* Provides a standard point(DOM element) of refernce for theming and related tasks.
* Data attributes used for embed are separate from the actual embed so both can be handled differently, if required. (Kinda similar to how iframes work)
* Others?

CONS:
* More clean output.
* In case embed fails, no stray divs will be produced. (Might be desired in some cases)
* Inline elements like images may become block elements due to wrapper. (Can try a workaround for this?)
* Others?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

cs_shadow created an issue. See original summary.

f2boot’s picture

CONS:
Quotes or other text references often need to be inline elements (entity_embed would be a great step forward to ease the creation of hypermedia website for scholarly associations or learned societies)

Dave Reid’s picture

Yeah, we've seen in File Entity that having the wrapping div is very much undesirable in a lot of cases. If there is a failure (like the entity fails to load) then we should log it.

Maybe we could do the best of both worlds and make it configurable from the button what behavior to use (replace contents inside and leave wrapping div, or replace div entirely)?

cs_shadow’s picture

I can definitely imagine cases where wrapping div can cause problems.

I like the idea of making it configurable and on the same note, should we also add a configuration option about what to do in case of a failure - retain the wrapper or just log the error?

cs_shadow’s picture

Another issue that we'll need to address if we decide to go with this configuration plan - This works well for embeds created with a button but what happens when no button is used and the filter is invoked directly. There are three ways that I can think of at the moment to handle this case:

- Replace/Retain always, whatever is default behavior
- Allow this default behavior to be configurable (this would be global module-level config)
- Add a data attribute to specify this

Dave Reid’s picture

I'm starting to feel stronger and stronger about replacing always.

cs_shadow’s picture

Title: Decide whether or not to retain wrapping div » Always remove the wrapping div
Category: Plan » Task

Alright, lets do this - lets remove the wrapping div. But I think that we should still copy all the data attributes to the first child of the wrapping div

Dave Reid’s picture

I feel strongly about not copying the data attributes still. If someone wants that behavior, I think they should be able to do so using hook_entity_embed_alter(). I'd rather just replace the content like all other filters do.

Dave Reid’s picture

Assigned: Unassigned » Dave Reid
Dave Reid’s picture

tkoleary’s picture

I doing this this might have been a mistake.

The first thing I wanted to do was create a class and add it to the "styles" dropdown in CK so I could style embedded entities. This was not possible because there was no wrapping div.

Assuming a use case (as I am) in which the author does not have the ability to view source, in order to style an embedded entity they need to:

1. Create some text
2. Style the text from the styles dropdown with div element style
3. select the text
4. click the embed link and embed the entity which replaces the text and is now wrapped in the div with the class

After this the embedded entity is still not styled in the WYSIWYG, but is styled on the live page.

If it's wrapped in a div: select it, style it, done. That seems like a far more usable feature.

Wim Leers’s picture

Assigned: Dave Reid » Wim Leers
Priority: Normal » Major

#8:

I feel strongly about not copying the data attributes still. If someone wants that behavior, I think they should be able to do so using hook_entity_embed_alter(). I'd rather just replace the content like all other filters do.

+1000


#11:

The first thing I wanted to do was create a class and add it to the "styles" dropdown in CK so I could style embedded entities. This was not possible because there was no wrapping div.

You're misunderstanding this. We're talking about the markup that Entity Embed transforms: <drupal-entity data-entity-type="node" data-entity-uuid=… />. Currently, the content that that the filter should put in its place, is not replacing that <drupal-entity> tag. It's being added as the child of the <drupal-entity> tag.

What you're talking about is that any class attribute set on <drupal-entity> should persist, should make its way onto the final HTML.

i.e.:

<drupal-entity class="FANCY-KEVIN-ARTICLE" data-entity-type="node" data-entity-uuid=… />

->

<article role="article" class="FANCY-KEVIN-ARTICLE node node--type-page node--promoted node--view-mode-teaser">

That is true, and is a separate problem. Entity Embed should behave like \Drupal\filter\Plugin\Filter\FilterCaption does in that case: it correctly passes on classes.


I ran into this bug in yet another way: via the test coverage while working on #2628358: Disallow <div>, only allow <drupal-entity>:

    // Test that tag of container element is not replaced when it's not
    // 'drupal-entity'.
    $content = '<not-drupal-entity data-entity-type="node" data-entity-id="' . $this->node->id() . '" data-view-mode="teaser">this placeholder should not be rendered.</not-drupal-entity>';
    $settings = array();
    $settings['type'] = 'page';
    $settings['title'] = 'test entity embed with entity-id and view-mode';
    $settings['body'] = array(array('value' => $content, 'format' => 'custom_format'));
    $node = $this->drupalCreateNode($settings);
    $this->drupalget('node/' . $node->id());
    $this->asserttext($this->node->body->value, 'embedded node exists in page');
    $this->assertRaw('</not-drupal-entity>');

It says "test that anything else than is NOT replaced" … but then it tests that it DOES get replaced! Yet it also tests that </not-drupal-entity> still exists… And both tests pass! That is not logically possible!

Except this bug makes it possible: because we never ever replace the original DOM node, we also cannot reliably test some cases, because the original HTML is never actually replaced.


Working on this.

Wim Leers’s picture

Wim Leers’s picture

Title: Always remove the wrapping div » Remove the <drupal-entity>/<div> placeholder instead of embedding the entity as a child

Better title.

Wim Leers’s picture

Status: Active » Needs review
FileSize
4.29 KB
3.54 KB

Just using \Drupal\embed\DomHelperTrait::replaceNodeContent() instead of \Drupal\embed\DomHelperTrait::setNodeContent() is all that's necessary!

Test coverage updated.

Note that these bits of test changes are due to #12 and they will be fixed in #2628358: Disallow <div>, only allow <drupal-entity>:

@@ -102,6 +106,9 @@ class EntityEmbedFilterTest extends EntityEmbedTestBase {
 
     // Test that tag of container element is not replaced when it's not
     // 'drupal-entity'.
+    // @todo This does NOT actually work, despite the test comment having
+    //   claimed otherwise for more than a year. The test is simply wrong. It
+    //   will be fixed in https://www.drupal.org/node/2628358
     $content = '<not-drupal-entity data-entity-type="node" data-entity-id="' . $this->node->id() . '" data-view-mode="teaser">this placeholder should not be rendered.</not-drupal-entity>';
     $settings = array();
     $settings['type'] = 'page';
@@ -109,8 +116,8 @@ class EntityEmbedFilterTest extends EntityEmbedTestBase {
     $settings['body'] = array(array('value' => $content, 'format' => 'custom_format'));
     $node = $this->drupalCreateNode($settings);
     $this->drupalget('node/' . $node->id());
-    $this->asserttext($this->node->body->value, 'embedded node exists in page');
-    $this->assertRaw('</not-drupal-entity>');
+    $this->assertText($this->node->body->value, 'embedded node exists in page');
+    $this->assertNoRaw('</not-drupal-entity>');
Wim Leers’s picture

Title: Remove the <drupal-entity>/<div> placeholder instead of embedding the entity as a child » [PP-1] Remove the <drupal-entity>/<div> placeholder instead of embedding the entity as a child
Status: Needs review » Postponed

But… HAH! That won't actually work, because embed's replaceNodeContent() is broken: see #2602316: Allow any HTML as content for replaceNodeContent. It will only actually import the first DOM node. And the first DOM node when rendering an article template happens to be… a text DOM node with a newline in it. The second DOM node is the <article class="type-node" …> HTML that we expect.

So, with the above, tests actually fail for both patches because embed is broken…

Now working on #2602316: Allow any HTML as content for replaceNodeContent.

The last submitted patch, 15: 2547085-15.patch, failed testing.

Status: Postponed » Needs work

The last submitted patch, 15: 2547085-15-FAIL-test-only.patch, failed testing.

Wim Leers’s picture

As predicted, both patches failed.

Forgot to add a related issue.

tkoleary’s picture

@Wim Leers

What you're talking about is that any class attribute set on should persist, should make its way onto the final HTML.

IIRC the class was not even added to drupal-entity when I attempted to do so via the styles dropdown, but maybe there was just no visual feedback?

slashrsm’s picture

Status: Needs work » Needs review
Issue tags: +Zurich media sprint 2015

Embed patch was committed. Re-testing.

Status: Needs review » Needs work

The last submitted patch, 15: 2547085-15-FAIL-test-only.patch, failed testing.

slashrsm’s picture

Status: Needs work » Fixed

Fail was expected. No idea why bot didn't recognize test only patch. Committing this as it blocks us on other issues.

If we still want to preserve classes let's do that in a separate issue. Keeping in rendered output isn't option IMO.

Thank you all!

  • slashrsm committed 4ed6ddb on 8.x-1.x authored by Wim Leers
    Issue #2547085 by Wim Leers: Remove the <drupal-entity>/<div>...
Wim Leers’s picture

I will open a separate issue for the class attribute persistence support.

Wim Leers’s picture

Title: [PP-1] Remove the <drupal-entity>/<div> placeholder instead of embedding the entity as a child » Remove the <drupal-entity>/<div> placeholder instead of embedding the entity as a child
Wim Leers’s picture

  • Devin Carlson committed b87efec on 7.x-3.x
    Issue #2547085 by Wim Leers: Remove the <drupal-entity>/<div>...

  • Devin Carlson committed db4e634 on 7.x-2.x
    Issue #2547085 by Wim Leers: Remove the <drupal-entity>/<div>...

  • Devin Carlson committed 02289ea on 7.x-1.x
    Issue #2547085 by Wim Leers: Remove the <drupal-entity>/<div>...

Status: Fixed » Closed (fixed)

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