From e21d2a736da6b81c76d80d023d11cf04b57354d6 Mon Sep 17 00:00:00 2001 From: Oliver Steele Date: Tue, 27 Jun 2017 07:43:42 -0400 Subject: [PATCH] Add public DefineTag --- chunks/definitions.go | 17 +++++++++++------ liquid.go => engine.go | 35 ++++++++--------------------------- template.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 33 deletions(-) rename liquid.go => engine.go (67%) create mode 100644 template.go diff --git a/chunks/definitions.go b/chunks/definitions.go index b148509..b9295e4 100644 --- a/chunks/definitions.go +++ b/chunks/definitions.go @@ -18,10 +18,15 @@ func assignTagDef(source string) (func(io.Writer, Context) error, error) { }, nil } -func FindTagDefinition(name string) (TagDefinition, bool) { - switch name { - case "assign": - return assignTagDef, true - } - return nil, false +var tagDefinitions = map[string]TagDefinition{ + "assign": assignTagDef, +} + +func DefineTag(name string, td TagDefinition) { + tagDefinitions[name] = td +} + +func FindTagDefinition(name string) (TagDefinition, bool) { + td, ok := tagDefinitions[name] + return td, ok } diff --git a/liquid.go b/engine.go similarity index 67% rename from liquid.go rename to engine.go index 3780513..932e8b2 100644 --- a/liquid.go +++ b/engine.go @@ -6,7 +6,7 @@ It's intended for use in for use in https://github.com/osteele/gojekyll. package liquid import ( - "bytes" + "io" "github.com/osteele/liquid/chunks" ) @@ -15,18 +15,14 @@ import ( // // In the future, it will be configured with additional tags, filters, and the {%include%} search path. type Engine interface { + DefineTag(string, func(form string) (func(io.Writer, chunks.Context) error, error)) + ParseTemplate(text []byte) (Template, error) ParseAndRender(text []byte, scope map[string]interface{}) ([]byte, error) ParseAndRenderString(text string, scope map[string]interface{}) (string, error) } -// Template renders a template according to scope. -// -// Scope is a map of liquid variable names to objects. -type Template interface { - Render(scope map[string]interface{}) ([]byte, error) - RenderString(scope map[string]interface{}) (string, error) -} +type TagDefinition func(expr string) (func(io.Writer, chunks.Context) error, error) type engine struct{} @@ -39,6 +35,10 @@ func NewEngine() Engine { return engine{} } +func (e engine) DefineTag(name string, td func(form string) (func(io.Writer, chunks.Context) error, error)) { + chunks.DefineTag(name, chunks.TagDefinition(td)) +} + func (e engine) ParseTemplate(text []byte) (Template, error) { tokens := chunks.Scan(string(text), "") ast, err := chunks.Parse(tokens) @@ -66,22 +66,3 @@ func (e engine) ParseAndRenderString(text string, scope map[string]interface{}) } return string(b), nil } - -// Render applies the template to the scope. -func (t *template) Render(scope map[string]interface{}) ([]byte, error) { - buf := new(bytes.Buffer) - err := t.ast.Render(buf, chunks.NewContext(scope)) - if err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -// RenderString is a convenience wrapper for Render, that has string input and output. -func (t *template) RenderString(scope map[string]interface{}) (string, error) { - b, err := t.Render(scope) - if err != nil { - return "", err - } - return string(b), nil -} diff --git a/template.go b/template.go new file mode 100644 index 0000000..9150a38 --- /dev/null +++ b/template.go @@ -0,0 +1,34 @@ +package liquid + +import ( + "bytes" + + "github.com/osteele/liquid/chunks" +) + +// Template renders a template according to scope. +// +// Scope is a map of liquid variable names to objects. +type Template interface { + Render(scope map[string]interface{}) ([]byte, error) + RenderString(scope map[string]interface{}) (string, error) +} + +// Render applies the template to the scope. +func (t *template) Render(scope map[string]interface{}) ([]byte, error) { + buf := new(bytes.Buffer) + err := t.ast.Render(buf, chunks.NewContext(scope)) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// RenderString is a convenience wrapper for Render, that has string input and output. +func (t *template) RenderString(scope map[string]interface{}) (string, error) { + b, err := t.Render(scope) + if err != nil { + return "", err + } + return string(b), nil +}