Make WordPress Core

Opened 6 months ago

Closed 3 months ago

Last modified 3 months ago

#59673 closed enhancement (fixed)

Add viewStyle block.json property for frontend-only block styles

Reported by: gaambo's profile gaambo Owned by: gziolo's profile gziolo
Milestone: 6.5 Priority: normal
Severity: normal Version: 6.4
Component: Editor Keywords: has-patch has-unit-tests needs-dev-note
Focuses: Cc:

Description

Based on GitHub issue 54491 for Gutenberg - see below why created here as well.

What problem does this address?

At the moment block.json allows adding styles and editorStyles - where the assets of style are loaded in the editor and in the frontend. There's no way to add styles which are only added in the frontend. Not having this assumes, frontend styles can be used 1:1 in the editor. I've encountered many situations where that's just not true - it has gotten a lot better with the apiVersion: 2 blocks, but there are still many cases where I want to enqueue a style only in the frontend. Examples:

  • Very complex blocks - where I will develop a very specific block editing experience in the editor with components and editor styles and want to load the "real" styles for the (dynamically) rendered block only in the frontend.
  • JavaScript-heavy frontend - the most basic example being slider. I will have a lot of CSS which only styles the JS-initialized version of the block and they just don't need to be loaded in the editor.
  • There are cases where the frontend styles are just not used in the editor (and the block-developer knows that while developing), so it's a performance slow-down if you have many such blocks. But there are also cases where the frontend styles may just "destroy" the editing experience of a block because they just don't work in that context.

What is your proposed solution?

For scripts there's already script, viewScript and editorScript. #33542 also brought parity to those so all of those support the same values (file paths, asset handles, one or multiple).
Therefore I propose a viewStyle property which works just like the viewScript property but for styles.
The style property should stay the way it is now (load in frontend + editor).
See GitHub issue #33542 and GitHub issue #41236 for prior discussion.

Why trac ticket?

It seems only the schema of block.json and documentation is in the Gutenberg repository. The code to load those assets is in core in register_block_type_from_metadata. Therefore a trac ticket seems the better place instead of GitHub.

Change History (12)

This ticket was mentioned in PR #5531 on WordPress/wordpress-develop by @gaambo.


6 months ago
#1

  • Keywords has-patch has-unit-tests added

Adds a viewStyle property for block metadata to allow registering stylesheets/handles, that will only be enqueued on the frontend if a block is rendered (not in the backend). Similar to viewScript.
See trac ticket for more information.

Trac ticket: 59673

#2 @gaambo
6 months ago

I've added a PR which adds the viewStyle handling to core.

  • Added asset handle generation and asset registering
  • Added asset enqueueing in the frontend
  • Added property to REST API for blocks
  • Added php unit tests

How to test

I've created a simple test block which uses the new property here: https://github.com/gaambo/test-block-viewStyle

  1. cd src/wp-content/plugins && git clone git@github.com:gaambo/test-block-viewStyle.git
  2. npm run dev
  3. npm run env:start && npm run env:install
  4. Enable the "Test Block" plugin
  5. Create a new post and insert the "Test block"
  6. In the editor the block should have a green background (as set in the editorStyle editor.scss)
  7. Save the post. In the frontend the block should have a red background (as set in the viewStyle view.scss)

You can't check the network tab in developer tools for loaded assets, since both are so small and are inlined.

Alternative: Use your custom block and add a viewStyle property in block.json. The property has the same schema as style and editorStyle - so a singular string or array is allowed and style handles as well as file: links to files. See the test block repository above for an example.

TODO

Gutenberg

  • In Gutenberg we need to add the viewStyle property to the block.json schema. See GitHub issue https://github.com/WordPress/gutenberg/issues/54491
  • In Gutenberg probably the @wordpress/scripts package needs to be adapted to read viewStyle property from block.json to look for assets to build and link.

What's the process of adding such changes to Gutenberg while changes for the property handling are added here in trac?

Tests

  • At the moment there are no e2e/phpunit tests which check if viewStyle/viewScript get only enqueued in the frontend. Should I add tests for that? And if yes, could someone help me where they have to go? Are those e2e? Are there some other tests testing the rendering of blocks? The unit tests only check if the path registered in wp_scripts is correct.

Core blocks

  • I didn't add any special handling for core blocks, since no core block uses viewStyle obviously. But in the future that might be the case. So I think the phpunit tests checking for the correct core styles to be loaded in regard to should_load_separate_core_block_assets must be adapted. But I'm not fully sure I understand those. Maybe someone can help me with that.
Last edited 6 months ago by gaambo (previous) (diff)

#3 @gaambo
6 months ago

Added a PR for the Gutenberg part here: https://github.com/WordPress/gutenberg/pull/55492
Actually it's just the schema + documentation changes and adding it to the create-block package. The @wordpress/scripts packages needs no changes as far as I can see.

#4 @gziolo
6 months ago

  • Milestone changed from Awaiting Review to 6.5
  • Version set to trunk

Actually it's just the schema + documentation changes and adding it to the create-block package. The @wordpress/scripts packages needs no changes as far as I can see.

Yes, I tested what happens when you import a style inside the viewScript (src/view.js or similar) for the block scaffolded with @wordpress/create-block. It simply creates a CSS file with the same name as the entry point, so in the example it's build/view.css. No further changes are necessary.

#5 @gziolo
3 months ago

  • Keywords needs-dev-note added

#6 @gaambo
3 months ago

Thank you @gziolo, for moving this forward.
I guess apart from the code-changes in core, especially documentation in Gutenberg would be important. I've left my PR there in draft status still, because I wasn't sure if there should be more discussion whether this should be included or not: https://github.com/WordPress/gutenberg/pull/55492/

#7 @gziolo
3 months ago

Excellent, @gaambo. I need two-three days to land your changes in WP core. Then we can discuss next steps on Gutenberg PR.

#8 @gziolo
3 months ago

I didn't add any special handling for core blocks, since no core block uses viewStyle obviously. But in the future that might be the case. So I think the phpunit tests checking for the correct core styles to be loaded in regard to should_load_separate_core_block_assets must be adapted. But I'm not fully sure I understand those. Maybe someone can help me with that.

That one is indeed a complex one. It isn't an issue at the moment, but I expect that if we were to use viewStyle for core blocks we would have to provide two versions of CSS. The bundled one that would get registered separately and the regular one should work out of the box.

At the moment there are no e2e/phpunit tests which check if viewStyle/viewScript get only enqueued in the frontend. Should I add tests for that?

It would be nice to add unit tests as follow up. I'm not entirely sure how to approach it as we would need to print the HTML for a page using block theme that renders a custom block that defines viewStyle and viewScript. Something, that would be useful in general.

#9 @gziolo
3 months ago

  • Owner set to gziolo
  • Resolution set to fixed
  • Status changed from new to closed

In 57493:

Editor: Add viewStyle property to block.json for frontend-only block styles

Related issue in Gutenberg: https://github.com/WordPress/gutenberg/issues/54491.

For block scripts there was already script, viewScript and editorScript. For block styles there was only style and editorStyle. This brings the parity.

Props gaambo.
Fixes #59673.

#11 @gaambo
3 months ago

Thank you very much @gziolo!

I didn't add any special handling for core blocks, since no core block uses viewStyle obviously. But in the future that might be the case. So I think the phpunit tests checking for the correct core styles to be loaded in regard to should_load_separate_core_block_assets must be adapted. But I'm not fully sure I understand those. Maybe someone can help me with that.

That one is indeed a complex one. It isn't an issue at the moment, but I expect that if we were to use viewStyle for core blocks we would have to provide two versions of CSS. The bundled one that would get registered separately and the regular one should work out of the box.

Should this be handled in core or in Gutenberg?

At the moment there are no e2e/phpunit tests which check if viewStyle/viewScript get only enqueued in the frontend. Should I add tests for that?

It would be nice to add unit tests as follow up. I'm not entirely sure how to approach it as we would need to print the HTML for a page using block theme that renders a custom block that defines viewStyle and viewScript. Something, that would be useful in general.

Same question as above. Also: My experience with writing tests is minimal, not sure how we'd build and print HTML in unit tests to account for that. I would be glad to help or learn, if somebody is willing to guide me through it.

#12 @gziolo
3 months ago

Should this be handled in core or in Gutenberg?

No need to do anything for now.

Same question as above. Also: My experience with writing tests is minimal, not sure how we'd build and print HTML in unit tests to account for that. I would be glad to help or learn, if somebody is willing to guide me through it.

Maybe we could cover it with e2e tests in Gutenberg by registering a custom plugin, like the one I used to test changes.

Note: See TracTickets for help on using tickets.