Last active
October 10, 2024 18:10
-
-
Save joemcgill/77a37e862d49bf47db9c06c8265338e0 to your computer and use it in GitHub Desktop.
Experimental: image sizes calculation during block rendering
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: Experimental Image Sizes | |
* Description: MU plugin for experiemnting with `sizes` calulations. | |
* Version: 0.1.0 | |
*/ | |
add_filter( 'render_block_core/image', 'wpp_add_image_block_sizes', 10, 3 ); | |
/** | |
* Calculate image sizes attribute for an image block during rendering. | |
* | |
* @param string $block_content The block content. | |
* @param array $parsed_block The parsed block data. | |
* @param WP_Block $wp_block The block instance. | |
* @return string The updated block content. | |
*/ | |
function wpp_add_image_block_sizes( $block_content, $parsed_block, $wp_block ) { | |
/** | |
* Callback for calculating image sizes attribute value for an image block. | |
* | |
* This is a workaround to use block context data when calculating the img sizes attribute. | |
* | |
* @since 😎 | |
* | |
* @param string $sizes The image sizes attribute value. | |
* @param array $size The image size data. | |
*/ | |
$filter = function( $sizes, $size ) use ( $wp_block ) { | |
$alignment = $wp_block->attributes['align'] ?? ''; | |
// Hypotehtical function to calculate better sizes. | |
$sizes = wpp_better_sizes_calc( $size, $alignment ); | |
return $sizes; | |
}; | |
// Hook this filter early, before default fitlers are run. | |
add_filter( 'wp_calculate_image_sizes', $filter, 9, 2 ); | |
/* | |
* A performance problem to still be solved with this approach is that | |
* wp_calculate_image_sizes() will make a DB query to get the image metadata. | |
* It does this to get the image width, which is needed to calculate | |
* the sizes attribute. Currently, this function is called from `wp_filter_content_tags` | |
* which has already primed the cache with the image metadata. That cache priming | |
* will need to be hanlded earlier if sizes is calculated during block rendering. | |
*/ | |
$sizes = wp_calculate_image_sizes( | |
// If we don't have a size slug, assume the full size was used. | |
$parsed_block['attrs']['sizeSlug'] ?? 'full', | |
null, | |
null, | |
$parsed_block['attrs']['id'] ?? 0 | |
); | |
remove_filter( 'wp_calculate_image_sizes', $filter, 9 ); | |
// Bail early if sizes are not calculated. | |
if ( ! $sizes ) { | |
return $block_content; | |
} | |
// Add the sizes attribute to the image tag here. | |
$processor = new WP_HTML_Tag_Processor( $block_content ); | |
$processor->next_tag( 'img' ); | |
$processor->set_attribute( 'sizes', $sizes ); | |
$return = $processor->get_updated_html(); | |
return $return; | |
}; | |
/** | |
* Hypothetical function to calculate better sizes. | |
* | |
* @param array $size The image size data. | |
* @param string $alignment The image alignment. | |
* @return string The sizes attribute value. | |
*/ | |
function wpp_better_sizes_calc( $size, $alignment ) { | |
switch ( $alignment ) { | |
case 'full': | |
return '100vw'; | |
break; | |
case 'wide': | |
// Hard coded wide size from TT4 theme for demo only. | |
return '(max-width: 1280px) 100vw, 1280px'; | |
break; | |
default: | |
// Hard coded wide size from TT4 theme for demo only. | |
return '(max-width: 620px) 100vw, 620px'; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment