-
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
Pattern Overrides epic (WordPress 6.5) #53705
Comments
Thanks for exploring this! It looks great so far 👏 One thing that could be relevant here: In the custom fields experiment, we are connecting block attributes to custom fields, but it was designed to be connected to any other source. This means that, whenever it is needed, support for other sources could be added. I say this because we might want to consider "partial_synced_pattern" as a new source, and the values wouldn't need to be stored in the custom fields. Bear in mind that I am unfamiliar with patterns so this might not make sense, but this is an idea of how it could work: Imagine we have a pattern block with an image and a paragraph. We could store the values in the pattern block attributes and "connect" the inner blocks to that. Something like this:
Being the "dynamic_content: {
"1234": {
"url": {
"value": "<https://test.local/image.png>"
},
"styles": {
"color": {
"value": "#fff"
}
}
}
} And the "connections: {
"url": {
"source": "pattern",
"fallback": "https://mysite.com/image.png"
},
"styles": {
"color": {
"source": "pattern"
}
}
} Keep in mind that I am just making the APIs to show an example, they don't exist and they might look different if we pursue this approach. This way, each time the user modifies the content of a partially synced pattern, they would modify the Additionally, the attributes included in the "connections" could be used to define the editable parts of the pattern.
I believe this could be easily supported by adding a "content": {
"source": "meta",
"value": "my_custom_field",
"fallback": "Placeholder Text"
}
Regarding this, exploring the possibility of using the Custom naming of blocks to use unique ids: link was suggested. If I am correct, there is a proposal for that. Maybe the partial syncing could generate a unique hash until that is ready. |
With four weeks left until 6.4, let's punt this to a future release as there's not enough time to reasonably get this in. This was a stretch goal to begin with 😄 so great job continuing to explore and try to make something happen. |
Thank you for putting this together, @glendaviesnz. While I'm bummed this didn't make it into 6.4, I'm glad to see it on the list for 6.5. Our team just migrated a 400+ post/page site to a block theme, and our number one pain point was having to manually update pattern styles across all posts when a design change was made. We have several site migrations coming up for 100+ post sites, and the lack of a partially synced pattern has us exploring other options for converting large sites to FSE. My team and I are following this closely and look forward to contributing. |
thanks @unscripted, are you able to provide a more detailed description of how you would see partially synced patterns working in your perfect world? Obviously, the world isn't perfect so there are no guarantees we can meet all your requirements, but it would help to flesh out exactly how we approach this if we have as much understanding as possible of the potential real-world use cases. |
Our use case is similar and the lack of this feature is holding us back a ton.
We want a set of section template parts with certain parts of the layout locked, but the actual content editable. This would allow us to create pages rapidly and update and debug the design over time since the template is separate from its contents. This already works really well with ACF blocks, but those blocks have limitations. When trying to do the same thing with Gutenberg the closest thing is a global pattern. A concrete example of this is a large hero template where the background image, form, title, etc. can be changed. We'd like to lock the layout of the template and its inner blocks while keeping the content of those blocks editable. That way, all the hero headers throughout the site would use a single template and we could update it in the future e.g. add buttons below the title and set them to be visible by default on all heroes. This small change would take hours updating 100+ heroes individually. We will also use dynamic blocks so that the templates can be updated without editor errors. This concept works really well with ACF, but ACF lacks the granular composability and block editing experience we need. |
@ridinghoodmedia - It sounds like we have encountered some of the same ACF limitations.
TBH, I think it may take a few iterations to identify my perfect world solution, but my MVP goals are below. I should say these come from the mindset of a developer/agency building sites for a client (end-user). MVPIssueA user must manually edit and update each post to apply design or settings changes to every instance of a standard pattern within the site. While a minor inconvenience on a small site, this results in extensive work on 100+ page websites. ObjectiveEnhance the block editor by introducing the concept of "Partially Synced Patterns" to maintain a consistent design across various pages and posts by controlling block settings and styles from a centralized pattern library. Feature DescriptionNew Pattern Type: Develop a new type of syncing available to patterns in the block editor that allows for partial synchronization with the pattern library. This means that while certain stylistic and structural elements of the pattern are controlled and updated via the pattern library, the content within the pattern can be edited by the end user at the post level. This pattern type could be a new top-level type or could be a subgroup of the Synced type. Locking should be synced so that the developer or designer can prevent items such as the h1 from being removed from the block. Pattern Library Integration: The pattern library will house these partially synced patterns and manage the style updates. When a pattern’s style is updated in the library, it automatically propagates to all instances of that pattern across posts without altering the unique content added by the post author. Block Editor: End users can apply these patterns to their pages and have the freedom to edit the content within the blocks while the overall style and structure of the blocks are maintained from the pattern library. I see the block editor output similar to how the The user should have the ability to remove non-locked blocks from the pattern but not add new blocks. An example is a page header pattern that may utilize a cover block with a heading, paragraph, default image and a button. While the default pattern is created in the pattern library, the end user can remove the heading, paragraph, default image or button if they are not needed for that page. Benefits:Consistency in Design: Maintain a consistent design across various pages and posts by controlling block settings and styles from a centralized pattern library. Flexibility in Content: Allow the end user to focus on their unique content as opposed to being concerned with style tweaks on a per-post basis. Efficiency: Streamline the content management and design update process by allowing admins, developers or designers to make block-style updates in one place (the pattern library) that automatically reflect wherever the pattern is utilized. |
@unscripted great description, that sounds like our use case exactly. Import/export patterns would be important too. I think the use case for this is a lot more in demand than it seems since people don't even know how to describe this feature. I had a developer working on an internal workaround before he found this thread and we decided to wait since a solution in core would be a lot better. |
On that front, that's coming to WordPress 6.4: #53288 |
Thanks @unscripted, @ridinghoodmedia, what you have outlined matches exactly with what we are hoping to achieve 🤞 with the partially synced patterns work, which is good to know. Thanks for taking the time to flesh out your requirements. |
@talldan updated the description of the issue to reflect the current state of the project based on the prototyping work done in the past weeks (months already? 😄). The most up to date prototype can be found in #55807. The next step is to evaluate if the linked solution is good enough to land it in Gutenberg as an existing experiment behind the feature flag. |
I think @ridinghoodmedia and @unscripted have created an awesome outline for how this should work. I have just a couple other specifics for our use cases. @talldan's prototype at #55807 is really impressive. Right now it shows text values of basic blocks like paragraph and heading being set to metafields, which will be a critical feature. But for us it would be really important that any content type be able to work with this system. For instance, let's say I have a series of profile pages for college professors. I want to be able to create a partially-synced pattern that has:
Ideally, I would be able to assign the source of the image block from the media library, the InnerBlocks of the group block, the list items for the list block, and the This would allow the user to create significant freeform content for the professor's bio, but only add list items for the credentials or modify the Finally, it would be wonderful if these metafield values could also be assigned to blocks within a query block. Again using the professor bio pages example above, I could create the equivalent of an archive page of all professors with a query block that, for each professor, showed an image block with their photo (retrieved from the relevant metafield), page title (which is already possible), and a link to their email address (again retrieved from the relevant metafield). I'm not sure if all of this is outside the scope of what's being worked on, but that would be the "MVP" solution for us, as it would allow for a wide range of flexibility or rigidity based on the content type that we're creating for our users. As a crazy long shot request, eventually having the ability to assign any value or setting of a block within a partially-synced pattern as a metafield to be customized on an instance-by-instance basis, like even the color of a button, would be absolutely amazing. But I have to imagine that would be a ton of work. |
@draganescu That particular 'patch' format was never released in the gutenberg plugin. It was briefly shipped to trunk, but reverted, and you must have created the pattern during that brief period. No back compat is present for that format. |
Yes I see no reason to include any migration for an implementation that was never shipped in a release.
As a result of this it's my understanding that we can assume the issue @draganescu reported is no longer a problem. |
This is an interesting observation. Perhaps we could consider avoiding creating bindings if/when a pattern is created using this workflow. |
Honestly, I don't think that is making the experience any more clear. I really think we should go with what is outlined in #59583. Having a clear toggle is key for the experience to not be so confusing. |
I’m sure it’s already working like that because the name gets set before the block is even within the scope of the pattern that initiates the binding. Anyway, I agree with @fabiankaegy that it’s going to be confusing from the user's perspective. |
To avoid any confusion, I was acknowledging the observation rather than suggesting it as an overarching solution to the issue at hand.
This is the current behaviour. If you create a pattern containing a block that is already renamed then it auto-creates a binding. This is because there is an effect which runs when in the pattern editor. The binding does not seem to be added during creation of the Screen.Capture.on.2024-03-05.at.16-32-33.mp4 |
For what it's worth, today when creating a Synced Pattern I was very confused when the checkbox to enable instance overrides was missing. Then I felt frustrated upon realizing I would need to give the block an explicit name in order to enable overrides for it, then moreso when I realized would need to do that for every block in the pattern. Needing to devise names for blocks within a pattern that I was just experimenting with, and for which I had no good names yet, really broke my mental flow. Granted, the context for this was doing some testing, but it also feels awkward to explain in testing instructions, "To enable overrides in the pattern, you need to give these blocks a name" — it seems counterintuitive. Overall I see this as adding an extra unnecessary barrier between a user and their content, and I disagree that this would be only used by power users. Let's say I'm just a person with average technical skills who wants to build their site using WordPress — I'm in a creative flow building it, experimenting, and I want to use some patterns, but suddenly I need to start giving each overridable block an explicit name when I'm not ready to do that yet. A checkbox seems like a reasonable amount of overhead to enable the instance overrides; for me at least, needing to name each block to enable that feels like a frustrating experience. |
After reading the user's testing experience in #59651, I believe it reiterates the importance of a dedicated control for enabling an override. I've gone back through this thread, re-reading how we got to this point and trying to understand the impact of the control being tied to the Block Renaming API as outlined in this comment. In a later comment, @kevin940726 mentioned
and @glendaviesnz pointed out
A key point in this exchange is the "where users can make changes with no understanding of the impact of the change" statement. I feel we've traded one approach for another that may still result in a user making changes without understanding the potential impact. Given the desire to not paint ourselves in a corner for the future shuffling feature, the idea of a fallback gave me an idea of a dedicated key-value pair for the override. Would the approach outlined below be feasible?
My thought by making the override separate from the block id and block name is it would potentially lessen the impact of changes made to the Block Renaming API and could provide a unique id that could be used during a future implementation of the shuffling feature. I'm sure there are technical challenges with this approach that I'm unaware of, and that it may not be possible. We would probably need UI guidance from @richtabor, as well. I'd love your feedback and hope we can step back and think of a solution that is more intuitive for the end user and doesn't dual-purpose the Block Name field. |
Auto-generated keys allow uniqueness, but we can also allow them to be duplicated when the user decides to "opt-in". Using the Block Renaming API puts the burden of naming things on the developers/users instead, which is one of the most difficult things to do as a human 😅. Using auto-generated ids as the "default" releases that burden but also empowers users to achieve advanced features. In addition, in the use cases you described, I'd imagine that "nested patterns" could achieve similar results. I don't think it's ever officially supported but I think it's worth looking into separately. |
Following the recent changes and discussion I stand by the above view. I can understand the thinking behind the desire to link this to the name, but I believe that due to the above issues the disadvantages outweigh the advantages. In my view the best approach would be to stick with original explicit opt-in with random id generation as the default, but with the ability for advanced users to assign their own ids either in the UX or in the pattern serialized HTML. This would be very easy to achieve with the original architecture as prototyped here. |
I also just want to share that since the original checkbox UI had been present until the very end of Beta 3, there already is training material like the fantastic overview by Jamie Marsland here which train users on this UX: https://youtu.be/tf8w0xMNToY?si=a6VdLrzKkXevCyse |
Hey folks, thanks for raising your concerns. It’s clear that the feature doesn’t seem entirely ready to be shipped in WordPress, so we have made the decision to move it to WordPress 6.6 instead and keep it plugin only for now. You can read more about this on make/core The first big action time here is to work on protecting the feature behind the “IS_GUTENBERG_PLUGIN” flag. Cc @kevin940726 @talldan — For later, I’d like to note that the feature is not just about “making things overridable” by the user, while it’s the immediate use-case, we should think about this more holistically, it’s about separating content and presentation of patterns. It’s about providing a schema for the pattern. So there’s a few things on my mind that I think we need to clarify
About using the name as the source, I think at the moment we should continue with it. |
I've made a PR to make the feature plugin only - Implement pattern overrides behind IS_GUTENBERG_PLUGIN flag I've been working on this while at WC Asia, so would appreciate some thorough testing, as I've just been doing bits here and there! |
I've started working on a new epic issue focusing on what's needed for 6.6 - Pattern Overrides Epic (WordPress 6.6). It might potentially be best to close this issue out, and move all future conversation there? I've run out of time today, but will make sure this is communicated more widely tomorrow. |
Thanks @talldan Let's close this one then. |
N.B. Previously referred to as partially synced patterns.
What problem does this address?
Currently when adding a synced pattern all parts of that pattern are synced across every instance, so changes in any part of the pattern are reflected across as instances of the pattern.
It has been discussed in a number of places (#48458, #50456 ) that patterns would be much more useful/flexible if parts of them, particularly the layout and styling components, could be locked and synced across instances while allowing parts of the content to be updated independently.
An example workflow for a user could be a partially synced 'Recipe' pattern. A user could insert this pattern into multiple posts and any content (Ingredients, Steps) would be local to the post rather than synced in the pattern itself. The user would also be able to go back and modify the design of the recipe pattern, and this should have no effect on their content.
What is your proposed solution?
A number of potential solutions were discussed here with a few proofs of concepts. The current thinking is to use of the proposed block bindings api to implement partial syncing, since there's some overlap in requirements. The block bindings API mostly describes a way to use external data for a block attribute value (e.g. using a custom field for paragraph content). For patterns, child blocks of a pattern block could get and set their attribute values to the pattern block instance itself. This way, different instances of patterns could inject different data into the same pattern.
See the current prototype in #56235.
Tasks
V1 (Completed)
Pattern override tasks
contentOnly
mode - this is also covered by Patterns: edit source pattern in focus mode in post and site editors #57036wp/block
block) based on the changes in functionality (see Pattern Overrides epic (WordPress 6.5) #53705 (comment)) (PR: Update pattern block copy in light of pattern overrides #58231)linkTarget
ofcore/button
for Pattern Overrides #58165Reset
- (PR - Patterns: Change text on pattern reset button #58286)Block Binding Intergration
(add subtasks here as required)
Bugs
template-lock: all
to pattern inner blocks to prevent deletion/insertion #57661)template-lock: all
to pattern inner blocks to prevent deletion/insertion #57661)contentOnly
UI for editing overriden blocks currently shows the text align tool on the toolbar, but this isn't supported (it can be changed but the changes aren't saved). (PR: Remove text align control for paragraph, heading, and button in contentOnly editing mode #57906)Follow Ups
template-only
mode from editor and edit-post packages #57700)Suggested enhancements/explorations
content
- (PR - #58596)Block specific issues
Image Block
Supported attributes:
url
,id
,title
,alt
Button Block
Supported attributes:
text
,url
url
) attribute is supported, but related attributeslinkTarget
andrel
are not supported as block bindings attributes, but are still editable in the UI (PR: Support button's link settings for Pattern Overrides #58587)Heading block
Supported attributes:
content
Paragraph block
Supported attributes:
content
No known issues
General Bugs
Code quality
blockEditingMode
doesn't quite work for the pattern block (see Patterns: edit source pattern in focus mode in post and site editors #57036 (comment))Future
contentOnly
locking to allow insertion of new inner blocks #52018 for similar challenges withcontentOnly
mode). One solution explored here [PoC] Patterns: try partial syncing of inner blocks #56348The text was updated successfully, but these errors were encountered: