Documentation
¶
Overview ¶
Package template provides a lightweight template engine with Django/Jinja-style syntax.
Package template provides a simple and efficient template engine for Go.
The template engine supports:
- Variable interpolation: {{ variable }}
- Filters: {{ variable|filter:arg }}
- Control structures: {% if condition %}, {% for item in collection %}
- Comments: {# comment #}
Basic Usage:
tmpl, err := template.Compile("Hello, {{ name|upper }}!")
if err != nil {
panic(err)
}
output, err := tmpl.Render(map[string]any{"name": "world"})
// Output: "Hello, WORLD!"
Architecture:
The package is organized into several key components:
- Lexer: Tokenizes template source into a token stream
- Parser: Converts tokens into an AST (Abstract Syntax Tree)
- Expression Parser: Parses expressions with operator precedence
- Template: Executes the AST with a given context
- Filters: Transforms values during template execution
- Context: Stores and retrieves template variables
Control Flow:
The template engine supports break and continue statements within loops:
{% for item in items %}
{% if item == "skip" %}
{% continue %}
{% endif %}
{% if item == "stop" %}
{% break %}
{% endif %}
{{ item }}
{% endfor %}
Loop Context:
Within loops, a special "loop" variable is available providing:
- loop.Index: Current index (0-based)
- loop.Revindex: Reverse index
- loop.First: True if first iteration
- loop.Last: True if last iteration
- loop.Length: Total collection length
For detailed examples, see the examples/ directory.
Index ¶
- Variables
- func HasFilter(name string) bool
- func HasTag(name string) bool
- func IsKeyword(ident string) bool
- func IsSymbol(s string) bool
- func ListFilters() []string
- func ListTags() []string
- func RegisterFilter(name string, fn FilterFunc)
- func RegisterTag(name string, parser TagParser) error
- func Render(source string, data map[string]any) (string, error)
- func UnregisterFilter(name string)
- func UnregisterTag(name string)
- type BinaryOpNode
- type BreakError
- type BreakNode
- type Context
- type ContextBuilder
- type ContinueError
- type ContinueNode
- type ExecutionContext
- type ExprParser
- type Expression
- type FilterFunc
- type FilterNode
- type ForNode
- type IfBranch
- type IfNode
- type Lexer
- type LexerError
- type LiteralNode
- type LoopContext
- type Node
- type OutputNode
- type ParseError
- type Parser
- func (p *Parser) Advance()
- func (p *Parser) Current() *Token
- func (p *Parser) Error(msg string) error
- func (p *Parser) Errorf(format string, args ...any) error
- func (p *Parser) ExpectIdentifier() (*Token, error)
- func (p *Parser) Match(tokenType TokenType, value string) *Token
- func (p *Parser) Parse() ([]Statement, error)
- func (p *Parser) ParseExpression() (Expression, error)
- func (p *Parser) ParseUntil(endTags ...string) ([]Statement, string, error)
- func (p *Parser) ParseUntilWithArgs(endTags ...string) ([]Statement, string, *Parser, error)
- func (p *Parser) Remaining() int
- type PropertyAccessNode
- type Registry
- type Statement
- type SubscriptNode
- type TagParser
- type Template
- type TextNode
- type Token
- type TokenType
- type UnaryOpNode
- type Value
- func (v *Value) Bool() bool
- func (v *Value) Compare(other *Value) (int, error)
- func (v *Value) Equals(other *Value) bool
- func (v *Value) Field(name string) (*Value, error)
- func (v *Value) Float() (float64, error)
- func (v *Value) Index(i int) (*Value, error)
- func (v *Value) Int() (int64, error)
- func (v *Value) Interface() any
- func (v *Value) IsNil() bool
- func (v *Value) IsTrue() bool
- func (v *Value) Iterate(fn func(idx, count int, key, val *Value) bool) error
- func (v *Value) Key(key any) (*Value, error)
- func (v *Value) Len() (int, error)
- func (v *Value) String() string
- type VariableNode
Constants ¶
This section is empty.
Variables ¶
var ( ErrContextKeyNotFound = errors.New("key not found in context") ErrContextInvalidKeyType = errors.New("invalid key type for navigation") ErrContextIndexOutOfRange = errors.New("index out of range in context") )
ErrContextKeyNotFound indicates a key was not found in the execution context. ErrContextInvalidKeyType indicates an invalid key type during context navigation. ErrContextIndexOutOfRange indicates an index out of range during context navigation.
var ( ErrFilterNotFound = errors.New("filter not found") ErrFilterExecutionFailed = errors.New("filter execution failed") ErrFilterInputInvalid = errors.New("filter input is invalid") ErrFilterArgsInvalid = errors.New("filter arguments are invalid") ErrFilterInputEmpty = errors.New("filter input is empty") ErrFilterInputNotSlice = errors.New("filter input is not a slice") ErrFilterInputNotNumeric = errors.New("filter input is not numeric") ErrFilterInputInvalidTimeFormat = errors.New("filter input has an invalid time format") ErrFilterInputUnsupportedType = errors.New("filter input is of an unsupported type") ErrInsufficientArgs = errors.New("insufficient arguments provided") ErrInvalidFilterName = errors.New("invalid filter name") ErrUnknownFilterArgumentType = errors.New("unknown argument type") ErrExpectedFilterName = errors.New("expected filter name after '|'") )
ErrFilterNotFound indicates a referenced filter does not exist. ErrFilterExecutionFailed indicates a filter failed during execution. ErrFilterInputInvalid indicates the filter received invalid input. ErrFilterArgsInvalid indicates the filter received invalid arguments. ErrFilterInputEmpty indicates the filter received empty input. ErrFilterInputNotSlice indicates the filter expected a slice input. ErrFilterInputNotNumeric indicates the filter expected numeric input. ErrFilterInputInvalidTimeFormat indicates the filter received an invalid time format. ErrFilterInputUnsupportedType indicates the filter received an unsupported input type. ErrInsufficientArgs indicates insufficient arguments were provided to a filter. ErrInvalidFilterName indicates an invalid filter name was used. ErrUnknownFilterArgumentType indicates an unknown argument type was passed to a filter. ErrExpectedFilterName indicates a filter name was expected after the pipe operator.
var ( ErrUnexpectedCharacter = errors.New("unexpected character") ErrUnterminatedString = errors.New("unterminated string literal") )
ErrUnexpectedCharacter indicates the lexer encountered an unexpected character. ErrUnterminatedString indicates a string literal was not properly closed.
var ( ErrInvalidNumber = errors.New("invalid number") ErrExpectedRParen = errors.New("expected ')'") ErrUnexpectedToken = errors.New("unexpected token") ErrUnknownNodeType = errors.New("unknown node type") ErrIntegerOverflow = errors.New("unsigned integer value exceeds maximum int64 value") )
ErrInvalidNumber indicates the parser encountered an invalid numeric literal. ErrExpectedRParen indicates a closing parenthesis was expected but not found. ErrUnexpectedToken indicates the parser encountered an unexpected token. ErrUnknownNodeType indicates an unknown AST node type was encountered. ErrIntegerOverflow indicates an unsigned integer value exceeds the maximum int64 value.
var ( ErrUnsupportedType = errors.New("unsupported type") ErrUnsupportedOperator = errors.New("unsupported operator") ErrUnsupportedUnaryOp = errors.New("unsupported unary operator") )
ErrUnsupportedType indicates an unsupported type was encountered. ErrUnsupportedOperator indicates an unsupported operator was used. ErrUnsupportedUnaryOp indicates an unsupported unary operator was used.
var ( ErrUndefinedVariable = errors.New("undefined variable") ErrUndefinedProperty = errors.New("undefined property") ErrNonStructProperty = errors.New("cannot access property of non-struct value") ErrCannotAccessProperty = errors.New("cannot access property") ErrNonObjectProperty = errors.New("cannot access property of non-object") ErrInvalidVariableAccess = errors.New("invalid variable access") )
ErrUndefinedVariable indicates a referenced variable is not defined. ErrUndefinedProperty indicates a referenced property is not defined. ErrNonStructProperty indicates a property access was attempted on a non-struct value. ErrCannotAccessProperty indicates a property cannot be accessed. ErrNonObjectProperty indicates a property access was attempted on a non-object value. ErrInvalidVariableAccess indicates an invalid variable access pattern.
var ( ErrCannotAddTypes = errors.New("cannot add values of these types") ErrCannotSubtractTypes = errors.New("cannot subtract values of these types") ErrCannotMultiplyTypes = errors.New("cannot multiply values of these types") ErrCannotDivideTypes = errors.New("cannot divide values of these types") ErrCannotModuloTypes = errors.New("cannot modulo values of these types") ErrDivisionByZero = errors.New("division by zero") ErrModuloByZero = errors.New("modulo by zero") ErrCannotConvertToBool = errors.New("cannot convert type to boolean") ErrCannotNegate = errors.New("cannot negate value") ErrCannotApplyUnaryPlus = errors.New("cannot apply unary plus") ErrCannotCompareTypes = errors.New("cannot compare values of these types") )
ErrCannotAddTypes indicates addition is not supported for the given types. ErrCannotSubtractTypes indicates subtraction is not supported for the given types. ErrCannotMultiplyTypes indicates multiplication is not supported for the given types. ErrCannotDivideTypes indicates division is not supported for the given types. ErrCannotModuloTypes indicates modulo is not supported for the given types. ErrDivisionByZero indicates a division by zero was attempted. ErrModuloByZero indicates a modulo by zero was attempted. ErrCannotConvertToBool indicates a value cannot be converted to boolean. ErrCannotNegate indicates a value cannot be negated. ErrCannotApplyUnaryPlus indicates unary plus cannot be applied to the value. ErrCannotCompareTypes indicates comparison is not supported for the given types.
var ( ErrInvalidIndexType = errors.New("invalid index type") ErrInvalidArrayIndex = errors.New("invalid array index") ErrIndexOutOfRange = errors.New("index out of range") ErrCannotIndexNil = errors.New("cannot index nil") ErrTypeNotIndexable = errors.New("type is not indexable") ErrCannotGetKeyFromNil = errors.New("cannot get key from nil") ErrTypeNotMap = errors.New("type is not a map") ErrCannotGetFieldFromNil = errors.New("cannot get field from nil") ErrStructHasNoField = errors.New("struct has no field") ErrTypeHasNoField = errors.New("type has no field") ErrUnsupportedArrayType = errors.New("unsupported array type") )
ErrInvalidIndexType indicates an invalid index type was used. ErrInvalidArrayIndex indicates an invalid array index was used. ErrIndexOutOfRange indicates an index is out of range. ErrCannotIndexNil indicates an indexing operation was attempted on nil. ErrTypeNotIndexable indicates the type does not support indexing. ErrCannotGetKeyFromNil indicates a key lookup was attempted on nil. ErrTypeNotMap indicates the type is not a map. ErrCannotGetFieldFromNil indicates a field access was attempted on nil. ErrStructHasNoField indicates the struct does not have the requested field. ErrTypeHasNoField indicates the type does not have the requested field. ErrUnsupportedArrayType indicates an unsupported array type was encountered.
var ( ErrUnsupportedCollectionType = errors.New("unsupported collection type for for loop") ErrTypeNotIterable = errors.New("type is not iterable") ErrTypeHasNoLength = errors.New("type has no length") )
ErrUnsupportedCollectionType indicates the collection type is not supported in a for loop. ErrTypeNotIterable indicates the type does not support iteration. ErrTypeHasNoLength indicates the type does not support the length operation.
var ( ErrCannotConvertNilToInt = errors.New("cannot convert nil to int") ErrCannotConvertToInt = errors.New("cannot convert value to int") ErrCannotConvertNilToFloat = errors.New("cannot convert nil to float") ErrCannotConvertToFloat = errors.New("cannot convert value to float") ErrExpectedSliceOrArray = errors.New("expected slice or array") )
ErrCannotConvertNilToInt indicates nil cannot be converted to int. ErrCannotConvertToInt indicates the value cannot be converted to int. ErrCannotConvertNilToFloat indicates nil cannot be converted to float. ErrCannotConvertToFloat indicates the value cannot be converted to float.
var ( ErrBreakOutsideLoop = errors.New("break statement outside of loop") ErrContinueOutsideLoop = errors.New("continue statement outside of loop") )
ErrBreakOutsideLoop indicates a break statement was used outside of a loop. ErrContinueOutsideLoop indicates a continue statement was used outside of a loop.
var ( ErrTagAlreadyRegistered = errors.New("tag already registered") ErrMultipleElseStatements = errors.New("multiple 'else' statements found in if block, use 'elif' for additional conditions") ErrUnexpectedTokensAfterCondition = errors.New("unexpected tokens after condition") ErrElseNoArgs = errors.New("else does not take arguments") ErrEndifNoArgs = errors.New("endif does not take arguments") ErrElifAfterElse = errors.New("elif cannot appear after else") ErrExpectedVariable = errors.New("expected variable name") ErrExpectedSecondVariable = errors.New("expected second variable name after comma") ErrExpectedInKeyword = errors.New("expected 'in' keyword") ErrUnexpectedTokensAfterCollection = errors.New("unexpected tokens after collection") ErrEndforNoArgs = errors.New("endfor does not take arguments") ErrBreakNoArgs = errors.New("break does not take arguments") ErrContinueNoArgs = errors.New("continue does not take arguments") )
ErrTagAlreadyRegistered indicates a tag with the same name is already registered.
ErrMultipleElseStatements indicates multiple else clauses were found in an if block. ErrUnexpectedTokensAfterCondition indicates unexpected tokens after a condition expression. ErrElseNoArgs indicates the else tag received unexpected arguments. ErrEndifNoArgs indicates the endif tag received unexpected arguments. ErrElifAfterElse indicates an elif clause appeared after an else clause.
ErrExpectedVariable indicates a variable name was expected but not found. ErrExpectedSecondVariable indicates a second variable name was expected after a comma. ErrExpectedInKeyword indicates the "in" keyword was expected but not found. ErrUnexpectedTokensAfterCollection indicates unexpected tokens after a collection expression. ErrEndforNoArgs indicates the endfor tag received unexpected arguments.
ErrBreakNoArgs indicates the break tag received unexpected arguments. ErrContinueNoArgs indicates the continue tag received unexpected arguments.
Functions ¶
func HasFilter ¶ added in v0.4.0
HasFilter reports whether the default registry contains a filter with the given name.
func HasTag ¶ added in v0.4.0
HasTag checks if a tag with the given name is registered. It is safe to call from multiple goroutines.
func IsSymbol ¶ added in v0.4.0
IsSymbol reports whether s is a valid operator or punctuation symbol.
func ListFilters ¶ added in v0.4.0
func ListFilters() []string
ListFilters returns a sorted list of all filter names in the default registry.
func ListTags ¶ added in v0.4.0
func ListTags() []string
ListTags returns a sorted list of all registered tag names. It is safe to call from multiple goroutines.
func RegisterFilter ¶
func RegisterFilter(name string, fn FilterFunc)
RegisterFilter registers a filter in the default registry. It panics if fn is nil.
func RegisterTag ¶ added in v0.4.0
RegisterTag registers a tag parser. It is safe to call from multiple goroutines.
func Render ¶
Render compiles and renders a template in one step.
Render is a shorthand for calling Compile followed by Template.Render. For repeated rendering of the same template, compile once with Compile and call Template.Render to avoid redundant compilation.
func UnregisterFilter ¶ added in v0.4.0
func UnregisterFilter(name string)
UnregisterFilter removes a filter from the default registry.
func UnregisterTag ¶ added in v0.4.0
func UnregisterTag(name string)
UnregisterTag removes a tag from the registry. It is safe to call from multiple goroutines.
Types ¶
type BinaryOpNode ¶ added in v0.4.0
type BinaryOpNode struct {
Operator string
Left Expression
Right Expression
Line int
Col int
}
BinaryOpNode represents a binary operation.
func NewBinaryOpNode ¶ added in v0.4.0
func NewBinaryOpNode(operator string, left, right Expression, line, col int) *BinaryOpNode
NewBinaryOpNode returns a new BinaryOpNode.
func (*BinaryOpNode) Evaluate ¶ added in v0.4.0
func (n *BinaryOpNode) Evaluate(ctx *ExecutionContext) (*Value, error)
Evaluate computes the binary operation result.
func (*BinaryOpNode) Position ¶ added in v0.4.0
func (n *BinaryOpNode) Position() (int, int)
Position returns the position of the BinaryOpNode.
func (*BinaryOpNode) String ¶ added in v0.4.0
func (n *BinaryOpNode) String() string
String returns a debug representation of the BinaryOpNode.
type BreakError ¶ added in v0.4.0
type BreakError struct{}
BreakError signals loop termination.
func (*BreakError) Error ¶ added in v0.4.0
func (e *BreakError) Error() string
Error implements the error interface.
type BreakNode ¶ added in v0.4.0
BreakNode represents a {% break %} statement.
func (*BreakNode) Execute ¶ added in v0.4.0
func (n *BreakNode) Execute(_ *ExecutionContext, _ io.Writer) error
Execute signals loop termination via BreakError.
type Context ¶
Context stores template variables as a string-keyed map. Values can be of any type. Dot-notation (e.g., "user.name") is supported for nested access.
func (Context) Get ¶
Get retrieves a value from the Context by key. Dot-separated keys (e.g., "user.profile.name") navigate nested structures. Array indices are supported (e.g., "items.0").
Get returns ErrContextKeyNotFound, ErrContextIndexOutOfRange, or ErrContextInvalidKeyType on failure.
type ContextBuilder ¶ added in v0.3.6
type ContextBuilder struct {
// contains filtered or unexported fields
}
ContextBuilder provides a fluent API for building a Context with error collection.
func NewContextBuilder ¶ added in v0.3.6
func NewContextBuilder() *ContextBuilder
NewContextBuilder creates a new ContextBuilder for fluent Context construction.
ctx, err := NewContextBuilder().
KeyValue("name", "John").
Struct(user).
Build()
func (*ContextBuilder) Build ¶ added in v0.3.6
func (cb *ContextBuilder) Build() (Context, error)
Build returns the constructed Context and any collected errors. Errors from ContextBuilder.KeyValue or ContextBuilder.Struct operations are joined into a single error.
func (*ContextBuilder) KeyValue ¶ added in v0.3.6
func (cb *ContextBuilder) KeyValue(key string, value any) *ContextBuilder
KeyValue sets a key-value pair and returns the builder for chaining.
builder := NewContextBuilder().
KeyValue("name", "John").
KeyValue("age", 30)
func (*ContextBuilder) Struct ¶ added in v0.3.6
func (cb *ContextBuilder) Struct(v any) *ContextBuilder
Struct expands struct fields into the Context using JSON serialization. Fields are flattened to top-level keys based on their json tags. Nested structs are preserved as nested maps accessible via dot notation. If serialization fails, the error is collected and returned by ContextBuilder.Build.
type ContinueError ¶ added in v0.4.0
type ContinueError struct{}
ContinueError signals loop continuation.
func (*ContinueError) Error ¶ added in v0.4.0
func (e *ContinueError) Error() string
Error implements the error interface.
type ContinueNode ¶ added in v0.4.0
ContinueNode represents a {% continue %} statement.
func (*ContinueNode) Execute ¶ added in v0.4.0
func (n *ContinueNode) Execute(_ *ExecutionContext, _ io.Writer) error
Execute signals loop continuation via ContinueError.
func (*ContinueNode) Position ¶ added in v0.4.0
func (n *ContinueNode) Position() (int, int)
Position returns the position of the ContinueNode.
func (*ContinueNode) String ¶ added in v0.4.0
func (n *ContinueNode) String() string
String returns a debug representation of the ContinueNode.
type ExecutionContext ¶ added in v0.4.0
type ExecutionContext struct {
Public Context // user-provided variables
Private Context // internal variables (e.g., loop counters)
}
ExecutionContext holds the execution state for template rendering, separating user-provided variables (Public) from internal variables (Private).
func NewChildContext ¶ added in v0.4.0
func NewChildContext(parent *ExecutionContext) *ExecutionContext
NewChildContext creates a child ExecutionContext that shares the parent's Public context but copies the Private context for isolated scope.
func NewExecutionContext ¶ added in v0.4.0
func NewExecutionContext(data map[string]any) *ExecutionContext
NewExecutionContext creates a new ExecutionContext from user data.
func (*ExecutionContext) Get ¶ added in v0.4.0
func (ec *ExecutionContext) Get(name string) (any, bool)
Get retrieves a variable, checking Private first, then Public.
func (*ExecutionContext) Set ¶ added in v0.4.0
func (ec *ExecutionContext) Set(name string, value any)
Set stores a variable in the private context.
type ExprParser ¶ added in v0.4.0
type ExprParser struct {
// contains filtered or unexported fields
}
ExprParser parses expressions from a token stream. It handles operator precedence, filters, property access, etc.
func NewExprParser ¶ added in v0.4.0
func NewExprParser(tokens []*Token) *ExprParser
NewExprParser creates a new expression parser.
func (*ExprParser) ParseExpression ¶ added in v0.4.0
func (p *ExprParser) ParseExpression() (Expression, error)
ParseExpression parses a complete expression. This is the entry point for expression parsing.
type Expression ¶ added in v0.4.0
type Expression interface {
Node
Evaluate(ctx *ExecutionContext) (*Value, error)
}
Expression is the interface for all expression nodes. Expressions are evaluated to produce values.
type FilterFunc ¶
FilterFunc represents the signature of functions that can be applied as filters.
func Filter ¶
func Filter(name string) (FilterFunc, bool)
Filter retrieves a filter from the default registry.
type FilterNode ¶ added in v0.4.0
type FilterNode struct {
Expr Expression
Name string
Args []Expression
Line int
Col int
}
FilterNode represents a filter application.
func NewFilterNode ¶ added in v0.4.0
func NewFilterNode(expr Expression, name string, args []Expression, line, col int) *FilterNode
NewFilterNode returns a new FilterNode.
func (*FilterNode) Evaluate ¶ added in v0.4.0
func (n *FilterNode) Evaluate(ctx *ExecutionContext) (*Value, error)
Evaluate applies the named filter to the expression value.
func (*FilterNode) Position ¶ added in v0.4.0
func (n *FilterNode) Position() (int, int)
Position returns the position of the FilterNode.
func (*FilterNode) String ¶ added in v0.4.0
func (n *FilterNode) String() string
String returns a debug representation of the FilterNode.
type ForNode ¶ added in v0.4.0
type ForNode struct {
Vars []string
Collection Expression
Body []Node
Line int
Col int
}
ForNode represents a for loop.
func (*ForNode) Execute ¶ added in v0.4.0
func (n *ForNode) Execute(ctx *ExecutionContext, w io.Writer) error
Execute evaluates the iterable and executes the loop body for each element.
type IfBranch ¶ added in v0.4.0
type IfBranch struct {
Condition Expression
Body []Node
}
IfBranch represents a single if or elif branch.
type IfNode ¶ added in v0.4.0
IfNode represents an if-elif-else conditional block.
func (*IfNode) Execute ¶ added in v0.4.0
func (n *IfNode) Execute(ctx *ExecutionContext, w io.Writer) error
Execute runs the first truthy branch, or the else block if no branch matches.
type Lexer ¶ added in v0.2.0
type Lexer struct {
// contains filtered or unexported fields
}
Lexer performs lexical analysis on template input.
type LexerError ¶ added in v0.4.0
LexerError represents a lexical analysis error with position information.
func (*LexerError) Error ¶ added in v0.4.0
func (e *LexerError) Error() string
Error implements the error interface.
type LiteralNode ¶ added in v0.4.0
LiteralNode represents a literal value (string, number, boolean).
func NewLiteralNode ¶ added in v0.4.0
func NewLiteralNode(value any, line, col int) *LiteralNode
NewLiteralNode returns a new LiteralNode.
func (*LiteralNode) Evaluate ¶ added in v0.4.0
func (n *LiteralNode) Evaluate(_ *ExecutionContext) (*Value, error)
Evaluate returns the literal value wrapped in a Value.
func (*LiteralNode) Position ¶ added in v0.4.0
func (n *LiteralNode) Position() (int, int)
Position returns the position of the LiteralNode.
func (*LiteralNode) String ¶ added in v0.4.0
func (n *LiteralNode) String() string
String returns a debug representation of the LiteralNode.
type LoopContext ¶ added in v0.2.8
type LoopContext struct {
Index int
Counter int
Revindex int
Revcounter int
First bool
Last bool
Length int
Parent *LoopContext
}
LoopContext represents loop metadata for templates.
type Node ¶
type Node interface {
// Position returns the line and column where this node starts.
Position() (line, col int)
// String returns a string representation of the node for debugging.
String() string
}
Node is the interface that all AST nodes must implement. Each node represents a part of the template syntax tree.
type OutputNode ¶ added in v0.4.0
type OutputNode struct {
Expr Expression
Line int
Col int
}
OutputNode represents a variable output {{ ... }}.
func NewOutputNode ¶ added in v0.4.0
func NewOutputNode(expr Expression, line, col int) *OutputNode
NewOutputNode returns a new OutputNode.
func (*OutputNode) Execute ¶ added in v0.4.0
func (n *OutputNode) Execute(ctx *ExecutionContext, w io.Writer) error
Execute evaluates the expression and writes its string value.
func (*OutputNode) Position ¶ added in v0.4.0
func (n *OutputNode) Position() (int, int)
Position returns the position of the OutputNode.
func (*OutputNode) String ¶ added in v0.4.0
func (n *OutputNode) String() string
String returns a debug representation of the OutputNode.
type ParseError ¶ added in v0.4.0
ParseError represents a parsing error with source location.
func (*ParseError) Error ¶ added in v0.4.0
func (e *ParseError) Error() string
Error returns a human-readable error message with source location.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser consumes tokens and builds an AST.
func (*Parser) Advance ¶ added in v0.4.0
func (p *Parser) Advance()
Advance moves to the next token.
func (*Parser) Current ¶ added in v0.4.0
Current returns the current token without advancing the parser.
func (*Parser) Errorf ¶ added in v0.4.0
Errorf creates a formatted parse error at the current token position.
func (*Parser) ExpectIdentifier ¶ added in v0.4.0
ExpectIdentifier expects and consumes an identifier token.
func (*Parser) Match ¶ added in v0.4.0
Match consumes and returns the current token if type and value match. It returns nil when there is no match.
func (*Parser) ParseExpression ¶ added in v0.4.0
func (p *Parser) ParseExpression() (Expression, error)
ParseExpression parses an expression from the current token position.
func (*Parser) ParseUntil ¶ added in v0.4.0
ParseUntil parses nodes until one of the given end tags is encountered.
Returns the parsed nodes, the matched end-tag name, and any error.
func (*Parser) ParseUntilWithArgs ¶ added in v0.4.0
ParseUntilWithArgs parses nodes until one of the given end tags is encountered, and also returns a parser for the end-tag arguments.
type PropertyAccessNode ¶ added in v0.4.0
type PropertyAccessNode struct {
Object Expression
Property string
Line int
Col int
}
PropertyAccessNode represents property/attribute access.
func NewPropertyAccessNode ¶ added in v0.4.0
func NewPropertyAccessNode(object Expression, property string, line, col int) *PropertyAccessNode
NewPropertyAccessNode returns a new PropertyAccessNode.
func (*PropertyAccessNode) Evaluate ¶ added in v0.4.0
func (n *PropertyAccessNode) Evaluate(ctx *ExecutionContext) (*Value, error)
Evaluate returns the property value from the evaluated object.
func (*PropertyAccessNode) Position ¶ added in v0.4.0
func (n *PropertyAccessNode) Position() (int, int)
Position returns the position of the PropertyAccessNode.
func (*PropertyAccessNode) String ¶ added in v0.4.0
func (n *PropertyAccessNode) String() string
String returns a debug representation of the PropertyAccessNode.
type Registry ¶ added in v0.4.0
type Registry struct {
// contains filtered or unexported fields
}
Registry is a concurrency-safe collection of named filter functions. Use NewRegistry to create an instance, or use the package-level functions that operate on the default registry.
func NewRegistry ¶ added in v0.4.0
func NewRegistry() *Registry
NewRegistry creates an empty filter registry.
func (*Registry) Filter ¶ added in v0.4.0
func (r *Registry) Filter(name string) (FilterFunc, bool)
Filter returns the filter registered under name and a boolean indicating whether it was found.
func (*Registry) Has ¶ added in v0.4.0
Has reports whether a filter with the given name is registered.
func (*Registry) List ¶ added in v0.4.0
List returns the names of all registered filters in sorted order.
func (*Registry) Register ¶ added in v0.4.0
func (r *Registry) Register(name string, fn FilterFunc)
Register adds a filter function under the given name. If a filter with the same name already exists, it is overwritten.
Register panics if fn is nil.
func (*Registry) Unregister ¶ added in v0.4.0
Unregister removes the filter registered under name. It is a no-op if no such filter exists.
type Statement ¶ added in v0.4.0
type Statement interface {
Node
Execute(ctx *ExecutionContext, writer io.Writer) error
}
Statement is the interface for all statement nodes. Statements are executed and produce output or side effects.
type SubscriptNode ¶ added in v0.4.0
type SubscriptNode struct {
Object Expression
Index Expression
Line int
Col int
}
SubscriptNode represents subscript/index access.
func NewSubscriptNode ¶ added in v0.4.0
func NewSubscriptNode(object, index Expression, line, col int) *SubscriptNode
NewSubscriptNode returns a new SubscriptNode.
func (*SubscriptNode) Evaluate ¶ added in v0.4.0
func (n *SubscriptNode) Evaluate(ctx *ExecutionContext) (*Value, error)
Evaluate returns the indexed or keyed value.
func (*SubscriptNode) Position ¶ added in v0.4.0
func (n *SubscriptNode) Position() (int, int)
Position returns the position of the SubscriptNode.
func (*SubscriptNode) String ¶ added in v0.4.0
func (n *SubscriptNode) String() string
String returns a debug representation of the SubscriptNode.
type TagParser ¶ added in v0.4.0
TagParser is the parse function signature for template tags.
Parameters:
- doc: The document-level parser used to parse nested tag bodies. Example: an if tag parses content between {% if %} and {% endif %}.
- start: The tag-name token (for example "if", "for"), including source position information used in error reporting.
- arguments: A dedicated parser for tag arguments. Example: in {% if x > 5 %}, this parser sees "x > 5".
Returns:
- Statement: The parsed statement node.
- error: Any parse error encountered.
type Template ¶
type Template struct {
// contains filtered or unexported fields
}
Template represents a compiled template ready for execution. A Template is immutable after compilation.
func Compile ¶ added in v0.4.0
Compile compiles a template source string and returns an executable Template.
Compile performs lexical analysis, parsing, and template creation in sequence. On failure, the returned error wraps the underlying lexer or parser error.
tmpl, err := template.Compile("Hello {{ name }}!")
if err != nil {
log.Fatal(err)
}
output, _ := tmpl.Render(map[string]any{"name": "World"})
func NewTemplate ¶
NewTemplate creates a new Template from parsed AST nodes.
Most callers should use Compile instead, which handles lexing and parsing automatically.
func (*Template) Execute ¶
func (t *Template) Execute(ctx *ExecutionContext, w io.Writer) error
Execute writes the template output to w using the given execution context.
For most use cases, Template.Render is simpler. Use Execute when you need control over the output destination or execution context.
type TextNode ¶ added in v0.4.0
TextNode represents plain text outside of template tags.
func NewTextNode ¶ added in v0.4.0
NewTextNode returns a new TextNode.
func (*TextNode) Execute ¶ added in v0.4.0
func (n *TextNode) Execute(_ *ExecutionContext, w io.Writer) error
Execute writes the raw text to the output.
type TokenType ¶ added in v0.2.0
type TokenType int
TokenType represents the type of a token.
const ( // TokenError indicates a lexical error. TokenError TokenType = iota // TokenEOF indicates the end of input. TokenEOF // TokenText represents plain text outside of template tags. TokenText // TokenVarBegin represents the {{ variable tag opener. TokenVarBegin // TokenVarEnd represents the }} variable tag closer. TokenVarEnd // TokenTagBegin represents the {% block tag opener. TokenTagBegin // TokenTagEnd represents the %} block tag closer. TokenTagEnd // TokenIdentifier represents an identifier such as a variable name or keyword. TokenIdentifier // TokenString represents a quoted string literal. TokenString // TokenNumber represents an integer or floating-point literal. TokenNumber // TokenSymbol represents an operator or punctuation character. TokenSymbol )
type UnaryOpNode ¶ added in v0.4.0
type UnaryOpNode struct {
Operator string
Operand Expression
Line int
Col int
}
UnaryOpNode represents a unary operation.
func NewUnaryOpNode ¶ added in v0.4.0
func NewUnaryOpNode(operator string, operand Expression, line, col int) *UnaryOpNode
NewUnaryOpNode returns a new UnaryOpNode.
func (*UnaryOpNode) Evaluate ¶ added in v0.4.0
func (n *UnaryOpNode) Evaluate(ctx *ExecutionContext) (*Value, error)
Evaluate computes the unary operation result.
func (*UnaryOpNode) Position ¶ added in v0.4.0
func (n *UnaryOpNode) Position() (int, int)
Position returns the position of the UnaryOpNode.
func (*UnaryOpNode) String ¶ added in v0.4.0
func (n *UnaryOpNode) String() string
String returns a debug representation of the UnaryOpNode.
type Value ¶ added in v0.2.0
type Value struct {
// contains filtered or unexported fields
}
Value wraps a Go value for template execution, providing type checking, conversion, and comparison operations.
func (*Value) Compare ¶ added in v0.4.0
Compare compares v with other. It returns -1 if v < other, 0 if v == other, 1 if v > other.
func (*Value) Field ¶ added in v0.4.0
Field returns the value of a struct field or map key by name. For structs, it searches by JSON tag first, then by exported field name.
func (*Value) Index ¶ added in v0.4.0
Index returns the element at index i (for slices, arrays, strings).
func (*Value) IsTrue ¶ added in v0.4.0
IsTrue reports whether the value is truthy in a template context. False values: nil, false, 0, "", empty slice/map/array.
func (*Value) Iterate ¶ added in v0.4.0
Iterate calls fn for each element in a collection (slice, array, map, string). fn receives the iteration index, total count, key, and value. Returning false from fn stops iteration early.
type VariableNode ¶ added in v0.2.0
VariableNode represents a variable reference.
func NewVariableNode ¶ added in v0.4.0
func NewVariableNode(name string, line, col int) *VariableNode
NewVariableNode returns a new VariableNode.
func (*VariableNode) Evaluate ¶ added in v0.2.0
func (n *VariableNode) Evaluate(ctx *ExecutionContext) (*Value, error)
Evaluate resolves the variable in the current execution context.
func (*VariableNode) Position ¶ added in v0.4.0
func (n *VariableNode) Position() (int, int)
Position returns the position of the VariableNode.
func (*VariableNode) String ¶ added in v0.4.0
func (n *VariableNode) String() string
String returns a debug representation of the VariableNode.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
custom_filters
command
Package main demonstrates registering custom filters.
|
Package main demonstrates registering custom filters. |
|
custom_tags
command
Package main demonstrates registering a custom tag via RegisterTag.
|
Package main demonstrates registering a custom tag via RegisterTag. |
|
usage
command
Package main demonstrates typical template usage.
|
Package main demonstrates typical template usage. |