Documentation
¶
Overview ¶
Package template provides a lightweight template engine with Django/Jinja-style syntax.
Package template provides a Go template engine built around a single core concept: Engine.
Use New with WithLoader, WithFormat, WithLayout, and WithFeatures to define how templates are loaded, what output semantics they use, and which optional language features are enabled.
loader, _ := template.NewDirLoader("./templates")
engine := template.New(
template.WithLoader(loader),
template.WithFormat(template.FormatHTML),
template.WithLayout(),
template.WithDefaults(template.Data{"site": siteData}),
)
_ = engine.RenderTo("layouts/blog.html", os.Stdout, template.Data{"page": pageData})
Core design rules:
- Engine is the only public entry point.
- FormatHTML and FormatText define output semantics.
- WithLayout is optional and must be enabled explicitly.
- HTML auto-escape exists only behind FormatHTML.
- Layout inheritance, include, raw, and safe-aware behavior exist only behind WithLayout (internally this maps to FeatureLayout).
Supported syntax summary:
- Variable interpolation: {{ variable }}
- Filters: {{ variable | filter:arg }}
- Control structures: {% if %}, {% for %}
- Comments: {# ... #}
- (FeatureLayout only) {% include "x" [with k=v] [only] [if_exists] %}
- (FeatureLayout only) {% extends "parent" %} + {% block name %}...{% endblock %}
- (FeatureLayout only) {{ block.super }}
- (FeatureLayout only) {% raw %}...{% endraw %}
- (FeatureLayout only) {{ x | safe }} and (FormatHTML only) auto-escape of {{ x }}
For detailed examples, see the examples/ directory.
Index ¶
- Variables
- func IsKeyword(ident string) bool
- func IsSymbol(s string) bool
- func ValidateName(name string) error
- type BinaryOpNode
- type BlockNode
- type BreakError
- type BreakNode
- type ContinueError
- type ContinueNode
- type Data
- type DataBuilder
- type Engine
- func (e *Engine) Clone(opts ...EngineOption) *Engine
- func (e *Engine) Filters() *Registry
- func (e *Engine) HasFeature(feature Feature) bool
- func (e *Engine) Load(name string) (*Template, error)
- func (e *Engine) MustRegisterFilter(name string, fn FilterFunc)
- func (e *Engine) MustRegisterTag(name string, parser TagParser)
- func (e *Engine) ParseString(source string) (*Template, error)
- func (e *Engine) RegisterFilter(name string, fn FilterFunc)
- func (e *Engine) RegisterTag(name string, parser TagParser) error
- func (e *Engine) Render(name string, data Data) (string, error)
- func (e *Engine) RenderTo(name string, w io.Writer, data Data) error
- func (e *Engine) ReplaceFilter(name string, fn FilterFunc)
- func (e *Engine) ReplaceTag(name string, parser TagParser)
- func (e *Engine) Reset()
- func (e *Engine) Tags() *TagRegistry
- type EngineOption
- type ExprParser
- type Expression
- type ExtendsNode
- type Feature
- type FilterFunc
- type FilterNode
- type ForNode
- type Format
- type IfBranch
- type IfNode
- type IncludeNode
- type Lexer
- type LexerError
- type LiteralNode
- type Loader
- type LoopContext
- type Node
- type OutputNode
- type ParseError
- type Parser
- func (p *Parser) Advance()
- func (p *Parser) Current() *Token
- func (p *Parser) Engine() *Engine
- 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
- func (r *Registry) Clone() *Registry
- func (r *Registry) Filter(name string) (FilterFunc, bool)
- func (r *Registry) Has(name string) bool
- func (r *Registry) List() []string
- func (r *Registry) MustRegister(name string, fn FilterFunc)
- func (r *Registry) Register(name string, fn FilterFunc)
- func (r *Registry) Replace(name string, fn FilterFunc)
- func (r *Registry) Unregister(name string)
- type RenderContext
- type RenderError
- type SafeString
- type Statement
- type SubscriptNode
- type TagParser
- type TagRegistry
- func (r *TagRegistry) Clone() *TagRegistry
- func (r *TagRegistry) Get(name string) (TagParser, bool)
- func (r *TagRegistry) Has(name string) bool
- func (r *TagRegistry) List() []string
- func (r *TagRegistry) MustRegister(name string, parser TagParser)
- func (r *TagRegistry) Register(name string, parser TagParser) error
- func (r *TagRegistry) Replace(name string, parser TagParser)
- func (r *TagRegistry) Unregister(name string)
- 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
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrTemplateNotFound = errors.New("template not found") ErrInvalidTemplateName = errors.New("invalid template name") ErrIncludeDepthExceeded = errors.New("include depth exceeded") ErrExtendsDepthExceeded = errors.New("extends depth exceeded") ErrCircularExtends = errors.New("circular extends detected") ErrExtendsNotFirst = errors.New("extends must be the first tag") ErrExtendsPathNotLiteral = errors.New("extends path must be a string literal") ErrBlockRedefined = errors.New("block redefined in same template") ErrUnclosedRaw = errors.New("unclosed raw block") ErrIncludePathNotString = errors.New("include path did not evaluate to string") )
ErrTemplateNotFound indicates a loader could not locate the named template. ErrInvalidTemplateName indicates the template name failed fs.ValidPath validation (contains "..", is absolute, contains NUL, backslash, or similar). ErrIncludeDepthExceeded indicates include nesting exceeded the hard limit. ErrExtendsDepthExceeded indicates the extends chain exceeded the hard limit. ErrCircularExtends indicates a cycle was detected in the extends chain. ErrExtendsNotFirst indicates an extends tag appeared after other content. ErrExtendsPathNotLiteral indicates an extends path was an expression, not a string literal. ErrBlockRedefined indicates the same block name appeared twice in one template. ErrUnclosedRaw indicates a raw block was not terminated with endraw. ErrIncludePathNotString indicates a dynamic include path evaluated to a non-string value.
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 render data. 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 IsSymbol ¶ added in v0.4.0
IsSymbol reports whether s is a valid operator or punctuation symbol.
func ValidateName ¶ added in v0.6.0
ValidateName checks that name is safe to use as a template path. It rejects:
- anything fs.ValidPath rejects (empty element, "..", absolute, trailing /)
- backslash (Windows path separator; forces forward-slash discipline)
- NUL byte (path injection)
Loader implementations must call this on every name they receive.
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 *RenderContext) (*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 BlockNode ¶ added in v0.6.0
BlockNode is a forward declaration stub filled in when {% block %} is implemented. Defined here so Template.blocks can reference it without import cycles.
func (*BlockNode) Execute ¶ added in v0.6.0
func (n *BlockNode) Execute(ctx *RenderContext, w io.Writer) error
Execute renders this block, resolving overrides across the extends chain. If the current template is not part of a chain (or this block is inside an included partial), the block simply renders its own body inline.
The {{ block.super }} expression is supported by injecting a "block" variable into the render context whose "super" field is the pre-rendered parent block body (already a SafeString so it survives HTML auto-escape untouched).
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(_ *RenderContext, _ io.Writer) error
Execute signals loop termination via BreakError.
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(_ *RenderContext, _ 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 Data ¶ added in v0.7.0
Data 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 (Data) Get ¶ added in v0.7.0
Get retrieves a value from the Data 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 DataBuilder ¶ added in v0.7.0
type DataBuilder struct {
// contains filtered or unexported fields
}
DataBuilder provides a fluent API for building a Data with error collection.
func NewDataBuilder ¶ added in v0.7.0
func NewDataBuilder() *DataBuilder
NewDataBuilder creates a new DataBuilder for fluent Data construction.
ctx, err := NewDataBuilder().
KeyValue("name", "John").
Struct(user).
Build()
func (*DataBuilder) Build ¶ added in v0.7.0
func (cb *DataBuilder) Build() (Data, error)
Build returns the constructed Data and any collected errors. Errors from DataBuilder.KeyValue or DataBuilder.Struct operations are joined into a single error.
func (*DataBuilder) KeyValue ¶ added in v0.7.0
func (cb *DataBuilder) KeyValue(key string, value any) *DataBuilder
KeyValue sets a key-value pair and returns the builder for chaining.
builder := NewDataBuilder().
KeyValue("name", "John").
KeyValue("age", 30)
func (*DataBuilder) Struct ¶ added in v0.7.0
func (cb *DataBuilder) Struct(v any) *DataBuilder
Struct expands struct fields into the Data 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 DataBuilder.Build.
type Engine ¶ added in v0.7.0
type Engine struct {
// contains filtered or unexported fields
}
Engine is the entry point for the loader-backed template system.
An Engine holds a loader, compile cache, rendering format, feature flags, and per-engine tag/filter registries. Engines are safe for concurrent use: compiled templates are cached and treated as read-only after compilation.
func New ¶ added in v0.7.0
func New(opts ...EngineOption) *Engine
New constructs an Engine with the provided options.
func (*Engine) Clone ¶ added in v0.7.0
func (e *Engine) Clone(opts ...EngineOption) *Engine
Clone copies engine configuration into a fresh Engine with an empty cache.
func (*Engine) HasFeature ¶ added in v0.7.0
HasFeature reports whether the engine has an optional feature enabled.
func (*Engine) MustRegisterFilter ¶ added in v0.7.0
func (e *Engine) MustRegisterFilter(name string, fn FilterFunc)
MustRegisterFilter adds or replaces an engine-local filter and panics on nil.
func (*Engine) MustRegisterTag ¶ added in v0.7.0
MustRegisterTag registers an engine-local tag parser and panics on duplicate registration or nil parser.
func (*Engine) ParseString ¶ added in v0.7.0
ParseString compiles a template source string in the context of this engine.
Example ¶
package main
import (
"fmt"
"log"
"github.com/kaptinlin/template"
)
func main() {
engine := template.New()
tmpl, err := engine.ParseString("Hello, {{ name|upcase }}!")
if err != nil {
log.Fatal(err)
}
out, err := tmpl.Render(template.Data{"name": "alice"})
if err != nil {
log.Fatal(err)
}
fmt.Println(out)
}
Output: Hello, ALICE!
func (*Engine) RegisterFilter ¶ added in v0.7.0
func (e *Engine) RegisterFilter(name string, fn FilterFunc)
RegisterFilter adds or replaces an engine-local filter.
func (*Engine) RegisterTag ¶ added in v0.7.0
RegisterTag adds an engine-local tag parser. Duplicate names return ErrTagAlreadyRegistered.
func (*Engine) Render ¶ added in v0.7.0
Render loads the named template and returns its output as a string.
Example ¶
package main
import (
"fmt"
"log"
"github.com/kaptinlin/template"
)
func main() {
loader := template.NewMemoryLoader(map[string]string{
"base.html": `<h1>{{ page.title }}</h1>{% block content %}{% endblock %}`,
"page.html": `{% extends "base.html" %}{% block content %}{{ page.content }} {{ page.safe | safe }}{% endblock %}`,
})
engine := template.New(
template.WithLoader(loader),
template.WithFormat(template.FormatHTML),
template.WithLayout(),
)
out, err := engine.Render("page.html", template.Data{
"page": map[string]any{
"title": "Hello <world>",
"content": "<p>escaped</p>",
"safe": template.SafeString("<p>trusted</p>"),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(out)
}
Output: <h1>Hello <world></h1><p>escaped</p> <p>trusted</p>
func (*Engine) RenderTo ¶ added in v0.7.0
RenderTo loads the named template and writes its output to w. data is merged with any defaults configured via WithDefaults; data keys take precedence over defaults.
func (*Engine) ReplaceFilter ¶ added in v0.7.0
func (e *Engine) ReplaceFilter(name string, fn FilterFunc)
ReplaceFilter overwrites an engine-local filter.
func (*Engine) ReplaceTag ¶ added in v0.7.0
ReplaceTag overwrites an engine-local tag parser.
func (*Engine) Tags ¶ added in v0.7.0
func (e *Engine) Tags() *TagRegistry
Tags returns the engine-local tag registry layer.
type EngineOption ¶ added in v0.7.0
type EngineOption func(*Engine)
EngineOption configures an Engine at construction time.
func WithDefaults ¶ added in v0.7.0
func WithDefaults(g Data) EngineOption
WithDefaults injects variables available to every render call. Render-time ctx keys override defaults on conflict.
func WithFeatures ¶ added in v0.7.0
func WithFeatures(features ...Feature) EngineOption
WithFeatures enables optional language features.
func WithFilters ¶ added in v0.7.0
func WithFilters(r *Registry) EngineOption
WithFilters replaces the engine-local filter registry layer.
func WithFormat ¶ added in v0.7.0
func WithFormat(format Format) EngineOption
WithFormat configures how output is rendered.
func WithLayout ¶ added in v0.7.0
func WithLayout() EngineOption
WithLayout enables layout features such as include, extends, block, raw, and safe-aware engine behavior.
func WithLoader ¶ added in v0.7.0
func WithLoader(loader Loader) EngineOption
WithLoader configures the Engine loader used by Load and Render.
func WithTags ¶ added in v0.7.0
func WithTags(r *TagRegistry) EngineOption
WithTags replaces the engine-local tag registry layer.
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 *RenderContext) (*Value, error)
}
Expression is the interface for all expression nodes. Expressions are evaluated to produce values.
type ExtendsNode ¶ added in v0.6.0
ExtendsNode is a marker for {% extends "parent" %}. It produces no output directly; inheritance is handled by Template.Execute when it detects a non-nil parent field.
func (*ExtendsNode) Execute ¶ added in v0.6.0
func (n *ExtendsNode) Execute(_ *RenderContext, _ io.Writer) error
Execute is a no-op. The parent relationship is established at parse time and consumed by Template.Execute.
func (*ExtendsNode) Position ¶ added in v0.6.0
func (n *ExtendsNode) Position() (int, int)
Position returns the source position of the extends tag.
func (*ExtendsNode) String ¶ added in v0.6.0
func (n *ExtendsNode) String() string
String returns a debug representation.
type Feature ¶ added in v0.7.0
type Feature uint8
Feature is an optional language capability that can be enabled per engine.
type FilterFunc ¶
FilterFunc represents the signature of functions that can be applied as filters.
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 *RenderContext) (*Value, error)
Evaluate applies the named filter to the expression value.
Filter lookup consults the per-engine filter registry first, falling back to the built-in registry. This gives each engine access to its own feature-gated filters and format-specific overrides.
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 *RenderContext, 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 *RenderContext, w io.Writer) error
Execute runs the first truthy branch, or the else block if no branch matches.
type IncludeNode ¶ added in v0.6.0
IncludeNode represents an {% include %} statement.
Shapes:
- Static path (string literal), resolved at parse time: prepared != nil.
- Parse-time circular static path: prepared == nil, staticName holds the literal for runtime lookup.
- Dynamic path (expression): pathExpr != nil.
Options:
- withPairs: {% include "x" with k1=expr1 k2=expr2 %}
- only: {% include "x" only %} — fully isolates the child context, excluding parent variables AND defaults.
- ifExists: {% include "x" if_exists %} — missing template is a no-op instead of an error.
func (*IncludeNode) Execute ¶ added in v0.6.0
func (n *IncludeNode) Execute(ctx *RenderContext, w io.Writer) error
Execute renders the included template. The parser only produces IncludeNode inside an Engine with layout enabled, so ctx.engine is guaranteed non-nil by the time we reach here.
func (*IncludeNode) Position ¶ added in v0.6.0
func (n *IncludeNode) Position() (int, int)
Position returns the source position of the include tag.
func (*IncludeNode) String ¶ added in v0.6.0
func (n *IncludeNode) String() string
String returns a debug representation.
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(_ *RenderContext) (*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 Loader ¶ added in v0.6.0
Loader locates and loads template source code by name.
Implementations must validate the name with ValidateName (which adds backslash and NUL rejection on top of fs.ValidPath) and return ErrInvalidTemplateName for any path that fails the check. Unknown names must return ErrTemplateNotFound.
The returned resolved name is used as the cache key and should be stable and unique within a loader (e.g., include a layer prefix when chained).
func NewChainLoader ¶ added in v0.6.0
NewChainLoader returns a Loader that queries the given loaders in order and returns the first one that has the requested template.
Chain loaders are typically used to implement override layers like user > theme > builtin. Each hit's resolved name is prefixed with the layer index so the same name in different layers produces distinct cache keys in an Engine.
func NewDirLoader ¶ added in v0.6.0
NewDirLoader returns a Loader that reads templates from the given local directory, sandboxed by os.Root. Symbolic links cannot escape the root: following any link whose target lies outside dir results in an error.
This is the default, recommended way to load templates from disk.
For development workflows that deliberately require symlink following (theme dev, monorepo sharing), use NewFSLoader with os.DirFS and accept responsibility for the relaxed sandbox.
func NewFSLoader ¶ added in v0.6.0
NewFSLoader wraps any fs.FS as a Loader. Intended for already- sandboxed filesystems such as embed.FS, testing/fstest.MapFS, and archive/zip.Reader.
Warning: if you pass a non-sandboxed fs.FS (for example os.DirFS pointing at a real directory) the library cannot prevent symbolic links from escaping. Prefer NewDirLoader for local directories unless you deliberately need this escape hatch.
func NewMemoryLoader ¶ added in v0.6.0
NewMemoryLoader returns a Loader that serves templates from an in-memory map. Intended for tests and small pre-registered sets.
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 *RenderContext, w io.Writer) error
Execute evaluates the expression and writes its string value.
When the render context has autoescape enabled (FormatHTML engine rendering), the output is HTML-escaped UNLESS the underlying Go value is a SafeString. In the non-autoescape path (text engine or standalone Compile), SafeString is treated as a plain string.
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) Engine ¶ added in v0.7.0
Engine returns the template engine associated with this parser, if any. Tag parsers can use this to load referenced templates at parse time.
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 *RenderContext) (*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.
Registry supports an optional parent: when a lookup misses in this registry, the parent is consulted. This allows an Engine to layer its own private filters (like safe and the HTML-aware escape) over the global registry without copying entries.
func NewRegistry ¶ added in v0.4.0
func NewRegistry() *Registry
NewRegistry creates an empty filter registry.
func (*Registry) Clone ¶ added in v0.7.0
Clone returns a shallow copy of the registry and its direct entries. The parent registry reference is preserved.
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. If not found locally and a parent registry is set, the parent is consulted.
func (*Registry) Has ¶ added in v0.4.0
Has reports whether a filter with the given name is registered (including in ancestor registries).
func (*Registry) List ¶ added in v0.4.0
List returns the names of all registered filters in sorted order.
func (*Registry) MustRegister ¶ added in v0.7.0
func (r *Registry) MustRegister(name string, fn FilterFunc)
MustRegister is an explicit panic-on-failure registration helper.
For Registry this currently matches Registry.Replace, and exists to make bootstrap code read consistently with TagRegistry.MustRegister.
func (*Registry) Register ¶ added in v0.4.0
func (r *Registry) Register(name string, fn FilterFunc)
Register adds or replaces a filter function under the given name.
Register preserves the original Registry behavior for compatibility. For new code, prefer Registry.Replace when overwrite semantics are intentional, or introduce a higher-level guard before calling Register.
func (*Registry) Replace ¶ added in v0.7.0
func (r *Registry) Replace(name string, fn FilterFunc)
Replace stores fn under name, overwriting any direct existing entry.
Replace 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 RenderContext ¶ added in v0.7.0
type RenderContext struct {
Data Data // render input data
Locals Data // local bindings (e.g., loop counters)
// contains filtered or unexported fields
}
RenderContext holds the execution state for template rendering, separating render input data (Data) from local bindings (Locals).
func NewChildContext ¶ added in v0.4.0
func NewChildContext(parent *RenderContext) *RenderContext
NewChildContext creates a child RenderContext that shares the parent's Data, copies the Locals for isolated scope, and preserves runtime rendering state.
func NewIsolatedChildContext ¶ added in v0.7.0
func NewIsolatedChildContext(parent *RenderContext) *RenderContext
NewIsolatedChildContext creates a child RenderContext with fresh Data/Locals while preserving runtime rendering state.
func NewRenderContext ¶ added in v0.7.0
func NewRenderContext(data Data) *RenderContext
NewRenderContext creates a new RenderContext from user data.
func (*RenderContext) Get ¶ added in v0.7.0
func (ec *RenderContext) Get(name string) (any, bool)
Get retrieves a variable, checking Locals first, then Data.
func (*RenderContext) Set ¶ added in v0.7.0
func (ec *RenderContext) Set(name string, value any)
Set stores a variable in the local bindings.
type RenderError ¶ added in v0.8.0
type RenderError struct {
// Template is the loader-resolved template name where the failure
// originated; empty for templates parsed via Engine.ParseString.
Template string
// Line is the 1-based line where the failing node starts; 0 if unknown.
Line int
// Col is the 1-based column where the failing node starts; 0 if unknown.
Col int
// Cause is the underlying error. It is always non-nil for a
// well-formed RenderError and is suitable for errors.Is / errors.As
// against the sentinels in errors.go.
Cause error
}
RenderError carries machine-readable context for a render-time failure.
It always wraps an underlying sentinel from errors.go (directly or through fmt.Errorf wrapping). Callers identify the failure mode with errors.Is and recover position information with errors.As:
var re *template.RenderError
if errors.As(err, &re) {
log.Printf("%s:%d:%d: %v", re.Template, re.Line, re.Col, re.Cause)
}
if errors.Is(err, template.ErrFilterNotFound) {
// ...
}
The Error() string is human-readable and may evolve; the Template, Line, Col, and Cause fields are part of the public contract and will not change shape across minor versions.
func (*RenderError) Error ¶ added in v0.8.0
func (e *RenderError) Error() string
Error returns a human-readable representation. The format is not part of the public contract; consume Template, Line, Col, and Cause directly for stable output.
func (*RenderError) Unwrap ¶ added in v0.8.0
func (e *RenderError) Unwrap() error
Unwrap exposes the underlying cause for errors.Is / errors.As.
type SafeString ¶ added in v0.6.0
type SafeString string
SafeString marks a string value as pre-escaped or otherwise trusted HTML content. When a template rendered by an engine with FormatHTML outputs a SafeString, the auto-escaper bypasses escaping. In text-format engine renders or [Compile]-path templates, SafeString behaves identically to a plain string.
Producing a SafeString from untrusted input is a security bug: the contents are emitted verbatim into HTML.
type Statement ¶ added in v0.4.0
type Statement interface {
Node
Execute(ctx *RenderContext, 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 *RenderContext) (*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 TagRegistry ¶ added in v0.6.0
type TagRegistry struct {
// contains filtered or unexported fields
}
TagRegistry stores tag parsers. An optional parent registry is consulted when a lookup misses, enabling an Engine to layer its own private tags over the global registry without copying entries.
TagRegistry is safe for concurrent use.
func NewTagRegistry ¶ added in v0.6.0
func NewTagRegistry() *TagRegistry
NewTagRegistry creates an empty TagRegistry.
func (*TagRegistry) Clone ¶ added in v0.7.0
func (r *TagRegistry) Clone() *TagRegistry
Clone returns a shallow copy of the registry and its direct entries. The parent registry reference is preserved.
func (*TagRegistry) Get ¶ added in v0.6.0
func (r *TagRegistry) Get(name string) (TagParser, bool)
Get looks up a tag parser by name. If not found and a parent registry is set, the parent is consulted.
func (*TagRegistry) Has ¶ added in v0.6.0
func (r *TagRegistry) Has(name string) bool
Has reports whether a tag is registered (including in ancestors).
func (*TagRegistry) List ¶ added in v0.6.0
func (r *TagRegistry) List() []string
List returns a sorted list of tag names registered directly in this registry (excluding parents).
func (*TagRegistry) MustRegister ¶ added in v0.7.0
func (r *TagRegistry) MustRegister(name string, parser TagParser)
MustRegister registers parser under name and panics on duplicate registration or nil parser.
func (*TagRegistry) Register ¶ added in v0.6.0
func (r *TagRegistry) Register(name string, parser TagParser) error
Register adds a tag parser. Duplicate names return ErrTagAlreadyRegistered.
func (*TagRegistry) Replace ¶ added in v0.7.0
func (r *TagRegistry) Replace(name string, parser TagParser)
Replace stores parser under name, overwriting any direct existing entry.
Replace panics if parser is nil.
func (*TagRegistry) Unregister ¶ added in v0.6.0
func (r *TagRegistry) Unregister(name string)
Unregister removes a tag from this registry (does not touch parents).
type Template ¶
type Template struct {
// contains filtered or unexported fields
}
Template represents a compiled template ready for execution. A Template is immutable after compilation.
Templates parsed without a loader-backed engine have no resolved name or engine reference. Templates loaded via Engine.Load carry an engine reference and a resolved name for caching, dependency tracking, and multi-file rendering.
func NewTemplate ¶
NewTemplate creates a new Template from parsed AST nodes.
Most callers should use Engine.ParseString or Engine.Load, which handle lexing and parsing automatically.
func (*Template) Execute ¶
func (t *Template) Execute(ctx *RenderContext, w io.Writer) error
Execute writes the template output to w using the given render context.
For most use cases, Template.Render is simpler. Use Execute when you need control over the output destination or render context.
When the template extends a parent (via {% extends %}), Execute walks up to the root of the extends chain and runs that template's body. The current template is recorded as ctx.currentLeaf so BlockNode.Execute can resolve overrides across the chain. For templates without a parent the loop is a no-op and the template runs its own body.
func (*Template) Render ¶ added in v0.4.0
Render executes the template with data and returns the output as a string.
Render is a convenience wrapper around Template.RenderTo for the common case where a string result is needed.
func (*Template) RenderTo ¶ added in v0.7.0
RenderTo writes the template output to w using plain render data.
Use RenderTo for the common writer-based path. Reach for Template.Execute only when you need direct control over RenderContext.
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(_ *RenderContext, 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 *RenderContext) (*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 *RenderContext) (*Value, error)
Evaluate resolves the variable in the current render 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
¶
- compile.go
- convert.go
- data.go
- doc.go
- engine.go
- errors.go
- expr.go
- filter_array.go
- filter_date.go
- filter_format.go
- filter_map.go
- filter_math.go
- filter_number.go
- filter_string.go
- filters.go
- lexer.go
- loader.go
- nodes.go
- parser.go
- parser_helpers.go
- render_error.go
- safe.go
- tag_block.go
- tag_break.go
- tag_continue.go
- tag_extends.go
- tag_for.go
- tag_if.go
- tag_include.go
- tags.go
- template.go
- token.go
- value.go
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 on an Engine.
|
Package main demonstrates registering a custom tag on an Engine. |
|
layout
command
Package main demonstrates multi-file HTML templating with layout inheritance, includes, block.super, and HTML auto-escape.
|
Package main demonstrates multi-file HTML templating with layout inheritance, includes, block.super, and HTML auto-escape. |
|
multifile_text
command
Package main demonstrates multi-file text generation with Engine.
|
Package main demonstrates multi-file text generation with Engine. |
|
secret_redaction
command
Package main demonstrates redacting secrets from rendered output.
|
Package main demonstrates redacting secrets from rendered output. |
|
usage
command
Package main demonstrates typical template usage.
|
Package main demonstrates typical template usage. |