-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Image Block: Add data-id attribute on server side render for core galleries #35975
Conversation
@celloexpressions I couldn't get things working with Arbutus. The Do you have any ideas of how I could test this? Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice simple fix @ramonjd! This is testing nicely for me with normal images. Just left a note about adding an isset
check to prevent a warning when dealing with images that are linked to external images (and so don't have an id
), but otherwise LGTM!
I appreciate the test @andrewserong It was a bit of a push and run today, so thanks for catching those oversights. 🙇 |
This tests well for me in terms of adding the data-id to the frontend. The issue with the Arbutus theme is that the method that is creating the gallery excerpt is running against the raw post content before this callback is applied, eg.: $result = preg_match_all( '/(<img[^>]+data-id="([^\\"]+)"[^>]+\\/>)/', $post->post_content, $matches ); is running against:
I will have a look and see if there is someway of modifying the post content before it hits the theme functions. |
I have also tried |
Thanks for running those tests @glendaviesnz I don't know if I'll get further than you but I'll do some further digging around as well. |
I think by using the_post action hook we can modify I didn't get very far yet, and I'm not sure this is the right direction. We need to:
function get_block_core_image_post_content( $post, $query ) {
if ( has_blocks( $post->post_content ) ) {
$content = $post->post_content;
$blocks = parse_blocks( $content );
foreach ( $blocks as $block ) {
if ( 'core/gallery' === $block['blockName'] ) {
foreach ( $block['innerBlocks'] as $inner_block ) {
if ( 'core/image' === $inner_block['blockName'] ) {
if ( isset( $inner_block['attrs']['id'] ) ) {
$data_id_attribute = 'data-id="' . esc_attr( $inner_block['attrs']['id'] ) . '"';
// do something with the content
}
}
}
}
}
$post->post_content = $content;
}
return $post;
}
add_action( 'the_post', 'get_block_core_image_post_content', 10, 2 ); Seems very convoluted to satisfy a theme. I wonder if there are other themes doing something similar to Arbutus. Or maybe we could somehow suggest a patch for the theme. |
15d5b12
to
41a0e88
Compare
Thanks for looking into this. Confirming that any server side filtering on the output needs to run on a hook before the global The Arbutus theme is an example, but this fix would apply to any themes or plugins that need to find the image's attachment ID in pre- or post-processing. This data attribute has been in the markup for a few years now, so there are likely to be a lot of different things expecting this markup (including non-public themes and plugins). Filtering as early as possible on the output is probably the second-best option in terms of strictly maintaining backwards compatibility, after saving the data attribute with the markup in the post content. Any solution here of course needs to be balanced with performance; however, the burden of preserving backwards compatibility should generally be with core first, then themes/plugins, then end users last. |
Thanks for the feedback @celloexpressions 🙇
Maybe there is a case to be had to continue on with #30710 and add the deprecation. Though you make a good point about the order of responsibility of backwards compatibility. I'm not completely over @glendaviesnz's work in WordPress/wordpress-develop#1788, but hopefully it might serve to mitigate the need for post processing. |
@ramonjd the change I just pushed seems to add the data-id to the post content at a point that prior to when the Arbutus theme templates parses the content, and with this change in place the gallery excerpt appears as expected. For some reason the id is gone again when it is actual output to the front end though - which may be an issue if other themes were using it as a css or js target - we could combine @celloexpressions we are also hoping to get https://core.trac.wordpress.org/ticket/43826 merged into 5.9, in which case @mtias FYI - in order to get the |
* @return string Returns the post content with the data-id attribute added to gallery images. | ||
*/ | ||
function get_block_core_image_post_content( $post ) { | ||
if ( is_admin() ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ( is_admin() ) { | |
if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { |
Is there are case where we'd want to run this code for rest requests?
I'm thinking it's safe to return early if we're targeting post data on the frontend, unless I'm missing a use case.
if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
return;
}
For example, add a var_dump('I LOVE THE BAND KISS!')
or some other logging after this if statement, and try to save a post. It doesn't have to contain a gallery.
The POST response will contain invalid, but possibly true, content: string(21) "I LOVE THE BAND KISS!" {id: 115, date: "2021-11-02T03:18:06", date_gmt: "2021-11-02T03:18:06",…}
Pinging a WP API endpoint that contains gallery post content still works for me with this check in place:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be somewhat wary about using is_admin()
in a condition check here. All it means is that the context when this post is setup is happening without wp-admin
, it doesn't actually mean that the post is being edited or the like. Somewhat could just as easily be expecting to get this data over an admin-ajax.php
call or simply trying to render their gallery in an admin page.
The same goes for REST_REQUEST
. It can both be used in the Block Editor. But it can also be used by someone making an API call to grab data for somewhere on the front-end of their website where they would expect the ids to be present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the advice @TimothyBJacobs 🙇
I think @glendaviesnz was trying to find ways to isolate the logic to frontend rendering to avoid block validation errors, given that data-id
isn't output by the save method of the image block.
🤔 Assuming block validation wasn't an issue, do you see any issues with removing the if check here entirely?
Cheers!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming block validation wasn't an issue, do you see any issues with removing the if check here entirely?
No, I think removing the check entirely would be ideal.
Thanks for the change @glendaviesnz The I checked TwentyTwentyOne/Twenty/Nineteen. I also checked in Arbutus and the gallery posts appear as expected. A question just to make sure: do we need to cater for v1 Galleries? Or will the migration to v2 ensure that this script picks up the image blocks?
Is that just for Arbutus? I checked a few core themes and things were working as expected. I assume because Arbutus is taking the img tag with the |
It was missing even on the standard post page as well as the gallery summary that Arbutus is constructing, strange. Given the fact that we can't reliable stop the modified content ending up back in the editor, and that we are hopefully getting a fix for get_post_galleries into 5.9, I am not sure that adding this value back in server side is worth the extra overhead. |
ec50ca8
to
9f98093
Compare
f1d27b6ae971ff73fad2156a1afa81e048fae737 adds a This filter adds a custom The Image Block render callback looks out for this custom attribute and will edit the image tag accordingly. This way, we can target gallery images only. @glendaviesnz rightly pointed out that we'd be safer to avoid adding the attribute to all images to avoid unknown unknowns. The imaginary scenario was:
|
There's an issue in It doesn't seem to be related to the filters, only the fact that we've added And it's specific to the gallery block. Other blocks in the |
bdad12e
to
ff17062
Compare
So it turns that that, for styles to be enqueued for block based themes, I didn't know that
I'm not sure why however. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is working as advertised for me now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is testing well for me, @ramonjd! Just left a couple of comments where I think we need to add an isset
check to avoid throwing PHP Notices, but otherwise it's looking good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing up those array access issues @glendaviesnz! This PR is testing well for me now, the data-id
is added to images within a Gallery block that have an id
attribute, images without that attribute, or that are rendered outside of a gallery block, do not have the data-id
added to the markup.
LGTM!
I forgot those issets again. Thanks! |
…o the image element. Check for existing data-id attribute on the image block content Wrapping $attributes['id'] in an isset check to catch undefined indexes
…allery before render. The image block render callback can detect this and add it to the image elements. Because the gallery block is adding the attribute, we can target images inside galleries.
…n a string or an integer.
…y correctly. Without this dummy render function, the gallery styles do not load with the block-library build.
e8e582f
to
ff4ba58
Compare
Resolves #35907
Description
This PR renders a
data-id
attribute on the image element of Image Blocks on if adata-id
property exists in the block's attributes.The Gallery Block now has a filter
render_block_data
which adds adata-id
to Image Blocks before the Gallery Block is processed.Why?
The answer is phrased very succinctly in the issue
Testing
Enable the Gallery experiment on Gutenberg
Insert a gallery and a single image into a post.
Make sure that the published gallery images and single image markup includes the data-id attribute on the
<img />
tags.Check that other galleries are still working, e.g., Jetpack tiled gallery.
Types of changes
Checklist:
*.native.js
files for terms that need renaming or removal).