Block registration: offer option to register a block only in a specific editor
This issue is part 2 of a larger discussion spanning multiple issues, about the potential issues plugin authors may face when developing blocks that rely on the @wordpress/editor dependency.
- This trac ticket is part 1: it suggests an option to make conditional asset enqueuing easier in the different block editors. This is a way to work around the problem.
- In part 2 (this very issue), I would like to suggest an option to declare support for specific editors at block registration. This would address the root issue imo.
What problem does this address?
Today, when enqueuing assets for a block registered in a plugin, one can rely on block.json or hook into the enqueue_block_editor_assets hook to enqueue necessary scripts and styles in the block editor.
This works well, but offers some challenges with some specific blocks. For instance, your block may rely on the @wordpress/editor dependency to handle some of its functionality. That dependency is available in the post editor, but cannot be used in the widget editor or the site editor.
See #53569-trac and #33203 for more information on this topic.
In this situation, the block you registered ends up enqueuing the wp-editor dependency everywhere, thus triggering the warnings added in #53569-core, even though you may not have intended for that block to be available in the site editor or widget editor. It may not even be a block, it could be a plugin you've registered with registerPlugin, that you meant to only appear in one of the publish panels.
What is your proposed solution?
I've recently opened #57421-trac to offer a way to conditionally enqueue scripts when using enqueue_block_editor_assets. I think that can help, but I think it only brings up half way there.
Ideally, when registering a block or a plugin, I would want to declare support for the site editor / widget editor / post editor, or exclude my block / plugin from specific editors so its JavaScript (and its dependencies) would automatically never be enqueued there.
What do you think of the idea? Is there a way to do that today that I'm missing?
Going to tag in some folks who I think might have some interesting thoughts/ideas cc @ryanwelcher @adamziel @dmsnell
Thanks @annezazu for the invite.
Thought about this over the weekend and here are some of my inadequate responses:
- it's a bit dizzying following the conversation around the various PRs and tickets. I don't think this is anyone's fault, but it would be helpful to have a header on all the related tickets listing each related ticket/issue/PR, a link to it, a summary of what role it plays, and an indication for where the canonical discussion should take part (e.g. "Please discuss this change at {link} to avoid duplicating in all these places.")
- the
admin_enqueue_scriptshook uses the$hook_suffixname for its parameter but it looks like we're using$hookin this proposal. Is there a reason to use two names for what I think is intended to be the same value and serve the same purpose? - doesn't seem like this is a very risky change, though if we're only exposing a
globalparameter, what is the value of the abstraction over the counter-example, where a function implementing theenqueue_block_assetshook itself pulls in theglobal? - if we're talking about adding parameters to the hook, do we reasonably predict any others might come in the future? if so, does this one warrant being in the first/front argument position? would an associative array or "option bag" argument better serve it?
Sharing thoughts given the ask, but I don't have strong feelings here. I think from what I can see my biggest question revolves around the motivation for adding this. That is, if you are looking for critical feedback, I propose asking if it's adding much over directly adding global $pagenow; to one's own enqueue_block_assets
it's a bit dizzying following the conversation around the various PRs and tickets.
Let me see if I can try to clarify things a bit. I would suggest keeping the conversations in 2 places:
- In the trac ticket for discussions about asset enqueuing.
- Here for discussions about block registration
I've updated this issue description to add the header you suggest. I cannot do the same for the Trac ticket though; if you have that option, feel free to edit my ticket description!
1. The workaround
This would be better discussed in the trac ticket imo.
We can at times work around the root problem by only enqueuing assets in the right editor.
- This is something plugin authors can already do in their own code by adding
global $pagenow;, as you mentioned. - We could consider adding an extra parameter to
enqueue_block_editor_assets, as I suggest in the trac ticket.
I've added a comment to the trac ticket with your questions and my answers.
2. The root problem
This is what I think would be worth discussing here
In some scenarios (e.g. when relying fully on block.json and letting core take care of enqueuing assets for us), a plugin author may not have the option to conditionally enqueue their block's assets in the right editor. The workaround won't be useful to them.
In those scenarios, when registering a block or a plugin, it would be nice if plugin authors add an option to declare support for the site editor / widget editor / post editor. Core would then enqueue the assets accordingly.
@jeherve, thank you for starting the conversation. I added this issue as an item in Block API: Tracking issue. If we had this mechanism in place, we could take advantage of it for some of the core blocks like:
- Classic block would load only in the post editor
- we could avoid explicitly excluding blocks like Template Part or Post Content from the post editor
- on the widgets screen, we exclude a lot of blocks, we also register only in that context special Widget blocks
It might be not trivial to cover all those use case, but the developer experience would be excellent when you could just list supported editors as proposed.
I also wanted to note that this issue is related to #41062, which proposes allowing/denying block use based on post-type or template context. In some cases, providing a post type would be equivalent to limiting access to the post editor, and providing a template would be equivalent to limiting access to the site/template editor.
Sharing a very relevant comment from @dinhtungdu left under https://github.com/WordPress/gutenberg/issues/41062 that was closed as duplicate:
In https://github.com/woocommerce/woocommerce-blocks/issues/6342, the Mini Cart block is excluded from the Post Editor and included in other screens. But if the store admins edit a page template using the edit link in the Templates Panel (which opens a Template Editor), the popup editor doesn't include the Mini Cart block because the screen is still the post edit screen.
I tried using the editor context with the
allowed_block_types_allfilter to register blocks conditionally but it doesn't work with the embedded Template Editor, the filter is only fired for the initial load when the admins edit a post/page.