Implement HasMenuCurrent and IsMenuCurrent for Nodes

Prior to this commit, `HasMenuCurrent` and `IsMenuCurrent` on `Node` always returned false.

This made it hard (if possible at all) to mark the currently selected menu item/group for non-Page content (home page, category pages etc.), i.e. for menus defined in the site configuration.

This commit provides an implementation of these two methods.

Notable design choices:

* These menu items have a loose coupling to the the resources they navigate to; the `Url` is the best common identificator. To facilitate a consistent matching, and to get it in line with the menu items connected to `Page`, relative Urls (Urls starting with '/') for menu items in the site configuration are converted to permaLinks using the same rules used for others’.
* `IsMenuCurrent` only looks at the children of the current node; this is in line with the implementation on `Page`.
* Due to this loose coupling, `IsMenuCurrent` have to search downards in the tree to make sure that the node is inside the current menu. This could have been made simpler if it could answer `yes` to any match of any menu item matching the current resource.

This commit also adds a set of unit tests for the menu system.

Fixes #367
This commit is contained in:
bep
2014-10-18 20:25:10 +02:00
committed by spf13
parent 2b412d4ac7
commit d013edb7f8
4 changed files with 404 additions and 12 deletions

View File

@@ -533,6 +533,10 @@ func (s *Site) getMenusFromConfig() Menus {
}
menuEntry.MarshallMap(ime)
if strings.HasPrefix(menuEntry.Url, "/") {
// make it absolute so it matches the nodes
menuEntry.Url = s.permalinkStr(menuEntry.Url)
}
if ret[name] == nil {
ret[name] = &Menu{}
}
@@ -822,16 +826,23 @@ func (s *Site) RenderTaxonomiesLists() error {
return nil
}
func (s *Site) newTaxonomyNode(t taxRenderInfo) (*Node, string) {
base := t.plural + "/" + t.key
n := s.NewNode()
n.Title = strings.Replace(strings.Title(t.key), "-", " ", -1)
s.setUrls(n, base)
if len(t.pages) > 0 {
n.Date = t.pages[0].Page.Date
}
n.Data[t.singular] = t.pages
n.Data["Pages"] = t.pages.Pages()
return n, base
}
func taxonomyRenderer(s *Site, taxes <-chan taxRenderInfo, results chan<- error, wg *sync.WaitGroup) {
defer wg.Done()
for t := range taxes {
base := t.plural + "/" + t.key
n := s.NewNode()
n.Title = strings.Replace(strings.Title(t.key), "-", " ", -1)
s.setUrls(n, base)
n.Date = t.pages[0].Page.Date
n.Data[t.singular] = t.pages
n.Data["Pages"] = t.pages.Pages()
n, base := s.newTaxonomyNode(t)
layouts := []string{"taxonomy/" + t.singular + ".html", "indexes/" + t.singular + ".html", "_default/taxonomy.html", "_default/list.html"}
err := s.render("taxononomy "+t.singular, n, base+".html", s.appendThemeTemplates(layouts)...)
if err != nil {
@@ -911,11 +922,16 @@ func (s *Site) RenderSectionLists() error {
return nil
}
func (s *Site) RenderHomePage() error {
func (s *Site) newHomeNode() *Node {
n := s.NewNode()
n.Title = n.Site.Title
s.setUrls(n, "/")
n.Data["Pages"] = s.Pages
return n
}
func (s *Site) RenderHomePage() error {
n := s.newHomeNode()
layouts := []string{"index.html", "_default/list.html", "_default/single.html"}
err := s.render("homepage", n, "/", s.appendThemeTemplates(layouts)...)
if err != nil {
@@ -1040,7 +1056,11 @@ func (s *Site) setUrls(n *Node, in string) {
}
func (s *Site) permalink(plink string) template.HTML {
return template.HTML(helpers.MakePermalink(string(viper.GetString("BaseUrl")), s.prepUrl(plink)).String())
return template.HTML(s.permalinkStr(plink))
}
func (s *Site) permalinkStr(plink string) string {
return helpers.MakePermalink(string(viper.GetString("BaseUrl")), s.prepUrl(plink)).String()
}
func (s *Site) prepUrl(in string) string {