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.
Issue fork entity_embed-2640398
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:
Comments
Comment #2
slashrsm CreditAttribution: slashrsm at Examiner.com commentedPull request: https://github.com/drupal-media/entity_embed/pull/200
Comment #3
slashrsm CreditAttribution: slashrsm at Examiner.com commentedOne comment on pull. It would make sense to have this configurable per-button.
Comment #4
smazI'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
Comment #5
Wim LeersComment #6
ramarajuk CreditAttribution: ramarajuk as a volunteer commentedThe patch only works for images. Is it possible to embed drupal-entity element within p tag.
Comment #7
Dave ReidFrom #drupal-media in IRC, this discussion here was useful for thinking through how we could solve this
Comment #8
sgp913 CreditAttribution: sgp913 commentedI 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.
Comment #9
smazI 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.
Comment #10
Sam152 CreditAttribution: Sam152 as a volunteer and at PreviousNext commented#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.
Comment #11
John Pitcairn CreditAttribution: John Pitcairn commentedAnother 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.
Comment #12
John Pitcairn CreditAttribution: John Pitcairn commentedAnd: 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.
Comment #13
John Pitcairn CreditAttribution: John Pitcairn commentedFor 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.
Comment #14
sgp913 CreditAttribution: sgp913 commentedThis 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.
Get your HTML and use this to add strings into the mix
Then totally replace the 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.
Comment #15
marcoscano#2511404: Image entities/fields embedded using Entity Embed cannot be linked in CKEditor seems related
Comment #16
joelhsmith CreditAttribution: joelhsmith commented@John Pitcairn Can you update your patch? It seems like the best option for my specific use-case. I would appreciate it very much.
Comment #17
John Pitcairn CreditAttribution: John Pitcairn commented@joelhsmith: try this patch against current dev. Untested because I am not using this module at present.
Comment #18
joelhsmith CreditAttribution: joelhsmith commented@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!
Comment #19
bkosborneI 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.
Comment #20
joelhsmith CreditAttribution: joelhsmith commentedCheck 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.
Comment #21
jonathanshawMy 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.
Comment #22
bkosborne@joelhsmith the problem is that you still cannot link to that document inline a paragraph of text.
Comment #23
benjy CreditAttribution: benjy at Unearthed commented@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
Comment #24
John Pitcairn CreditAttribution: John Pitcairn commented@bkosborne: See comment #11 and #12 for use cases which are not about media.
Comment #25
jonathanshaw@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?
Comment #26
benjy CreditAttribution: benjy at Unearthed commented@jonathanshaw no what you say is correct. I was only pointing out that @bkosborne comment about the solution here causing invalid HTML was incorrect.
Comment #27
jonathanshawI 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.Comment #28
joelhsmith CreditAttribution: joelhsmith commentedEdit: "@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.
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):
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:
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:
Expand Entity Browser Settings to "Display the Entity after selection"
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.
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
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
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!
Comment #29
Tomazetti CreditAttribution: Tomazetti commentedBased 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.
Could this approach be considered a future workaround?
P.S.: Sorry about the incorrect comment number on the patch file.
Comment #30
a.milkovskyMy workaround for floating embedded media entities:
Comment #31
marcvangendLooking 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.
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.
Comment #32
adam-delaney CreditAttribution: adam-delaney at The University of Iowa commentedLinking 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.
Comment #33
Soundvessel CreditAttribution: Soundvessel commentedA 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.
Comment #34
idflood CreditAttribution: idflood at Stimul.ch commentedI 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.
Comment #35
marcvangendI'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.
Comment #36
zepner CreditAttribution: zepner at Aten Design Group commentedThe script.js change in the patch was causing an error, but the twig tpl change seems to work for inlining the embedded element.
Comment #37
facine CreditAttribution: facine as a volunteer and at Cambrico commented@marcvangend It is a problem with editable widgets, see:
Comment #38
Wim LeersComment #39
code-brighton CreditAttribution: code-brighton commentedThis 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
Comment #40
Wim Leers@benjy in #23:
This addresses @marcoscano's #15.
Comment #41
Wim LeersIn 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?
Comment #42
bkosborneI'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:
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.
Comment #43
Wim Leers@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.Comment #44
John Pitcairn CreditAttribution: John Pitcairn commentedJust 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.
Comment #45
Wim LeersThat’d be even less markup than a link, that’d be *only* text! That’s what the Token Filter module is for?
Comment #46
John Pitcairn CreditAttribution: John Pitcairn commentedYeah 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 :-/
Comment #47
Wim LeersYou'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 :)
Comment #48
kerby70 CreditAttribution: kerby70 commentedI 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.
Comment #49
marcvangendRe #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.
Comment #50
John Pitcairn CreditAttribution: John Pitcairn commentedI 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?
Comment #51
jonathanshawA 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".
Comment #52
marcvangendAgree 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.
Comment #53
mortona2k CreditAttribution: mortona2k commented#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.
Comment #54
alisonThank 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.......
Comment #55
bkosborneSee #2801307: [META] Support WYSIWYG embedding of media entities
Comment #56
alisonThanks, @bkosborne!
Comment #57
rooby CreditAttribution: rooby commentedI 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.
Comment #58
Henry Tran CreditAttribution: Henry Tran at Deloitte Digital commentedTo 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.
Comment #59
bdanin CreditAttribution: bdanin commentedOn 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
Comment #60
Martijn de WitIf this is as simple as #patch. It is maybe something to add to #2801307: [META] Support WYSIWYG embedding of media entities
Comment #61
sime#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 replacediv
withspan
), andentity-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.
Comment #62
gbeezus CreditAttribution: gbeezus as a volunteer commentedI 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.
Comment #63
AndraeRay CreditAttribution: AndraeRay as a volunteer commentedAfter 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.
You can use a hook_ckeditor_css_alter to add it.
As a permanent solution Krzysztof had this to say.
This something for the maintainers to consider.
Comment #64
marcvangendAndrae, thanks for the detailed info.
Comment #65
azinck CreditAttribution: azinck at Forum One commented@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.
Comment #66
elgordogrande CreditAttribution: elgordogrande commentedI rolled this patch against the 1.0 version and based it on the patch from #58.
Comment #67
Christopher Riley CreditAttribution: Christopher Riley commentedI 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?
Comment #68
marcvangendIn #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.Comment #69
azinck CreditAttribution: azinck at Forum One commentedI 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.
Comment #70
marcvangendThanks 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.
Comment #71
azinck CreditAttribution: azinck at Forum One commentedThanks 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 :).
Comment #72
trishkaideka CreditAttribution: trishkaideka commentedAnother 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
Comment #73
foreveryo CreditAttribution: foreveryo commentedI'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!
Comment #74
marcvangend@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.Comment #75
GrimreaperHello,
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.
Comment #76
GrimreaperI still have the problem of applying the patch.
I run the composer update command in verbose mode and I got:
So I ran the command on the cloned repository and I got the same issue:
I do not understand why it fails for this file. Path seems ok.
Comment #77
marcvangend@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?
Comment #78
Grimreaper@marcvangend, ok. Here is a new patch. I will try but I see almost no diff in the patch.
Comment #79
GrimreaperI 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.
Comment #80
lukusOkay, 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:
However:
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.
correctly via the CKEditorPlugin definition (`src/Plugin/CKEditorPlugin/DrupalEntityInline.php`).
My proposal
Comment #81
marcvangendThank 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.
Comment #82
lukusHi Marc - thanks for getting back to me so quickly.
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'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...
Comment #83
lukusAgain, 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?
Comment #84
marcvangendThanks 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'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.
<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.)<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.
Comment #85
lukusHi 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.
Comment #86
lukusI've spent some time on this, and worked on a solution that:
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.
Comment #87
niles38 CreditAttribution: niles38 commentedI 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.
Comment #88
jasonawantThanks 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
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
<drupal-entity>
and<drupal-entity-inline>
and properly update dtdWe'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?
Comment #89
niles38 CreditAttribution: niles38 commentedWe 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.Comment #90
jasonawantThanks 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!
Comment #91
simeYes @jasonawant your description at #88 is exactly what I experienced.
Comment #92
jeffamFor 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.
Comment #93
steveoriolThe patch on #88 does apply well with entity_embed 8.x-1.1
Comment #94
niles38 CreditAttribution: niles38 commentedIs 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!
Comment #95
azinck CreditAttribution: azinck at Forum One commented@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 :).
Comment #96
azinck CreditAttribution: azinck at Forum One commentedActually, I think I missed something. Let me try that again.
Comment #97
azinck CreditAttribution: azinck at Forum One commentedGah, screwed up again. Let me try one more time, being slightly more careful. Sorry everyone.
Comment #101
azinck CreditAttribution: azinck at Forum One commentedThis time I forgot to reference the updated config property name.
Comment #102
niles38 CreditAttribution: niles38 commented@azinck Thank you! The patch works for us. We are now on Entity Embed 1.2 running Drupal 9.2.7.
Comment #103
Martijn de Wittriggered test for patch #101
Comment #105
cameron prince CreditAttribution: cameron prince as a volunteer commentedThe patch in #101 applies cleanly to the dev release and works well. Here's an example preprocessor and twig template as mentioned #89.
entity-embed-container.html.twig:
Comment #106
ghenov.andrei CreditAttribution: ghenov.andrei as a volunteer commentedI 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.
Comment #107
Krishna Sugureddy CreditAttribution: Krishna Sugureddy commentedHi,
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.
Comment #108
niles38 CreditAttribution: niles38 commented@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.
Comment #109
pbone3b CreditAttribution: pbone3b commented#88 works for us. Entity Embed 1.1 running Drupal 9.2.5.
Comment #110
1mly CreditAttribution: 1mly at Forum One commented#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.
Comment #111
vistree CreditAttribution: vistree commentedI 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)
Comment #112
pbone3b CreditAttribution: pbone3b commentedSince upgrading Entity Embed to 1.2, #106
works.
Comment #114
roshkovanv CreditAttribution: roshkovanv at FFW commentedPatch 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"
}
}
Comment #115
thetailwind CreditAttribution: thetailwind commented8.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
Comment #116
Serhii Shandaliuk CreditAttribution: Serhii Shandaliuk as a volunteer and at Drupfan for Drupal Ukraine Community commentedSolved #115
Comment #117
Serhii Shandaliuk CreditAttribution: Serhii Shandaliuk as a volunteer and at Drupfan for Drupal Ukraine Community commentedThis one extends #106 because #113 cannot be applied to 1.3
Comment #118
Martijn de WitComment #120
pbone3b CreditAttribution: pbone3b commentedWrong format, sorry
Comment #121
pbone3b CreditAttribution: pbone3b commentedThis is a copy of #117 with a small change for D10
Comment #122
cameron prince CreditAttribution: cameron prince as a volunteer commentedHello,
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.
Comment #123
pbone3b CreditAttribution: pbone3b commentedAny 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.
Comment #124
ajay547 CreditAttribution: ajay547 as a volunteer commentedHi 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.
Comment #125
jannakha CreditAttribution: jannakha as a volunteer and at Tomato Elephant Studio commentedhere's a MR which allows inlining entity embed
https://git.drupalcode.org/project/entity_embed/-/merge_requests/28
Comment #126
edwardsay CreditAttribution: edwardsay commentedAdded support for drupal-entity-inline in CKEditor 5
Comment #127
pbone3b CreditAttribution: pbone3b commented#126 Working well, Thanks!
Comment #128
darvanenCouldn't get #126 to apply, #125 is working well for us on a site that required it for a D10 upgrade.