wpseek.com
A WordPress-centric search engine for devs and theme authors
wp_hoist_late_printed_styles › WordPress Function
Since6.9.0
Deprecatedn/a
› wp_hoist_late_printed_styles ( No parameters )
See: | |
Defined at: |
|
Codex: |
Adds the hooks needed for CSS output to be delayed until after the content of the page has been established.
Related Functions: wp_print_styles, wp_style_engine_get_styles, print_late_styles, wp_maybe_inline_styles, wp_register_style
Source
function wp_hoist_late_printed_styles() { // Skip the embed template on-demand styles aren't relevant, and there is no wp_head action. if ( is_embed() ) { return; } /* * While normally late styles are printed, there is a filter to disable prevent this, so this makes sure they are * printed. Note that this filter was intended to control whether to print the styles queued too late for the HTML * head. This filter was introduced in <https://core.trac.wordpress.org/ticket/9346>. However, with the template * enhancement output buffer, essentially no style can be enqueued too late, because an output buffer filter can * always hoist it to the HEAD. */ add_filter( 'print_late_styles', '__return_true', PHP_INT_MAX ); /* * Print a placeholder comment where the late styles can be hoisted from the footer to be printed in the header * by means of a filter below on the template enhancement output buffer. */ $placeholder = sprintf( '/*%s*/', uniqid( 'wp_late_styles_placeholder:' ) ); wp_add_inline_style( 'wp-block-library', $placeholder ); // Wrap print_late_styles() with a closure that captures the late-printed styles. $printed_late_styles = ''; $capture_late_styles = static function () use ( &$printed_late_styles ) { ob_start(); print_late_styles(); $printed_late_styles = ob_get_clean(); }; /* * If _wp_footer_scripts() was unhooked from the wp_print_footer_scripts action, or if wp_print_footer_scripts() * was unhooked from running at the wp_footer action, then only add a callback to wp_footer which will capture the * late-printed styles. * * Otherwise, in the normal case where _wp_footer_scripts() will run at the wp_print_footer_scripts action, then * swap out _wp_footer_scripts() with an alternative which captures the printed styles (for hoisting to HEAD) before * proceeding with printing the footer scripts. */ $wp_print_footer_scripts_priority = has_action( 'wp_print_footer_scripts', '_wp_footer_scripts' ); if ( false === $wp_print_footer_scripts_priority || false === has_action( 'wp_footer', 'wp_print_footer_scripts' ) ) { // The normal priority for wp_print_footer_scripts() is to run at 20. add_action( 'wp_footer', $capture_late_styles, 20 ); } else { remove_action( 'wp_print_footer_scripts', '_wp_footer_scripts', $wp_print_footer_scripts_priority ); add_action( 'wp_print_footer_scripts', static function () use ( $capture_late_styles ) { $capture_late_styles(); print_footer_scripts(); }, $wp_print_footer_scripts_priority ); } // Replace placeholder with the captured late styles. add_filter( 'wp_template_enhancement_output_buffer', function ( $buffer ) use ( $placeholder, &$printed_late_styles ) { // Anonymous subclass of WP_HTML_Tag_Processor which exposes underlying bookmark spans. $processor = new class( $buffer ) extends WP_HTML_Tag_Processor { public function get_span(): WP_HTML_Span { $instance = $this; // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewClosure.ThisFoundOutsideClass -- It is inside an anonymous class. $instance->set_bookmark( 'here' ); return $instance->bookmarks['here']; } }; // Loop over STYLE tags. while ( $processor->next_tag( array( 'tag_name' => 'STYLE' ) ) ) { // Skip to the next if this is not the inline style for the wp-block-library stylesheet (which contains the placeholder). if ( 'wp-block-library-inline-css' !== $processor->get_attribute( 'id' ) ) { continue; } // If the inline style lacks the placeholder comment, then something went wrong and we need to abort. $css_text = $processor->get_modifiable_text(); if ( ! str_contains( $css_text, $placeholder ) ) { break; } // Remove the placeholder now that we've located the inline style. $processor->set_modifiable_text( str_replace( $placeholder, '', $css_text ) ); $buffer = $processor->get_updated_html(); // Insert the $printed_late_styles immediately after the closing inline STYLE tag. This preserves the CSS cascade. $span = $processor->get_span(); $buffer = implode( '', array( substr( $buffer, 0, $span->start + $span->length ), $printed_late_styles, substr( $buffer, $span->start + $span->length ), ) ); break; } return $buffer; } ); }