shithub: hugo

Download patch

ref: d4acacd4f50a6c0c25c22e7cc989f196bd225fd5
parent: beb4ab162da1efa299c814acbd3b26fe6a479349
author: bep <[email protected]>
date: Tue Jan 6 13:11:06 EST 2015

Section menu for the lazy blogger

The current menu system works great, but is too much work if all you want is a simple menu with the sections as menu items, and having these menu items connected to the pages in a way that enables setting the correct menu item as active for both the section lists and the pages itself.

This commit adds a new option `SectionPagesMenu' which, if set, will create a new menu with that name with all the sections as menu items. The pages in the sections will behave as "shadow members" of these section items as `blogpage.HasMenuCurrent "sectionmenu" $sectionmenuitem` will return true.

If a menu item with the same `identifier` is defined in site config, *that* item will take precedence.

--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -104,7 +104,7 @@
 
 	// This message will be shown to Windows users if Hugo is opened from explorer.exe
 	cobra.MousetrapHelpText = `
-	
+
   Hugo is a command line tool
 
   You need to open cmd.exe and run it from there.`
@@ -153,6 +153,7 @@
 	viper.SetDefault("PaginatePath", "page")
 	viper.SetDefault("Blackfriday", helpers.NewBlackfriday())
 	viper.SetDefault("RSSUri", "index.xml")
+	viper.SetDefault("SectionPagesMenu", "")
 
 	if hugoCmdV.PersistentFlags().Lookup("buildDrafts").Changed {
 		viper.Set("BuildDrafts", Draft)
--- a/hugolib/menu_test.go
+++ b/hugolib/menu_test.go
@@ -11,6 +11,7 @@
 	"github.com/spf13/hugo/source"
 	"github.com/spf13/viper"
 	"github.com/stretchr/testify/assert"
+	"path/filepath"
 )
 
 const (
@@ -90,9 +91,15 @@
 Front Matter with Menu Pages`)
 
 var MENU_PAGE_SOURCES = []source.ByteSource{
-	{"sect/doc1.md", MENU_PAGE_1},
-	{"sect/doc2.md", MENU_PAGE_2},
-	{"sect/doc3.md", MENU_PAGE_3},
+	{filepath.FromSlash("sect/doc1.md"), MENU_PAGE_1},
+	{filepath.FromSlash("sect/doc2.md"), MENU_PAGE_2},
+	{filepath.FromSlash("sect/doc3.md"), MENU_PAGE_3},
+}
+
+var MENU_PAGE_SECTIONS_SOURCES = []source.ByteSource{
+	{filepath.FromSlash("first/doc1.md"), MENU_PAGE_1},
+	{filepath.FromSlash("first/doc2.md"), MENU_PAGE_2},
+	{filepath.FromSlash("second-section/doc3.md"), MENU_PAGE_3},
 }
 
 func tstCreateMenuPageWithNameTOML(title, menu, name string) []byte {
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -556,6 +556,12 @@
 
 func (p *Page) HasMenuCurrent(menu string, me *MenuEntry) bool {
 	menus := p.Menus()
+	sectionPagesMenu := viper.GetString("SectionPagesMenu")
+
+	// page is labeled as "shadow-member" of the menu with the same identifier as the section
+	if sectionPagesMenu != "" && p.Section() != "" && sectionPagesMenu == menu && p.Section() == me.Identifier {
+		return true
+	}
 
 	if m, ok := menus[menu]; ok {
 		if me.HasChildren() {
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -762,8 +762,25 @@
 		}
 	}
 
+	sectionPagesMenu := viper.GetString("SectionPagesMenu")
+	sectionPagesMenus := make(map[string]interface{})
 	//creating flat hash
 	for _, p := range s.Pages {
+
+		if sectionPagesMenu != "" {
+			if _, ok := sectionPagesMenus[p.Section()]; !ok {
+				if p.Section() != "" {
+					me := MenuEntry{Identifier: p.Section(), Name: helpers.MakeTitle(p.Section()), URL: s.permalinkStr(p.Section())}
+					if _, ok := flat[twoD{sectionPagesMenu, me.KeyName()}]; ok {
+						// menu with same id defined in config, let that one win
+						continue
+					}
+					flat[twoD{sectionPagesMenu, me.KeyName()}] = &me
+					sectionPagesMenus[p.Section()] = true
+				}
+			}
+		}
+
 		for name, me := range p.Menus() {
 			if _, ok := flat[twoD{name, me.KeyName()}]; ok {
 				jww.ERROR.Printf("Two or more menu items have the same name/identifier in %q Menu. Identified as %q.\n Rename or set a unique identifier. \n", name, me.KeyName())