From d831d2fce8198fb814ea4d3d8c311db5c388d04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Tue, 20 Jul 2021 12:10:22 +0200 Subject: Simplify "active menu" logic for section menus Fixes #8776 --- navigation/menu.go | 15 +++++++++++++++ navigation/pagemenus.go | 44 ++++++++++++++++---------------------------- 2 files changed, 31 insertions(+), 28 deletions(-) (limited to 'navigation') diff --git a/navigation/menu.go b/navigation/menu.go index 3ef06f6a9..7c6a1ccc7 100644 --- a/navigation/menu.go +++ b/navigation/menu.go @@ -32,6 +32,7 @@ var smc = newMenuCache() type MenuEntry struct { ConfiguredURL string // The URL value from front matter / config. Page Page + PageRef string // The path to the page, only relevant for site config. Name string Menu string Identifier string @@ -63,6 +64,8 @@ type Page interface { Section() string Weight() int IsPage() bool + IsSection() bool + IsAncestor(other interface{}) (bool, error) Params() maps.Params } @@ -106,16 +109,28 @@ func (m *MenuEntry) IsEqual(inme *MenuEntry) bool { // IsSameResource returns whether the two menu entries points to the same // resource (URL). func (m *MenuEntry) IsSameResource(inme *MenuEntry) bool { + if m.isSamePage(inme.Page) { + return m.Page == inme.Page + } murl, inmeurl := m.URL(), inme.URL() return murl != "" && inmeurl != "" && murl == inmeurl } +func (m *MenuEntry) isSamePage(p Page) bool { + if !types.IsNil(m.Page) && !types.IsNil(p) { + return m.Page == p + } + return false +} + func (m *MenuEntry) MarshallMap(ime map[string]interface{}) { for k, v := range ime { loki := strings.ToLower(k) switch loki { case "url": m.ConfiguredURL = cast.ToString(v) + case "pageref": + m.PageRef = cast.ToString(v) case "weight": m.Weight = cast.ToInt(v) case "name": diff --git a/navigation/pagemenus.go b/navigation/pagemenus.go index 1dfa71255..f783e30cf 100644 --- a/navigation/pagemenus.go +++ b/navigation/pagemenus.go @@ -15,6 +15,7 @@ package navigation import ( "github.com/gohugoio/hugo/common/maps" + "github.com/gohugoio/hugo/common/types" "github.com/pkg/errors" "github.com/spf13/cast" @@ -97,31 +98,25 @@ func PageMenusFromPage(p Page) (PageMenus, error) { } func NewMenuQueryProvider( - setionPagesMenu string, pagem PageMenusGetter, sitem MenusGetter, p Page) MenuQueryProvider { return &pageMenus{ - p: p, - pagem: pagem, - sitem: sitem, - setionPagesMenu: setionPagesMenu, + p: p, + pagem: pagem, + sitem: sitem, } } type pageMenus struct { - pagem PageMenusGetter - sitem MenusGetter - setionPagesMenu string - p Page + pagem PageMenusGetter + sitem MenusGetter + p Page } func (pm *pageMenus) HasMenuCurrent(menuID string, me *MenuEntry) bool { - // page is labeled as "shadow-member" of the menu with the same identifier as the section - if pm.setionPagesMenu != "" { - section := pm.p.Section() - - if section != "" && pm.setionPagesMenu == menuID && section == me.Identifier { + if !types.IsNil(me.Page) && me.Page.IsSection() { + if ok, _ := me.Page.IsAncestor(pm.p); ok { return true } } @@ -143,18 +138,15 @@ func (pm *pageMenus) HasMenuCurrent(menuID string, me *MenuEntry) bool { } } - if pm.p == nil || pm.p.IsPage() { + if pm.p == nil { return false } - // The following logic is kept from back when Hugo had both Page and Node types. - // TODO(bep) consolidate / clean - nme := MenuEntry{Page: pm.p, Name: pm.p.LinkTitle()} - for _, child := range me.Children { - if nme.IsSameResource(child) { + if child.isSamePage(pm.p) { return true } + if pm.HasMenuCurrent(menuID, child) { return true } @@ -172,20 +164,16 @@ func (pm *pageMenus) IsMenuCurrent(menuID string, inme *MenuEntry) bool { } } - if pm.p == nil || pm.p.IsPage() { + if pm.p == nil { return false } - // The following logic is kept from back when Hugo had both Page and Node types. - // TODO(bep) consolidate / clean - me := MenuEntry{Page: pm.p, Name: pm.p.LinkTitle()} - - if !me.IsSameResource(inme) { + if !inme.isSamePage(pm.p) { return false } - // this resource may be included in several menus - // search for it to make sure that it is in the menu with the given menuId + // This resource may be included in several menus. + // Search for it to make sure that it is in the menu with the given menuId. if menu, ok := pm.sitem.Menus()[menuID]; ok { for _, menuEntry := range menu { if menuEntry.IsSameResource(inme) { -- cgit v1.2.3