Problem/Motivation
We wanted to add a link to an image so that the image points to another page.
When we tried it by adding the image, selecting the image and adding the link (all via WYSIWYG editor) the link appeared above the image as a text link.
It seems that there is no option to add a link to an image via WYSIWYG editor at the moment. It needs to be added to the source code manually.
Proposed resolution
Please add the possibility to add a link to an image via WYSIWYG editor
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#112 | entity_embed_1_5_bc_link_to-112.patch | 4.19 KB | SpadXIII |
#110 | entity_embed_1_5_bc_link_to.patch | 4.14 KB | Daniel Korte |
#107 | entity_embed_1_3_bc_link_to.patch | 4.68 KB | jOpdebeeck |
#106 | entity-embed-link-2511404-106.patch | 9.02 KB | Binoli Lalani |
#104 | entity_embed_1_1_bc_link_to.patch | 4.52 KB | podarok |
Comments
Comment #1
slashrsm CreditAttribution: slashrsm commentedComment #2
slashrsm CreditAttribution: slashrsm commentedComment #3
Lukas von BlarerThis doesn't work in D7 either.
Comment #4
cs_shadow CreditAttribution: cs_shadow commentedOne way could be to provide such a formatter for image fields which links images to other URLs.
Although I'm not sure whose job it should be to add such a formatter - we can add one in entity_embed but wouldn't it be better if that gets added to Core?
Comment #5
Dave ReidYou would need an Image field formatter that does what you'd like. It might be worth writing a patch for core's Image field formatter to provide a third option for instead of linking to content or file, it provides a 'Custom' link where you can type whatever to link it to.
Comment #6
Lukas von BlarerThat sounds reasonable.
Comment #7
Wim Leers"pure images" (i.e. not embedded using Entity Embed) can be linked since a few days before Drupal 8.0.0 — see #2510380: Images cannot be linked in CKEditor.
Which makes me wonder whether @jzech meant:
<img>
, click the "Link" button, and end up with<a><img></a>
, or:<drupal-entity>
, click the "Link" button, and end up with<drupal-entity><img></a>
?
If it's the first: Drupal core supports that now, and that'd actually be out of scope here.
If it's the second: the Entity Embed plugin for CKEditor will need to explicitly support that, but it should definitely be possible.
The second option above seems like an excellent thing to add after a 1.0 release :)
Comment #8
Wim LeersUpdating the issue title to match my understanding. The current title is very vague.
Comment #9
BerdirI guess it was kind of both. Both drupal-entity does not work and until recently, a normal image also didn't work. That was fixed, so this is now only about drupal-entity.
Comment #10
Wim LeersOkay, cool :)
Comment #11
Michèle CreditAttribution: Michèle commentedQuote from "Problem/Motivation":
This does not work on my site...
1. Edit node, insert embedded image
2. Open source code, add a tag around the drupal-entity tag
3. Save -> the image link works!
4. Open Edit mode once again
5. Open source code. The link is not there anymore!
6. Save node without any changes -> The image is not linked anymore!
Do I miss something here? Or is this a known behaviour?
It would be so nice to have the possibility to link embedded images...! Thanks! :-)
Comment #12
larowlanSuggestion at #5 works perfect - thanks!
Comment #13
slashrsm CreditAttribution: slashrsm commentedThere is also a "Link formatter" in the Field formatter module that might do the job too.
Comment #14
slashrsm CreditAttribution: slashrsm commentedOrganizing tags a bit.
It would be nice to document possible solutions in our D8 guide.
Comment #15
Corregidor CreditAttribution: Corregidor commentedSorry, could someone explain how to get this working? I'm probably misunderstanding something fundamental, but where would I go to change the field formatter for embedding image media? Or changing "core's Image field formatter" as described in #5? This is the one thing stopping us from adopting Media. Any help is greatly appreciated!
Comment #16
hansfn CreditAttribution: hansfn as a volunteer commentedIt doesn't work AFAICT. You still can't embed an image and link it to a webpage using Entity Embed in CKEditor.
I have created an ugly, ugly, ugly workaround:
"image_link":"media"
"image_link":"http://example.org"
(to link to example.org).I told you it was ugly.
Comment #17
Ankabout CreditAttribution: Ankabout commentedThis topic has been dormant for a few months, and I was wondering whether there's any progress?
What would be the easiest way for me to make an embedded image "linkable" right now? I've looked through the above options, but I'm afraid it hasn't helped me yet...
Comment #18
jwineichen CreditAttribution: jwineichen commentedI am also interested in any update on this.
Comment #19
LiamPower CreditAttribution: LiamPower at Reading Room commentedI feel this is a really important feature which is currently missing from Media
Comment #20
BartK CreditAttribution: BartK commentedHere's a patch that adds the ability to make any embedded entity into a link in a clean way (note: currently tested only with images; ymmv depending on the contents of the entity, particularly with stuff like iframes).
In the meantime, I've also created a module that does exactly the same thing, here:
https://www.drupal.org/project/entity_embed_link
DO NOT INSTALL BOTH THE MODULE AND THIS PATCH. THEY DO THE SAME THING.
Comment #21
BartK CreditAttribution: BartK commentedComment #22
Arlina CreditAttribution: Arlina at Chapter Three commentedThe patch in #20 solves the issue for me, and works against 8.x-1.0-beta2.
Thanks @BartK!
Comment #23
jwineichen CreditAttribution: jwineichen commentedThanks for the patch, BartK! Worked for me too.
Comment #24
LiamPower CreditAttribution: LiamPower at Reading Room commentedPatch #20 worked for me too. Thanks BartK.
Comment #25
eric.chenchao CreditAttribution: eric.chenchao commentedThanks Bartk. This patch works for me too. I have also altered form to add basic integration with linkit by
This does not support linkit attributes plugins.
Comment #26
kiwimind CreditAttribution: kiwimind at Investis Digital commentedMostly Drupal Coding Standards issues.
Otherwise patch applies cleanly to 8.x-1.x.
Needs trailing whitespace removed.
This seems a little long to be using a ternary operator.
They're useful for short, concise conditions but become a little unreadable like this.
Needs trailing whitespace removed.
Needs trailing whitespace removed.
Double space needs removing.
Space between `{%` and `if`.
Comment #27
BartK CreditAttribution: BartK commentedHere's an updated patch with the above issues resolved.
Comment #28
Lukas von BlarerComment #30
eric.chenchao CreditAttribution: eric.chenchao commentedThanks @BartK. I am working on the integration of the entity_embed and linkit 8.x-5.x, and reviewed this code again.
I could not find where 'image_link' is used in other places of the module. Could you add a comment about this, please?
I am wondering if we could add
{{ url_attributes|default('') }}
to let other modules to inject attributes in element. So, we could avoid to override this template again when extending URL attributes in other modules.Comment #31
BartK CreditAttribution: BartK commentedComment #32
BartK CreditAttribution: BartK commentedComment #33
eric.chenchao CreditAttribution: eric.chenchao commentedThanks @BartK.
I have added a new module to integrate with Linkit 8.x-4.x in https://www.drupal.org/project/entity_embed_linkit in case anyone interested in.
Comment #34
JamesK CreditAttribution: JamesK at Advisor Websites commentedI tried using this patch but the link isn't using any of the classes or structure that Drupal provides so it makes it totally inconsistent and unpredictable. The link should be a render element, the url should be a Drupal\Core\Url object, and the link attributes should be passed in the #options array.
Comment #35
BartK CreditAttribution: BartK commentedSorry, I don't have time to continue making changes to this. Hopefully someone else can pick it up.
Comment #36
JamesK CreditAttribution: JamesK at Advisor Websites commentedUpdated patch that fixes #34
Comment #38
AnybodyIf this issue fixes #2764353: How to link entity to alternate resource and #2773489: How to link an entity? we should perhaps close the others as duplicate?
Does it?
Comment #39
wrd CreditAttribution: wrd commentedIf I'm reading the test results correctly -- and I could well not be -- the failure is simply caused by a missing route that is only used by the test. Otherwise, #36 seems to be working fine for me.
Comment #40
wrd CreditAttribution: wrd commentedOne possible issue I can see is that this results in a link option for every entity type. This won't make sense for some entities -- an embedded video, for example, or a custom entity type that contains link fields of its own (say, a Contact entity that includes email, web, and tel links).
Should the option to allow an entity to be linked be selectable somewhere? Perhaps the entity type form, or on the display mode?
Comment #41
fox mulder CreditAttribution: fox mulder commentedI'm experiencing same as like #11.
Comment #42
amaisano CreditAttribution: amaisano commentedSpoke too soon. Had manually patch applied and had missed a line.
Comment #43
wrd CreditAttribution: wrd commentedOK, here's a problem I've encountered: if the link field is given an internal path (using, e.g., "/about-us" or "internal:/about-us"), the entity doesn't render. "internal:/about-us" works fine if UrlHelper::filterBadProtocol() is removed. And it kind of seems like using just the path without a protocol should also work, but it doesn't.
Any suggestions?
Comment #44
RenrhafConfirming comment #43, I encountered the same issue.
Comment #45
wrd CreditAttribution: wrd commentedThis tries to solve #43 by setting "mailto" and "internal" as valid schemes before creating the URL.
Comment #46
a.milkovskyComment #47
a.milkovskyI have added an autocomplete to the patch of @wrd.
I have used code from \Drupal\link\Plugin\Field\FieldWidget\LinkWidget.
How do you find this idea?
Comment #48
a.milkovskyComment #50
Tomotsugu Kaneko CreditAttribution: Tomotsugu Kaneko commentedPatch #47 working great.
Comment #51
Rajab Natshah CreditAttribution: Rajab Natshah at Vardot commentedUsing Patch #47
Comment #52
duncan.moo CreditAttribution: duncan.moo as a volunteer commentedI found that setting UrlHelper::setAllowedProtocols() (line 38 of entity_embed.module after applying the patch), resulted in other links in the menu which are not included in the protocol list throwing an exception. Namely it was a tel: link in the main menu.
In the attached patch I have simply removed that line as it is unnecessary and should use the global settings.
Comment #53
leisurman CreditAttribution: leisurman commentedIt would be great if this could work with Linkit 8.5
Comment #54
a.milkovsky+1 for the #52, thanks.
Comment #55
a.milkovskyComment #57
Ruuds CreditAttribution: Ruuds at Groowup Digital Agency commented#52 breaks when selecting a node with entity_reference_autocomplete. This results in a link_url in the 'node/7' form, which errors:
InvalidArgumentException: The URI 'node/7' is invalid. You must use a valid URI scheme. in Drupal\Core\Url::fromUri() (regel 281 van /Users/ruud/Groowup/minkema.nl/web/core/lib/Drupal/Core/Url.php).
I've added an UrlHelper::isExternal() check to template_preprocess_entity_embed_container which prepends "internal:/" for when it is an internal link. I don't know if this is the correct solution to the problem (only developing on Drupal 8 since 3 months), but it works for me.
Comment #58
marcoscanoComment #60
Ruuds CreditAttribution: Ruuds at Groowup Digital Agency commentedSorry, here's a new patch.
Comment #61
Ruuds CreditAttribution: Ruuds at Groowup Digital Agency commentedComment #63
a.milkovskyAdded "'#maxlength' => 2048," to #60 to support longer links.
Comment #65
a.milkovskyTest fails look unrelated.
Comment #66
gcardoso CreditAttribution: gcardoso commentedI found a trick for images:
Comment #67
sawtell CreditAttribution: sawtell commentedTesting patch #63 works well apart from when entering URLs such as "/node/123". When the URL is parsed the host and path are incorrect.
I'm not sure what the best fix is here. I can replace
$link = 'internal:/'.$link;
with$link = 'base:'.$link;
which fixes the issue with paths like "/node/123" but removes aliasing for entity routes:Comment #68
sawtell CreditAttribution: sawtell commentedI've amended patch #63 to trim any preceding slashes on internal links:
Comment #69
Stephen Ollman#68 seems to work as intended. Thank you!
Comment #70
Wim LeersComment #71
Wim LeersJust closed #2764353: How to link entity to alternate resource as a duplicate. #2773489: How to link an entity? was already marked as a duplicate a long time ago.
Bumping priority since this is something many people are clearly running into.
Comment #72
Wim Leers#2544020: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin should land first, will at minimum simplify this, and may even solve this for us.
Comment #73
Wim LeersI started working this, and compared this with how Drupal 8's
drupalimage
plugin does this. It achieves this mostly thanks to https://github.com/ckeditor/ckeditor-dev/blob/major/plugins/image2/plugi... doing the bulk of the work.If I port key bits of what that does over to the
drupalentity
CKEditor plugin and widget (reusing the same code is impossible because CKEditorimage2
code is assuming it's dealing with<img>
all over the place), I can get it to work. But … one key assumption rooted in the inception of this Drupal module prominently gets in the way: the<figure>
tag is not added on the client-side, but on the server side: the Entity Embed module sends some HTML to the server and asks it to pass it through the filter system, which results in<figure>
and so on being added on the server side. This means the client side has to treat it as one immutable blob. Which results in not just the embed being linked, but also the caption itself turning into a link.So alas, this CKEditor plugin must implement it differently; it has no choice but to decorate the original HTML and ask the server to re-render it.
Attached is the patch for this failed attempt. And here's a screenshot showing how it breaks:
Comment #74
Wim LeersThanks to the work in #73, I ended up with #2544020-18: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin. That made #2282957-13: Caption should work like the drupalimage plugin (editable in WYSIWYG, not in dialog) stupidly easy.
But it also made this possible, and much is inspired by and very similar to
image2
anddrupalimage
.Blocking this on #2282957: Caption should work like the drupalimage plugin (editable in WYSIWYG, not in dialog), which in turn is blocked on #2544020: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin.
This is basically fully working (albeit with rough edges):
One of those rough edges is that it currently requires a core patch, because
drupallink
is hardcoded to interact withdrupalimage
…Comment #75
Wim LeersA bit in the
parts
documentation was not yet clear, and much more importantly, #2544020-25: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin made it possible to avoid fetching a new preview when that's not necessary; this takes advantage of that for linking support.This patch is relative to #2544020-25: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin and #2282957-19: Caption should work like the drupalimage plugin (editable in WYSIWYG, not in dialog).
Comment #76
Wim LeersI've been working on cleaning this up further, and I've got it working quite nicely. For a long time, I thought we could just not integrate with the existing
drupallink
command sincecore/modules/ckeditor/js/plugins/drupallink/plugin.js
has a hardcoded integration withdrupalimage
.But I found a way around that!
🥳
So the core patch that #74 refers to is no longer necessary!
Comment #77
Wim LeersThe
parts.link
stuff was incomplete, and … turns out we don't actually need it! This was just a necessity in thedrupalimage
plugin based on its overall DOM-centric approach. The approach in #2544020: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin — validated by the CKEditor team — does not rely on that. So we can make this completely functional with a much simpler approach.Note that due to pre-existing focus issues (which also cause #3060245: [upstream] CKEditor's "undo" functionality not working correctly for embeds: offers multiple undo steps where there should be only one), the
unlink
button state is not updated after decorating an embedded entity with a link. Explicitly focusing it fixes that though. We'll need to fix that in a follow-up. I spent hours trying to figure out a work-around, but … turns out that the existingdrupalimage
plugin has the same problem 🤦♂️This is now working 100% the same as the link support in
drupalimage
!Comment #78
Wim LeersAlas …
fails when the
drupalimage
plugin is not loaded. (Yay for test coverage!)I guess … that … if that doesn't exist, we can just define it? 😏
Comment #79
Wim Leers#2544020: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin and #2282957: Caption should work like the drupalimage plugin (editable in WYSIWYG, not in dialog) just landed, let's test this.
Comment #80
Wim LeersThe combined patch was green already, the non-combined one just came back green too!
Comment #82
Wim Leers🚢🥳
I've credited everyone who participated in this issue. For a while, it went a direction different than what Drupal core did. It was blocked on people finding the time to dig into CKEditor to figure out how to achieve that. All patches prior to #73 tried to achieve it using Twig templates and additional dialog options. That meant they weren't truly integrated with the rich text editor experience, at least not to the same extent as the image uploading and linking experience in Drupal core was.
As you can see in #2544020: CKEditor plugin not written with CKEditor >=4.4 in mind; rewrite it based on core's `drupalimage` plugin and #2282957: Caption should work like the drupalimage plugin (editable in WYSIWYG, not in dialog), it also took me a lot of effort to dig into the CKEditor code base to make this happen, and I actually had worked on CKEditor plugins before (albeit five years ago).
I recognize this may cause some inconvenience to those who have already adopted one of the patches prior to #73. But those never got committed, so it never was actually supported by the module. Rather than sticking to that approach, I believe it's better in the long run to match what Drupal core does, which also yields a significantly better content authoring experience.
I did make this an RC1 blocker (see #2577891: Entity Embed 8.x-1.0.0-rc1 release) because this issue had by far the highest number of followers (currently 83!), and because it is necessary for feature parity between embedding an image "directly" using core (
drupalimage
CKEditor plugin) and embedding a media entity that happens to represent an image.Looking forward to your feedback when you try RC1 :)
Comment #83
AnybodyHey Wim, just wanted to say THANK YOU for picking this up and investing a lot of time into this issue. The sulution is great and another wonderful step in Drupal 8 progress!
THANK YOU! GREAT WORK! :)
Comment #84
Wim Leers@Anybody: I'm assuming this means that you actually updated to RC1 and used it, and most importantly … were satisfied? :)
Comment #85
AnybodyExactly @Wim Leers, it works great! :)
One little point: The update text might be improvable, it was a bit strange...
"entity_embed 8004 hook_update_n Installs the fake entity type."
Thanks! ;)
Comment #86
Wim LeersOh, that'd good feedback! Could you please open an issue for that so we can fix it? (That update hook is unrelated to this particular issue, but it shipped with RC1, and indeed should be clearer.)
Comment #87
artis CreditAttribution: artis at Texas Creative commentedI believe there is some broken logic in this patch...although I'm new to this issue so I might be missing something.
js/plugins/drupalentity/plugin.js lines 73 - 90 (on RC1 which includes the patch)
It's possible for line 87 'return originalGetFocusedWidget(editor);' to get called even if 'originalGetFocusedWidget' was never defined as a function since CKEDITOR.plugins.drupalimage is set in the else (line 78) even if it wasn't previously set. I'm not familiar enough with what this section is trying to solve to provide a solution that won't break something else, but maybe changing line 86 to:
would do the trick since it would be null if CKEDITOR.plugins.drupalimage isn't loaded.
I can open this as a new issue if necessary, but I thought those who knew most about this patch would still be watching here.
Thanks!
Comment #88
Wim Leers#87: Well-spotted. We still need JS test coverage for that edge case; that wasn't done by #3060396: Add CKEditor Widget JS test coverage. It'd be wonderful if you could create a new issue for it! 🙏
Comment #89
artis CreditAttribution: artis at Texas Creative commentedComment #90
AnybodyComment #91
marcoscanoThanks everyone who worked on this!
I opened #3061449: Prevent drupal links being added to embedded entities that contain links when rendered as a follow-up improvement.
Comment #93
sjancich CreditAttribution: sjancich commentedApologies if I'm missing something obvious -- but: is there a configuration change needed to get the link field added to the embed wizard? Do I need a separate patch? I have the latest release (8.x-1.0-rc2). I am using am custom embed button in ckeditor. No link field. Thanks!
Comment #94
oknateYou have to enable the drupalink plugin in your editor. For example, if you're using full_html, edit that editor and drag the link button to the allowed buttons.
Comment #95
sjancich CreditAttribution: sjancich commentedThanks oknate. If anyone stumbles across this who was using the old patch, note that the workflow is now different. You need to add the drupalink button to your editor. Then, embed the media (don't expect the link field in this wizard), click on the image and then click on the drupalink button. If you have the linkit button already, you will end up with two link buttons in ckeditor.
Comment #96
wrd CreditAttribution: wrd commentedI'm not having any luck with the new workflow. Clicking the embedded entity has no apparent effect, and then following up by using the link button simply inserts the link above the embedded entity.
I had both LinkIt and Advanced Link installed, but have uninstalled them for testing; no change, however.
Comment #97
Rajab Natshah CreditAttribution: Rajab Natshah at Vardot commentedBack to use the patch from #47
Not sure if this could be in a new feature issue.
Comment #98
Rajab Natshah CreditAttribution: Rajab Natshah at Vardot commentedA follow up issue as a request for a new feature.
#3070343: Allow to add a Drupal core link with Link Widget for Image entities using Entity Embed Dialog in CKEditor
Comment #99
sjancich CreditAttribution: sjancich commented@wrd, try this patch: https://www.drupal.org/node/3068469
Comment #100
s_kulyk CreditAttribution: s_kulyk commentedThe patch is already applied in the module but in my instance but it doesn't work. Drupal version: 8.6.16
Comment #101
bkosborneHmm I'm also not able to get this to work. Using core's link dialog, nothing happens after inserting the link. The link is not inserted at all. Using LinkIt's link dialog, the link gets inserted above the embedded entity. What's strange is that I believe this was working previously. Some module or core update may have broken it.
Comment #102
bkosborneEdit: After triple checking all my module versions, I have this working again. I think I needed to update the entity embed module to 1.1 in conjunction with Drupal 8.8.
Comment #103
podarokRe #31
If you created a bunch of content with patch #31 - here is a Backward compatibility layer patch https://gist.github.com/podarok/47b9e38df6570a31d1ea87fea250d6c2 that provides content managers with a good error message for old content and keeps old untouched content working in 1.1 entity_embed
Comment #104
podarokComment #105
imre.horjanJust in case anyone is looking for LinkIt version 8.x-5.x compatibility: I think I found the solution directly in the LinkIt module.
Leaving the issue here for reference: https://www.drupal.org/project/linkit/issues/3290717
Comment #106
Binoli Lalani CreditAttribution: Binoli Lalani for Drupal India Association commentedHello,
I have rerolled entity-embed-link-2511404-68.patch.
Thank you!
Comment #107
jOpdebeeck CreditAttribution: jOpdebeeck commentedWe had some content on one of our projects using patch #31.
I rerolled the backwards compatibility patch from #104 to apply to 8.x-1.3.
Comment #108
rschwab CreditAttribution: rschwab at University of California commentedIs it possible this is still broken in 2023? I'm using what seems to be a pretty straightforward configuration of CKeditor link with the entity embed. Adding a link to a drupal-media tag doesn't work, the link is placed above the media in the html. Am I doing something wrong or is this really still not working?
Comment #109
acbramley CreditAttribution: acbramley at PreviousNext for Service NSW commented@rschwab are you using CKE5? It seems to no longer work with that :(
Comment #110
Daniel KorteBackwards compatibility patch for 8.x-1.5
Comment #111
SpadXIII CreditAttribution: SpadXIII at SIM commentedFound a small bug where it would set an error on the values array from the form_state; fixed it by pointing the error to the form field instead
old:
$form_state->setError($entity_element, $this->t('Link to is deprecated. Remove its value and use WYSIWYG Link button functionality over embedded entity.'));
new:
$form_state->setError($form['attributes']['data-entity-embed-display-settings']['link_url'], $this->t('Link to is deprecated. Remove its value and use WYSIWYG Link button functionality over embedded entity.'));
Comment #112
SpadXIII CreditAttribution: SpadXIII at SIM commentedAttached the wrong patch file, oops!