package page import ( "bufio" "bytes" "fmt" "io" "os" "text/template" "time" "github.com/russross/blackfriday" "gopkg.in/yaml.v2" ) type Page struct { Name string Head string Date *time.Time Published bool Vars map[string]interface{} Markdown []byte } // 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())) p.Markdown = markdownBuf.Bytes() return nil } func (p *Page) RenderBody() (string, error) { buf := &bytes.Buffer{} t, err := template.New("Body").Parse(string(p.Markdown)) if err != nil { return "", err } err = t.Execute(buf, p) if err != nil { return "", err } return string(blackfriday.Run(buf.Bytes())), nil // return buf.String(), nil } func (p Page) String() string { return fmt.Sprintf("Page: %s", p.Name) }