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

Assign unique IDs to blocks that persist in the Wordpress database #10157

Closed
korynorthrop opened this issue Sep 25, 2018 · 10 comments
Closed

Assign unique IDs to blocks that persist in the Wordpress database #10157

korynorthrop opened this issue Sep 25, 2018 · 10 comments
Labels
Needs Technical Feedback Needs testing from a developer perspective. [Type] Help Request Help with setup, implementation, or "How do I?" questions.

Comments

@korynorthrop
Copy link

korynorthrop commented Sep 25, 2018

If I understand correctly, blocks do have a unique ID, but they only exist in the editor, are not saved in the database, and change every time the editor is reloaded. My goal is to monitor changes to the blocks in a post (e.g. changes to the copy in a paragraph block, the re-ordering of blocks within the content area, the selecting a different photo in an image block, etc.) and trigger actions that would affect a different post that is associated with it. The purpose is to help keep manually translated posts of a multi-language website up-to-date whenever the posts in the original language are modified. Perhaps my use case is unique and not indicative of other developers' needs, but I can imagine this being useful for others as well.

I would love to see a unique ID associated with each block object that doesn't change, can be accessed in the editor (at minimum), and potentially be accessed server-side.

Right now I'm using apiFetch() in a custom block to get the raw content of the original language post. I figure I would parse the content and save its checksum in the block's state or as an attribute. The original checksum can be compared with a new one whenever a change is detected in the original post. Having unique block IDs available will allow me to associate blocks in the translated post with the equivalent block in the original post so that when a change is made to the original post I can isolate which block(s) need to be updated in the translated post.

Perhaps the blocks.getSaveContent.extraProps filter is the appropriate place to add an ID, but I wasn't sure if it would help accomplish my goal.

@designsimply designsimply added [Type] Help Request Help with setup, implementation, or "How do I?" questions. Needs Technical Feedback Needs testing from a developer perspective. labels Sep 26, 2018
@mcsf
Copy link
Contributor

mcsf commented Oct 3, 2018

Permanent block IDs are not something we expect to have in Gutenberg. There are many ways in which we could argue this, the first of which based on the idea of block identity and how identity changes over time — over editing, conversion, splitting, merging, etc. Indeed, introducing so-called permanent block IDs would place Gutenberg in a hard contract with the developer, as guaranteeing this permanence would be impractical given the fundamental discrepancy in how the data is actually saved in the backend (as a single post in post_content). The notable exception to this is Reusable Blocks, whose instances are individually saved as wp_block posts in the backend.

With this preface, I should now ask: why is tracking individual blocks necessary to the solution you seek? From a translator's perspective, context is crucial, and I'd expect to work on an entire post or page when updating translations. Thus, if only a block is changed, I'd still expect to update the translation by looking at the entire page — though complementary visual diffing tools could be helpful to pinpoint the changes, obviously.

@korynorthrop
Copy link
Author

Thank you for your response @mcsf. I can understand the reasons why y'all don't want to have permanent block IDs. My interest in tracking individual blocks is to be able to pinpoint what changed in the original post and develop a way to flag and inform our translators which blocks in the translated posts are affected by the change(s) in the original. There's probably a more elegant and straightforward approach to solving this, but I am struggling to conceptualize one.

@mcsf
Copy link
Contributor

mcsf commented Oct 5, 2018

@korynorthrop, all things considering, I think an easier way would be to look at this on the server upon saving changes to a post using diffing tools, however unexciting this sounds. :)

You could either diff the whole post based on the last revision, getting no benefits from Gutenberg, or you could separately parse the revisions for their block lists and operate on that. Advantages include being able to exclude changes that shouldn't affect translators (e.g. if the block changed is a layout element like core/spacer, ignore; if the block changed is of type core/image and the attributes changed don't include alt or caption, ignore). The right diffing algorithm should be able to track block movements with some acceptable accuracy.

@mcsf mcsf closed this as completed Oct 5, 2018
@korynorthrop
Copy link
Author

@mcsf thank you for your thoughts on this and for taking the time to respond.

@dikium
Copy link

dikium commented Jan 12, 2021

Hi! I'm having this idea too. My goal is to add comment section to each block of an article. And i have no other way except storing each block id in the database. How can i do this? May be i can add such attribute to each block? But what is the better way? Thanks!

@mcsf
Copy link
Contributor

mcsf commented Jan 12, 2021

Hi!

I think any approach that tries to ascribe unique identifiers to blocks will at some point leak, especially when dealing with text or transformations, so I recommend moving with care and acknowledging the trade-offs involved.

If you'd like to use IDs, then the most straightforward way would be to extend all available block types so that they support an extra attribute, e.g. dikium_block_id. This can be done client-side using the blocks.registerBlockType hook.

That said, do consider that this is more than a technical issue. There is an ontological question behind "permanent block IDs", as I tried to articulate in #10157 (comment). More sophisticated solutions could track blocks based on similitude of content. This is something we see in good diffing tools — for instance, when I silently move and edit a file within a Git repository, Git is still capable of recognising the new file as an edited and renamed version of the former.

@tiennguyenvan
Copy link

@korynorthrop
I am developing a custom style panel which will generate CSS for blocks and I need to constraint the effect of the styles inside each block (and their nested children) only.

So that's why I tried to saved the clientID to a customID attribute. Everything worked very well until I realized that if users duplicate a block (via the duplicate menu), the customID on the cloned block will be the same as the original block's.

I would like to ask if you found any way to have an unique ID attribute for your blocks?

Thanks a lot.

@kory-northrop
Copy link

@tiennguyenvan my team and I abandoned our efforts to use unique IDs for the blocks, so I don't have an answer from personal experience. Would it be feasible for you to hook into the block duplication event and modify the original block's ID and save the modified ID to the duplicated block's custom attribute?

@tiennguyenvan
Copy link

@korynorthrop Thank you very much for the reply.

I still cannot find a hook for the duplication event. So I modify the block custom ID attribute every time it is selected if there is a duplicated ID from all other blocks.

@kory-northrop
Copy link

@tiennguyenvan while these aren't existing solutions, there is some conversation about creating a filter/hook for the block duplication and copy events: #49464 and #49463

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Technical Feedback Needs testing from a developer perspective. [Type] Help Request Help with setup, implementation, or "How do I?" questions.
Projects
None yet
Development

No branches or pull requests

6 participants