Skip to content

Instantly share code, notes, and snippets.

@KevinBatdorf
Created February 25, 2022 20:49
Show Gist options
  • Save KevinBatdorf/daec9345115279f1c9fe49deb589882f to your computer and use it in GitHub Desktop.
Save KevinBatdorf/daec9345115279f1c9fe49deb589882f to your computer and use it in GitHub Desktop.
Render WP block with inline styling - headless
<?php
add_filter('render_block', function ($block_content, $block) {
$block_type = \WP_Block_Type_Registry::get_instance()->get_registered($block['blockName']);
$support_layout = block_has_support($block_type, array( '__experimentalLayout' ), false);
if (! $support_layout) {
return $block_content;
}
$block_gap = wp_get_global_settings(array( 'spacing', 'blockGap' ));
$default_layout = wp_get_global_settings(array( 'layout' ));
$has_block_gap_support = isset($block_gap) ? null !== $block_gap : false;
$default_block_layout = _wp_array_get($block_type->supports, array( '__experimentalLayout', 'default' ), array());
$used_layout = isset($block['attrs']['layout']) ? $block['attrs']['layout'] : $default_block_layout;
if (isset($used_layout['inherit']) && $used_layout['inherit']) {
if (! $default_layout) {
return $block_content;
}
$used_layout = $default_layout;
}
$id = uniqid();
$gap_value = _wp_array_get($block, array( 'attrs', 'style', 'spacing', 'blockGap' ));
// Skip if gap value contains unsupported characters.
// Regex for CSS value borrowed from `safecss_filter_attr`, and used here
// because we only want to match against the value, not the CSS attribute.
$gap_value = preg_match('%[\\\(&=}]|/\*%', $gap_value) ? null : $gap_value;
$style = wp_get_layout_style(".wp-container-$id", $used_layout, $has_block_gap_support, $gap_value);
// This assumes the hook only applies to blocks with a single wrapper.
// I think this is a reasonable limitation for that particular hook.
$content = preg_replace(
'/' . preg_quote('class="', '/') . '/',
'class="wp-container-' . $id . ' ',
$block_content,
1
);
// This is all that's really being modified here
return $content . ($style ? '<style>' . $style . '</style>' : '');
}, 10, 2);
@KevinBatdorf
Copy link
Author

KevinBatdorf commented Jul 10, 2023

Sorry for the late reply. It seems to be working okay to me still though.

Another option would be to use pre_render_block and load them in yourself.

add_filter('pre_render_block', function($pre_render, $parsed_block) {
    // $pre_render is null
   
    // Get the block id somehow to use when registering the script below
    $id = 123;

    // Get the styles, possibly using the method in the gist above
    $css = 'body { color: red; }';

    wp_register_style("block-{$id}", false, [], null);
    wp_enqueue_style("block-{$id}");

    // WP style of safe echoing inline styles
    // See: https://github.com/WordPress/WordPress/blob/9ecfdd8e5a42ed4b66ffecb88321242717c89831/wp-includes/theme.php#L1920
    wp_add_inline_style("block-{$id}", wp_strip_all_tags($css));

    return $pre_render;
}, 10, 2);

Edit: Actually, that's not right. I forgot about the purpose of this gist :D The code above actually is for inlining new css into non-headless WP, so the exact inverse. Oops. Well, it's a good snippet to bookmark anyway. render_block should work still, but if you share some code broken I can try running it.

@qurtopianodesign
Copy link

Thanks a lot for the answer.
Let me explain, after upgrading to wp 6.2.2 the inline styles of wp-block-gallery are not exposed.
The rest works fine.

@KevinBatdorf
Copy link
Author

Is the $style var on line 26 empty? Or where exactly does it break down?

@qurtopianodesign
Copy link

I try to upload a screenshot
headless-styles

@KevinBatdorf
Copy link
Author

Weird. Not sure why it still works for me, but I may need to go and reconfirm it.

I think you will have to look into the render function and use the filter to pull in the styles another way.

https://github.com/WordPress/wordpress-develop/blob/trunk/src/wp-includes/class-wp-block.php#L293

Right now it's using wp_enqueue_style( $style_handle ); to enqueue all the styles

Maybe there's an easier way now to use that information to grab the styles directly. The filter can accept $block_content, $this->parsed_block, $this which should hopefully be enough context. Do you know what I mean?

@qurtopianodesign
Copy link

Yes of course, I understand you.
After that I'll do some tests by modifying the code.
However I can confirm that up to the wp 6.0 version it worked perfectly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment