You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Internal attributes behave like regular attributes except that they are:
Not serialised. Internal attributes won't be written to post_content and do not appear in serialize( block ).
Not persistent. Modifying an internal attribute does not create an undo level.
Not copyable. Duplicating a block will unset any internal attributes.
The motivation for this is to fix a longstanding issue we've had in Gutenberg which is that we use attributes to store "internal" state in certain blocks. For example an undo level is created when dragging-and-dropping an image or file into the editor because the blob URL is stored in the url attribute while the file is uploaded. I've included a fix for the File block (61ad707) to illustrate how this can be fixed using an internal_blobURL attribute.
I've also included fixes for two other issues to illustrate that there are many uses for such an API:
Removing the __internalWidgetId attribute in favour of an explicit _widgetId internal attribute. __internalWidgetId is how the widget editor tracks which widget entity should be updated when a block is modified. It's a hack that works because __internalWidgetId does not appear in the block.json and so is filtered out by serialize(). Using an internal attribute works exactly the same but is more explicit.
Allowing Menu widgets wrapped in a Legacy Widget block to be converted to a Navigation block. This is fixed by having the transform provide the Navigation block with the menu to convert via an internal _classicMenuId attribute. See Widget Importer: ensure it works with importing menus #47285.
The downside of this is that implementation details appear for all to see in block.json.
I wanted to re-share my comment #49391 (comment) where I expressed my sympathy towards this PR:
One potential solution could be to keep the temporary value in a separate attribute (transient one) and have the block fallback to that one when defined. It feels acceptable to me.
I'm leaning towards the idea shared by @youknowriad where the transient value should be represented as a separate attribute that is never persisted by the block editor. It's a very simple way to apply changes to the existing blocks that use transient values for showing media previews as exercised in #49457. In addition to that, it's a minimal change that adds only a flag to the definition of attributes which is the most convenient way for block developers. The API changes necessary in this PR would be more complex and difficult to explain in the documentation.
It's also an alternative approach to #34750 where @stacimc proposed extending the __experimentRole to cover also internal as one of the options. Example:
How do you feel about using role (assuming we stabilize this API) instead of a new internal field? It could be also extended with different values like metadata for storing information useful only during editing of the block like allowedBlocks or lock.
In effect, this PR could potentially close #29693.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Feature] Block APIAPI that allows to express the block paradigm.[Type] New APINew API to be used by plugin developers or package users.[Type] Technical PrototypeOffers a technical exploration into an idea as an example of what's possible
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
This PR is an alternative approach to #49391 and experiments with adding the concept of internal attributes to the block API.
Internal attributes behave like regular attributes except that they are:
post_contentand do not appear inserialize( block ).The motivation for this is to fix a longstanding issue we've had in Gutenberg which is that we use attributes to store "internal" state in certain blocks. For example an undo level is created when dragging-and-dropping an image or file into the editor because the blob URL is stored in the
urlattribute while the file is uploaded. I've included a fix for the File block (61ad707) to illustrate how this can be fixed using an internal_blobURLattribute.I've also included fixes for two other issues to illustrate that there are many uses for such an API:
__internalWidgetIdattribute in favour of an explicit_widgetIdinternal attribute.__internalWidgetIdis how the widget editor tracks which widget entity should be updated when a block is modified. It's a hack that works because__internalWidgetIddoes not appear in theblock.jsonand so is filtered out byserialize(). Using an internal attribute works exactly the same but is more explicit._classicMenuIdattribute. See Widget Importer: ensure it works with importing menus #47285.The downside of this is that implementation details appear for all to see in
block.json.