Make WordPress Core


Ignore:
Timestamp:
07/11/2023 01:56:55 PM (9 months ago)
Author:
joemcgill
Message:

Media: Optimize images created in shortcodes.

This fixes an issue where images dynamically created during shortcode rendering (e.g., shortcode image galleries), were not getting image optimizations like loading="lazy" or fetchpriority="hight" applied. Note that even after this commit, shortcodes are processed after the main content images, which can affect the order in which optimizations are applied in content areas.

Follow-up to [56037].

Props spacedmonkey, flixos90, thekt12, swissspidy, joemcgill.
Fixes #58681.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/media.php

    r56164 r56214  
    7979     * Ensures that the static content media count, fetchpriority element flag and related filter are reset between tests.
    8080     */
    81     public function set_up() {
    82         parent::set_up();
     81    public function tear_down() {
     82        parent::tear_down();
    8383
    8484        $this->reset_content_media_count();
     
    50035003            wp_get_loading_optimization_attributes( 'img', $attr, 'test' ),
    50045004            'loading optimization attr array should be empty.'
     5005        );
     5006    }
     5007
     5008    /**
     5009     * @ticket 58681
     5010     *
     5011     * @dataProvider data_wp_get_loading_optimization_attributes_in_shortcodes
     5012     */
     5013    public function test_wp_get_loading_optimization_attributes_in_shortcodes( $setup, $expected, $message ) {
     5014        $attr = $this->get_width_height_for_high_priority();
     5015        $setup();
     5016
     5017        // The first image processed in a shortcode should have fetchpriority set to high.
     5018        $this->assertSame(
     5019            $expected,
     5020            wp_get_loading_optimization_attributes( 'img', $attr, 'do_shortcode' ),
     5021            $message
     5022        );
     5023    }
     5024
     5025    public function data_wp_get_loading_optimization_attributes_in_shortcodes() {
     5026        return array(
     5027            'main_shortcode_image_should_have_fetchpriority_high'  => array(
     5028                'setup'    => function () {
     5029                    global $wp_query;
     5030
     5031                    // Set WP_Query to be in the loop and the main query.
     5032                    $wp_query->in_the_loop = true;
     5033                    $this->set_main_query( $wp_query );
     5034                },
     5035                'expected' => array(
     5036                    'fetchpriority' => 'high',
     5037                ),
     5038                'message'  => 'Fetch priority not applied to during shortcode rendering.',
     5039            ),
     5040            'main_shortcode_image_after_threshold_is_loading_lazy' => array(
     5041                'setup'    => function () {
     5042                    global $wp_query;
     5043
     5044                    // Set WP_Query to be in the loop and the main query.
     5045                    $wp_query->in_the_loop = true;
     5046                    $this->set_main_query( $wp_query );
     5047
     5048                    // Set internal flags so lazy should be applied.
     5049                    wp_high_priority_element_flag( false );
     5050                    wp_increase_content_media_count( 3 );
     5051                },
     5052                'expected' => array(
     5053                    'loading' => 'lazy',
     5054                ),
     5055                'message'  => 'Lazy-loading not applied to during shortcode rendering.',
     5056            ),
     5057            'shortcode_image_outside_of_the_loop_are_loaded_lazy'  => array(
     5058                'setup'    => function () {
     5059                    // Avoid setting up the WP_Query object for the loop.
     5060                    return;
     5061                },
     5062                'expected' => array(
     5063                    'loading' => 'lazy',
     5064                ),
     5065                'message'  => 'Lazy-loading not applied to shortcodes outside the loop.',
     5066            ),
     5067        );
     5068    }
     5069
     5070    /**
     5071     * @ticket 58681
     5072     */
     5073    public function test_content_rendering_with_shortcodes() {
     5074        // The gallery shortcode will dynamically create image markup that should be optimized.
     5075        $content = "[gallery ids='" . self::$large_id . "' size='large']";
     5076        $actual  = apply_filters( 'the_content', $content );
     5077
     5078        $this->assertStringContainsString(
     5079            // Since the main query and loop isn't set, this should be lazily loaded.
     5080            'loading="lazy"',
     5081            $actual,
     5082            'Could not confirm shortcodes get optimizations applied.'
     5083        );
     5084    }
     5085
     5086    /**
     5087     * @ticket 58681
     5088     */
     5089    public function test_content_rendering_with_shortcodes_nested() {
     5090        global $wp_query;
     5091
     5092        // Set WP_Query to be in the loop and the main query.
     5093        $wp_query->in_the_loop = true;
     5094        $this->set_main_query( $wp_query );
     5095
     5096        add_shortcode(
     5097            'div',
     5098            function ( $atts, $content = null ) {
     5099                $parsed_atts = shortcode_atts(
     5100                    array(
     5101                        'class' => '',
     5102                    ),
     5103                    $atts
     5104                );
     5105
     5106                $class = ! empty( $parsed_atts['class'] ) ? sprintf( ' class="%s"', $parsed_atts['class'] ) : null;
     5107
     5108                return sprintf( '<div %s>%s</div>', $class, do_shortcode( $content ) );
     5109            }
     5110        );
     5111
     5112        // The gallery shortcode will dynamically create image markup that should be optimized.
     5113        $content = "[div][gallery ids='" . self::$large_id . "' size='large'][div]";
     5114        $actual  = apply_filters( 'the_content', $content );
     5115
     5116        $this->assertStringContainsString(
     5117            // Since this is in the loop, it should have a high fetchpriority.
     5118            'fetchpriority="high"',
     5119            $actual,
     5120            'Could not confirm shortcodes get optimizations applied.'
    50055121        );
    50065122    }
Note: See TracChangeset for help on using the changeset viewer.