jet

package module
v2.1.3+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 2, 2018 License: Apache-2.0 Imports: 20 Imported by: 0

README

Jet Template Engine for Go Build Status

Jet is a template engine developed to be easy to use, powerful, dynamic, yet secure and very fast.

  • supports template inheritance with extends, import and include statements
  • descriptive error messages with filename and line number
  • auto-escape
  • simple C-like expressions
  • very fast execution – Jet can execute templates faster than some pre-compiled template engines
  • very light in terms of allocations and memory footprint
  • simple and familiar syntax
  • easy to use

You can find the documentation in the wiki.

Upgrade to v2

The last release of v1 was v1.2 which is available at https://github.com/CloudyKit/jet/releases/tag/v1.2 and the tag v1.2.

To upgrade to v2 a few updates to your templates are necessary – these are explained in the upgrade guide.

IntelliJ Plugin

If you use IntelliJ there is a plugin available at https://github.com/jhsx/GoJetPlugin. There is also a very good Go plugin for IntelliJ – see https://github.com/go-lang-plugin-org/go-lang-idea-plugin. GoJetPlugin + Go-lang-idea-plugin = happiness!

Examples

You can find examples in the wiki.

Running the example application

An example application is available in the repository. Use go get -u github.com/CloudyKit/jet or clone the repository into $GOPATH/github.com/CloudyKit/jet, then do:

  $ cd examples/todos; go run main.go
Faster than some pre-compiled template engines

The benchmark consists of a range over a slice of data printing the values, the benchmark is based on https://github.com/SlinSo/goTemplateBenchmark, Jet performs better than all template engines without pre-compilation, and performs better than gorazor, Ftmpl and Egon, all of which are pre-compiled to Go.

Benchmarks

go 1.6.2

PASS
BenchmarkEgonSlinso-4      	 2000000	       989 ns/op	     517 B/op	       0 allocs/op
BenchmarkQuicktemplate-4   	 1000000	      1004 ns/op	     999 B/op	       0 allocs/op
BenchmarkEgo-4             	 1000000	      2137 ns/op	     603 B/op	       8 allocs/op

BenchmarkJet-4             	  500000	      2798 ns/op	     536 B/op	       0 allocs/op
BenchmarkJetHTML-4         	  500000	      2822 ns/op	     536 B/op	       0 allocs/op

BenchmarkGorazor-4         	  500000	      3028 ns/op	     613 B/op	      11 allocs/op
BenchmarkFtmpl-4           	  500000	      3192 ns/op	    1152 B/op	      12 allocs/op
BenchmarkEgon-4            	  300000	      4673 ns/op	    1172 B/op	      22 allocs/op
BenchmarkKasia-4           	  200000	      6902 ns/op	    1789 B/op	      26 allocs/op
BenchmarkSoy-4             	  200000	      7144 ns/op	    1684 B/op	      26 allocs/op
BenchmarkMustache-4        	  200000	      8213 ns/op	    1568 B/op	      28 allocs/op
BenchmarkPongo2-4          	  200000	      9989 ns/op	    2949 B/op	      46 allocs/op
BenchmarkGolang-4          	  100000	     16284 ns/op	    2039 B/op	      38 allocs/op
BenchmarkAmber-4           	  100000	     17208 ns/op	    2050 B/op	      39 allocs/op
BenchmarkHandlebars-4      	   50000	     29864 ns/op	    4258 B/op	      90 allocs/op
BenchmarkAce-4             	   30000	     40771 ns/op	    5710 B/op	      77 allocs/op
BenchmarkDamsel-4          	   20000	     95947 ns/op	   11160 B/op	     165 allocs/op
ok  	github.com/SlinSo/goTemplateBenchmark	34.384s

go tip

BenchmarkQuicktemplate-4      	 2000000	       916 ns/op	     999 B/op	       0 allocs/op
BenchmarkEgonSlinso-4         	 2000000	      1074 ns/op	     517 B/op	       0 allocs/op
BenchmarkEgo-4                	 1000000	      1822 ns/op	     603 B/op	       8 allocs/op

BenchmarkJetHTML-4            	  500000	      2627 ns/op	     536 B/op	       0 allocs/op
BenchmarkJet-4                	  500000	      2652 ns/op	     536 B/op	       0 allocs/op

BenchmarkFtmpl-4              	  500000	      2700 ns/op	    1152 B/op	      12 allocs/op
BenchmarkGorazor-4            	  500000	      2858 ns/op	     613 B/op	      11 allocs/op
BenchmarkEgon-4               	  500000	      4023 ns/op	     827 B/op	      22 allocs/op
BenchmarkSoy-4                	  300000	      5590 ns/op	    1784 B/op	      26 allocs/op
BenchmarkKasia-4              	  200000	      6487 ns/op	    1789 B/op	      26 allocs/op
BenchmarkMustache-4           	  200000	      6515 ns/op	    1568 B/op	      28 allocs/op
BenchmarkPongo2-4             	  200000	      7602 ns/op	    2949 B/op	      46 allocs/op
BenchmarkAmber-4              	  100000	     13942 ns/op	    2050 B/op	      39 allocs/op
BenchmarkGolang-4             	  100000	     16945 ns/op	    2039 B/op	      38 allocs/op
BenchmarkHandlebars-4         	  100000	     20152 ns/op	    4258 B/op	      90 allocs/op
BenchmarkAce-4                	   50000	     33091 ns/op	    5509 B/op	      77 allocs/op
BenchmarkDamsel-4             	   20000	     86340 ns/op	   11159 B/op	     165 allocs/op
PASS
ok  	github.com/SlinSo/goTemplateBenchmark	36.200s
Contributing

All contributions are welcome – if you find a bug please report it.

Thanks
  • @golang developers for the awesome language and the standard library
  • @SlinSo for the benchmarks that I used as a base to show the results above

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsEmptyTree

func IsEmptyTree(n Node) bool

IsEmptyTree reports whether this tree (node) is empty of everything but space.

Types

type ActionNode

type ActionNode struct {
	NodeBase
	Set  *SetNode
	Pipe *PipeNode
}

ActionNode holds an action (something bounded by delimiters). Control actions have their own nodes; ActionNode represents simple ones such as field evaluations and parenthesized pipelines.

func (*ActionNode) String

func (a *ActionNode) String() string

type AdditiveExprNode

type AdditiveExprNode struct {
	// contains filtered or unexported fields
}

AdditiveExprNode represents an add or subtract expression ex: expression ( '+' | '-' ) expression

func (*AdditiveExprNode) String

func (node *AdditiveExprNode) String() string

type Arguments

type Arguments struct {
	// contains filtered or unexported fields
}

Arguments holds the arguments passed to jet.Func.

func (*Arguments) Get

func (a *Arguments) Get(argumentIndex int) reflect.Value

Get gets an argument by index.

func (*Arguments) NumOfArguments

func (a *Arguments) NumOfArguments() int

NumOfArguments returns the number of arguments

func (*Arguments) Panicf

func (a *Arguments) Panicf(format string, v ...interface{})

Panicf panics with formatted error message.

func (*Arguments) RequireNumOfArguments

func (a *Arguments) RequireNumOfArguments(funcname string, min, max int)

RequireNumOfArguments panics if the number of arguments is not in the range specified by min and max. In case there is no minimum pass -1, in case there is no maximum pass -1 respectively.

func (*Arguments) Runtime

func (a *Arguments) Runtime() *Runtime

Runtime get the Runtime context

type BlockNode

type BlockNode struct {
	NodeBase        //The line number in the input. Deprecated: Kept for compatibility.
	Name     string //The name of the template (unquoted).

	Parameters *BlockParameterList
	Expression Expression //The command to evaluate as dot for the template.

	List    *ListNode
	Content *ListNode
}

BlockNode represents a {{block }} action.

func (*BlockNode) String

func (t *BlockNode) String() string

type BlockParameter

type BlockParameter struct {
	Identifier string
	Expression Expression
}

type BlockParameterList

type BlockParameterList struct {
	NodeBase
	List []BlockParameter
}

func (*BlockParameterList) Param

func (bplist *BlockParameterList) Param(name string) (Expression, int)

func (*BlockParameterList) String

func (bplist *BlockParameterList) String() (str string)

type BoolNode

type BoolNode struct {
	NodeBase
	True bool //The value of the boolean constant.
}

BoolNode holds a boolean constant.

func (*BoolNode) String

func (b *BoolNode) String() string

type BranchNode

type BranchNode struct {
	NodeBase
	Set        *SetNode
	Expression Expression
	List       *ListNode
	ElseList   *ListNode
}

BranchNode is the common representation of if, range, and with.

func (*BranchNode) String

func (b *BranchNode) String() string

type CallExprNode

type CallExprNode struct {
	NodeBase
	BaseExpr Expression
	Args     []Expression
}

CallExprNode represents a call expression ex: expression '(' (expression (',' expression)* )? ')'

func (*CallExprNode) String

func (s *CallExprNode) String() string

type ChainNode

type ChainNode struct {
	NodeBase
	Node  Node
	Field []string //The identifiers in lexical order.
}

ChainNode holds a term followed by a chain of field accesses (identifier starting with '.'). The names may be chained ('.x.y'). The periods are dropped from each ident.

func (*ChainNode) Add

func (c *ChainNode) Add(field string)

Add adds the named field (which should start with a period) to the end of the chain.

func (*ChainNode) String

func (c *ChainNode) String() string

type CommandNode

type CommandNode struct {
	NodeBase
	Call     bool
	BaseExpr Expression
	Args     []Expression
}

CommandNode holds a command (a pipeline inside an evaluating action).

func (*CommandNode) String

func (c *CommandNode) String() string

type ComparativeExprNode

type ComparativeExprNode struct {
	// contains filtered or unexported fields
}

ComparativeExprNode represents a comparative expression ex: expression ( '==' | '!=' ) expression

func (*ComparativeExprNode) String

func (node *ComparativeExprNode) String() string

type Expression

type Expression interface {
	Node
}

type FieldNode

type FieldNode struct {
	NodeBase
	Ident []string //The identifiers in lexical order.
}

FieldNode holds a field (identifier starting with '.'). The names may be chained ('.x.y'). The period is dropped from each ident.

func (*FieldNode) String

func (f *FieldNode) String() string

type Func

type Func func(Arguments) reflect.Value

Func function implementing this type is called directly, which is faster than calling through reflect. If a function is being called many times in the execution of a template, you may consider implementing a wrapper for that function implementing a Func.

type IdentifierNode

type IdentifierNode struct {
	NodeBase
	Ident string //The identifier's name.
}

IdentifierNode holds an identifier.

func (*IdentifierNode) String

func (i *IdentifierNode) String() string

type IfNode

type IfNode struct {
	BranchNode
}

IfNode represents an {{if}} action and its commands.

type IncludeNode

type IncludeNode struct {
	NodeBase
	Name       Expression
	Expression Expression
}

IncludeNode represents a {{include }} action.

func (*IncludeNode) String

func (t *IncludeNode) String() string

type IndexExprNode

type IndexExprNode struct {
	NodeBase
	Base  Expression
	Index Expression
}

func (*IndexExprNode) String

func (s *IndexExprNode) String() string

type ListNode

type ListNode struct {
	NodeBase
	Nodes []Node //The element nodes in lexical order.
}

ListNode holds a sequence of nodes.

func (*ListNode) String

func (l *ListNode) String() string

type Loader

type Loader interface {
	// Open opens the underlying reader with template content.
	Open(name string) (io.ReadCloser, error)
	// Exists checks for template existence and returns full path.
	Exists(name string) (string, bool)
}

Loader is a minimal interface required for loading templates.

type LogicalExprNode

type LogicalExprNode struct {
	// contains filtered or unexported fields
}

LogicalExprNode represents a boolean expression, 'and' or 'or' ex: expression ( '&&' | '||' ) expression

func (*LogicalExprNode) String

func (node *LogicalExprNode) String() string

type MultiplicativeExprNode

type MultiplicativeExprNode struct {
	// contains filtered or unexported fields
}

MultiplicativeExprNode represents a multiplication, division, or module expression ex: expression ( '*' | '/' | '%' ) expression

func (*MultiplicativeExprNode) String

func (node *MultiplicativeExprNode) String() string

type NilNode

type NilNode struct {
	NodeBase
}

NilNode holds the special identifier 'nil' representing an untyped nil constant.

func (*NilNode) String

func (n *NilNode) String() string

type Node

type Node interface {
	Type() NodeType
	String() string
	Position() Pos
	// contains filtered or unexported methods
}

type NodeBase

type NodeBase struct {
	TemplateName string
	Line         int
	NodeType
	Pos
}

type NodeType

type NodeType int

NodeType identifies the type of a parse tree node.

const (
	NodeText    NodeType = iota //Plain text.
	NodeAction                  //A non-control action such as a field evaluation.
	NodeChain                   //A sequence of field accesses.
	NodeCommand                 //An element of a pipeline.

	NodeField      //A field or method name.
	NodeIdentifier //An identifier; always a function name.
	NodeIf         //An if action.
	NodeList       //A list of Nodes.
	NodePipe       //A pipeline of commands.
	NodeRange      //A range action.

	//NodeWith                       //A with action.
	NodeBlock
	NodeInclude
	NodeYield
	NodeSet

	NodeString //A string constant.
	NodeNil    //An untyped nil constant.
	NodeNumber //A numerical constant.
	NodeBool   //A boolean constant.
	NodeAdditiveExpr
	NodeMultiplicativeExpr
	NodeComparativeExpr
	NodeNumericComparativeExpr
	NodeLogicalExpr
	NodeCallExpr
	NodeNotExpr
	NodeTernaryExpr
	NodeIndexExpr
	NodeSliceExpr
)

func (NodeType) Type

func (t NodeType) Type() NodeType

Type returns itself and provides an easy default implementation for embedding in a Node. Embedded in all non-trivial Nodes.

type NotExprNode

type NotExprNode struct {
	NodeBase
	Expr Expression
}

NotExprNode represents a negate expression ex: '!' expression

func (*NotExprNode) String

func (s *NotExprNode) String() string

type NumberNode

type NumberNode struct {
	NodeBase

	IsInt      bool       //Number has an integral value.
	IsUint     bool       //Number has an unsigned integral value.
	IsFloat    bool       //Number has a floating-point value.
	IsComplex  bool       //Number is complex.
	Int64      int64      //The signed integer value.
	Uint64     uint64     //The unsigned integer value.
	Float64    float64    //The floating-point value.
	Complex128 complex128 //The complex value.
	Text       string     //The original textual representation from the input.
}

NumberNode holds a number: signed or unsigned integer, float, or complex. The value is parsed and stored under all the types that can represent the value. This simulates in a small amount of code the behavior of Go's ideal constants.

func (*NumberNode) String

func (n *NumberNode) String() string

type NumericComparativeExprNode

type NumericComparativeExprNode struct {
	// contains filtered or unexported fields
}

NumericComparativeExprNode represents a numeric comparative expression ex: expression ( '<' | '>' | '<=' | '>=' ) expression

func (*NumericComparativeExprNode) String

func (node *NumericComparativeExprNode) String() string

type OSFileSystemLoader

type OSFileSystemLoader struct {
	// contains filtered or unexported fields
}

OSFileSystemLoader implements Loader interface using OS file system (os.File).

func NewOSFileSystemLoader

func NewOSFileSystemLoader(paths ...string) *OSFileSystemLoader

NewOSFileSystemLoader returns an initialized OSFileSystemLoader.

func (*OSFileSystemLoader) AddGopathPath

func (l *OSFileSystemLoader) AddGopathPath(path string)

AddGopathPath adds a path located in the GOPATH. Example: l.AddGopathPath("github.com/CloudyKit/jet/example/views")

func (*OSFileSystemLoader) AddPath

func (l *OSFileSystemLoader) AddPath(path string)

AddPath adds the path to the internal list of paths searched when loading templates.

func (*OSFileSystemLoader) Exists

func (l *OSFileSystemLoader) Exists(name string) (string, bool)

Exists checks if the template name exists by walking the list of template paths returns string with the full path of the template and bool true if the template file was found

func (*OSFileSystemLoader) Open

func (l *OSFileSystemLoader) Open(name string) (io.ReadCloser, error)

Open opens a file from OS file system.

type PipeNode

type PipeNode struct {
	NodeBase                //The line number in the input. Deprecated: Kept for compatibility.
	Cmds     []*CommandNode //The commands in lexical order.
}

PipeNode holds a pipeline with optional declaration

func (*PipeNode) String

func (p *PipeNode) String() string

type Pos

type Pos int

Pos represents a byte position in the original input text from which this template was parsed.

func (Pos) Position

func (p Pos) Position() Pos

type RangeNode

type RangeNode struct {
	BranchNode
}

RangeNode represents a {{range}} action and its commands.

type Ranger

type Ranger interface {
	Range() (reflect.Value, reflect.Value, bool)
}

Ranger a value implementing a ranger interface is able to iterate on his value and can be used directly in a range statement

type Renderer

type Renderer interface {
	Render(*Runtime)
}

Renderer any resulting value from an expression in an action that implements this interface will not be printed, instead, we will invoke his Render() method which will be responsible to render his self

type RendererFunc

type RendererFunc func(*Runtime)

RendererFunc func implementing interface Renderer

func (RendererFunc) Render

func (renderer RendererFunc) Render(r *Runtime)

type Runtime

type Runtime struct {
	// contains filtered or unexported fields
}

Runtime this type holds the state of the execution of an template

func (*Runtime) Context

func (r *Runtime) Context() reflect.Value

Context returns the current context value

func (*Runtime) Resolve

func (state *Runtime) Resolve(name string) reflect.Value

Resolve resolves a value from the execution context

func (*Runtime) Set

func (state *Runtime) Set(name string, val interface{})

Set sets variable ${name} in the current template scope

func (Runtime) Write

func (w Runtime) Write(b []byte) (int, error)

func (*Runtime) YieldBlock

func (st *Runtime) YieldBlock(name string, context interface{})

YieldBlock yields a block in the current context, will panic if the context is not available

func (*Runtime) YieldTemplate

func (st *Runtime) YieldTemplate(name string, context interface{})

YieldTemplate yields a template same as include

type SafeWriter

type SafeWriter func(io.Writer, []byte)

SafeWriter escapee func. Functions implementing this type will write directly into the writer, skipping the escape phase; use this type to create special types of escapee funcs.

type Set

type Set struct {
	// contains filtered or unexported fields
}

Set is responsible to load,invoke parse and cache templates and relations every jet template is associated with one set. create a set with jet.NewSet(escapeeFn) returns a pointer to the Set

func NewHTMLSet

func NewHTMLSet(dirs ...string) *Set

NewHTMLSet creates a new set, dirs is a list of directories to be searched for templates

func NewHTMLSetLoader

func NewHTMLSetLoader(loader Loader) *Set

NewHTMLSetLoader creates a new set with custom Loader

func NewSet

func NewSet(escapee SafeWriter, dirs ...string) *Set

NewSet creates a new set, dirs is a list of directories to be searched for templates

func NewSetLoader

func NewSetLoader(escapee SafeWriter, loader Loader) *Set

NewSetLoader creates a new set with custom Loader

func (*Set) AddGlobal

func (s *Set) AddGlobal(key string, i interface{}) *Set

AddGlobal add or set a global variable into the Set

func (*Set) AddGlobalFunc

func (s *Set) AddGlobalFunc(key string, fn Func) *Set

func (*Set) AddGopathPath

func (s *Set) AddGopathPath(path string)

AddGopathPath add path based on GOPATH env to the lookup list, when loading a template the Set will look into the lookup list for the file matching the provided name.

func (*Set) AddPath

func (s *Set) AddPath(path string)

AddPath add path to the lookup list, when loading a template the Set will look into the lookup list for the file matching the provided name.

func (*Set) GetTemplate

func (s *Set) GetTemplate(name string) (template *Template, err error)

func (*Set) LoadTemplate

func (s *Set) LoadTemplate(name, content string) (template *Template, err error)

func (*Set) LookupGlobal

func (a *Set) LookupGlobal(key string) (val interface{}, found bool)

func (*Set) Parse

func (s *Set) Parse(name, content string) (*Template, error)

Parse parses the template, this method will link the template to the set but not the set to

func (*Set) SetDevelopmentMode

func (s *Set) SetDevelopmentMode(b bool) *Set

SetDevelopmentMode set's development mode on/off, in development mode template will be recompiled on every run

type SetNode

type SetNode struct {
	NodeBase
	Let                bool
	IndexExprGetLookup bool
	Left               []Expression
	Right              []Expression
}

SetNode represents a set action, ident( ',' ident)* '=' expression ( ',' expression )*

func (*SetNode) String

func (set *SetNode) String() string

type SliceExprNode

type SliceExprNode struct {
	NodeBase
	Base     Expression
	Index    Expression
	EndIndex Expression
}

func (*SliceExprNode) String

func (s *SliceExprNode) String() string

type StringNode

type StringNode struct {
	NodeBase

	Quoted string //The original text of the string, with quotes.
	Text   string //The string, after quote processing.
}

StringNode holds a string constant. The value has been "unquoted".

func (*StringNode) String

func (s *StringNode) String() string

type Template

type Template struct {
	Name      string // name of the template represented by the tree.
	ParseName string // name of the top-level template during parsing, for error messages.

	Root *ListNode // top-level root of the tree.
	// contains filtered or unexported fields
}

Template is the representation of a single parsed template.

func (*Template) Execute

func (t *Template) Execute(w io.Writer, variables VarMap, data interface{}) error

Execute executes the template in the w Writer

func (*Template) ExecuteI18N

func (t *Template) ExecuteI18N(translator Translator, w io.Writer, variables VarMap, data interface{}) (err error)

func (*Template) String

func (t *Template) String() (template string)

type TernaryExprNode

type TernaryExprNode struct {
	NodeBase
	Boolean, Left, Right Expression
}

TernaryExprNod represents a ternary expression, ex: expression '?' expression ':' expression

func (*TernaryExprNode) String

func (s *TernaryExprNode) String() string

type TextNode

type TextNode struct {
	NodeBase
	Text []byte
}

TextNode holds plain text.

func (*TextNode) String

func (t *TextNode) String() string

type Translator

type Translator interface {
	Msg(key, defaultValue string) string
	Trans(format, defaultFormat string, v ...interface{}) string
}

type VarMap

type VarMap map[string]reflect.Value

func (VarMap) Set

func (scope VarMap) Set(name string, v interface{}) VarMap

func (VarMap) SetFunc

func (scope VarMap) SetFunc(name string, v Func) VarMap

func (VarMap) SetWriter

func (scope VarMap) SetWriter(name string, v SafeWriter) VarMap

type YieldNode

type YieldNode struct {
	NodeBase          //The line number in the input. Deprecated: Kept for compatibility.
	Name       string //The name of the template (unquoted).
	Parameters *BlockParameterList
	Expression Expression //The command to evaluate as dot for the template.
	Content    *ListNode
	IsContent  bool
}

YieldNode represents a {{yield}} action

func (*YieldNode) String

func (t *YieldNode) String() string

Directories

Path Synopsis
examples
asset_packaging
+Build ignore
+Build ignore
todos
+Build ignore
+Build ignore
loaders

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL