WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.34k stars 4.13k forks source link

Hybrid themes: Block CSS is missing when using do_blocks() #40018

Open carolinan opened 2 years ago

carolinan commented 2 years ago

Description

If you use do_blocks() to render a block, the CSS normally placed in a style tag for the wp-container-uniqueID inline in the document is missing. Such as the flex, margins, widths and alignments.

Step-by-step reproduction instructions

Use do_blocks() (in a front facing template file) to render a block with a layout setting like a group or template part. Confirm that the CSS is missing on the front.

In empty theme, create file called search.php (Place it in the root directory, not templates) Add this sample code:

<!doctype html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
    <div class="wp-site-blocks">
    <?php
    echo do_blocks( '<!-- wp:template-part {"slug":"header","theme":"emptytheme","align":"full","className":"site-header"} /-->' );

    echo do_blocks(
        '<!-- wp:group {"tagName":"main","align":"full","layout":{"inherit":true}} -->
        <main class="wp-block-group alignfull"><!-- wp:spacer {"height":"20px"} -->
        <div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
        <!-- /wp:spacer -->

        <!-- wp:group {"align":"wide","layout":{"inherit":true}} -->
        <div class="wp-block-group alignwide"><!-- wp:heading {"textAlign":"center"} -->
        <h2 class="has-text-align-center">No results found</h2>
        <!-- /wp:heading -->

        <!-- wp:paragraph -->
        <p>Sorry, but nothing matched your search terms. Please try again with some different keywords</p>
        <!-- /wp:paragraph -->

        <!-- wp:search {"label":"Search","showLabel":false,"buttonText":"Search"} /--></div>
        <!-- /wp:group -->

        <!-- wp:spacer {"height":"20px"} -->
        <div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
        <!-- /wp:spacer --></main>
        <!-- /wp:group -->'
        );
    ?>
    </div>
<?php wp_footer(); ?>
</body>
</html>

Go to the front of the test site and do a search. See that the layout is left aligned, not wide with a centered heading. View the source and see that the CSS styles for alignments in wp-container-uniqueID is not printed.

Copy paste the same block markup to a post or page and compare the two layouts and the CSS. The post has the following CSS applied:

.wp-container-1 > * {
    margin-block-start: 0;
    margin-block-end: 0;
}

.wp-container-1 > :where(:not(.alignleft):not(.alignright)) {
    max-width: 840px;
    margin-left: auto !important;
    margin-right: auto !important;
}

Screenshots, screen recording, code snippet

No response

Environment info

WordPress 5.9.3 RC1 nightly With and without Gutenberg trunk, Gutenberg 12.9.0. WordPress beta tester plugin

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

No

illycz commented 2 years ago

WP 5.9.3 Gutenberg 12.9.0

Problem still persist...

fredy31 commented 2 years ago

Same problem here. The CSS related to the blocks is not included.

Would there be a way to just basically include all CSS of the possible blocks (and thus fix our issue?)

carolinan commented 2 years ago

The solution right now is to:

assign all your do_blocks() to variables before calling wp_head() and then print those variables where you need them.

<?php
  $header = do_blocks('<!-- wp:template-part {"slug":"header","theme":"themeName"} /-->');
  $footer = do_blocks('<!-- wp:template-part {"slug":"footer","theme":"themeName"} /-->');
?>
<head>
  <?php wp_head(); ?>
</head>
<body>
  <?php echo $header; ?>
  <?php echo $footer; ?>
</body>

I am not sure that is the long term solution that we want....

Rushmark commented 2 years ago

This seems like quite a big deal to me. Trying to merge a site with custom post types and custom fields into FSE is going to be very problematic until this is resolved? The do_blocks solution above works for including template parts. But things get very messy if trying to pull in anything more complex? Unless I'm missing something?

carolinan commented 2 years ago

The only thing that changes is the position so I don't think it is necessarily more messy. Less intuitive yes but that is because we are not used to placing the code there, are there any other side effects than that?

khromov commented 2 years ago

@carolinan 👋 Hi! I have a related problem to this but a bit different context. I'm trying to make an Advanced Custom Field PHP block template behave like a FSE HTML template (basically I want to paste Gutenberg output into the template and have it render correctly.)

I've attached a Gist of my code which uses do_blocks() to render the output: https://gist.github.com/khromov/b0f3838aaf663896e0ae94f0db111b92

This actually works great on the frontend of the site, but when in the Gutenberg editor, the styles do not get applied, probably for the reason discussed in this thread where the CSS does not get applied.

It should be possible to make it work inside Gutenberg if I can just access the generated CSS when using do_blocks(). Is this at all possible?

Example of the problem:

Backend (preview does not look right)

gutenberg-bug

Frontend (everything works)

guten-frontend

thekendog commented 1 year ago

The solution right now is to:

assign all your do_blocks() to variables before calling wp_head() and then print those variables where you need them.

<?php
  $header = do_blocks('<!-- wp:template-part {"slug":"header","theme":"themeName"} /-->');
  $footer = do_blocks('<!-- wp:template-part {"slug":"footer","theme":"themeName"} /-->');
?>
<head>
  <?php wp_head(); ?>
</head>
<body>
  <?php echo $header; ?>
  <?php echo $footer; ?>
</body>

I am not sure that is the long term solution that we want....

Is this still the recommended workaround? I'm trying this exact solution and the block CSS still isn't being enqueued.

carolinan commented 1 year ago

I am not aware of any changes that would affect it.

carolinan commented 1 year ago

I made a quick test with a classic theme, I added the code above and the two template parts, and the styles are applied.

thekendog commented 1 year ago

Weird. Maybe it's the theme I'm using or something.

codersantosh commented 3 months ago

A similar issue and solution regarding the failure of CSS to load when using the template_include hook to override a template. Specifically, the Block CSS fails to load when the template is overridden by a standard PHP template.

<?php //phpcs:ignore
/**
 * Single post type template.
 */
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
    <?php
    wp_body_open();
    /* Main loop */
    while ( have_posts() ) :
        the_post();

        the_content();

    endwhile; // End of the loop.

    /* Wp footer */
    wp_footer();
    ?>
</body>
</html>

Here's a template that successfully loads the block CSS:

<?php //phpcs:ignore
/**
 * Single post type template.
 */
global $post;

// Sometimes the initial `\` is missing, so look for both versions.
$content = str_replace( array( '\u0026amp;', 'u0026amp;' ), '&', $post->post_content );

// Remove `ref` from all content.
$content = preg_replace( '/"ref":\d+,?/', '', $content );

$do_blocks_pattern_content = do_blocks( $content );
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
    <?php
    wp_body_open();
    echo $do_blocks_pattern_content;//phpcs:ignore
    /* Wp footer */
    wp_footer();
    ?>
</body>
</html>
editandpost commented 2 months ago

This continues to persist, but it's exceptionally odd. I'm attempting to exclusively use FSE so that my client can manage her blog layouts in the site editor. Let's say each blog post has a "card". That "card" should be used in the query loop as well as anywhere else the post gets displayed. FSE allows me to have a singular template part with a synced pattern inside it to display everywhere. This MOSTLY works perfectly until I have to interact with plugins. I'm currently trying to use:

block_template_part('block-post-single'); or do_blocks('');

to display the template part inside a plugin's filter, and while the actual CONTENT is perfect, and the inline styles ARE coming over, the formatting of the wp-container-core-group-is-layout-ID does not work because weirdly, the ID in wp-container-core-group-is-layout-ID actually changes when the page gets rendered. So at the outset, let's say that ID is 104, when the page rendering is complete, it ends up being 82 (as an example) and therefore, the CSS that does output for wp-container-core-group-is-layout-104 is irrelevant.

And even worse, the styling for layout 82 (which obviously would have been completely different) now applies to what should be ID 104.

(I hope this spaghetti is making sense).

If anyone has any thoughts on a workaround, I'd very much appreciate it.