Replies: 14 comments 34 replies
-
Exciting! First question I'd ask if whether we'd need to distinguish between partial and full syncing? Could we instead make use of the already familiar locking experience? e.g. a pattern is either synced or not, if it is, you can lock certain blocks that you don't want to be editable. |
Beta Was this translation helpful? Give feedback.
-
It seems the ideal solution is to actually "mix" the source with the saved pattern on the server. The problem is that we don't have "full parsing" in the server just yet. Meaning we can't extract and update the blocks in the server sing the format you proposed above. So:
|
Beta Was this translation helpful? Give feedback.
-
This isn't how I imagined it would work. I want to draw attention to an example shared in another issue that I think would struggle to fit into the above format. In the linked screenshot, the orange text is intended to be locked and not editable, while the black text is editable. I also think that users and theme authors should be able to use the full suite of lock types to compose partially synced patterns, not just the content lock. The linked example would probably use a template lock on the right-hand column, an individual lock on the left-hand heading and a content lock on the columns block. For cases like these, each block in the pattern instance needs to indicate where it sits in relation to other blocks within the pattern. It seems to be the same task that was identified in the phase 3 roadmap of making post revisions "aware of individual blocks" and able to "roll back individual blocks." In my view, partially synced patterns could automatically invoke the "roll back" procedure to keep themselves in sync. Thinking more broadly, automatic "roll back" could also be used to prevent changes to locked blocks directly within a post, e.g. through code view. The key difference with partially synced patterns is that the "roll back" would be based on the pattern source rather than the previous revision of the current post. As others identified, though, the same procedure would need to run on both the client-side and server-side. |
Beta Was this translation helpful? Give feedback.
-
To try and help with exploring/testing possible implementations of this I have added a PR here which adds an experimental flag for Pattern block enhancements. As a starting point if the flag is enabled and a Pattern has a Patterns without the |
Beta Was this translation helpful? Give feedback.
-
I am wondering what would/should happen when a block in the source pattern is transformed. How would such a change be synced? Would a block level key system provide enough info or would it need a attribute level key system? |
Beta Was this translation helpful? Give feedback.
-
I've the description with some of the feedback. Notably including the ideas from @gziolo's post on how the source patterns could indicate which parts of the pattern can be replaced (see: #50456 (reply in thread)), and how they would be transformed. |
Beta Was this translation helpful? Give feedback.
-
Hello all; some great conversation here exploring the design space. Yesterday I spoke with @gziolo at length on a call and wanted to share some ideas we discussed. I've been watching this issue and thinking a lot about it for some time. Starting a new discussion thread here to escape some long reply chains. I'm very consistently confused trying to understand the various proposals and problem statements and solutions. Much of this surely stems from the large combination of extremely generic words: "block," "pattern," "sync," "partial sync," and "content." I sympathize very much here because I find it incredibly difficult myself to talk about any of this without falling back to these same overloaded terms. I will try to be specific here, but I do believe that the lack of clarity around our vocabulary indicates that we still have opportunity to better understand what we want. I'm also confused because I think many of the conversations (both in this thread and also in other issues and places) talk about at least three separate concepts as the same thing, or at least we talk about three different purposes for creating these things we want to mix and match:
I want to propose another concept that I believe could ease the confusion. This new concept is (again for lack of less generic wording) a kind of block templating. We have talk about separating data and presentation, but when I assess some of these proposals what I see is not a real separation, but pushing "data" or "content" into the block JSON attributes while leaving it coupled with the presentation inside the same block. A real separation completely severs that blocks that provide inner content from the block specifying where they belong. We also have a framework in place that lets us do this: inner blocks. Much of the confusion stems from the fact that we have no solid way to declare placeholders for content. This is a problem we've been actively working on solving and have multiple candidate solutions for. What @gziolo and I discussed essentially forms around a template block whose first inner block is the "format string" just as it is in This simple idea only relies on existing code and existing concepts, apart from the placeholder, which itself could be created as another block whose type means "I am a content placeholder." What are some of the prime motivators behind such a structure?
This is trivial to handle on the server render because it embraces the same data design language that powers blocks. Everything is just a block. It's also a heavy up-front cost because we have to design new flows in the editor to properly display and edit these templates, but then again, we have to do a fair amount of that either way regardless. The entire problem of diffing patterns and auto-updating derived patterns is a difficult task I think is best scoped out of the one of solving the "synced patterns" problem. Specifically there's no automated way we can determine what the right thing to do is; plus there are a host of simple solutions that let a site author determine the best resolution, because we can know that patterns updated without trying to resolve inherent ambiguities. In the given approach, by separating the format block from the data placeholders we can choose to have the format as This comment is radically terse for what I'm tossing out there, but it's long enough and I wanted to share this as an alternative way of thinking about the problem, a way which fully embraces the block model and pushes it into templating. There are more challenges and more benefits, but I believe these challenges are solved or mostly solved. Happy to discuss further. |
Beta Was this translation helpful? Give feedback.
-
One use case I was pondering, which may or may not be valid, but which may affect the implementation detail, is the injection of custom content into the pattern from an external source rather than from a user interaction. One use case of Patterns I can see is for the addition of unique starter content that is generated by AI. There is some debate about whether it is better to get AI generated content from an LLM as structured JSON rather than the full block syntax. If it is some sort of JSON structure, then for the likes of site starter content you might say "I want a cover block for a coffee shop called Dan's Filter Coffee" and instead of getting cover block syntax you would instead get something like: {
"block":"home-cover",
"content": {
"heading": {
"content": "Dan's filter coffee"
},
"paragraph": {
"content": "If you hate filter coffee then you obviously haven't tried Dan's"
}
}
} This could then easily be injected into the pattern by overriding the relevant attributes if using the approach outlined by @talldan and @gziolo, but it seems like it would take more of a search/replace approach if using the placeholder approach @dmsnell suggests. But I may be overlooking something, and as mentioned, this may in fact not be a valid use case, just putting it out there in case it is something we need to take into account. |
Beta Was this translation helpful? Give feedback.
-
There is one more important consideration that I discussed this week at length with @ellatrix and @dmsnell, how to handle the case when someone deletes the pattern that provides the design/presentation aspect of the Partially Synced Pattern. Today, the problem doesn’t exist because we always copy/detach the blocks when inserting the pattern. In the case of Reusable Blocks, we only store the It gets more nuanced when entering the world of blocks that store unique input from users and only reference the design aspect. Do you think that site authors will feel comfortable showing nothing on the site when they can’t load the design? What sources for the pattern’s design do we plan to offer? Some possibilities:
If necessary, we could always create a local copy of the pattern as soon as it gets used with the Partially Synced Pattern. |
Beta Was this translation helpful? Give feedback.
-
I briefly explored the option of adding a Pattern Part block as a way of keeping changes to individual block content/settings much closer to the block in question rather than pushing them up to the parent Pattern block and then having to track which block it came from. However, it adds a lot of layout issues and complexity in the Editor with all the additional divs added. It may be possible to make them useful without needing to show them in the Editor, but not sure how, so have shelved them for now. Just noting here as a record of things that have been explored. |
Beta Was this translation helpful? Give feedback.
-
I wanted to reshare my #50649 (comment) for visibility. I left it under the exploration from @talldan where he was trying to synchronize inner block attribute updates to a partially synced parent pattern block. I've been playing with two different prototypes to see whether we can avoid changing the block editor store and/or overloading First, I started with #50777 implementing the concept of converting all template content data into virtual blocks named I switched to another prototype that is still in progress, but you can watch the progress in #50901. It should be compatible with the ideas explained by @dmsnell, because the PR concentrates on the editing experience by storing a local copy of the pattern with edits applied to the content. I'm trying to understand how we can build the editing workflow in the block editor that allows to merge the design coming from one pattern with the content coming from another pattern. My initial conclusion is that the simplest model for editing would be the one that always uses the local copy of the pattern providing the design (from Some high-level thoughts based on the explorations above.
|
Beta Was this translation helpful? Give feedback.
-
Like @gziolo says
Maybe you can have a kind of a 'attributes bridge' to sync your Patterns. I don't have any clear idea's on how to tackle this but for a starter i made a kinda example of syncing and unsyncing attributes between blocks and patterns. It would be nice that you can sync & unsync styles as well content |
Beta Was this translation helpful? Give feedback.
-
I have had a look at whether the connecting block attributes and custom fields might be a way forward for implementing partial syncing of patterns, and it looks like it has potential: partial-sync.mp4In the above, I just enabled the
Of the implementation options discussed so far this currently seems like the best approach to follow. What do others think? |
Beta Was this translation helpful? Give feedback.
-
I have added a tracking issue for the work around using custom fields for partial syncing. |
Beta Was this translation helpful? Give feedback.
-
Related: #48458
The concept of partial syncing of patterns has been discussed in #48458. There's a good idea of the goal, but a challenge has been developing a mental model for how this might work technically. I think it's worth writing down ideas for how it might work, and hopefully this will allow all contributors to discuss and develop the idea, and have some alignment.
The thoughts here are mostly developed from conversations with various contributors across github issues, prs and other discussions. This is an attempt to piece it all together.
The Goal
Today, when you insert a pattern, the blocks from that pattern are completely decoupled and standalone. There's no way to tell that those blocks originated from a pattern, especially since they can be edited to no longer resemble the source pattern.
Partially synced mode is different. When a pattern that's partially synced is inserted, it retains a reference to the source pattern. The blocks within the pattern are locked so that they cannot be removed or reordered and new blocks cannot be inserted (this is called
contentOnly
locking). Only specific parts of the pattern considered 'content' can be edited (denoted by adding__experimentalRole: 'content'
to a block's definition).When the source pattern is updated, all instances of blocks that reference the source pattern are updated too (much like a reusable block), but the
content
values the user entered are retained. The best way to think of this is that the user can update the design of a pattern, but doesn't lose content that exists in templates and posts.Similar concepts
The concept of partial syncing could be considered as similar to the way a handlebars, mustache, or other templating system works.
In templating systems, an important part is that data is kept separate from the template markup. A developer can update the markup to something very different, but the data can still be interpolated into the template to produce resulting HTML. The same data can even be applied to different templates.
For partially synced patterns, I think it's also important that the data (the values of 'content' attributes) is kept separate from the template (the source pattern). This way, the data can be interpolated or injected into the pattern to produce the resulting HTML.
An implementation
Source pattern
Usually, a templating system includes tokens that indicate which parts can be replaced. e.g.
<h2>{{ callToAction.title }}</h2>
.For blocks, this could be achieved using a data attribute.
The
html
part of the attribute name (data-wp-pattern-html
) implies that the inner html of the tag can be replaced by a pattern block'sheading.content
data.This way, the pattern is still valid HTML and can contain fallback values.
Pattern blocks
So far, there have been explorations for making both the pattern and reusable block the one that has the partially synced mode. For this issue, I'll use the pattern block as the example, but it's arbitrary, and it could work the same way on either block.
A partially synced pattern block could exist in a user's content in the following way:
The attributes are:
wp_block
post typeThe other thing to note is that the block is dynamic and runs the interpolation process when rendering.
Rendering a pattern instance
When the pattern is rendered the data attributes are used to replace the data in the user's pattern.
The source pattern:
Is updated with the block's content data:
To produce the desired html:
Challenges
A big challenge is that when a user updates the design of the source pattern, they may do so in a way that makes it difficult to reconcile the pattern instance's
content
data and the source pattern's data attributes. They might reorder, remove blocks or add multiple blocks of the same type. An area for exploration will be ensuring the keys used in both places remain as correct as possible when the source pattern is modified.One positive is that if the user is updating a
wp_block
post type that's considered a pattern, it should be possible to detect where problems may occur by comparing the content attributes of the previous revision with those of the version the user is trying to save. It might be possible to offer tools for resolving issues if the UX can be made simple enough.I also don't have a clear idea of what the UX will be when a user updates the design of a pattern, I think this needs some design work.
Next steps
Let's discuss. Does this solve the problem? Any alternative ideas?
In terms of the implementation, I think the best option is to start by developing around the simplest possible use case. A very simple pattern that can be updated and only has a few content attributes. From that initial implementation it should be possible to start considering more advanced use cases.
cc @WordPress/gutenberg-core, @aaronrobertshaw, @glendaviesnz, @kevin940726
Beta Was this translation helpful? Give feedback.
All reactions