1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-27 08:44:41 +01:00
gojekyll/pipelines/pipeline.go

121 lines
3.2 KiB
Go
Raw Normal View History

2017-06-24 20:00:19 +02:00
package pipelines
2017-06-24 19:30:01 +02:00
import (
"io"
"io/ioutil"
"path/filepath"
"github.com/osteele/gojekyll/config"
"github.com/osteele/gojekyll/helpers"
"github.com/osteele/gojekyll/liquid"
"github.com/osteele/gojekyll/templates"
"github.com/russross/blackfriday"
)
2017-06-24 20:00:19 +02:00
// PipelineInterface applies transformations to a document.
type PipelineInterface interface {
ApplyLayout(string, []byte, templates.VariableMap) ([]byte, error)
OutputExt(pathname string) string
Render(io.Writer, []byte, string, templates.VariableMap) ([]byte, error)
}
2017-06-24 19:30:01 +02:00
// Pipeline applies a rendering transformation to a file.
type Pipeline struct {
PipelineOptions
2017-06-24 19:30:01 +02:00
config config.Config
liquidEngine liquid.Engine
sassTempDir string
}
// PipelineOptions configures a pipeline.
type PipelineOptions struct {
SourceDir string
RelativeFilenameToURL liquid.LinkTagHandler
2017-06-24 19:30:01 +02:00
}
// NewPipeline makes a rendering pipeline.
func NewPipeline(c config.Config, options PipelineOptions) (*Pipeline, error) {
p := Pipeline{PipelineOptions: options, config: c}
2017-06-29 13:27:43 +02:00
p.liquidEngine = p.makeLiquidEngine()
2017-06-24 19:30:01 +02:00
if err := p.CopySassFileIncludes(); err != nil {
return nil, err
}
return &p, nil
}
2017-06-30 18:53:34 +02:00
// Engine returns the Liquid engine.
func (p *Pipeline) TemplateEngine() liquid.Engine {
return p.liquidEngine
}
2017-06-24 19:30:01 +02:00
// OutputExt returns the output extension.
func (p *Pipeline) OutputExt(pathname string) string {
return p.config.OutputExt(pathname)
}
// Render returns nil iff it wrote to the writer
func (p *Pipeline) Render(w io.Writer, b []byte, filename string, e templates.VariableMap) ([]byte, error) {
if p.config.IsSassPath(filename) {
return nil, p.WriteSass(w, b)
}
b, err := p.renderTemplate(b, e, filename)
if err != nil {
return nil, err
}
if p.config.IsMarkdown(filename) {
b = blackfriday.MarkdownCommon(b)
}
return b, nil
}
func (p *Pipeline) renderTemplate(b []byte, e templates.VariableMap, filename string) ([]byte, error) {
b, err := p.liquidEngine.ParseAndRender(b, e)
if err != nil {
2017-06-29 13:27:43 +02:00
return nil, helpers.PathError(err, "Liquid Error", filename)
2017-06-24 19:30:01 +02:00
}
return b, err
}
// ApplyLayout applies the named layout to the data.
func (p *Pipeline) ApplyLayout(name string, data []byte, e templates.VariableMap) ([]byte, error) {
2017-06-24 19:30:01 +02:00
for name != "" {
var lfm templates.VariableMap
t, err := p.FindLayout(name, &lfm)
if err != nil {
return nil, err
}
le := templates.MergeVariableMaps(e, templates.VariableMap{
"content": string(data),
2017-06-24 19:30:01 +02:00
"layout": lfm,
})
data, err = t.Render(le)
2017-06-24 19:30:01 +02:00
if err != nil {
return nil, helpers.PathError(err, "render template", name)
2017-06-24 19:30:01 +02:00
}
name = lfm.String("layout", "")
}
return data, nil
2017-06-24 19:30:01 +02:00
}
2017-06-29 13:27:43 +02:00
func (p *Pipeline) makeLiquidEngine() liquid.Engine {
engine := liquid.NewEngine()
2017-06-24 19:30:01 +02:00
includeHandler := func(name string, w io.Writer, scope map[string]interface{}) error {
filename := filepath.Join(p.SourceDir, p.config.IncludesDir, name)
2017-06-24 19:30:01 +02:00
template, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
text, err := engine.ParseAndRender(template, scope)
if err != nil {
return err
}
_, err = w.Write(text)
return err
}
2017-06-30 18:53:34 +02:00
engine.AbsoluteURL = p.config.AbsoluteURL
engine.BaseURL = p.config.BaseURL
2017-06-24 19:30:01 +02:00
engine.IncludeHandler(includeHandler)
engine.LinkTagHandler(p.RelativeFilenameToURL)
2017-06-24 19:30:01 +02:00
return engine
}