Skip to content

Some inline styles specific to block variations are still missing #1

Description

@miftygusein

Example from the Thenty Twenty-Four theme, a page with About pattern applied to it.

It contains a few blocks with rounded corners, and in the rendered source code we have this inline style:

<style id='block-style-variation-styles-inline-css'>
:root :where(.wp-block-image.is-style-rounded--972cc0b5fceed9af05d7197276745377 img,.wp-block-image.is-style-rounded--972cc0b5fceed9af05d7197276745377  .wp-block-image__crop-area,.wp-block-image.is-style-rounded--972cc0b5fceed9af05d7197276745377  .components-placeholder){border-radius: var(--wp--preset--spacing--20);}
:root :where(.wp-block-image.is-style-rounded--fdf1f7e807467625e5659d338a369774 img,.wp-block-image.is-style-rounded--fdf1f7e807467625e5659d338a369774  .wp-block-image__crop-area,.wp-block-image.is-style-rounded--fdf1f7e807467625e5659d338a369774  .components-placeholder){border-radius: var(--wp--preset--spacing--20);}
:root :where(.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a img,.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a  .wp-block-image__crop-area,.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a  .components-placeholder){border-radius: var(--wp--preset--spacing--20);}
:root :where(.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a img,.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a  .wp-block-image__crop-area,.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a  .components-placeholder){border-radius: var(--wp--preset--spacing--20);}
:root :where(.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a img,.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a  .wp-block-image__crop-area,.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a  .components-placeholder){border-radius: var(--wp--preset--spacing--20);}
:root :where(.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a img,.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a  .wp-block-image__crop-area,.wp-block-image.is-style-rounded--81b116806b00ae7b81277b5de4ff0d8a  .components-placeholder){border-radius: var(--wp--preset--spacing--20);}
:root :where(.wp-block-button.is-style-outline--30ab812d8ff1e5a5dd8b5ef3169abe49 .wp-block-button__link){background: transparent none;border-color: currentColor;border-width: 1px;border-style: solid;color: currentColor;padding-top: calc(0.6rem - 1px);padding-right: calc(1rem - 1px);padding-bottom: calc(0.6rem - 1px);padding-left: calc(1rem - 1px);}
:root :where(.wp-block-image.is-style-rounded--b1122f438d41eff65844539f9899cfca img,.wp-block-image.is-style-rounded--b1122f438d41eff65844539f9899cfca  .wp-block-image__crop-area,.wp-block-image.is-style-rounded--b1122f438d41eff65844539f9899cfca  .components-placeholder){border-radius: var(--wp--preset--spacing--20);}
</style>

This covers variations defined for core/image block in wp-content/themes/twentytwentyfour/theme.json. But because these variations are specific to an individual block, they are not picked up and rendered by this plugin as it stands now.

Apparently, we need to load the actual page/post and parse the blocks so that Wordpress is aware of them, and as the result renders the individual stylesheets for them.

Here's an experimental file to do that, save it as wp-content/plugins/wordpress-export-css/emperiment.php and access directly as wp-content/plugins/wordpress-export-css/experiment.php?slug=home (where home is the slug for the home page if you have one, can be any other page):

<?php
/*
Plugin Name: Page-Specific CSS Extractor
Description: Retrieves inline CSS styles specific to a given page based on its slug, including block variation styles from theme.json.
Version: 1.6
Author: Your Name
*/

// Load WordPress environment if accessed directly
if (!defined('ABSPATH')) {
    require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/wp-load.php';
}

/**
 * Function to retrieve inline CSS styles for a given page by its slug, including block variation styles.
 *
 * @param string $slug The slug of the page.
 * @return string The CSS styles specific to the page, if available.
 */
function get_page_specific_css_by_slug($slug) {
    // Get the page by slug
    $page = get_page_by_path($slug, OBJECT, 'page');
    if (!$page) {
        return 'Page not found';
    }
    // Set up the page context and process blocks
    //setup_postdata($page); // seems to not be required
    $content = $page->post_content;
    // Load blocks
    do_blocks($content);
    //wp_render_block_style_variation_support_styles($blocks); // seems to not be required
    // Start output buffering to capture inline styles
    ob_start();

    // Ensure any styles or assets for blocks and theme.json are enqueued
    ////do_action('wp_enqueue_scripts'); // seems to not be required

    // Enqueue global styles to load theme.json settings
    if (function_exists('wp_enqueue_global_styles')) {
        ////wp_enqueue_global_styles();
    }

    // Capture head styles including block and theme.json styles
    wp_head(); // this is required, variations won't be rendered without this

    // Render the blocks to trigger all variation and inline styles

    // Clean up global context
    ////wp_reset_postdata(); // seems to not be required

    // Get the buffered output, containing rendered blocks and inline styles
    $output = ob_get_clean();
    // Extract <style> tags from the output to isolate inline CSS
    if (preg_match_all('/<style[^>]*>(.*?)<\/style>/is', $output, $matches)) {
        return implode("\n", $matches[1]);
    }

    return 'No inline CSS found for this page.';
}

// Check if the 'slug' parameter is set in the URL for direct access
if (isset($_GET['slug'])) {
    // Sanitize and retrieve the slug from the URL
    $slug = sanitize_text_field($_GET['slug']);
    $css = get_page_specific_css_by_slug($slug);

    // Set the correct content type for CSS output
    header("Content-Type: text/css");

    // Output the CSS or an error message if not found
    echo $css ? $css : "/* No inline CSS found for this page. */";
    exit;
}

The good news is the above does render the variations we're looking for, although in an ungly way - by having to render the whole thing and then parse out the inline stylesheets.

But the problem is that it makes these stylesheets have selectors that are pointing to a specific element, like .wp-block-image.is-style-rounded--0 img, while the actual content we render straight from the database does is simply .wp-block-image.is-style-rounded. without the --0. It seems Wordpress applies these identifiers dynamically, and it may require some logic on the external site where we render the content.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions