package main import ( "fmt" "os" "path" "text/template" "time" "github.com/google/shlex" "github.com/pelletier/go-toml" ) // Site represents a site. type Site struct { Title string `toml:"title"` Tasks []*Task `toml:"tasks"` Params map[string]interface{} `toml:"params"` Permalinks map[string]string `toml:"permalinks"` Generated time.Time `toml:"-"` Root *Page `toml:"-"` permalinks map[string]*template.Template templates Templates } // Task represents a site build task. type Task struct { Name string `toml:"name"` Input []string `toml:"input"` OutputExt string `toml:"output"` TemplateExt string `toml:"template"` Preprocess map[string]string `toml:"preprocess"` Postprocess string `toml:"postprocess"` StaticDir string `toml:"static_dir"` OutputDir string `toml:"output_dir"` URL string `toml:"url"` UglyURLs bool `toml:"ugly_urls"` Feeds []Feed `toml:"feeds"` preprocess map[string][]string postprocess []string feeds map[string][]Feed } type Feed struct { InputDir string `toml:"input_dir"` Title string `toml:"title"` Template string `toml:"template"` Output string `toml:"output"` } func (t *Task) Match(ext string) bool { for i := range t.Input { if t.Input[i] == ext { return true } } return false } // LoadSite loads the site with the given configuration file. func LoadSite(config string) (*Site, error) { f, err := os.Open(config) if err != nil { return nil, err } defer f.Close() site := &Site{ Generated: time.Now(), } if err := toml.NewDecoder(f).Decode(site); err != nil { return nil, err } funcs := site.funcs() // Parse permalinks site.permalinks = map[string]*template.Template{} for path := range site.Permalinks { t := template.New(fmt.Sprintf("permalink %q", path)).Funcs(funcs) _, err := t.Parse(site.Permalinks[path]) if err != nil { return nil, err } site.permalinks[path] = t } // Load templates templateExts := []string{} for _, task := range site.Tasks { if task.TemplateExt != "" { templateExts = append(templateExts, task.TemplateExt) } } site.templates.Funcs(funcs) if err := site.templates.Load("templates", templateExts); err != nil { return nil, err } for _, task := range site.Tasks { // Populate feeds task.feeds = map[string][]Feed{} for _, feed := range task.Feeds { dir := path.Clean(feed.InputDir) task.feeds[dir] = append(task.feeds[dir], feed) } // Parse commands task.preprocess = map[string][]string{} for path := range task.Preprocess { preprocess, err := shlex.Split(task.Preprocess[path]) if err != nil { return nil, err } task.preprocess[path] = preprocess } if task.Postprocess != "" { postprocess, err := shlex.Split(task.Postprocess) if err != nil { return nil, err } task.postprocess = postprocess } } return site, nil } func (s *Site) page(path string) *Page { return s.Root.getPage(path) }