2017-06-24 20:00:19 +02:00
|
|
|
package pipelines
|
2017-06-16 21:14:56 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
|
2017-07-09 17:57:20 +02:00
|
|
|
"github.com/osteele/gojekyll/frontmatter"
|
2017-07-24 14:09:14 +02:00
|
|
|
"github.com/osteele/gojekyll/templates"
|
|
|
|
"github.com/osteele/gojekyll/utils"
|
2017-06-29 13:27:43 +02:00
|
|
|
"github.com/osteele/liquid"
|
2017-06-16 21:14:56 +02:00
|
|
|
)
|
|
|
|
|
2017-07-24 14:09:14 +02:00
|
|
|
// ApplyLayout applies the named layout to the data.
|
|
|
|
func (p *Pipeline) ApplyLayout(name string, data []byte, e map[string]interface{}) ([]byte, error) {
|
|
|
|
for name != "" {
|
|
|
|
var lfm map[string]interface{}
|
|
|
|
tpl, err := p.FindLayout(name, &lfm)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
b := utils.MergeStringMaps(e, map[string]interface{}{
|
|
|
|
"content": string(data),
|
|
|
|
"layout": lfm,
|
|
|
|
})
|
|
|
|
data, err = tpl.Render(b)
|
|
|
|
if err != nil {
|
|
|
|
return nil, utils.WrapPathError(err, name)
|
|
|
|
}
|
|
|
|
name = templates.VariableMap(lfm).String("layout", "")
|
|
|
|
}
|
|
|
|
return data, nil
|
|
|
|
}
|
|
|
|
|
2017-06-16 21:14:56 +02:00
|
|
|
// FindLayout returns a template for the named layout.
|
2017-07-10 15:17:31 +02:00
|
|
|
func (p *Pipeline) FindLayout(base string, fm *map[string]interface{}) (tpl *liquid.Template, err error) {
|
2017-07-14 18:12:25 +02:00
|
|
|
// not cached, but the time here is negligible
|
2017-06-16 21:14:56 +02:00
|
|
|
exts := []string{"", ".html"}
|
2017-06-24 19:30:01 +02:00
|
|
|
for _, ext := range strings.SplitN(p.config.MarkdownExt, `,`, -1) {
|
2017-06-16 21:14:56 +02:00
|
|
|
exts = append(exts, "."+ext)
|
|
|
|
}
|
|
|
|
var (
|
2017-07-01 03:06:12 +02:00
|
|
|
filename string
|
|
|
|
content []byte
|
|
|
|
found bool
|
2017-06-16 21:14:56 +02:00
|
|
|
)
|
2017-07-24 14:09:14 +02:00
|
|
|
loop:
|
|
|
|
for _, dir := range p.layoutDirs() {
|
|
|
|
for _, ext := range exts {
|
|
|
|
filename = filepath.Join(dir, base+ext)
|
|
|
|
content, err = ioutil.ReadFile(filename)
|
|
|
|
if err == nil {
|
|
|
|
found = true
|
|
|
|
break loop
|
|
|
|
}
|
|
|
|
if !os.IsNotExist(err) {
|
|
|
|
return nil, err
|
|
|
|
}
|
2017-06-16 21:14:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
2017-06-29 13:41:14 +02:00
|
|
|
return nil, fmt.Errorf("no template for %s", base)
|
2017-06-16 21:14:56 +02:00
|
|
|
}
|
2017-07-09 17:57:20 +02:00
|
|
|
lineNo := 1
|
|
|
|
*fm, err = frontmatter.Read(&content, &lineNo)
|
2017-06-16 21:14:56 +02:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2017-07-14 16:57:14 +02:00
|
|
|
tpl, err = p.liquidEngine.ParseTemplateLocation(content, filename, lineNo)
|
2017-07-04 23:13:47 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return
|
2017-06-24 19:30:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// LayoutsDir returns the path to the layouts directory.
|
2017-07-24 14:09:14 +02:00
|
|
|
func (p *Pipeline) layoutDirs() []string {
|
|
|
|
dirs := []string{filepath.Join(p.SourceDir(), p.config.LayoutsDir)}
|
|
|
|
if p.ThemeDir != "" {
|
|
|
|
dirs = append(dirs, filepath.Join(p.ThemeDir, "_layouts"))
|
|
|
|
}
|
|
|
|
return dirs
|
2017-06-16 21:14:56 +02:00
|
|
|
}
|