-
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
Navigation preservation plan #36087
Comments
Why not just mimic the way that menus work with PHP themes, and store the area identifier as an attribute of the navigation block? Why do template parts have to be involved? |
@carlomanf It was explored by @getdave in #36002. Storing that identifier with the block creates a scenario where you have two different data sources: there’s the custom post type with navigation items, and there’s the area identifier. Which one wins? What happens if I change the area from „primary” to „secondary”? What happens if I customize menu items? My thinking is that it’s weird because the „slot” (/area) and the „menu” are really two different concepts. A theme may specify two slots, but I may have the same menu in both, two different menus, three menus in total, etc. Template parts are handy in that they provide all the „slot” mechanics required to model that. |
I haven't seen that branch, but is it possibly a similar conundrum to what I described at the end of this comment? For example, you have a navigation with post ID 101 and area "primary," and another navigation with post ID 102 and area "secondary." Then you have a navigation block instance with attribute "primary" and you want to change the block to render the other navigation. How should this be done?
If I'm reading the conundrum correctly, then I would say it will be tricky to get the user experience right, but at least it has no technical limitations. The template part approach proposed here has a few limitations, one being that it won't work for navigations included directly in a template, and another being that it forces the template part identifier to have the "navigation" prefix. |
I don't really see this as much of an issue:
Is this something we tried? We are in full control over the navigation block's UI, so if it needs to look different when an area is assigned, that's completely possible. |
@carlomanf navigations included directly in a template are equivalent to navigations with area = none from Dave's implementation. I don't think of it as of a limitation, as much as a way of having both "labeled" navigations and "unlabeled" navigations. How do you see it?
I agree this isn't ideal, although I don't think it's terrible either. I experimented with using template areas instead in #36117. It would also be easy to add a new free-text field such as |
I drafted that idea in #36117 @talldan I want to avoid yet another implementation of reusable content. That's the entire reason why I'm proposing an approach based on the existing primitives. We already have reusable blocks, template parts, options-backed blocks like site logo, and now we're talking about navigation areas. The experience already tends to be confusing for me, and I use it every day. I imagine it's even more confusing for the regular user. It's hard enough to make a simple popup work consistently across the regular links and navigation links. I'd rather avoid running into that in the "reusable content" world. I think the source of trickyness is that the "navigation area" model is, essentially, a one-to-many relationship with three parts:
To manage the data effectively, you need to have some UI for each part. Posts are displayed as Navigation Blocks. Areas are not displayed right now, besides the "area" dropdown in the block inspector. As @getdave noted:
Adding an "area" attribute to the navigation block = managing this "one-to-many" relationship via the block's inspector. I don't think it's a right place for such an important piece of UI. It would have to be a new control or a modal, which would disconnect it from the visual experience provided by Gutenberg. I believe all these problems were already solved: One-to-many relationships are easily managed through template parts. I can create a template part and use it in multiple places. Applying that to menus: If I want a different menu in just one place, I can choose a different template part or even have a "one-off" menu not wrapped in any template part. If I want to change the "primary" menu everywhere, I do the same familiar thing as when I want to change the header everywhere. I want that to be the same experience because I heavily agree with what @jasmussen said:
Staying in the "template part" world is IMHO a good forcing function to discover any shortcomings they have. All the improvements would move the larger FSE project forward. Rolling out a custom implementation, however, would create a new pocket of expertise somewhat separate from the bigger picture. Also, tactically:
This restriction could work, but I'd much rather have a data model where an invalid state can't be expressed in the first place. I fear that, sooner or later, we'd end up with blocks that somehow got both attributes set. |
One thing I thought is that using template parts removes the need for a "special" isolated editor as well, because now we always have the navigation block wrapper :) |
Ok. I'd encourage exploration around this. I think my concerns would be a more complex user experience (there are now two blocks instead of one), and also the complexity of theme switching has increased (we're explicitly re-writing content, while the other proposal should just work based on matching template part area names, an already well defined semantic). There are some possibilities for invalid state here too. Like if I wrap my navigation block with another template part in the editor, the navigation block will no longer be in my special navigation template area and theme switching breaks. Another downside is that some block attributes specific to a theme (like colors, custom block styles, and other style attributes) are saved and transferred to the new theme where they're potentially meaningless or look out of place. This advantage of keeping visual style separate from menu data is no longer as much of an advantage. I don't want to dissuade though, just provide some constructive feedback, maybe these are things you already have ideas for, they just haven't been made visible in the discussion yet. |
I agree it's more complex than having just a single block. At the same time I like it because in my mental model there are two entities there (navigation area and navigation post), so this at least makes that visible. My question now is "how should that work for the user?"
It's true that re-writing content adds complexity. At the same time, I understand the other proposal introduces a new concept of "navigation areas" and does not rely on the existing template areas semantics. I like the idea of matching the names, though. I'm exploring a related idea that combines both approaches and doesn't involve re-writing content on theme switch.
Do you mean a structure like below?
Agreed, that would be a problem. It would be nice to only accept navigation blocks in that navigation template part. Or at least don't accept nested template parts. Maybe that could be a new flavor of the template part block.
I don't follow – the idea is to only rewrite
Much appreciated @talldan! It's helpful, to the point, and helps me direct these explorations. Please keep it coming. |
@talldan I added a new idea to #36117: In that implementation, we'd still have template areas such as <!-- wp:navigation { "initialNavigationMenuArea": "primary-menu" } --> When such template part is saved, This way we:
The only remaining problem I see here is having an extra template part inside |
When switching to a new theme, my new theme would have a different header template part, and it might have
Looks like I'm wrong about this, only the |
Yes, this is a challenge. Possibly the easiest flow would be to add a button to the navigation block itself that when clicked wraps the nav block with the template part (titled something like 'Define as navigation area'). Also have to consider flows like pattern insertion, because that was flagged in #35947 as already being more difficult with the current version of the block. I think the right direction would be to encourage pattern developers to already have the navigation area within patterns where it makes sense.
A dedicated navigation area block may be the most simple option. It could have templated inner blocks to ensure it only has a direct navigation block child that can't be removed. I was also wondering whether there might be a way to avoid needing to modify the template part content on theme switch. I had a vague idea:
|
Is this now able to be closed out? |
Architecture for #35750
System* for navigation preservation on block theme switch using template parts:
to define navigation "areas" or "slots" or "locations" we use template parts, with the added convention that they're named
navigation-*
, where*
is wildcardin these
navigation-*
template parts themes can add navigation blocks with all attributes set, and inner blocks defined for default presentation and contentwhen the user changes the theme's default navigation content, for instance creates a menu, uses an existing menu or imports a classic menu, then the wrapping
navigation-*
template is updated and has to be saved, because the navigation block gets the newnavigationPostId
attributeon saving the template part we hook into the saving flow and check if the slug of the template part is of the
navigation-*
form, and if it is:navigationPostId
attributenavigationPostId
attributeon theme switch:
navigation-*
template parts withnavigationPostId
associations (wherever we decided to store them)navigation-*
associated slugs that we found in the DBnavigation-*
form whose slug has a DB association to anavigationPostId
navigation-*
template part contentsnavigationPostId
as an attribute of the first found navigation blocknavigation-*
template part to the DBThis system has the following advantages:
This system has the following disadvantages:
To mitigate some of the disadvantages:
A reference implementation to follow.
*resulted from a discussion between @adamziel and @draganescu
The text was updated successfully, but these errors were encountered: