func (p *Page) CreateMenu() {
	var item anchor
	p.Menu = []anchor{}
	files := filterList(p.FileDir, directoryFilter)
	for _, file := range files {
		item = p.CreateLink(file, p.BasePath)
		children := filterList(p.FileDir+pathSeparator+file.Name(), directoryFilter)
		if len(children) > 0 {
			item.children = make([]anchor, 0, len(children))
			for _, child := range children {
				childItem := p.CreateLink(child, p.BasePath+file.Name())
				item.children = append(item.children, childItem)
			}
		}
		p.Menu = append(p.Menu, item)
	}
}
CreateMenu scans files and directories and builds a list of children links.
package page
import (
	"fmt"
	"html/template"
	"log"
	"os"
	"path"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"github.com/extemporalgenome/slug"
)
var titlePattern = regexp.MustCompile(`<h([\d])>(.+)</h[\d]>`)
type anchor struct {
	Text     string
	URL      string
	children []anchor
}
var homeAnchor = anchor{Text: "Home", URL: "/"}
var (
	titleReplacePattern = regexp.MustCompile(`[-_]`)
)
type Page struct {
	Title string
	Content template.HTML
	ContentHeader template.HTML
	ContentFooter template.HTML
	Titles map[int][]anchor
	Menu []anchor
	SideMenu []anchor
	BreadCrumb []anchor
	CurrentPage anchor
	FilePath string
	FileDir string
	BasePath string
	BaseDir string
	IsHome bool
}
const (
	pathSeparator = string(os.PathSeparator)
)
var knownExtensions = []string{".html", ".md", ""}
type fileList []os.FileInfo
func (f fileList) Len() int {
	return len(f)
}
func (f fileList) Less(i, j int) bool {
	return f[i].Name() < f[j].Name()
}
func (f fileList) Swap(i, j int) {
	f[i], f[j] = f[j], f[i]
}
func removeKnownExtension(s string) string {
	fileExt := path.Ext(s)
	for _, ext := range knownExtensions {
		if ext != "" {
			if fileExt == ext {
				return s[:len(s)-len(ext)]
			}
		}
	}
	return s
}
func filterList(directory string, filter func(os.FileInfo) bool) fileList {
	var list fileList
	var err error
	var fp *os.File
	if fp, err = os.Open(directory); err != nil {
		panic(err)
	}
	defer fp.Close()
	var dirContents []os.FileInfo
	if dirContents, err = fp.Readdir(-1); err != nil {
		panic(err)
	}
	for _, file := range dirContents {
		if filter(file) == true {
			list = append(list, file)
		}
	}
	sort.Sort(struct{ fileList }{list})
	return list
}
func dummyFilter(f os.FileInfo) bool {
	if !strings.HasPrefix(f.Name(), ".") && !strings.HasPrefix(f.Name(), "_") {
		return true
	}
	return false
}
func directoryFilter(f os.FileInfo) bool {
	if !strings.HasPrefix(f.Name(), ".") && !strings.HasPrefix(f.Name(), "_") {
		return f.IsDir()
	}
	return false
}
func fileFilter(f os.FileInfo) bool {
	if !strings.HasPrefix(f.Name(), ".") && !strings.HasPrefix(f.Name(), "_") {
		return (f.IsDir() == false)
	}
	return false
}
func createTitle(s string) string {
	s = removeKnownExtension(s)
	s = titleReplacePattern.ReplaceAllString(s, " ")
	return strings.Title(s[:1]) + s[1:]
}
func (p *Page) CreateLink(file os.FileInfo, prefix string) anchor {
	item := anchor{}
	if file.IsDir() == true {
		item.URL = prefix + file.Name()
	} else {
		item.URL = prefix + removeKnownExtension(file.Name())
	}
	item.URL = path.Clean(item.URL)
	item.Text = createTitle(file.Name())
	return item
}