Reads data files inside data/ and makes data available in .Site.Data

Fixes #476.

Conflicts:
	hugolib/site.go
This commit is contained in:
Erlend Klakegg Bergheim
2015-01-20 23:08:01 +01:00
committed by bep
parent 4c7e119ca1
commit 773812de6f
4 changed files with 86 additions and 0 deletions

View File

@@ -34,6 +34,7 @@ import (
bp "github.com/spf13/hugo/bufferpool"
"github.com/spf13/hugo/helpers"
"github.com/spf13/hugo/hugofs"
"github.com/spf13/hugo/parser"
"github.com/spf13/hugo/source"
"github.com/spf13/hugo/target"
"github.com/spf13/hugo/tpl"
@@ -81,6 +82,7 @@ type Site struct {
params map[string]interface{}
draftCount int
futureCount int
Data map[string]interface{}
}
type targetList struct {
@@ -112,6 +114,7 @@ type SiteInfo struct {
BuildDrafts bool
canonifyUrls bool
paginationPageCount uint64
Data *map[string]interface{}
}
// SiteSocial is a place to put social details on a site level. These are the
@@ -264,12 +267,71 @@ func (s *Site) addTemplate(name, data string) error {
return s.Tmpl.AddTemplate(name, data)
}
func (s *Site) loadData(fs source.Input) (err error) {
s.Data = make(map[string]interface{})
for _, r := range fs.Files() {
// Crawl in data tree to insert data
var current map[string]interface{}
current = s.Data
for _, key := range strings.Split(r.Dir(), string(os.PathSeparator)) {
if key != "" {
if _, ok := current[key]; !ok {
current[key] = make(map[string]interface{})
}
current = current[key].(map[string]interface{})
}
}
// Read data file
data, err := readFile(r)
if err != nil {
return err
}
// Copy content from current to data when needed
if _, ok := current[r.BaseFileName()]; ok {
data := data.(map[string]interface{})
for key, value := range current[r.BaseFileName()].(map[string]interface{}) {
if _, override := data[key]; override {
return errors.New("Data in " + r.Path() + " is overrided in subfolder.")
} else {
data[key] = value
}
}
}
// Insert data
current[r.BaseFileName()] = data
}
return
}
func readFile(f *source.File) (interface{}, error) {
switch f.Extension() {
case "yaml", "yml":
return parser.HandleYamlMetaData(f.Bytes())
case "json":
return parser.HandleJsonMetaData(f.Bytes())
case "toml":
return parser.HandleTomlMetaData(f.Bytes())
default:
return nil, errors.New("Not supported for data: " + f.Extension())
}
}
func (s *Site) Process() (err error) {
if err = s.initialize(); err != nil {
return
}
s.prepTemplates()
s.Tmpl.PrintErrors()
if err = s.loadData(&source.Filesystem{Base: s.absDataDir()}); err != nil {
return
}
s.timerStep("load data")
s.timerStep("initialize & template prep")
if err = s.CreatePages(); err != nil {
return
@@ -379,6 +441,7 @@ func (s *Site) initializeSiteInfo() {
Menus: &s.Menus,
Params: params,
Permalinks: permalinks,
Data: &s.Data,
}
}
@@ -386,6 +449,10 @@ func (s *Site) hasTheme() bool {
return viper.GetString("theme") != ""
}
func (s *Site) absDataDir() string {
return helpers.AbsPathify(viper.GetString("DataDir"))
}
func (s *Site) absThemeDir() string {
return helpers.AbsPathify("themes/" + viper.GetString("theme"))
}