-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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 API: Allow for internal, non-duplicable block attributes #29693
Comments
I have similar problem. Here's my issue: #29694 I'm creating a form builder. I need a way to store reference to form id in database. When a block is made reusable it stores the reference, but if a user convert to normal block I need a way to detach the old reference in DB and create a new one. I've just discovered that there's a new |
Also related is the difficulty in declaring and using unique HTML ids within a block - #17246 |
I've been thinking about this and a possible solution I had in mind to try out involves these:
All the above are using experimental APIs though which were introduced here: #30469. I guess this could be okay though as the new functionality should also be experimental for start. |
This could also be relevant for the widget editors, which store an internal |
The related PR #28379. We discussed the potential new APIs for block attributes with @spacedmonkey on Twitter. Related thread: https://twitter.com/thespacedmonkey/status/1435530281595846663
The conclusion in the discussion is that "internal" attribute is more something stored in the memory during the block editor's runtime and
|
Not sure I understand this. What would a "secure location" be? |
I don’t know yet, too 😅 I understood that the value couldn’t be serialized to content as HTML, so it isn’t easily exposed. I also assume it should live somewhere in the database. I was trying to document potential options and their subtle differences. |
I've just opened #34750 borrowing the I think this issue may be trying to do too many things, largely because of my use of the loaded term Per @ntsekouras I like internal as an I think this would go a long way to addressing many of the use cases described here, excluding the |
Thank you for a quick follow-up 👍🏻
Feel free to edit the issue title and description according to the current direction of the PR you opened. It sounds like a good idea to open another issue to continue the discussion for other common scenarios that block authors have to deal with. |
Any update on this? |
Does copy+paste count as duplication event? |
Some other use cases for an API such as this were discussed in #23377. |
Any solution to this issue ? I’m creating a custom block and one of it’s attribute is a unique id which doesn’t have any UI, so that’s not editable by the user. It’s created automatically by useEffect hook on the component startup if that attribute is not set. If I duplicate the block then the attribute is copied too which makes a duplicate id. Is there any way so that I can detect if a block is being duplicated and generate a unique id and overwrite the duplicate id with the generated one programmatically ? |
Unfortunately not yet. Your use case is exactly the same with Query Loop block and |
@anver I had a similar problem for our Accordian block. We needed to generate unique ID's for use on the frontend. These were needed for aria labels and some frontend JS, etc. I put together a work around that appears to work. It's hacky but I think it will suffice for our needs for now. It's based on some great discussion here in a few issues and on what was done in the core heading block for generating anchors. Basically uses useEffect() combined with searching all the blocks in the editor to check for a duplicate id stored as a data attribute. If a duplicate is found it generates a new unique ID. That seems so far to work when a block is duplicated or copy/pasted, etc. bu-ist/bu-blocks#355. Example: |
@acketon Thanks for the right direction, i had to change few things on that code to make it work, but i had to ditch that completely and go for a reliable solution, finally I found a solution :) Thx for the comments bro. const getBlockCount = () => select( 'core/block-editor' ).getGlobalBlockCount();
let blockCount = getBlockCount();
useEffect( () => {
const unsub = subscribe( () => {
const newCount = getBlockCount();
if ( newCount === blockCount ) return;
blockCount = newCount;
const wrapper = select( 'core/block-editor' ).getBlock( clientId )!;
const formBlocks = wrapper.innerBlocks.filter(
( block ) => block.name === 'surveyboss/form'
);
const duplicates = formBlocks.filter( ( obj, index, arr ) =>
arr.find(
( innerObj ) =>
innerObj.attributes.formUuid ===
obj.attributes.formUuid &&
innerObj.clientId !== obj.clientId
)
);
if ( duplicates.length <= 1 ) return;
dispatch( 'core/block-editor' ).updateBlockAttributes(
duplicates[ 1 ].clientId,
{ formUuid: generateId() }
);
dispatch( 'core/block-editor' ).updateBlockAttributes(
duplicates[ 1 ].clientId,
{
metadata: {
...duplicates[ 1 ].attributes.metadata,
name: 'Untitled Form',
},
}
);
} );
return unsub;
}, [ clientId ] ); This is the part of the code i implemented and it just works fine. You got to put the effect in the parent of the duplicate components you are working with. |
What problem does this address?
Blocks cannot use attributes to store information that is
uniqueinternal to the block instance but also persisted across page loads. Here's an illustrative example:I'm working on the Jetpack
Pay with PayPal
block. It contains aproductId
attribute which uniquely identifies the actual product record referenced by the block. When a new block is inserted this attribute will be undefined; we hit the API to create a new product, and store the returned id in this attribute.When the block is duplicated, I'd like to create a new product record with identical fields (title/price/etc). But because the
productId
is cloned along with all the other attributes, both blocks will point to the same resource. It's possible to keep track of the block's uniqueclientId
and reset the product when this value changes — but while this detects block duplication, it also changes every time the post loads, and I only want to reset the product on duplication.What is your proposed solution?
A couple of options as a starting point for discussion:
unique
internal
attributes, which do not get copied during block duplication.The text was updated successfully, but these errors were encountered: