Original description by @phenaproxima:

I have a use case where it would be helpful for drupal-entity elements to be displayed inline. For instance, I may need to embed a tweet (from Media Entity Twitter) into a paragraph, floated to the left; or a video (through Media Entity Embeddable Video), floated to the right. Or perhaps an image (via Media Entity Image), inline with some text.

Right now the CKEditor DTD will not allow that, so this PR alters the DTD to allow drupal-entity elements as children of elements which can contain img elements.

CommentFileSizeAuthor
#126 entity_embed-inline-widget-2640398-126.patch76.28 KBedwardsay
#121 entity_embed-inline_widget-2640398-120.patch20.38 KBpbone3b
#120 drupal.org_files_issues_2023-07-21_entity_embed-inline_widget-2640398-120.patch.txt20.38 KBpbone3b
#117 entity_embed-inline_widget-2640398-117.patch20.39 KBSerhii Shandaliuk
#116 entity_embed-inline_widget-2640398-116.patch20.39 KBSerhii Shandaliuk
#114 entity_embed-inline_widget-2640398-113.patch25.22 KBroshkovanv
#106 entity_embed-inline_widget-2640398-102.patch20.4 KBghenov.andrei
#101 interdiff_97-101.txt716 bytesazinck
#101 entity_embed-inline_widget-2640398-101.patch24.88 KBazinck
#97 interdiff_88-97.txt1.2 KBazinck
#97 entity_embed-inline_widget-2640398-97.patch24.88 KBazinck
#96 interdiff_88-96.txt668 bytesazinck
#96 entity_embed-inline_widget-2640398-96.patch24.77 KBazinck
#95 interdiff_88-95.txt668 bytesazinck
#95 entity_embed-inline_widget-2640398-95.patch24.77 KBazinck
#88 interdiff_78-88.txt263 bytesjasonawant
#88 entity_embed-inline_widget-2640398-88.patch20.36 KBjasonawant
#78 entity_embed-inline_widget-2640398-78.patch25.15 KBGrimreaper
#75 entity_embed-inline_widget-2640398-75.patch25.15 KBGrimreaper
#70 2640398-70-entity-embed-inline.patch24.27 KBmarcvangend
#68 2640398-68-entity-embed-inline.patch20 KBmarcvangend
#66 entity_embed-inline-wdigets-2640398-66.patch1.77 KBelgordogrande
#63 entity_embed-inline-widgets-2640398-63.patch1.81 KBAndraeRay
#58 allow-inline-embed-2640398-58.patch602 bytesHenry Tran
#39 plugin-modified.js_.zip2.91 KBcode-brighton
#36 entity_embed-inline-widgets-2640398-32.patch491 byteszepner
#29 entity_embed-inline-widgets-2640398-18.patch1.07 KBTomazetti
#17 entity_embed-inline-widgets-2640398-17.patch487 bytesJohn Pitcairn
#13 entity_embed-inline-widgets-2640398-13.patch487 bytesJohn Pitcairn
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

slashrsm created an issue. See original summary.

slashrsm’s picture

Status: Active » Needs review
slashrsm’s picture

Status: Needs review » Needs work

One comment on pull. It would make sense to have this configurable per-button.

smaz’s picture

I'm very interested in this feature, especially per button.

For my use case, I have one file browser for images & one for files/attachments, so that they are displayed either as an image or link to file accordingly. Images are fine to be blocks, but files/attachments needs to be inline.

What can I do to help out? Try out the existing pull request?

Cheers

Wim Leers’s picture

Title: Edit Allow drupal-entity elements to be inline » Allow <drupal-entity> elements to be inline CKEditor Widgets
Issue tags: +JavaScript, +ckeditor
ramarajuk’s picture

The patch only works for images. Is it possible to embed drupal-entity element within p tag.

Dave Reid’s picture

From #drupal-media in IRC, this discussion here was useful for thinking through how we could solve this

9:41 PM <Sam152> Is there a way to use the entity_browser + entity_embed + associated modules to insert a link to a media entity instead of embedding it.
9:42 PM <Sam152> Does anyone know if there is any plugability around the insertion itself
9:42 PM <Sam152> And which module to go sniffing around in?
9:42 PM <Sam152> davereid: ^
9:43 PM <Sam152> I'd imagine entity_embed since that provides the bridge between the WYSWIYG and the entity browser.
9:43 PM <Sam152> But it's not technically embedding the entity
9:43 PM <Sam152> Perhaps integrate the WYSWIYG with entity_browser directly?
9:43 PM <Sam152> But seems like a lot of work.
12:45 AM <davereid> Sam152: Entity Embed is the way to go, the trick is is there a field formatter that could be used to output a media entity on an entity reference field using a link?
12:46 AM <davereid> That's all that would need to be written if it doesn't already exist
12:46 AM <Sam152> davereid: I considered that, but discredited it quickly
12:46 AM <davereid> I think core does provide an Entity Label formatter which can create a link
12:46 AM <davereid> (links to the entity)
12:47 AM <Sam152> davereid: I thought there was probably way too many block level elements/assumptions at play at the WYSIWYG integration level for that to be effective.
12:47 AM <Sam152> I don't think the full entity embed markup, transformed into a view mode is going to work.
12:47 AM <davereid> It's not a view mode
12:47 AM <Sam152> Has to be a more light weight integration that just wraps text in a link.
12:47 AM <davereid> It's a field formatter
12:47 AM <davereid> Ah, you want custom text
12:47 AM <Sam152> You can only embed the whole entity view mode right?
12:47 AM <davereid> No
12:47 AM <Sam152> Not individual fields?
12:48 AM <davereid> You can use any field formatter that entity reference fields can use
12:48 AM <Sam152> I see.
12:48 AM <davereid> Which includes rendering the entity, the label of the entity with an optional link, or the entity ID (is what core provides out of the box, the latter being very unuseful)
12:48 AM <Sam152> Sure.
12:49 AM <Sam152> Well, a formatter could easily ship with a settings for the custom label text.
12:49 AM <davereid> Yep!
12:49 AM <davereid> exactly
12:49 AM <Sam152> But I still think it might be a challenge to get it to sit inline in a paragraph.
12:49 AM <davereid> LinkIt might be the better use case for raw inline links
12:49 AM <Sam152> That was my fall back
12:49 AM <davereid> I'm not sure how we can best handle that with Entity Embed
12:49 AM <Sam152> But it doesn't allow the entities to be created.
12:49 AM <davereid> yeah :/
12:50 AM <davereid> I'm totally open to making this easier with Entity Embed but there are limits with the current embed structure/tag
12:51 AM <Sam152> davereid: It might simply be out of scope.
12:51 AM <davereid> That's my gut feeling as well, but I didn't want to say it's never not possible
12:51 AM <Sam152> davereid: If there was some kind of pluggability at the WYSIWYG JS level after the entity was selected, could probably get something going.
12:51 AM — davereid sets a record for negatives in a sentence
12:51 AM <Sam152> davereid: At the same time, if anything, the scope of all these modules needs to be reigned in.
12:51 AM <Sam152> Not expanded
12:52 AM <davereid> Yeah, agreed it's not at all the focus for MVP
12:53 AM <Sam152> davereid: My use case is documents, I'm going to suggest linkit to stick media/1 links in there and an input filter to replace media/1 with /sites/default/files/document.pdf
12:53 AM <Sam152> Unless.. the entity browser can be side-loaded cleanly and the javascript that does the insertion can be swapped out.
12:53 AM <Sam152> In any case, it'll work for this client.
12:54 AM <davereid> We should just make a 'Entity link' formatter that allows people to add custom text
12:54 AM <davereid> This is going to be a common use case
12:54 AM <davereid> Where people don't want to just use the entity label always as the link text
12:54 AM <Sam152> davereid: You think that is going to site nicely in a paragraph the way the plugin is currently written?
12:54 AM <davereid> and if we can get that to work inline, which we do have an open issue for, I think it would work then
12:55 AM <Sam152> davereid: That aspect sounds non trivial to me.
12:55 AM <davereid> we do want inline support, it may be an option on the embed
12:55 AM <davereid> checkbox for 'render this embed inline'
12:55 AM <davereid> could be an easy way
12:55 AM <davereid> but it would depend if the formatter supported it
12:56 AM <davereid> but for the entity link, image and file field formatters, it should be doable
12:56 AM <Sam152> Extra UI cruft, extra complexity in the JS plugin, extra overhead on developing these formatters.
12:56 AM <Sam152> Don't love it...
12:56 AM <Sam152> But it could be the only reasonable way to support this.
12:56 AM <davereid> Inline support is something we definitely do have to solve
12:57 AM <davereid> (common use case)
12:57 AM <davereid> embedded images inline we want to route through entity embed
12:57 AM <davereid> etc
sgp913’s picture

I hacked in the inlining by changing the DTD settings:

js/plugins/drupalentity/plugin.js line 27, added:

dtd.$inline['drupal-entity'] = 1; underneath the FOR function.

If I need a block for it, I will just press enter and stick it in a P.

Hopefully there can just be a checkbox for "inline", similar to the align functions, and that can just make a new tag which we can use such as <drupal-entity-inline>.

All this being said, I also went through all the twig files for the display mode and swapped all the article/div/etc. for SPAN since I only wanted an icon (set as field on node) next to a link to the node. I think having a div inside a p is invalid anyway...so your YMMV.

I still am not sure how to CSS the CKEditor in Admin to make it more bearable to look at while editing since it looks like it's using an iFrame, so if anyone has any idea it would be helpful.

smaz’s picture

I don't suppose there's been any plans/movement on this? Or at least a decision on the direction (per button or per item being embedded)? Willing to help out if I can.

Sam152’s picture

#2786049: Make entity URL substitutions pluggable to support a wider variety of use cases. can be used to create a plugin that processes an entity into a URL if you fancy using linkit to solve this problem.

John Pitcairn’s picture

Another use-case: Linkit won't support config entities, so you can't use it to link to a contact form.

I already have an entityreference field formatter that outputs a link to a contact form with custom link text, prefix and suffix. This works fine, but it needs to be able to be embedded inline in the wysiwyg editor, otherwise it isn't, um, wysiwyg.

John Pitcairn’s picture

And: Embedding a commerce product variation with a "price" view mode that just outputs the price. So my client can just update the variation price and have that reflected wherever they mention it in other content.

Also willing to help out if we can formulate a clear plan of attack. I'd favor a per-item setting if possible.

John Pitcairn’s picture

For my particular set of use cases, it is OK if all embedded entities are inline. We're not using Entity Embed to embed media or anything blocky into the wysiwyg, we are handling that sort of thing via Paragraphs module.

So here is a patch for anyone else who wants to do that. It adds the one-line hack from #8, making ALL embeds inline. Use with caution.

sgp913’s picture

This patch is no longer working with current versions...

I ended up not using this module and writing a text filter based on the Linkit Filter. I have this filter grab any links headed toward a specific content type, add the fields I want in front of the link by using spans, add a library for CSS on this "embed", then remove the [data-entity] tags so that Linkit will skip over it.

I also added a check to see if the node is accessible/published to determine whether or not to remove the anchor.

I hit some snags with this, specifically with the PHP DOMNode, so I will post here if anyone else is curious how to go about this:

Make a new element in the DOM (as span) and set a class.

$sE = $dom->createElement('span');
$sE->setAttribute('class', 'myembed');

Get your HTML and use this to add strings into the mix

$fragment = $dom->createDocumentFragment();
$fragment->appendXML($string);
$sE->appendChild($fragment);

Then totally replace the element:

$element->parentNode->replaceChild($sE, $element);

For my case, 'hijacking' Linkit works since I just want to display some icons (term reference) in front of links to a specific content type, and I don't need to mess around with CK or install complicated modules with tons of templating.

marcoscano’s picture

joelhsmith’s picture

@John Pitcairn Can you update your patch? It seems like the best option for my specific use-case. I would appreciate it very much.

John Pitcairn’s picture

@joelhsmith: try this patch against current dev. Untested because I am not using this module at present.

joelhsmith’s picture

@john Pitcairn thanks for writing that patch. It does apply, but at least in my implementation it no longer puts in embed code that CKEditor will accept. It does place the embedded entity in the CKEditor but the Source button gets disabled. Upon saving the node, the embed code gets stripped out. Thanks anyway for your time!

bkosborne’s picture

I think most people want this capability so they can link to document media entities, right? Right now we can't do that without finding the uploaded document path and linking directly to that, which is a poor UX.

The use case presented in the issue summary seems kind of weak to me. Embedding things like tweets and videos inline a paragraph. Assuming your entity renders out to anything other than an inline element like a , it wouldn't even be valid HTML.

To solve the issue for linking to documents though, I wonder if a different approach makes sense. How about a more intelligent link dialog that allows you to create links to a document entity? It could ask for a document entity by way of autocomplete or entity browser. Once selected, it would place a special token as the href attribute (or maybe some other attribute) that's parsed in a text filter to lookup the filepath and use it as the real href.

joelhsmith’s picture

Check this out https://stackoverflow.com/questions/41912292/drupal-8-how-to-render-a-me...

You can also make a custom display mode, it does not have to be the Token.

The first answer works well for us. It allows you to add a real link through the Entity to the document. It will not work inline inside a paragraph.

If this helps you please give it up upvote.

jonathanshaw’s picture

My use case is wanting to link to nodes in a similar way that Drupal.org's issue queue does when you link to another issue in a comment: the link text updates if the node title is changed, and additional entity fields are available to enrich the theming (by changing color depending on status in drupal.org's case).

What you're describing @bkosborne sounds very like Linkit. Unfortunately a truly satisfactory resolution for this in Linkit depends on #2827151: Insert node title instead of # when no link text is selected which is blocked by a core issue #2741945: Allow modules to alter EditorLinkDialog to specify link text which is basically fixed but has been stuck for a year waiting for someone competent to review it.

bkosborne’s picture

@joelhsmith the problem is that you still cannot link to that document inline a paragraph of text.

benjy’s picture

@bkosborne, it's perfectly valid for anchor tags to contain block level elements nowadays - https://www.w3.org/TR/html5/text-level-semantics.html#the-a-element

John Pitcairn’s picture

@bkosborne: See comment #11 and #12 for use cases which are not about media.

jonathanshaw’s picture

@benjy I think that's not the point here; entity embed in CK editor forces the embedded entity to be outside of a paragraph of text. It doesn't slip into the text flow where the cursor is, it forces the creation of a new block element outside the current block. Or am I missing something?

benjy’s picture

@jonathanshaw no what you say is correct. I was only pointing out that @bkosborne comment about the solution here causing invalid HTML was incorrect.

jonathanshaw’s picture

Embedding things like tweets and videos inline a paragraph. Assuming your entity renders out to anything other than an inline element like a , it wouldn't even be valid HTML.

I think he meant that if your entity rendered out to be e.g. <article> or some other block element then it wouldn't be valid inside a <p> paragraph.

joelhsmith’s picture

Edit: "@joelhsmith the problem is that you still cannot link to that document inline a paragraph of text."
This quick tutorial is not meant to address the inline inside paragraph issue. This is specific to @johnathanshaw. This issue probably needs split into two thing.

@jonathanshaw I think this is possible right now. You can even make a searchable Issue browser.

My use case is wanting to link to nodes in a similar way that Drupal.org's issue queue does when you link to another issue in a comment: the link text updates if the node title is changed, and additional entity fields are available to enrich the theming (by changing color depending on status in drupal.org's case).

Part one:

For my recipe, we will call the Content Type "MyIssueCT"

1. Go to the Display Modes and add another View Mode /admin/structure/display-modes/view that we will use later for that new "MyIssueCT" Content Type. Lets call the Display View Mode "My Issue link".

2. Save that.

3. Go to the Content Type's Field tab /admin/structure/types/manage/MyIssueCT/fields

4. Add your 'Status' Field so you can denote "color depending on status" /admin/structure/types/manage/MyIssueCT/fields (We will use this later in the template file so we can generate a class to wrap your drupal-entity MyIssueCT link).

5. Go to the Content Type's Display tab/admin/structure/types/manage/MyIssueCT/display

6. Expand "CUSTOM DISPLAY SETTINGS" at the bottom of the screen. Choose the Display View Mode we created earlier called "My Issue Link"

7. Save that

8. Go to the /admin/structure/media/manage/MyIssueCT/display/issue_link tab and add your desired Fields. You will need Title and Status at least. (If people are using this example for Media instead of Content Types they would also need the "File" and the "Format" as "Url to File" which we would use later in the template file).

9. Save that

Part Two
Make the TPL

1. Coming... gimme a minute and I'll paste in some TPL code you can work with. If you get success on the other parts of this tutorial I will spend the time to complete this step. It the whole reason you are doing all this work. But If the rest of the steps don't get you there, it would be a waste of time for me to write the template for you.

For Media I do this (we need to tweak it to make it work as a Node instead of Media):

<span{{ attributes }}>

  {# You can't strip tags until the value is converted to a variable https://www.drupal.org/node/2718721 #}

  {% set field_file %}
    {{ content.field_file }}
  {% endset %}

  {% set name %}
    {{ content.name }}
  {% endset %}

  <a href="{{ field_file|striptags|trim }}">{{ name|striptags|trim }}</a>

  {% if content %}

  {# You would add a wrapper with a class that designates your status here #}
    {{ content|without('field_file','name') }}
  {% endif %}
</span>

Part Three
Add CKeditor buttons so you can embed it the content area.

1. Go to /admin/config/content/embed

2. Create a new Embed button. Lets call it "My Issue CT Embed Button"

3. After you create the button configure your fields like this:

  • Embed Type: Entity
  • Entity Type: Content Types (for media choose media)
  • Bundle: Your Bundle "My Issue CT"
  • Media Browser: (crap you might not have one yet. lets make one next
  • Allowed Entity Embed Display plugins: Choose: "My Issue Link"
  • Try to save it. If not, we will do this step over again.

Part Four
Make the View for the Media Browser we will make in the next step of steps (or Media XXX List). this is where you will chose how your Issue Browser will look.

1. Go to /admin/structure/views/

2. Add "Issue CT Nodes Browser" I set it to use "Table". Do whatever is best for your use-case.

3. Add these Fields:

  • Media: Entity browser bulk select form
  • Media: My Issue CT name (Name) -- Expand Rewrite Enable "Output this field as a custom link" set Target to _Parent (trust me on this).
    Expand Entity Browser Settings to "Display the Entity after selection"
  • Media: Link to My Issue CT (View)
  • Media: Link to edit My Issue CT (Edit)
  • Media: Link to delete My Issue CT (Delete)

Part Five
Add Entity Browser so people can open your My Issue Browser in the CKEditor

1. Go to /admin/config/content/entity_browser
2. Add and Entity Browser.

  • Label: Name
  • Expand Rewrite: Enable Link to path: Leave empty

3. Display plugin: Some of the other options will white screen Drupal. Be careful.
4. Widget selector plugin: Tabs
5. Selection display plugin: No Selection Display
6. Next button
7. Default settings are fine
8. Next button
9: Next button
10. Now you are on the final tab of the wizard
11. Add Widget plugin View: Choose our View we just made

  • Label: set to 'My Issue Link'
  • View : View display

12. Click Finish

We can also add a tab in here where you can have an Upload tab so people can actually create the Issue inside the dialog box. It is sweet. Ask me later and we can do it.

Part Six
Go back to Part Two fill out the last Field we did not Fill out earlier because it didn't exist until we made the everything after.

Part Seven
You can add a button to the CKEditor so you can embed the Issue anywhere you want

1. Go to admin/config/content/embed
2. Add Embed Button

  • Choose your Bundle
  • Allowed Entity Embed Display plugins: Choose your My Issue Link
  • Choose our new Entity Browser we just created
  • Expand "ENTITY BROWSER SETTINGS: Display the entity after selection"

Part Eight
Add the button to the CKEditor toolbar
1. Go to the CKEditor configuration /admin/config/content/formats/manage/filtered_html
2. Drag your new button in there.

Hope this helps. There is no limit what you can do with these embeded entities, like adding a status and all that. Plus the browser bonus! Good luck!

Tomazetti’s picture

Based on #8, I believe the patch should be updated.

I need to insert inline media files and nodes, so I edited the drupalentity plugin to use another custom tag and added the following to allow this tag to be used inline.

if (dtd[tagName].a) {
  dtd[tagName]['drupal-entity-inline'] = 1;
}

Could this approach be considered a future workaround?

P.S.: Sorry about the incorrect comment number on the patch file.

a.milkovsky’s picture

My workaround for floating embedded media entities:

  1. Create view modes "Align left", "Align right", "Centered" for image media
  2. Enable the view modes for the embed button
  3. Use the following css code (I add my frontend theme library to ckeditor_stylesheets):
  /* Align embed media in CKEditor */
  .cke_widget_element[data-entity-embed-display="view_mode:media.align_right"] + .cke_widget_drag_handler_container {
    right: 0 !important;
    left: auto !important;
  }
marcvangend’s picture

Looking at the documentation, it seems that there is an "official" way to declare a widget as inline: Just add "inline: true" to the editor.widgets.add object.

      // Register the entity embed widget.
      editor.widgets.add('drupalentity', {
        inline: true,
        // Minimum HTML which is required by this widget to work.
        allowedContent: 'drupal-entity[data-entity-type,data-entity-uuid,data-entity-embed-display,data-entity-embed-display-settings,data-align,data-caption]',
        requiredContent: 'drupal-entity[data-entity-type,data-entity-uuid,data-entity-embed-display,data-entity-embed-display-settings,data-align,data-caption]',
        ...

This seems to work for inline widgets, but in my case it caused problems with embedded media entities. The error message in the console was "Uncaught TypeError: Cannot read property 'attributes' of null". To be continued.

adam-delaney’s picture

Linking to media assets like files/documents is my biggest use case for inline drupal media element. Most clients desire to have documents linked inline with supported text.

Soundvessel’s picture

A work-around I am proposing for a client is to complete the entity entry in WYSIWYG to get the file uploaded (the current block display entity will still be used with a custom file-link.html.twig, we are merely trying to add an inline option), remove it (it is uploaded as permanent so used in 0 places shouldn't delete it), and use https://www.drupal.org/project/linkit to link the file to desired text. We originally used this module for linking nodes to text but I discovered it also had an option to autocomplete search and link files too.

idflood’s picture

I tried the patch in #29 but even if in the wysiwyg it looked like it was working the data was not saved. In fact as soon as I inserted a pdf file link none of the content was saved.

Inserting a pdf link inside a paragraph of text seems like a "basic" thing but none of the solution I tried provide a good UX. Entity embed seems to be the best solution for wysiwyg, the "only" missing piece is to allow the embed to be inline. The option to be "inline" or "block" should not only be tied to an entity_embed button but also depend of the view mode selected. Probably the easiest solution would be to give the "inline" option by instance, just like the alignement option.

marcvangend’s picture

Probably the easiest solution would be to give the "inline" option by instance, just like the alignement option.

I'm afraid it's not that easy. CKeditor validates and repairs the resulting HTML, so if you insert a block-level widget in an inline-level element, the markup is altered when the node is saved. If the user then sees that he broke something, comes back to the edit form and applies the "inline option", it is already too late.

The nicest solution would be if entity_embed can return a boolean indicating if the output will be an inline of block element, based on the selected options (like view mode). Then CK editor would have to adjust its behavior to that boolean.

zepner’s picture

The script.js change in the patch was causing an error, but the twig tpl change seems to work for inlining the embedded element.

facine’s picture

This seems to work for inline widgets, but in my case it caused problems with embedded media entities. The error message in the console was "Uncaught TypeError: Cannot read property 'attributes' of null". To be continued.

@marcvangend It is a problem with editable widgets, see:

Wim Leers’s picture

Component: Code » CKEditor integration
code-brighton’s picture

FileSize
2.91 KB

This is a bit of a hack...but for those desperate to get this to work (in a way) this might help. Basically I was having the same problem as others with these patches embedding entries ("Uncaught TypeError: Cannot read property 'attributes' of null") the patches kind of work, but error and don't save (so they don't really work :))
Anyway attached is my version of the entity_embed/js/plugins/drupalentity/plugin.js file that uses some of the patch work, but doesn't try to fetch the preview of the embedded entity it just puts a placeholder in the editor. It does embed when viewing the node of course. Like I said no good for all use cases, but adequate for mine

Wim Leers’s picture

@benjy in #23:

@bkosborne, it's perfectly valid for anchor tags to contain block level elements nowadays - https://www.w3.org/TR/html5/text-level-semantics.html#the-a-element

This addresses @marcoscano's #15.

Wim Leers’s picture

Issue tags: +Usability

In many of the above comments, the primary reason that's cited for wanting inline embedding of entities is linking to documents.

The only reason that this is an expectation of this module is that this module allows embedding an entity and that resulting in just the (linked) label of the entity being rendered. I agree with @Dave Reid in #7 that in that case it's better to use https://www.drupal.org/project/linkit. I understand that LinkIt doesn't allow entity creation+referencing from within the editor … but that's "just" a feature request for LinkIt: the ability to have a different link entity UI, one that also allows entity creation.

IMHO Entity Embed is designed first and foremost to generate embedded visual representations of entities. A (linked) label of an entity is not a visual representation, that's just text. I believe that's the only way to ensure this module has a good UX.

Thoughts?

bkosborne’s picture

I'm leaning towards agreement with #41 lately. It's kind of odd to want to embed a "Document" entity, because in most cases you really just want to link to it.

Here's how I'm planning to setup a site to handle Documents:

  • Entity embed button to browse, upload, and embed images/video only
  • LinkIt to support linking to existing "Document" media entities
  • Custom "Document"-only media library that just is used for browsing and uploading documents
  • Customizing default "Media" views to hide "Document" media entities

The only problem with this scenario is that there's no way to upload document media entities from within the editor now. And I don't imagine that's something LinkIt would want to support either. So for now my editors will just need to upload on separate page first.

Wim Leers’s picture

@bkosborne: I'm very glad to hear you say that; I'm new to this issue, and you've been on this for a very long time. Your support means a lot to me!

I definitely sympathize with your use case too.

I'm wondering now … perhaps entity_embed could insert a <drupal-entity data-entity-uuid=…> tag for the visual representation case … and perhaps <a href="…" data-entity-uuid=…> for the linked label case? If a "Document" media type (or any other media type) is restricted to only links, then this would be feasible. I'm not saying it'll be trivial to implement/support (that needs investigation), but at least that UX would be reasonable.

John Pitcairn’s picture

Just a counter-argument: my use-case is not a linked label. It is a embedding a commerce product entity with a view mode that only displays its price, embedded inline, so that updating a price in the product updates it everywhere it is referenced in text. Linkit isn't able to handle that.

Wim Leers’s picture

That’d be even less markup than a link, that’d be *only* text! That’s what the Token Filter module is for?

John Pitcairn’s picture

Yeah but then there isn't an auto complete to select the entity, they have to remember the token format and know the entity ID. They won't do that, they'll just type in the price :-/

Wim Leers’s picture

You're right! So we need a better UI for Token. Using Entity Embed to do all the things just makes Entity Embed very complex too :)

kerby70’s picture

I had found this ticket while looking for a way to add media images with wrapped text possibly wrapped by a link added in the WYSIWYG. Pretty normal for an image but definitely complex for this.

marcvangend’s picture

Re #41: I'm not getting into the question if something is a visual representation or "just text" - that's merely a matter of definition. Let me tell you my use case so you can decide if it makes sense, in your opinion, to use entity browser / entity embed.

I have a node type which represents a scientific document. It contains a body text and information about the scientific literature it builds on. Those literature sources are stored as paragraph entities of type 'literature', attached to the node with an entity reference revision field (ie. the standard paragraphs setup). The body text contains references (visualised as foot notes, a superscript linked number) to the literature entities. The body text is only allowed to reference literature entities attached to the same node. A single document contains many literature sources, the longest document has 140 of them at the moment. With the combination of Entity Embed, Entity Browser and a bit of custom code, I was able to set this up while meeting the following requirements:
- Editors can easily find and select a literature source and insert a reference into the body text.
- The entity browser only offers literature paragraphs attached to the current node.
- Literature references can be moved in the body text with drag-and-drop.
- It is allowed to reference the same literature source multiple times.
- Foot notes are automatically numbered when rendering the node.
- All literature sources are listed at the bottom of the page.
- Each literature reference is rendered as a linked superscript number with a unique HTML ID.
- Each literature source shows anchor links, linking back to all places in the body text where is it referenced.

I hope that helps.

John Pitcairn’s picture

I think, on the whole, entity browser in its current form satisfies many of these kind of edge cases that are not the primary use-case (media) for which it was originally invented. And does so very well.

All the pieces are there, tested and working, except for being able to embed the entity inline.

It's a very good fit. Attempting to extend linkit or token browser to provide equivalent functionality would be a lot of work just to reinvent 99% of entity embed, no?

jonathanshaw’s picture

A different way to frame the discussion at this point could be not "should entity embed support xyz way of displaying entities" but rather "can we untangle our selection and storage logic from our display logic, to enable a wider range of display formats (e.g. links) to build on our selection and storage foundation, either in this module or in modules that extend it".

marcvangend’s picture

Agree with #51. I didn't come here because I *must* use Entity Embed, I ended up here because Entity Embed works well together with CKeditor and Entity Browser. It just seemed the most promising starting point to build what I need. If I can use Entity Browser to insert something (eg. a token) else into CKeditor and it fits my use case, that's fine too.

mortona2k’s picture

#18 is working great for me. A simple longer term solution would be to add an option for inline/block in the embed config. Another way to go might be some pluggable system so we can create base embed types that are extensible.

alison’s picture

Thank you all for this issue thread, seriously, it's helped me understand some of the intentions out there, AND it's great to see everybody's perspectives and methods. I hope that however this works out, maybe we can add some documentation on the subject -- I would be happy to help, FWIW.

I have felt frustration about how it goes to "insert"/embed a PDF in a WYSIWYG field -- I guess I just had the impression that we could/should use entity embed for that sort of thing, but of course, we weren't actually doing that, b/c they don't get rendered inline -- so we've been telling content folks to use LinkIt, and upload things beforehand. It feels good to know it isn't just me, and others use that same workflow :) Honestly, I don't even mind it being the workflow, if it becomes like, the suggested workflow, and if the idea of "embedding" documents inline is put to rest (as much as anything can be put to rest, obvs). To be sure, it would be fantastic if upload functionality were added to LinkIt, but as other have said, I understand if that's not realistic any time soon (and maybe not even desirable).

And I don't mean to convey any dissatisfaction about there not being a suggested workflow so far -- as I said, I've gotten a lot out of the conversation in this thread, I find the perspectives in #41 and #49 quite compelling, so I can see how a consensus hasn't yet been reached :) Good point also about the Token Filter / UI related to that functionality (#46). I also see the point in #50 -- it does sound like a *lot* of reworking...? Tho, there's more than document "embedding," right? Isn't there also a limitation for inline image embeds, or am I misunderstanding that part?

I do really like the idea of supporting a "linked label" rendering (#43).

Questionnnnnnnnnn: Are entity_embed OR linkit on their way to being integrated into core? I understand the concerns about making entity_embed overly complex, buuuut, if it's headed for core, somehow it feels more worth it to me.......

bkosborne’s picture

Are entity_embed OR linkit on their way to being integrated into core? I understand the concerns about making entity_embed overly complex, buuuut, if it's headed for core, somehow it feels more worth it to me.......

See #2801307: [META] Support WYSIWYG embedding of media entities

alison’s picture

Thanks, @bkosborne!

rooby’s picture

I have a similar use case (not exactly the same by any means, but in the same vein) to @marcvangend.

I am not embedding media, I am embedding other entities, like nodes, taxonomy terms and field collections and I need my users to be able to choose whether to embed the contents of the entity inline or link to the entity.

Ideally for the user, they would be able to use the same UI to embed regardless of the display mode, and they would be able to switch between display modes and have an entity edit link for a existing embeds.

Henry Tran’s picture

To allow both inline and block embed element we need to permit inside tags like this:
// Display the drupal-entity element inline.
dtd.$inline['drupal-entity'] = 1;
dtd['p']['drupal-entity'] = 1;
dtd['span']['drupal-entity'] = 1;
dtd['span']['article'] = 1;

In your admin theme, we need to add template for inline element and block element, use hook_theme_suggestions_HOOK_alter().
I attached my patch for that.

bdanin’s picture

On first impression, #58 worked in my admin theme, with inline embedded entities (I'm trying to embed taxonomy references into WYSIWYG, and I want them inside an unbroken <p> tag, but it's splitting into 2 sets of <p> tags), but then it didn't work in my anonymous display theme.

After, when I go edit the page again, I cannot view the source of the input, nor change the input type and there is a JS console error:
TypeError: e is null | ckeditor.js:878:368

Martijn de Wit’s picture

If this is as simple as #patch. It is maybe something to add to #2801307: [META] Support WYSIWYG embedding of media entities

sime’s picture

Issue tags: -JavaScript +JavaScript

#49 is a great read if you're building any sort of gov/edu site with heavy docs. And this is hard problem I'm finding and I'm leaning on scratching and going with linkit.

First the patch at #58 tells ckeditor to not to wrap the drupal-entity embed with <p>s

You then may need to twig override both media*.html.twig (to replace div with span), and entity-embed-container.html.twig to remove the <article> wrapper, as both these elements are not happy inside <p>. If you don't do these things then either Drupal's line break corrector will "fix" it, or browsers like chrome will force a <p> around your entity embed anyway. Be warned, a few edge cases I've found.

When you do this, ckeditor uses your new templates in ckeditor view, and suddenly there are bugs in the editor for me (hard to select, edit, and it randomly duplicates, and I'm seeing twig debugging in the source). I *think* this is what #39 is working around with the placeholder instead of a rendered element. And I think #58 hints at a solution to this but didn't come up with the goods.

gbeezus’s picture

I started a sandbox throwing out an approach to handling embedding media inline. The gist is to extend much of the work already done to embed media from the media library in D8.8 and add a widget and plugin for a "drupal-inline-media" tag. I am curious what the community would like to see as an approach to address such an issue. I'm aware this issue relates directly to Entity Embed but maybe this will shake something out for folks here. Also coming from #2801307: [META] Support WYSIWYG embedding of media entities.

AndraeRay’s picture

After spending many hours trying to get this to emebed inline, I spoke with Krzysztof Krztoń, the CKEditor 4 Lead Developer, about what is causing the error.

It turns out by having the dtd['drupal-entity'] overrides, a div tag in the template, and then trying to add an inline flag, it confuses the editor by making it both block and inline at the same time and then throws the error. Additionally, inline tags can't have block level children like a div.

I have taken his suggestion of removing the dtd overrides, changing the div to a span, and adding the inline true flag and it's working great for me. I've attached a patch.

This patch forces the entity embed to be inline all the time. This isn't a permanent solution to this ticket but it at least shows how to get it to be inline.

I found that it is also helpful to add some css in the editor to make it display inline in the ckeditor view as well.

drupal-entity {
  display:inline;
}
drupal-entity > p {
  margin:0
}

You can use a hook_ckeditor_css_alter to add it.

As a permanent solution Krzysztof had this to say.

Now the question is if you only need to make it an inline widget or you would like to be able to insert it as both block and inline widget? The 2nd is more complex since as I mentioned making the same element both block and inline is kind of problematic. TBH the best approach in this case would be having `drupal-entity` and `drupal-entityinline` tags. They can behave the same way internally the difference will be only in widget type (block/inline) and DTD (for block as it is and no additional DTD for inline one).
If two different tags doesn't bother you it would be a good direction. And if you need the editor output to always have only `drupalentity` tag (because it is used somewhere in DB or FE) it is possible to rename it on `editor.getData()` with content post-processing (need to be done both ways during input/output) - see toHtml and toData events.

This something for the maintainers to consider.

marcvangend’s picture

Andrae, thanks for the detailed info.

azinck’s picture

@AndraeRay, have you tried using the sandbox project linked in #62? We're building a new site based on it and it's been a pretty good approach for us so far and effectively implements something similar to what you describe as your "permanent" solution. We'd love to get more feedback on what we're doing in that project to improve it and possibly work towards getting it in core.

elgordogrande’s picture

I rolled this patch against the 1.0 version and based it on the patch from #58.

Christopher Riley’s picture

I cannot get the patch in #66 to apply via composer however 63 does but I still cannot achieve a link around a media image. I really need this functionality does anyone have any suggestions?

marcvangend’s picture

Status: Needs work » Needs review
FileSize
20 KB

In #63 Krzysztof is quoted saying "TBH the best approach in this case would be having `drupal-entity` and `drupal-entityinline` tags." Today, in order to solve the "Uncaught TypeError: Cannot read property 'attributes' of null" problem (see #31) once and for all, I did exactly that, although I decided to name the tag <drupal-entity-inline>.

This patch completely separates inline embedding from the default embedding by adding new CKEditorPlugin and EmbedType plugins. In the case of the PHP classes, this could be done with a minimal amount of code, extending the existing plugins. In the case of the newly added js/plugins/drupalentityinline/plugin.js, it was not easy to reuse code from the existing js/plugins/drupalentity/plugin.js, so I just copied it and made adjustments.

As a result, I can now choose between "Entity" and "Entity Inline" when defining a new embed button on /admin/config/content/embed/button/add. And more importantly, it works (for me) :-)

Extra tip: Normally, the embed type of an existing button should not and cannot be changed after it has been defined. In this case, because the Entity and EntityInline embed types are so similar, you can get away with it. I temporarily commented '#disabled' => !$button->isNew(), in [contrib-modules-folder]/embed/src/Form/EmbedButtonForm.php, changed the embed button that needed inline behavior at /admin/config/content/embed/button/manage/[button-name], and uncommented the line again. Be aware that if you change an existing embed button like this, you may also need to change occurrences of <drupal-entity ...> to <drupal-entity-inline ...> in your content.

azinck’s picture

I just want to take the chance to again reference #2640398-62: Allow <drupal-entity> elements to be inline CKEditor Widgets as the sandbox there solves this problem in what sounds like the same way as marcvangend is doing in #2640398-68: Allow <drupal-entity> elements to be inline CKEditor Widgets.

gbeezus and I are coworkers. We're currently basing the development of a large government site on the work in his sandbox module. I'm hoping we can coalesce on a given approach and work towards improving it rather than each of us re-inventing the wheel.

marcvangend’s picture

Thanks azinck, I appreciate the reminder, and I completely agree that it would be best if we can all work towards a single solution. I did see your comment before, so allow me to quickly explain why I chose not to use it, but to write the patch in #68. First of all, we were already running entity_embed in production, with one of the earlier patches. Writing a different patch is a much smaller change than migrating to a different module. Second, I did not try your Media Inline Embed sandbox but the name seems to suggest that it is intended only for media entities. As you can read in #49, my use case involves other entity types as well.

PS. here is a new patch, because I forgot to include the .png file in the previous one.

azinck’s picture

Thanks marcvangend, for explaining some of the unique aspects of your approach. You are correct, #62 is specifically for the Media embedding in Drupal 8.8+, not for Entity Embed. I almost forgot what queue I was in :).

trishkaideka’s picture

Another use case scenario often requested by clients for inline media is when they need an icon to be used inline with text.

It would be nice inline images were allowed for this

foreveryo’s picture

I've tried to use the patch on #70 but when I add an entity using the "Entity inline" button, the console error "Uncaught TypeError: Cannot read property 'attributes' of null" appears. There is anything else besides the patch to make it work? Thanks!

marcvangend’s picture

@foreveryo What is the HTML output of your embedded entity? It must be valid as inline HTML code, so you need to make sure in your templates that it does not output any block-level elements such as <div> or <p>. Here is a list of inline elements.

Grimreaper’s picture

Hello,

I wanted to test patch from comment 70 on a project I am working on and it was not applicable using Composer.

When cloning the project, it was perfectly applied on the last dev version of 8.x-1.x branch and on 8.x-1.1 (the version I used on my project).

So here is the same patch but done with a commit and then a 'git format-patch' command. Maybe it will be ok for Composer that way.

Grimreaper’s picture

I still have the problem of applying the patch.

I run the composer update command in verbose mode and I got:

patch '-p4' --no-backup-if-mismatch -d 'src/modules/contrib/entity_embed' < '/tmp/5f06d8faa73c6.patch'
Executing command (CWD): patch '-p4' --no-backup-if-mismatch -d 'src/modules/contrib/entity_embed' < '/tmp/5f06d8faa73c6.patch'
File entity.png: git binary diffs are not supported.

patching file plugin.js

patching file DrupalEntityInline.php

patching file EntityInline.php

can't find file to patch at input line 599
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git a/src/Plugin/Filter/EntityEmbedFilter.php b/src/Plugin/Filter/EntityEmbedFilter.php
|index f244f89..3fe5e84 100644
|--- a/src/Plugin/Filter/EntityEmbedFilter.php
|+++ b/src/Plugin/Filter/EntityEmbedFilter.php
--------------------------
File to patch: 
Skip this patch? [y] 
Skipping patch.

1 out of 1 hunk ignored

   Could not apply patch! Skipping. The error was: Cannot apply patch https://www.drupal.org/files/issues/2020-04-06/2640398-70-entity-embed-inline.patch

So I ran the command on the cloned repository and I got the same issue:

patch '-p4' --no-backup-if-mismatch < entity_embed-inline_widget-2640398-75.patch 
File entity.png: git binary diffs are not supported.
patching file plugin.js
patching file DrupalEntityInline.php
patching file EntityInline.php
can't find file to patch at input line 617
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git a/src/Plugin/Filter/EntityEmbedFilter.php b/src/Plugin/Filter/EntityEmbedFilter.php
|index f244f89..3fe5e84 100644
|--- a/src/Plugin/Filter/EntityEmbedFilter.php
|+++ b/src/Plugin/Filter/EntityEmbedFilter.php
--------------------------
File to patch: 
Skip this patch? [y] 
Skipping patch.
1 out of 1 hunk ignored

I do not understand why it fails for this file. Path seems ok.

marcvangend’s picture

@Grimreaper that's strange. Can you try to manually apply the change in src/Plugin/Filter/EntityEmbedFilter.php in the cloned repo and then roll a new patch?

Grimreaper’s picture

@marcvangend, ok. Here is a new patch. I will try but I see almost no diff in the patch.

Grimreaper’s picture

I have re-tested with patch from comment 78. Same problem.

Thanks @marcvangend for the help but I had manually applied the patch on my project to test if it will solve my issue. And no, so I need to focus on something else.

lukus’s picture

Okay, this is an epic thread; I've read it through, but please forgive me if I misunderstand any of the content (and also for the fact my proposal isn't necessarily stating new things! .. as much as anything, I'm trying to help create clarity in my own head.)

The situation from my point of view:

  • Having the ability provide embedded entities within a block of formatted text is useful.
  • I've read good arguments here which show that there are other techniques available to provide certain types of embedded entity within a block of markup.

However:

  • Entities / entity display view modes provide a well known, consistent and flexible core approach to outputting content.
  • The fact that entity_embed works with the paradigm of entities / view modes, is it's main benefit to me (e.g. by using this module, I can also use entity browser, which is very useful as I can provide a consistent UX for admin users)
  • To me, it feels very reasonable the output provided by the module should be unopinionated in terms of the markup produced (and by extension, whether a block or inline element is chosen).


Bearing this in mind, I agree that functionality should be implemented to allow the entity to be displayed inline.

Current proposed patch

I've tested the patch from #78 and this applies correctly for me using composer.

  • Once installed, I have access to a separate class of embed button definition.
  • Once implemented as a CKeditor button, I unfortunately don't get any result when the button is hit.
  • I can see that the approach used by the patch is to add a new ckeditor plugin (`drupalentityinline`).
  • I can definitely see the logic in this approach, but it seems that the plugin isn't currently being registered
    correctly via the CKEditorPlugin definition (`src/Plugin/CKEditorPlugin/DrupalEntityInline.php`).

My proposal

  • I think the solution should ideally modify the current ckeditor plugin (drupalentity) rather than introduce a second.
  • We should cater for switching between inline / block level insertion, without need to reinsert an entity.
  • The ckeditor API provides a way to switch between inline / block level insertion for the widget plugin, which is used to provide the element within the editor.
  • It would be possible to insert a button within the widget component to provide access to plugin settings via a ckeditor dialog.
  • This dialog would have one option: a checkbox to select inline mode
  • The checkbox would be unselected by default.
  • We need a way to indicate if the token should be displayed inline or block level, without breaking content that's already been created using entity_embed.
  • As we don't want this to be a breaking change, I'd suggest we add a new attribute which can be used to enable inline mode. Without the attribute, the current core solution would be used as usual.
  • If the checkbox (described in the above section) is selected, the token will be saved with an additional attribute (indicating it needs to be displayed inline).
  • The markup used to render the entity can already be customised using the core theming layer.
  • Bearing this in mind, I'd suggest the patch simply focuses on countering the issue of ckeditor incorrectly altering markup.
marcvangend’s picture

Thank you for the summary, Luke. I don't have much time but I wanted to quickly respond to your proposal.

If I understand correctly, you are proposing that a content author (the user who works with CKeditor) can choose if the entity they are embedding should be rendered inline or as block. However, these content authors usually have no control over templates and view modes, so they can't control if the HTML output of the entity contains block-level elements. That is where things start to break. CKeditor throws errors when it receives block-level HTML output to be rendered as an inline embed. In other words, such a switch would offer a way for editors to shoot themselves in the foot.

The current approach was suggested and introduced in #63 and #68. Assuming that the site builder correctly configures the entity view mode and the embed buttons, block-level HTML will never be presented to CKeditor as an inline embed. The content author cannot accidentally break this, ensuring a smooth authoring experience.

Finally, I don't even want to ask my editors "Do you want to embed this entity inline or as block?" Many users would not intuitively understand what this question means. Instead of asking questions and presenting choices, I strive for interfaces that get out of the way and do what the user expects.

lukus’s picture

Hi Marc - thanks for getting back to me so quickly.

Finally, I don't even want to ask my editors "Do you want to embed this entity inline or as block?" Many users would not intuitively understand what this question means. Instead of asking questions and presenting choices, I strive for interfaces that get out of the way and do what the user expects.

I think this is a great point. Users shouldn't need to make the distinction.

Since writing that, I've started looking at the plugin code in more detail. I think the solution could be a lot more straightforward.

  • I figure that this has to be a common problem for all ckeditor plugins that use widgets.
  • We shouldn't need to alter the DTD used by ckeditor, because the token we're using won't be output as markup, once it's transformed.
  • For these situations, I imagine it will be possible alter the way the element is parsed by ckeditor - so it's not compared against definitions in the DTD.

I'm still looking into this, but it seems ckeditor has functionality built in to help us, in the form of createFakeElement [1]. There's also createFakeParserElement.

I haven't managed to get anything working yet. But if it did work, I'm hoping this would solve part of the problem.

[1] https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#meth...
[2] https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#meth...

lukus’s picture

The current approach was suggested and introduced in #63 and #68. Assuming that the site builder correctly configures the entity view mode and the embed buttons, block-level HTML will never be presented to CKeditor as an inline embed. The content author cannot accidentally break this, ensuring a smooth authoring experience.

Again, this is a really good point.

I do have a use-case where the same type of entity should be able to exist as inline and block level elements, depending on placement - so for all intents and purposes, I am biased.

I wonder if providing an inline element as the default option would effectively solve both use cases in practice?

marcvangend’s picture

Thanks for sharing your thoughts, Luke.

Trying to work with the CKeditor API, expecially in a Drupal context, has been a bit of a struggle for me personally. But if you can manage to make the code on our side simpler by leveraging what is already built in, that would be great.

I do have a use-case where the same type of entity should be able to exist as inline and block level elements, depending on placement - so for all intents and purposes, I am biased.

I wonder if providing an inline element as the default option would effectively solve both use cases in practice?

I'm not sure how we could make this work. I am assuming here that the configured view mode of the embedded entity always produces the same HTML output, because I don't think we can make a Drupal template react to the CKeditor context. Now there are two scenarios.

  • If the embed HTML contains only inline-level elements (eg. <a> or <span>), then that code could in theory also be used as a block-level embed. The downside is that we are very limited in the HTML tags we can use. To display inline HTML as a block, we only need a way to wrap it in a <p> or <div>. Maybe CKeditor can help automate or streamline this wrapping. (This would effectively be like the proposed <drupal-entity-inline>, with a cherry on top.)
  • If the embed HTML contains at least one block-level elements (eg. <p> or <div>), and it is inserted as an inline embed, CKeditor will throw the "Uncaught TypeError: Cannot read property 'attributes' of null" error. In other words, this is not an option, we have to force a block-level embed in this case. (This would effectively be like <drupal-entity>.)

So to be clear, I'm not saying it can't be done. I'd love to see your solution.

lukus’s picture

Hi Marc

Thanks again for your speedy reply! I've been looking into the code and trying to think about how things can be simplified. I can see the CKeditor plugin has evolved quite a bit over the years, and as such, I don't know the full history behind all decisions.

There were a few questions that came to mind though, and I've summarised them here: https://www.drupal.org/project/entity_embed/issues/3164568. If you can put me right re. any of my assumption, I'd really appreciate the input.

lukus’s picture

I've spent some time on this, and worked on a solution that:

  • Extends the settings form for embed buttons definitions via '/admin/config/content/embed'
  • .. so definitions can be defined as either 'inline' or 'block-level'.
  • Provides this config value to the CKeditor plugin.

My main difficulty has been dynamically switching widgets between inline / block mode. Very much understand the difficulty now.

Unfortunately, I've learnt that the particular problem I'm working on can't be satisfied by this module, even once this issue has been addressed, so I need to pause. But will aim to follow up this work as soon as I have time.

niles38’s picture

I can confirm the patch for #78 works great! You guys are awesome! Saved me sooo much time.

I would like to note that if anyone else puts in the patch, make sure to add the following to your text formats and editors (/admin/config/content/formats):

<drupal-entity-inline data-entity-type data-entity-uuid data-entity-substitution data-entity-embed-display data-entity-embed-display-settings data-align data-caption data-embed-button alt title>

for the Limit allowed HTML tags section.

jasonawant’s picture

Thanks everyone for contributing to this feature request and issue! Thanks @niles38 for the reminder!

While evaluating this patch to embed a display mode that includes block-level elements, I observed the error commented by marcvangend in #84

If the embed HTML contains at least one block-level elements (eg. <p> or <div>), and it is inserted as an inline embed, CKeditor will throw the "Uncaught TypeError: Cannot read property 'attributes' of null" error. In other words, this is not an option, we have to force a block-level embed in this case. (This would effectively be like .)

Not only did we observe this when using a display mode with block-level elements, we observed this when using the (linked) label display which is uses inline <a> element. The error seemed to be caused by the entity embed container element, found within the entity-embed-container.html.twig, which wraps the embed with a <div>. Changing the entity embed container element from a <div> to an <span>, worked around this issue.

Also, a result of this JS error, the embedded content <drupal-entity-inline> does not save.

Did anyone else not experience this? Maybe my setup is different.

Even though I know this is not BC compatible and not the right solution, I've attached a new patch that changes this container element to use a span.

When looking at a more comprehensive solution, I realize there is no way to future-proof the functionality to prevent incompatible configuration with an inline embed CKEditor plugin/widget. We have to assume the individual configuring the inline entity embed button knows what they are doing, or create an elaborate way to validate the inline selections.

I imagine this is another reason to not give the inline or block option within the EntityEmbedDialog form experience. But todo that, we could offer

  • entity embed button configuration and help text for different display options per block and inline embed type
  • update the dialog experience to show/hide configured display options depending inline/block selections
  • update a single CKEditor plugin JS to manage both <drupal-entity> and <drupal-entity-inline> and properly update dtd

We'd likely need to add the inline/block selection into the data-entity-embed-display-settings attribute or another attribute for the inline vs. block usage to relay back to EntityEmbedBuilder::buildEntityEmbed() to conditionally prepare either a different theme wrapper or package inline vs. block info into a theme variable for use in rendering a block <div> or inline <span> elements within the entity-embed-container.html.twig.

Thoughts?

niles38’s picture

We did have some trouble installing the patch on our development server through composer install. We had to download the patch and save it in our repo then run the patch through git. It was issues with the image in the patch. Git didn't like it (older version of git I think).

Other than that, no issues. No JS errors. I am using a hook and template to output to the display though using hook_preprocess_entity_embed_container. Not sure if that's where your error was, on the front end.

jasonawant’s picture

Thanks for the response! The JS error occurred in the editor when editing content. Good call on the use of hook_preprocess_entity_embed_container to alter the container!

sime’s picture

Yes @jasonawant your description at #88 is exactly what I experienced.

jeffam’s picture

For what it's worth, I stumbled upon the relatively-new Linkit Media Library module today while researching the inline document use case.

For inline links to documents (like PDFs) in the media library, this works pretty well. It doesn't automatically insert the label of the media entity, but it does allow users to upload new documents and browse for existing ones.

steveoriol’s picture

The patch on #88 does apply well with entity_embed 8.x-1.1

niles38’s picture

Is anyone having problems with the latest release of entity embed (1.2) and this patch? The patch still applies properly but on our WYSIWYG editors, the entity inline object does not show up. Specifically the template isn't rendering. It does render for the regular entity embed objects. We need to roll back to entity embed 1.1.

We need to get this patch into this module since it's very much needed!

azinck’s picture

@niles38 I'm not using this module any longer and I haven't tested this patch, but I believe this should take care of it. Note that I also updated the patch with the binary image file to avoid problems with it applying, but I just re-used the same exact image as is used for the non-inline embed since I didn't have any good ideas handy. Someone will probably want to improve that :).

azinck’s picture

Actually, I think I missed something. Let me try that again.

azinck’s picture

Gah, screwed up again. Let me try one more time, being slightly more careful. Sorry everyone.

The last submitted patch, 95: entity_embed-inline_widget-2640398-95.patch, failed testing. View results

The last submitted patch, 96: entity_embed-inline_widget-2640398-96.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 97: entity_embed-inline_widget-2640398-97.patch, failed testing. View results

azinck’s picture

This time I forgot to reference the updated config property name.

niles38’s picture

@azinck Thank you! The patch works for us. We are now on Entity Embed 1.2 running Drupal 9.2.7.

Martijn de Wit’s picture

Status: Needs work » Needs review

triggered test for patch #101

Status: Needs review » Needs work

The last submitted patch, 101: entity_embed-inline_widget-2640398-101.patch, failed testing. View results

cameron prince’s picture

The patch in #101 applies cleanly to the dev release and works well. Here's an example preprocessor and twig template as mentioned #89.

/**
 * Implements hook_preprocess_entity_embed_container().
 */
function hook_preprocess_entity_embed_container(&$variables) {
  $variables['inline_image'] = NULL;

  if (
    $variables['element']['entity']['#view_mode'] !== 'inline'
    ||
    !isset($variables['element']['entity']['#media'])
  ) {
    return;
  }

  $media = $variables['element']['entity']['#media'];
  if (
    !$media instanceof MediaInterface
    ||
    !$media->hasField('field_inline_image')
    ||
    $media->get('field_inline_image')->isEmpty()
  ) {
    return;
  }

  $image_uri = $media->get('field_inline_image')->entity->uri->value;
  $image = \Drupal::service('image.factory')->get($image_uri);
  if ($image->isValid()) {
    $image_render_array = [
      '#theme' => 'image_style',
      '#width' => $image->getWidth(),
      '#height' => $image->getHeight(),
      '#style_name' => 'inline',
      '#uri' => $image_uri,
      '#attributes' => [
        'class' => ['inline-image'],
      ],
    ];
    $variables['inline_image'] = render($image_render_array);
  }
}

entity-embed-container.html.twig:

{% if inline_image is empty %}
  <div{{ attributes }}>{{ children }}</div>
{% else %}
  {{ inline_image }}
{% endif %}
ghenov.andrei’s picture

I ran into the problem that the patch is not being applied due to the png file embedded in it. But, if you remove part of the code from the patch associated with the entity.png file, everything works fine.

Krishna Sugureddy’s picture

Hi,
I'm able to apply the patch fine but when I tried to load the page with embeds, still embeds are not coming inline. Am I missing something like any other configurations? I even tried to look at the browser console > sources on chrome browser, it didn't show any JS files loading from Entity Embed module. Thanks in advance for the help.

niles38’s picture

@ghenov.andrei We have the same issue. We have to add this patch file to our repo so git will apply it. I'm not sure what the PNG is for... All I know is this needs to go into the module itself. I would love to see this no longer having to be a patch.

pbone3b’s picture

#88 works for us. Entity Embed 1.1 running Drupal 9.2.5.

1mly’s picture

#106 worked for me using version 1.2. @krishna-sugureddy, I had to create a new embed button and select "Entity Inline" from the Embed type options (as per #68). Then I ran into some difficulty because what I was trying to embed had block-level elements in it, so I had to replace all of the divs, headings and p tags that were in my entity twig file with spans and that got it working (see #84).

For example, if the twig for the entity I want to embed looks like this -
<div><h3>My Title</h3></div>, that would throw an error in the ckeditor when I try to embed it and it won't save.

The fix is to change all of the block-level elements to inline elements and then apply classes and style as needed.
<span><span>My Title</span></span>

We lose the semantic markup of the entity being embedded in-line, but I don't believe there is any other way around it.

vistree’s picture

I tried patch from #106 to embed PDF files. But it does not work for me. I get a browser console error and the entity is stripped out on node save:
ckeditor.js?v=4.18.0:932 Uncaught TypeError: Cannot read properties of null (reading 'attributes')
at ckeditor.js?v=4.18.0:932:211
at window.CKEDITOR.window.CKEDITOR.dom.CKEDITOR.htmlParser.element.forEach (ckeditor.js?v=4.18.0:302:462)
at window.CKEDITOR.window.CKEDITOR.dom.CKEDITOR.htmlParser.element.forEach (ckeditor.js?v=4.18.0:303:57)
at window.CKEDITOR.window.CKEDITOR.dom.CKEDITOR.htmlParser.element.forEach (ckeditor.js?v=4.18.0:303:57)
at b. (ckeditor.js?v=4.18.0:931:264)
at b.d (ckeditor.js?v=4.18.0:10:246)
at b. (ckeditor.js?v=4.18.0:12:91)
at b.window.CKEDITOR.window.CKEDITOR.dom.CKEDITOR.editor.CKEDITOR.editor.fire (ckeditor.js?v=4.18.0:13:285)
at CKEDITOR.htmlDataProcessor.toDataFormat (ckeditor.js?v=4.18.0:323:461)
at $.getData (ckeditor.js?v=4.18.0:1227:24)

pbone3b’s picture

Since upgrading Entity Embed to 1.2, #106
works.

roshkovanv made their first commit to this issue’s fork.

roshkovanv’s picture

Patch based on #101(not #106 as there png icon is excluded), this fix few "spacing" issues that are added by wysiwyg and template.

Important: If you are using composer and "dist" used as "preferred-source", you need to add following lines to composer to be able to apply binary patch:

"config": {
"preferred-install": {
"drupal/entity_embed": "source",
"*": "dist"
}
}

thetailwind’s picture

8.x-1.3 Has introduced breakage if you're using #114 or #106. Nothing shows up in Ckedit when inserted inline.

Reversion to 1.2 fixed the breakage

Serhii Shandaliuk’s picture

Solved #115

Serhii Shandaliuk’s picture

This one extends #106 because #113 cannot be applied to 1.3

Martijn de Wit’s picture

Status: Needs work » Needs review

The last submitted patch, 114: entity_embed-inline_widget-2640398-113.patch, failed testing. View results

pbone3b’s picture

pbone3b’s picture

cameron prince’s picture

Hello,

I've been trying to use this patch for some time and haven't really had any luck, so far. My goal is to place images inline with text. These are things like complex formulas or diagrams.

Here are the steps I've taken:
1) Added the latest patch from this issue
2) Created an "Inline" view mode on the image media type
3) Created an "Inline" image style
4) Created a new embed button with "Entity Inline" selected as the type
5) Selected the "Inline" view mode for the "Allowed Entity Embed Display plugins" setting of the button
6) Added the new button to the toolbar
7) Enabled the "Inline" view mode for the image media type
8) Set the "Inline" view mode to display the image using the "Inline" image style
9) Cleared cache

The issues I'm seeing are:
1) When embedding an image, the "Align" selector (None, Center, Left, Right) is still available, which doesn't make sense for an inline image.
2) After embedding an image, the "Source" button no longer works
3) The editor window does now show the image after embedding (which it wasn't doing on the previous patch), but when I save the node, the body is emptied.

I'd like to get this working and glad to help any way I can.

pbone3b’s picture

Any movement on a CKEditor 5 Plugin for drupalentityinline?
The patches here (2640398) create the drupalentityinline plugin for CKE4.
Thank You! :-)

https://www.drupal.org/project/entity_embed/issues/3272732 creates the CKE5 version of drupalentity plugin. So maybe a drupalentityinline version of this patch? I've tried to roll my own but I can't quite get it to work.

ajay547’s picture

Hi Team,
any luck here.

For me the patches are being applied but the link/document not coming inline and everytime it is going to new line.

https://www.drupal.org/files/issues/entity_embed-inline-widgets-2640398-...

this worked and I was able to add link of document inline, but it broke the image embed functionality.

Any help on this is highly appreciated.

Thanks in Advance.

jannakha’s picture

here's a MR which allows inlining entity embed
https://git.drupalcode.org/project/entity_embed/-/merge_requests/28

edwardsay’s picture

Added support for drupal-entity-inline in CKEditor 5

pbone3b’s picture

#126 Working well, Thanks!

darvanen’s picture

Couldn't get #126 to apply, #125 is working well for us on a site that required it for a D10 upgrade.