-
Notifications
You must be signed in to change notification settings - Fork 385
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
Use data-hero-candidate attribute in DetermineHeroImages #5934
Use data-hero-candidate attribute in DetermineHeroImages #5934
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #5934 +/- ##
=============================================
+ Coverage 75.28% 75.38% +0.09%
- Complexity 5722 5735 +13
=============================================
Files 214 214
Lines 17283 17312 +29
=============================================
+ Hits 13012 13050 +38
+ Misses 4271 4262 -9
Flags with carried forward coverage won't be shown. Click here to find out more.
|
7a0262a
to
f343d4e
Compare
Checking with Twenty Twelve, and the header image is not getting Same for Twenty Fourteen and Twenty Sixteen. However, Twenty Seventeen does add Also, if I have an Image block as the first block in a post, then I only get the header image in Twenty Seventeen gets prerendered. The Image block does not. Same for the Cover block. So in Twenty Twelve, I could have a header image set followed by a post with a Cover block or Image block as the first image, and nothing would be prerendered. This was an issue reported previously as well: #5824 (comment). |
@jono-alderson On your site, you are manually outputting your header image as well, as opposed to using any block or custom header code, correct? I don't believe it would be detected currently as a hero image candidate with this PR. |
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 feel that there are still too many scenarios where valid hero images are going to be missed.
What if we rendered out an HTML comment at the loop_start
action and then by default treated every non-tiny image before that in the DOM as being a hero image candidate? That should account for all images that are located in the header and would avoid accidentally prerendering any image that is not in the initial viewport. (Granted, sometimes singular templates will skip doing The Loop and will just put a the_post()
at the top even before get_header()
, however this is not done in any core theme and it would just mean none would be detected.) Consider this code:
$on_loop_start = function () use (&$on_loop_start) {
remove_action( 'loop_start', $on_loop_start );
if ( ! did_action( 'get_header' ) ) {
return;
}
echo '<!--AMP:LOOP_START-->';
};
add_action( 'loop_start', $on_loop_start );
The transformer could walk over all elements, marking non-tiny images as candidates, until it gets to this node and then exits.
Beyond the header, when is_singular()
, if there is a Cover block or Image block at the beginning of post content, then I think it should be made a hero image candidate as well. (Not even blocks-specifically, but rather whether the queried post content starts with an image at all, such as in the case of sites using the Classic Editor.)
$elements = $document->xpath->query( | ||
self::CUSTOM_HEADER_XPATH_QUERY, | ||
$document->body | ||
); |
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.
An alternative way to identify the header image which may be more robust as opposed to relying on element IDs is to obtain the header image URL and then query for image elements that have that src
:
$elements = $document->xpath->query( | |
self::CUSTOM_HEADER_XPATH_QUERY, | |
$document->body | |
); | |
$header_image = get_header_image(); | |
if ( ! $header_image ) { | |
return null; | |
} | |
$elements = $document->xpath->query( | |
sprintf( | |
'//*[ ( self::img or self::amp-img ) and @src = "%s" ]', | |
addcslashes( $custom_header->url, '"\\' ) | |
), | |
$document->body | |
); |
But this is going to have other problems, namely because get_header_image_tag()
allows for the markup to be filtered, meaning the image URL could be replaced with one that is pointing to a CDN.
An alternative idea to injecting a add_filter( 'wp_get_attachment_image_attributes', function ( $attrs ) {
if ( ! did_action( 'loop_start' ) ) {
$attrs['data-hero-candidate'] = '';
}
return $attrs;
} ); Nevertheless, this won't help with Twenty Sixteen which outputs its header image as follows: <img src="<?php header_image(); ?>" srcset="<?php echo esc_attr( wp_get_attachment_image_srcset( get_custom_header()->attachment_id ) ); ?>" sizes="<?php echo esc_attr( $custom_header_sizes ); ?>" width="<?php echo esc_attr( get_custom_header()->width ); ?>" height="<?php echo esc_attr( get_custom_header()->height ); ?>" alt="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>"> |
f343d4e
to
b126bc3
Compare
Co-authored-by: Weston Ruter <westonruter@google.com>
…github.com/ampproject/amp-wp into fix/5824-use-data-hero-candidate-attribute
This reverts commit 223b008.
Plugin builds for bcb50e5 are ready 🛎️!
|
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.
@schlessera I went about fixing #5923 in this PR as well, and while I was at fixing Cover Block detection I also added detection for Image blocks. As I've indicated in the updated description, only Cover/Image Blocks which are in the first child element of the first .entry-content
will be considered.
Since we know that the transformer works for core themes, I've decided to enable it via the core theme sanitizer. Other themes can opt-in at the 2.1 release, but we can flip it on for all themes at 2.1.x once we get testing with more themes.
Please review the changes.
@@ -375,8 +387,8 @@ public static function has_class( DOMElement $element, $class ) { | |||
* | |||
* @deprecated Use AmpProject\Dom\Document::getElementId() instead. | |||
* | |||
* @param DOMElement $element Element to get the ID for. | |||
* @param string $prefix Optional. Defaults to 'amp-wp-id'. | |||
* @param DOMElement|Element $element Element to get the ID for. |
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.
Rather than having to do this for static analysis, the getElementId
method could indicate the $element
is a DOMElement
or an Element
.
@westonruter The cover block image will now only work on the very latest WP release, and not be detecting on any prior release. Was that intended? IIRC we claim to support not only the latest stable version of Core, but all versions from 4.9 onwards or so? |
Prior versions of the Cover Block didn't use an |
(Not sure why code coverage is reporting untested lines.) |
Oh, right. So they would not need prerendering, but they would benefit from preloading. However, we were discussing removing the preloading from hero images anyway and just keep the prerendering, so this means it would be useless then. The |
I replaced a constant and I added covers annotations to fix the code coverage. LGTM now. |
Summary
This PR changes the
DetermineHeroImages
transformer to usedata-hero-candidate
attributes instead ofdata-hero
attributes. It also adds detection of WordPress custom header images, fixes detection for images in Cover blocks, and adds detection for Image blocks. For Cover blocks and Image blocks, only contained images which are in the first.entry-content
of the document which are additionally inside the first element child will be considered for hero image candidates.NOTE: As discussed,
this PR now removes theThe transformer is now enabled for all core themes by default. The transformer can be enabled for testing purposes (or for other themes) via theDetermineHeroImages
transformer from the list of default transformers, as the logic is too error-prone at this point.'amp_optimizer_config'
filter:It will likely be enabled by default in a subsequent release, even v2.1.x.
Fixes #5824
Fixes #5923
Checklist