Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block supports and dynamic rendering in JS and PHP #54047

Open
andrewserong opened this issue Aug 30, 2023 · 5 comments
Open

Block supports and dynamic rendering in JS and PHP #54047

andrewserong opened this issue Aug 30, 2023 · 5 comments
Labels
[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Type] Enhancement A suggestion for improvement.

Comments

@andrewserong
Copy link
Contributor

andrewserong commented Aug 30, 2023

Part of #53874

A number of block supports currently rely on server side rendering to generate frontend styles. This means that our serialization function (serialize) doesn't produce HTML that is ready to be rendered while including all styles. While in WordPress this can be beneficial so that block supports are dynamically generated at render-time via PHP, for 3rd party editors, a solution should be provided where these styles can be automatically injected at render-time via JS, to produce final render-ready HTML.

The task

Provide a way to generate the final HTML including styles (some kind of render function) that can be used by third-party JS editors. This code already exists and is being used to generate these styles in the editor. A solution could be introduced to allow the generated styles to be output in the editor, but to also be (optionally) output during serialization / render.

The generated styles for block supports includes (but is not limited to) inline styles within block markup, svg markup to be appended to the end of the HTML markup, and style tags / CSS intended to be output alongside the markup.

Block supports that depend on server-rendering include

  • Duotone
  • Elements styles
  • Layout
  • Position

For example, currently the Layout block support uses a portal to output generated layout styles in JS, running on a filter over editor.BlockListBlock:

return (
<>
{ shouldRenderLayoutStyles &&
element &&
!! css &&
createPortal(
<LayoutStyle
blockName={ name }
selector={ selector }
css={ css }
layout={ usedLayout }
style={ attributes?.style }
/>,
element
) }
<BlockListBlock
{ ...props }
__unstableLayoutClassNames={ layoutClassNames }
/>
</>
);

What if there was a parent function of some kind that performed similar logic, but that could output both in this filter for the editor, as well as when blocks are saved or rendered in JS for a 3rd party editor's frontend output. That output could either be dynamically generated in JS, or that JS could generate the HTML, and a 3rd party could store it in their own database somewhere, depending on the 3rd party's requirements.

Task breakdown

TBC, but some questions include:

  • What might the API for this look like?
  • How to ensure each block support's unique needs are covered by it.
  • Can a 3rd party easily switch the behaviour on-or-off to cover 3rd parties that do want to include styles, and those that do not (e.g. output that just wants semantic, unstyled markup for newsletters or feeds)
@andrewserong andrewserong changed the title Block supports and server side rendering: A lot of recent features of the block editor (theme.json and block supports) rely on server side rendering to generate the frontend styles, even for static markup and static blocks. This means that our serialization function (serialize) doesn't produce an HTML that is ready to be rendered. Provide a way to generate the final HTML including styles (some kind of render function) that can be used by third-party editors. This code already exists and is being used to generate these styles in the editor, but we should make sure to document properly for third-party usage. Block supports and dynamic rendering in JS and PHP Aug 30, 2023
@andrewserong andrewserong added [Type] Enhancement A suggestion for improvement. [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi labels Aug 30, 2023
@andrewserong
Copy link
Contributor Author

Note the work in #52888 could help quite a bit here, as it's looking to inject styles into EditorStyles rather than using a portal. If that approach winds up landing, perhaps that could be used as the basis for also outputting styles for the final rendered output for 3rd party editors?

@youknowriad
Copy link
Contributor

Thanks for the issue, it's looking great.

Can a 3rd party easily switch the behaviour on-or-off to cover 3rd parties that do want to include styles, and those that do not (e.g. output that just wants semantic, unstyled markup for newsletters or feeds)

I think it's fine for block supports to be opinionated about how they're supposed to be rendered (within the saved markup or not). Switching is not a high priority for me, it might be a good thing to have for historic block supports that we want to "switch" to server for instance or things like that.

@ramonjd
Copy link
Member

ramonjd commented Aug 31, 2023

Provide a way to generate the final HTML including styles (some kind of render function) that can be used by third-party JS editors.
How to ensure each block support's unique needs are covered by it.

Talking about blocks specifically, would we also need a JS to handle what PHP render functions currently do for blocks that skip serialization for some block supports? Examples could be the search or gallery blocks.

@youknowriad
Copy link
Contributor

Talking about blocks specifically, would we also need a JS to handle what PHP render functions currently do for blocks that skip serialization for some block supports? Examples could be the search or gallery blocks.

IMO, the question we should ask ourselves is: Is this block a "universal" block? Is a block that any block editor could be using? If the answer is yes, I think any dynamic rendering we choose to do for "optimization" reasons in WordPress should have a JS equivalent in this new "render" function.

I suspect that sometimes the answer to the question above is:

  • Yes the block is universal but we also want to augment this block with WP specific logic/behavior.

In this case, third-parties should be able to consume the block without these additional behaviors (either in terms of "edit" or "save") and in WordPress, we should be able to "augment" the block with these extra features. Also, third-parties might also decide to "augment" the block with similar features with their own implementation. An example to come to my mind here is the "Image" block. Think about how by default this block doesn't show an "upload" button but if the block editor provides an implementation for the "uploadMedia" function, the block starts allowing uploads. WordPress defines its own implementation function, and say Drupal could implement a separate one. So here we're augmenting the block by implementing a block-editor setting but I suspect that we could also do that by filtering the block or things like that.

@MadtownLems
Copy link

I'm not entirely sure if this is the best place for this, but I wanted to share a recent dev experience I had that felt like things should be much easier 😅

I wanted to use wp_remote_get to fetch a post from a different website (that we also run, thankfully) using the REST API. While it was trivial to get the html markup of the post, in contained dynamically generated markup such as .wp-elements-123456789, with no way to get the corresponding inline CSS required to actually display it as originally intended.

I ended up adding a custom field to the REST response that included the inline css (via wp_style_engine_get_stylesheet_from_context( 'block-supports' ); ), and then manually output that CSS after the post's HTML markup where I was using it - but the whole thing felt very wrong and possibly fragile going forward. Fetching a post with its dynamically generated styles should be much easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

No branches or pull requests

4 participants