Problem/Motivation
1) The caption filter currently always wraps the captioned element in a <figure>
block to which it adds its own <figcaption>
. This creates unnessecarily nested markup in case the element itself is already presented as/contains a <figure>
with a <figcaption>
.
2) Additionally, the $node->C14N()
call strips all comments, which includes Twig debug comments (we can deal with that) and compatibility comments like those used for responsive images: <!--[if IE 9]><video style="display: none;"><![endif]-->
(this is bad and will cause problems).
Example setup for 1) using entity_embed
:
- Media type "Image" with a template like
<figure>{{ content.field_image }}<figcaption>{{ name }}</figcaption></figure>
- Some content in which the media entity is embedded with a specified custom caption
Expected result:
<figure>{{ content.field_image }}<figcaption>{{ my overridden caption}}</figcaption></figure>
Actual result (using default filter-caption.html.twig
):
<figure>
<figure>
{{ content.field_image }}
<figcaption>{{ name }}</figcaption>
</figure>
<figcaption>{{ my overridden caption }}</figcaption>
</figure>
Proposed resolution
1) Re-use an already present <figcaption>
element.
2) Keep comments when building $altered_html
.
Remaining tasks
Discuss what we need/want to do. Review.
Comment | File | Size | Author |
---|---|---|---|
#2 | drupal-caption_filter_use_existing-2935625-2.patch | 2.79 KB | ckaotik |
Issue fork drupal-2935625
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
ckaotikI've written a patch that addresses both issues, but we should nontheless discuss if we need/want to address both parts.
The patch will use the first
<figcaption>
element found in the captioned element - for nested<figure>
s, this should be the group description, and if there's multiple captions in a figure we have invalid markup anyways.For the comments, I've changed the
$node->C14N()
call to$node->C14N(FALSE, TRUE)
which solves that nicely.Comment #3
ckaotikUpdated issue summary.
Comment #7
jonraedeke CreditAttribution: jonraedeke commentedThank you for this patch, it works very well. This is a common use case.
Comment #8
jonraedeke CreditAttribution: jonraedeke commentedOne thing I noticed with this patch is that you see both the caption from the field and the overridden caption in the text editing area.
In D7, it was possible to override fields on a file entity when embedding. This was ideal, because you could see the value of the caption field from the media entity before overriding.
Comment #9
jonraedeke CreditAttribution: jonraedeke commentedTaking another look, my caption field was not themed in the wysiwyg to output as figure and figcaption, so that is why it is not getting replaced. My other comment about pre-populating caption field data probably belongs in the Entity Embed module.
This patch looks good to me.
Comment #10
jonraedeke CreditAttribution: jonraedeke commentedThis filter should also check for the
<figure>
wrapper. An image themed like this with no caption:still gets double wrapped with the
<figure>
tag.Comment #11
ckaotikGood point, so basically add a fallback check if there's a
<figure>
element but no included<figcaption>
, place it last in the figure wrapper?Comment #12
jonraedeke CreditAttribution: jonraedeke commentedExactly, that would be great.
Comment #14
szeidler CreditAttribution: szeidler at Ramsalt Lab for Sykepleien commentedThis would be an excellent feature. I tried to utilize it for the Media embed option for CKEditor in Drupal 8.8. Unfortunately it fails by the fact, that "Caption images" filter is forced to run before "Embed media". This makes the caption filter not knowing if there will be a
<figcaption>
in the rendered media.Comment #16
jonraedeke CreditAttribution: jonraedeke commentedGood point szeidler, the order of the filters appears to be forced in https://www.drupal.org/project/entity_embed/issues/2752253.
This is really only an issue when using entity embed, so I think it might be better discussed there first.
It's too bad the caption filter
has tocan't run last. I was excited about this prospect as it would potentially let me replace existing rendered figcaptions displayed in the image media entity itself. That would be an easy way to override captions from the media object, like used to be possible in D7. Also, it would allow for printing fields after<figcaption>
, like Image Credit.This issue also prevents theming image media as without a caption since the filter doesn't run. So the markup for images changes depending on whether there is a caption or not, which is not ideal. The core caption filter really assumes that the contents of the item being captioned is a simple img element, not a fully fielded and rendered image media entity.
I wonder if entity embed needs it's own caption filter functionality to account for rendered entities, not just img tags.
Comment #17
jonraedeke CreditAttribution: jonraedeke commentedI was wrong that this is only relevant for the entity_embed module. Embedding media with core has this issue also. Moving back to core.
Comment #23
jonraedeke CreditAttribution: jonraedeke commentedUnfortunately, this is still an issue with CKEditor 5 implementation in core.
I'm just digging into CKEditor 5 plugin coding, but it appears that CKEditor 5 really isn't aware of the media markup.
Comment #25
jayhuskinsFor anyone interested, here's how I solved this for my website:
Here is the code for the process function in my custom text filter:
Comment #26
pawel.traczynski CreditAttribution: pawel.traczynski as a volunteer commentedThe Drupal core caption filter did not work for me either for the resons mentioned above.
Here is how I achived captions for embedded media images while being in full control of the HTML markup.
I needed to give the user an option to:
- embed image while being able to pick image style: I have created one style for tall/portrait image and one for wide/full content width image
- allow them to provide caption
- use my own markup for the image printed with image style and the caption
1. I have setup media bundle 'image' and added 'media_caption' formatted text field in it. The caption format allowed paragraphs and links so that instead of plain text captions, a caption could be multiple paragraphs or could contain a link. For this purpose I have used a text format that I already had on my site that allows exactly and only this.
2. Then configured two different view modes for media 'image', where each view mode used different image style for the media_image field. One view mode machine name was 'image_full' and the other was 'image_tall'.
3. The custom templates for embedded image media I needed to be global, that is I neeeded them to be picked up independently of theme being in use. For this reason I have registered my own media templates in my module:
As you can see I used single template for both view modes. Because of using my own templates only for my view modes, other view modes, like those used in the Media administration pages are not impacted and will continue to display normally without breaking the admin UI styling.
4. The custom media-image.html.twig template looked like this:
5. Then to support my own template and my markup requirements I added this template preprocess:
Thats it. Now when Embed Media button it pressed, when user uploads a new image, they will see a custom caption field. In addition when they insert the image into CKEditor5, they will see a dropdown to pick the image style to use.
I have implemented this as an "Insert" module replacement for CK5.
So far the only downsides of this solution that I see are:
- once the image has been inserted into ckeditor5 content, then if user wants to edit the caption again, they have to edit it in the media, for example by editing the media on the media administration page
- the caption is global for a single media item. You cannot insert the same media media in different nodes while having different captions for each