package page import ( "bufio" "bytes" "io" "os" "text/template" "time" "gopkg.in/russross/blackfriday.v2" "gopkg.in/yaml.v2" ) type Page struct { Name string Head string Body string Date *time.Time Published bool Templates map[string]string } // Can be adjusted to change the base template used in rendering var BaseTemplate = "inc/base.html" // Used to split the .md files into yaml and markdown var DocumentSplit = "|---\n" // Renders a page func (p *Page) Render(wr io.Writer) error { if err := p.Read(); err != nil { return err } t, err := template.ParseFiles(BaseTemplate) if err != nil { return err } // Automatically pull from the yml file if applicable if p.Head != "" { t, err = t.Parse(` {{define "head"}} {{.Head}} {{end}} `) if err != nil { return err } } return t.Execute(wr, p) } // Reads in the special markdown file format for the website off of the disk func (p *Page) Read() error { yamlBuf := bytes.NewBuffer(nil) markdownBuf := bytes.NewBuffer(nil) fh, err := os.Open(p.Name + ".md") if err != nil { return err } defer fh.Close() rdr := bufio.NewReader(fh) // Read in the file and split between markdown and yaml buffers yamlDone := false for { bytes, err := rdr.ReadBytes('\n') if err == io.EOF { break } else if err != nil { return err } // Is this the line where we stop reading the yaml and start reading markdown? if DocumentSplit == string(bytes) && !yamlDone { yamlDone = true continue } if !yamlDone { yamlBuf.Write(bytes) } else { markdownBuf.Write(bytes) } } err = yaml.Unmarshal(yamlBuf.Bytes(), p) if err != nil { return err } p.Body = string(blackfriday.Run(markdownBuf.Bytes())) return nil }