WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.51k stars 4.2k forks source link

Navigation Areas are overly complex #36524

Closed getdave closed 2 years ago

getdave commented 2 years ago

Having spent some time with Navigation Areas there is a concern that the concepts and UX we have introduced are going to be too complex.

In an informal discussion @mtias shared his concerns which I've attempted to summarise below along with a potential solution that he proposed.

Summary

The main problems are:

In the world of classic Themes, users switch themes in order to get new styles and visual appearance. In this world we have Menu Locations to try and allow us to map Menus from Theme to Theme. However, in practice this rarely works and the whole concept of Menu Locations has always been challenging for users to grasp.

In the world of block Themes, global styles will make it less likely users will need to switch Themes. After all colors, typography and more can be modified within any block Theme. Moreover you have near limitless layout flexible afforded via the block library in the Editor.

Whilst it is desirable to preserve menus when switching Themes, trying to use Navigation Areas to map the concept of "locations" into the block based world of the editor is not producing a great result. Indeed, it is bringing over concepts from the classic world that may no longer need to existexist. It is also producing a sub-optimal UX which requires the users to understand a number of complex concepts.

What is ~your~ the proposed solution?

Matias is proposing we retain the existing system of saving Navigation to a Custom Post Type. Decoupling presentation from data is a good idea. But...

Instead of burdening users with the concept of areas and locations, we should remove Navigation Areas and instead attempt to use a heuristic to automatically pick the correct Navigation CPT for a given Navigation block based on it's location within a template.

For example, imagine you insert a Navigation block into your Header Template Part on the Index template. That Navigation block should be automatically named as header-index-navigation. You then create some Nav items. This should create a Navigation CPT which a matching slug of header-index-navigation. This creates an implicit relationship between the block and its data via the slug.

Now in another Theme (let's called it B), the theme author has undertaken a similar exercise and therefore their header.html template part contains a Navigation block which has a slug reference of header-index-navigation (again this is based on it's template + template part location).

If I switch to Theme B then the Navigation block will attempt to look up Navigation CPTs with a slug matching header-index-navigation. As I created such a CPT in Theme A, the Nav block from Theme B will be able to pull through the correct navigation items by matching against the slug.

If there is no match then the Nav Block should fall back to a default output on the front end (Page List?), whilst within the editor a notice should be displayed prompting the user to resolve the Navigation block to select which menu they wish to display. It is key that the block should always output something sensible on the front end, but within the editor it is ok to prompt the user to take action.

This isn't a fully automated solution but it covers the 80% use case whilst also greatly simplifying the UX experience for users and authors within the Editor.

What do we think about this approach?

talldan commented 2 years ago

For example, imagine you insert a Navigation block into your Header Template Part on the Index template. That Navigation block should be automatically named as header-index-navigation. You then create some Nav items. This should create a Navigation CPT which a matching slug of header-index-navigation. This creates an implicit relationship between the block and its data via the slug.

I had the same idea about using a slug to represent the location, but discounted it. The reason is that it prevents the reusability of menus. My CPT has an implicit relationship to where it's rendered and that's not beneficial. If I want to use the same CPT in my footer, what's the solution? Can the CPT have two slugs?

Instead of burdening users with the concept of areas and locations, we should remove Navigation Areas and instead attempt to use a heuristic to automatically pick the correct Navigation CPT for a given Navigation block based on it's location within a template.

This is what I originally wanted, to use the concept of Template Areas for the value of a location (https://github.com/WordPress/gutenberg/issues/35750#issuecomment-951481961) and to keep the area concept implicit to the nav block and not introduce another block (https://github.com/WordPress/gutenberg/issues/36087#issuecomment-957044849).

As mentioned above though, I don't think a slug will work, the CPT should be fully decoupled from where it is rendered to ensure menu reusability.

I personally think the technical concept of areas can be kept, but we limit the amount of user interaction required by automatically using the parent template part area as the value (e.g. Header, Footer).

draganescu commented 2 years ago

imagine you insert a Navigation block into your Header Template Part on the Index template. That Navigation block should be automatically named as header-index-navigation. You then create some Nav items. This should create a Navigation CPT which a matching slug of header-index-navigation. This creates an implicit relationship between the block and its data via the slug.

Isn't that an explicit relationship if the block and the CPT share a string that links them? Also what happens when the user creates more menus using the same block that has this single slug form? Do we increment them?

their header.html template part contains a Navigation block which has a slug reference of header-index-navigation

Should a theme author code in the slug? Since we infer this from the tree of parent blocks that should not be needed.

adamziel commented 2 years ago

Great questions @draganescu and @talldan! I think the concept of slugs addresses these specific problems, but let's keep going – I'm just as curious as you.

If I want to use the same CPT in my footer, what's the solution? Can the CPT have two slugs?

It's the same as with numerical IDs. You'd just have two navigation blocks referring to the same slug.

Isn't that an explicit relationship if the block and the CPT share a string that links them?

Implicit/explicit thing is debatable. When you add a new navigation block in the header, it takes a slug like header by default. When you move it to the footer, it keeps referring to the same slug. You can choose a different menu to display.

Also what happens when the user creates more menus using the same block that has this single slug form? Do we increment them?

Yes, like header-2. Or we could default to the same header slug and enable users to choose a different menu.

Should a theme author code in the slug? Since we infer this from the tree of parent blocks that should not be needed.

Perhaps initially. Ideally they wouldn't have to. Perhaps a template part could provide that info through context?

talldan commented 2 years ago

It's the same as with numerical IDs. You'd just have two navigation blocks referring to the same slug.

So I have a slug header-index-navigation in my header, and header-index-navigation in my footer. How does this help my menu data transfer correctly when switching themes or inserting a new footer pattern/template area? It seems like the new footer will be expecting a slug of footer-index-navigation.

adamziel commented 2 years ago

So I have a slug header-index-navigation in my header, and header-index-navigation in my footer. How does this help my menu data transfer correctly when switching themes ​or inserting a new footer pattern/template area? It seems like the new footer will be expecting a slug of footer-index-navigation.

It doesn't. Only the header navigation would transfer correctly and the footer one would require a manual intervention. I believe @mtias's argument is that:

Did I get it right @mtias? Would you like to speak more about that?

talldan commented 2 years ago

Instead of automating as much as possible today, let's acknowledge that FSE will evolve tomorrow and trade off certain shortcomings for a cohesive feature base that will play nicely with things like template hierarchy

This is information that I personally am unaware of, the constraints here need to be made clearer so that developers can make better decisions.

getdave commented 2 years ago

Dan I think this was my biggest take away. My (previous) understanding was that we needed a hands-free solution that would work automatically in all cases without user intervention.

What I'm hearing now is that it's acceptable to require manual intervention (in the Editor) if the front end (of the site) shows a sensible / practical fallback.

The overall thread is now:

talldan commented 2 years ago

I don't think any of that means that encoding information in a slug is the best solution.

It is absolutely possible to achieve all of that, but still keep the wp_navigation decoupled from the block. The answer would be to continue using site options as a map from template part area to menu id. That's the solution I actually wanted from the start (#35750 (comment)).

So I think there's still context that's missing around why a slug is best.

getdave commented 2 years ago

I don't think any of that means that encoding information in a slug is the best solution.

I agree. I'm not advocating for slugs.

keep the wp_navigation decoupled from the block

This sounds like a good objective.

The answer would be to continue using site options as a map from template part area to menu id. That's the solution I actually wanted from the start (#35750 (comment)).

How easy is it to explore this?

Lastly - should we prepare a revert PR for Navigation Areas in case none of this comes to fruition in time? I'm not clear on the protocol.

mtias commented 2 years ago

If I want to use the same CPT in my footer, what's the solution? Can the CPT have two slugs?

In that case you'd just reference the one that's already created since you want it to be reusable.

As mentioned above though, I don't think a slug will work, the CPT should be fully decoupled from where it is rendered to ensure menu reusability.

It's not about decoupling, it's about not forcing a user to name and deal with an abstraction when it's not necessary. The place where a user first creates a menu carries enough contextual meaning to handle the naming we need for the CPT.

When a user is inserting a new navigation block, it's the block the one that should display if an existing menu is present to reuse. We can use semantic areas to automatically load the menu data from a corresponding area if there's one present (header, footer, etc).

Also what happens when the user creates more menus using the same block that has this single slug form? Do we increment them?

Yes, but it's also a bit of an abstract thought. If someone is creating a different menu for a header, it's almost a requirement that they'd also have a different template part in place (say, for a different header in an archive) so the menu created there would inherit that difference in name already.

Should a theme author code in the slug? Since we infer this from the tree of parent blocks that should not be needed.

Agreed, the more we can leave to "it just works" based on the presence of template areas, the better.

How does this help my menu data transfer correctly when switching themes or inserting a new footer pattern/template area?

A user / theme should be able to set a menu that was created in a different area (header) in the footer, and it'd be clear the data is coming from the menu in the header. If the user wants to have a different menu data in the footer they'd create a new one or delete the data coupling.

mtias commented 2 years ago

Writing some aims down in case it helps contextualize things:

talldan commented 2 years ago

In that case you'd just reference the one that's already created since you want it to be reusable.

Though as mentioned it does break with the idea of the slug being connected to the area. I would now have a header slug in my footer area. Some of the other behaviors that you describe, like automatically loading the correct menu when a new navigation block is inserted in a footer now won't work reliably.

It seems like a constraint that will be hard to solve, which is a shame as we already have another system that can (I think) do everything you describe. That would be to store the template area and menu relationship in a database table. The only part that's difficult here is handling multiple menus in the same area, but I think there's also the same challenge with slugs.

@adamziel also mentioned the idea of a conflict resolution UI for a user. The problem here is that until the user resolves this conflict, menus are not being shown on the front-end of a user's site. My feeling is that if we can do better than that, we should.

getdave commented 2 years ago

The problem here is that until the user resolves this conflict, menus are not being shown on the front-end of a user's site.

I mentioned above and in the issue description that if a block requires resolution within the editor, the front of the site should always show something. We need a good default fallback for the front end. Something like listing the site's top 6 pages for example.

noisysocks commented 2 years ago

Can I suggest we revert Navigation Areas for WP 5.9 (https://github.com/WordPress/gutenberg/pull/36604) and then explore this problem of how to automatically select a Navigation during a theme switch in the Gutenberg plugin for WP 6.0? It feels to me that some iteration is needed, more than we ought to do in a week, and that it's not a huge problem if WP 5.9 ships with the limitation of having to manually choose a Navigation again after switching theme.

getdave commented 2 years ago

Can I suggest we revert Navigation Areas for WP 5.9 (#36604) and then explore this problem of how to automatically select a Navigation during a theme switch in the Gutenberg plugin for WP 6.0? It feels to me that some iteration is needed, more than we ought to do in a week, and that it's not a huge problem if WP 5.9 ships with the limitation of having to manually choose a Navigation again after switching theme.

I agree with this. Having used the feature for a good week or so, I don't think it provides a good enough user experience. It's too complex and requires the user to understand too many concepts.

I think we should merge @adamziel's revert PR and look to address the concept of preserving Nav on theme switch in the 6.0 cycle when we have more time to provide a more considered approach. It will also afford more time for extenders to test any approach we do come up with.

I appreciate all the work that has gone into Nav Areas so I don't say this lightly but the priority should be ensuring we have a well considered feature for WP.

If anyone disagrees with this then please say so.

spacedmonkey commented 2 years ago

I have never really understood why navigation areas are needed. We already have menu locations, navigation areas feel very very similar. We could reuse those, instead of reinventing the wheel with this new watch of locating mechanism.

What do we think of finding way to pin a menu block to a location? I would like to explore this idea more, so I believe that navigation areas should be reverted for now and introduced ( if needed ) in WP 6.0.

adamziel commented 2 years ago

How would you connect the concept of a menu location, which is in a fixed place in classic themes, to block themes where nothing is fixed and users can create virtually any layout?

annezazu commented 2 years ago

Can this be closed since Navigation areas weren't pursued?

getdave commented 2 years ago

As Navigation Areas were deprecated we can safely close this one out.