1
0
mirror of https://github.com/danog/gojekyll.git synced 2025-01-22 20:41:13 +01:00

Implement liquid includes

This commit is contained in:
Oliver Steele 2017-06-16 23:36:27 -04:00
parent a7ae4bc3c6
commit f9c1469d6b
5 changed files with 42 additions and 12 deletions

View File

@ -129,8 +129,8 @@ func (p *DynamicPage) DebugVariables() VariableMap {
// Write applies Liquid and Markdown, as appropriate. // Write applies Liquid and Markdown, as appropriate.
func (p *DynamicPage) Write(w io.Writer) (err error) { func (p *DynamicPage) Write(w io.Writer) (err error) {
p.site.ConfigureLiquid() config := p.site.LiquidConfiguration()
body, err := helpers.ParseAndApplyTemplate(p.Content, p.TemplateVariables()) body, err := helpers.ParseAndApplyTemplate(p.Content, p.TemplateVariables(), config)
if err != nil { if err != nil {
err = &os.PathError{Op: "Liquid Error", Path: p.Source(), Err: err} err = &os.PathError{Op: "Liquid Error", Path: p.Source(), Err: err}
return return
@ -138,7 +138,7 @@ func (p *DynamicPage) Write(w io.Writer) (err error) {
if p.Site().IsMarkdown(p.relpath) { if p.Site().IsMarkdown(p.relpath) {
body = blackfriday.MarkdownCommon(body) body = blackfriday.MarkdownCommon(body)
body, err = p.applyLayout(p.frontMatter, body) body, err = p.applyLayout(p.frontMatter, body, config)
if err != nil { if err != nil {
return return
} }

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"github.com/acstech/liquid" "github.com/acstech/liquid"
"github.com/acstech/liquid/core"
) )
// RenderTemplate is a wrapper around liquid template.Render that turns panics into errors // RenderTemplate is a wrapper around liquid template.Render that turns panics into errors
@ -23,8 +24,8 @@ func RenderTemplate(template *liquid.Template, variables map[string]interface{})
} }
// ParseAndApplyTemplate parses and then renders the template. // ParseAndApplyTemplate parses and then renders the template.
func ParseAndApplyTemplate(bs []byte, variables map[string]interface{}) ([]byte, error) { func ParseAndApplyTemplate(bs []byte, variables map[string]interface{}, config *core.Configuration) ([]byte, error) {
template, err := liquid.Parse(bs, nil) template, err := liquid.Parse(bs, config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/osteele/gojekyll/helpers" "github.com/osteele/gojekyll/helpers"
"github.com/acstech/liquid" "github.com/acstech/liquid"
"github.com/acstech/liquid/core"
) )
// FindLayout returns a template for the named layout. // FindLayout returns a template for the named layout.
@ -42,10 +43,10 @@ func (s *Site) FindLayout(base string, fm *VariableMap) (t *liquid.Template, err
if err != nil { if err != nil {
return return
} }
return liquid.Parse(content, nil) return liquid.Parse(content, s.LiquidConfiguration())
} }
func (p *DynamicPage) applyLayout(frontMatter VariableMap, body []byte) ([]byte, error) { func (p *DynamicPage) applyLayout(frontMatter VariableMap, body []byte, config *core.Configuration) ([]byte, error) {
for { for {
layoutName := frontMatter.String("layout", "") layoutName := frontMatter.String("layout", "")
if layoutName == "" { if layoutName == "" {

37
site.go
View File

@ -1,14 +1,18 @@
package main package main
import ( import (
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
"time" "time"
"github.com/acstech/liquid"
"github.com/acstech/liquid/core"
"github.com/osteele/gojekyll/helpers" "github.com/osteele/gojekyll/helpers"
"github.com/osteele/gojekyll/liquid" liquidHelper "github.com/osteele/gojekyll/liquid"
) )
// Site is a Jekyll site. // Site is a Jekyll site.
@ -21,8 +25,9 @@ type Site struct {
Variables VariableMap Variables VariableMap
Paths map[string]Page // URL path -> Page Paths map[string]Page // URL path -> Page
config SiteConfig config SiteConfig
sassTempDir string liquidConfiguration *core.Configuration
sassTempDir string
} }
// NewSite creates a new site record, initialized with the site defaults. // NewSite creates a new site record, initialized with the site defaults.
@ -100,11 +105,14 @@ func (s *Site) LayoutsDir() string {
func (s *Site) ReadFiles() error { func (s *Site) ReadFiles() error {
s.Paths = make(map[string]Page) s.Paths = make(map[string]Page)
walkFn := func(name string, info os.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
} }
relname, err := filepath.Rel(s.Source, name)
if err != nil { if err != nil {
panic(err)
} }
switch { switch {
case info.IsDir() && s.Exclude(relname): case info.IsDir() && s.Exclude(relname):
@ -112,6 +120,8 @@ func (s *Site) ReadFiles() error {
case info.IsDir(), s.Exclude(relname): case info.IsDir(), s.Exclude(relname):
return nil return nil
} }
defaults := s.GetFrontMatterDefaults(relname, "")
p, err := ReadPage(s, nil, relname, defaults)
if err != nil { if err != nil {
return err return err
} }
@ -141,8 +151,25 @@ func (s *Site) initTemplateAttributes() {
} }
} }
func (s *Site) ConfigureLiquid() { // LiquidConfiguration configures the liquid tags with site-specific behavior.
liquid.SetFilePathURLGetter(s.GetFileURL) func (s *Site) LiquidConfiguration() *core.Configuration {
if s.liquidConfiguration != nil {
return s.liquidConfiguration
}
liquidHelper.SetFilePathURLGetter(s.GetFileURL)
includeHandler := func(name string, writer io.Writer, data map[string]interface{}) {
name = strings.TrimLeft(strings.TrimRight(name, "}}"), "{{")
filename := path.Join(s.Source, s.config.IncludesDir, name)
template, err := liquid.ParseFile(filename, s.liquidConfiguration)
if err != nil {
panic(err)
}
template.Render(writer, data)
}
s.liquidConfiguration = liquid.Configure().IncludeHandler(includeHandler)
return s.liquidConfiguration
}
// GetFrontMatterDefaults implements https://jekyllrb.com/docs/configuration/#front-matter-defaults // GetFrontMatterDefaults implements https://jekyllrb.com/docs/configuration/#front-matter-defaults
func (s *Site) GetFrontMatterDefaults(relpath, typename string) (m VariableMap) { func (s *Site) GetFrontMatterDefaults(relpath, typename string) (m VariableMap) {
for _, entry := range s.config.Defaults { for _, entry := range s.config.Defaults {

View File

@ -9,6 +9,7 @@ type SiteConfig struct {
Source string Source string
Destination string Destination string
LayoutsDir string `yaml:"layouts_dir"` LayoutsDir string `yaml:"layouts_dir"`
IncludesDir string `yaml:"includes_dir"`
Collections map[string]VariableMap Collections map[string]VariableMap
// Handling Reading // Handling Reading