pongo2 package - github.com/flosch/pongo2 - Go Packages (original) (raw)
A Django-syntax like template-engine
Blog posts about pongo2 (including introduction and migration):https://www.florian-schlachter.de/?tag=pongo2
Complete documentation on the template language:https://docs.djangoproject.com/en/dev/topics/templates/
Try out pongo2 live in the pongo2 playground:https://www.florian-schlachter.de/pongo2/
Make sure to read README.md in the repository as well.
A tiny example with template strings:
(Snippet on playground: https://www.florian-schlachter.de/pongo2/?id=1206546277)
// Compile the template first (i. e. creating the AST) tpl, err := pongo2.FromString("Hello {{ name|capfirst }}!") if err != nil { panic(err) } // Now you can render the template with the given // pongo2.Context how often you want to. out, err := tpl.Execute(pongo2.Context{"name": "fred"}) if err != nil { panic(err) } fmt.Println(out) // Output: Hello Fred!
- Constants
- Variables
- func ApplyFilter(name string, value *Value, param *Value) (*Value, *Error)
- func FilterExists(name string) bool
- func RegisterFilter(name string, fn FilterFunction) error
- func RegisterTag(name string, parserFn TagParser) error
- func ReplaceFilter(name string, fn FilterFunction) error
- func ReplaceTag(name string, parserFn TagParser) error
- func SetAutoescape(newValue bool)
- type Context
- type Error
- type ExecutionContext
- type Expression
- type FilterFunction
- type IEvaluator
- type INode
- type INodeTag
- type LocalFilesystemLoader
- type NodeWrapper
- type Options
- type Parser
- func (p *Parser) Consume()
- func (p *Parser) ConsumeN(count int)
- func (p *Parser) Count() int
- func (p *Parser) Current() *Token
- func (p *Parser) Error(msg string, token *Token) *Error
- func (p *Parser) Get(i int) *Token
- func (p *Parser) GetR(shift int) *Token
- func (p *Parser) Match(typ TokenType, val string) *Token
- func (p *Parser) MatchOne(typ TokenType, vals ...string) *Token
- func (p *Parser) MatchType(typ TokenType) *Token
- func (p *Parser) ParseExpression() (IEvaluator, *Error)
- func (p *Parser) Peek(typ TokenType, val string) *Token
- func (p *Parser) PeekN(shift int, typ TokenType, val string) *Token
- func (p *Parser) PeekOne(typ TokenType, vals ...string) *Token
- func (p *Parser) PeekType(typ TokenType) *Token
- func (p *Parser) PeekTypeN(shift int, typ TokenType) *Token
- func (p *Parser) Remaining() int
- func (p *Parser) SkipUntilTag(names ...string) *Error
- func (p *Parser) WrapUntilTag(names ...string) (*NodeWrapper, *Parser, *Error)
- type SandboxedFilesystemLoader
- type TagParser
- type Template
- func (tpl *Template) Execute(context Context) (string, error)
- func (tpl *Template) ExecuteBlocks(context Context, blocks []string) (map[string]string, error)
- func (tpl *Template) ExecuteBytes(context Context) ([]byte, error)
- func (tpl *Template) ExecuteWriter(context Context, writer io.Writer) error
- func (tpl *Template) ExecuteWriterUnbuffered(context Context, writer io.Writer) error
- type TemplateLoader
- type TemplateSet
- func (set *TemplateSet) AddLoader(loaders ...TemplateLoader)
- func (set *TemplateSet) BanFilter(name string) error
- func (set *TemplateSet) BanTag(name string) error
- func (set *TemplateSet) CleanCache(filenames ...string)
- func (set *TemplateSet) FromBytes(tpl []byte) (*Template, error)
- func (set *TemplateSet) FromCache(filename string) (*Template, error)
- func (set *TemplateSet) FromFile(filename string) (*Template, error)
- func (set *TemplateSet) FromString(tpl string) (*Template, error)
- func (set *TemplateSet) RenderTemplateBytes(b []byte, ctx Context) (string, error)
- func (set *TemplateSet) RenderTemplateFile(fn string, ctx Context) (string, error)
- func (set *TemplateSet) RenderTemplateString(s string, ctx Context) (string, error)
- type TemplateWriter
- type Token
- type TokenType
- type Value
- func (v *Value) Bool() bool
- func (v *Value) CanSlice() bool
- func (v *Value) Contains(other *Value) bool
- func (v *Value) EqualValueTo(other *Value) bool
- func (v *Value) Float() float64
- func (v *Value) Index(i int) *Value
- func (v *Value) Integer() int
- func (v *Value) Interface() interface{}
- func (v *Value) IsBool() bool
- func (v *Value) IsFloat() bool
- func (v *Value) IsInteger() bool
- func (v *Value) IsNil() bool
- func (v *Value) IsNumber() bool
- func (v *Value) IsString() bool
- func (v *Value) IsTime() bool
- func (v *Value) IsTrue() bool
- func (v *Value) Iterate(fn func(idx, count int, key, value *Value) bool, empty func())
- func (v *Value) IterateOrder(fn func(idx, count int, key, value *Value) bool, empty func(), reverse bool, ...)
- func (v *Value) Len() int
- func (v *Value) Negate() *Value
- func (v *Value) Slice(i, j int) *Value
- func (v *Value) String() string
- func (v *Value) Time() time.Time
const ( TokenError = iota EOF
TokenHTML
TokenKeyword
TokenIdentifier
TokenString
TokenNumber
TokenSymbol)
Version string
var (
TokenSymbols = [][string](/builtin#string){
"{{-", "-}}", "{%-", "-%}",
"==", ">=", "<=", "&&", "||", "{{", "}}", "{%", "%}", "!=", "<>",
"(", ")", "+", "-", "*", "<", ">", "/", "^", ",", ".", "!", "|", ":", "=", "%",
}
TokenKeywords = [][string](/builtin#string){"in", "and", "or", "not", "true", "false", "as", "export"})
var (
DefaultLoader = [MustNewLocalFileSystemLoader](#MustNewLocalFileSystemLoader)("")
DefaultSet = [NewSet](#NewSet)("default", [DefaultLoader](#DefaultLoader))
FromString = [DefaultSet](#DefaultSet).FromString
FromBytes = [DefaultSet](#DefaultSet).FromBytes
FromFile = [DefaultSet](#DefaultSet).FromFile
FromCache = [DefaultSet](#DefaultSet).FromCache
RenderTemplateString = [DefaultSet](#DefaultSet).RenderTemplateString
RenderTemplateFile = [DefaultSet](#DefaultSet).RenderTemplateFile
Globals = [DefaultSet](#DefaultSet).Globals)
func ApplyFilter(name string, value *Value, param Value) (Value, *Error)
ApplyFilter applies a filter to a given value using the given parameters. Returns a *pongo2.Value or an error.
FilterExists returns true if the given filter is already registered
ReplaceFilter replaces an already registered filter with a new implementation. Use this function with caution since it allows you to change existing filter behaviour.
Replaces an already registered tag with a new implementation. Use this function with caution since it allows you to change existing tag behaviour.
func SetAutoescape(newValue bool)
type Context map[string]interface{}
A Context type provides constants, variables, instances or functions to a template.
pongo2 automatically provides meta-information or functions through the "pongo2"-key. Currently, context["pongo2"] contains the following keys:
- version: returns the version string
Template examples for accessing items from your context:
{{ myconstant }} {{ myfunc("test", 42) }} {{ user.name }} {{ pongo2.version }}
func (c Context) Update(other Context) Context
Update updates this context with the key/value-pairs from another context.
The Error type is being used to address an error during lexing, parsing or execution. If you want to return an error object (for example in your own tag or filter) fill this object with as much information as you have. Make sure "Sender" is always given (if you're returning an error within a filter, make Sender equals 'filter:yourfilter'; same goes for tags: 'tag:mytag'). It's okay if you only fill in ErrorMsg if you don't have any other details at hand.
Returns a nice formatted error string.
RawLine returns the affected line from the original template, if available.
type ExecutionContext struct { Autoescape bool Public Context Private Context Shared Context
}
ExecutionContext contains all data important for the current rendering state.
If you're writing a custom tag, your tag's Execute()-function will have access to the ExecutionContext. This struct stores anything about the current rendering process's Context including the Context provided by the user (field Public). You can safely use the Private context to provide data to the user's template (like a 'forloop'-information). The Shared-context is used to share data between tags. All ExecutionContexts share this context.
Please be careful when accessing the Public data. PLEASE DO NOT MODIFY THE PUBLIC CONTEXT (read-only).
To create your own execution context within tags, use the NewChildExecutionContext(parent) function.
func NewChildExecutionContext(parent *ExecutionContext) *ExecutionContext
func (ctx *ExecutionContext) Logf(format string, args ...interface{})
func (ctx *ExecutionContext) OrigError(err error, token *Token) *Error
type Expression struct {
}
func (expr *Expression) Evaluate(ctx ExecutionContext) (Value, *Error)
func (expr *Expression) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error
func (expr *Expression) GetPositionToken() *Token
type FilterFunction func(in *Value, param *Value) (out *Value, err *Error)
FilterFunction is the type filter functions must fulfil
type IEvaluator interface { INode GetPositionToken() Token Evaluate(ExecutionContext) (*Value, *Error) FilterApplied(name string) bool }
type INode interface { Execute(*ExecutionContext, TemplateWriter) *Error }
type INodeTag interface { INode }
type LocalFilesystemLoader struct {
}
LocalFilesystemLoader represents a local filesystem loader with basic BaseDirectory capabilities. The access to the local filesystem is unrestricted.
func MustNewLocalFileSystemLoader(baseDir string) *LocalFilesystemLoader
MustNewLocalFileSystemLoader creates a new LocalFilesystemLoader instance and panics if there's any error during instantiation. The parameters are the same like NewLocalFileSystemLoader.
NewLocalFileSystemLoader creates a new LocalFilesystemLoader and allows templatesto be loaded from disk (unrestricted). If any base directory is given (or being set using SetBaseDir), this base directory is being used for path calculation in template inclusions/imports. Otherwise the path is calculated based relatively to the including template's path.
Abs resolves a filename relative to the base directory. Absolute paths are allowed. When there's no base dir set, the absolute path to the filename will be calculated based on either the provided base directory (which might be a path of a template which includes another template) or the current working directory.
Get reads the path's content from your local filesystem.
SetBaseDir sets the template's base directory. This directory will be used for any relative path in filters, tags and From*-functions to determine your template. See the comment for NewLocalFileSystemLoader as well.
type NodeWrapper struct { Endtag string
}
func (wrapper *NodeWrapper) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error
type Options struct {
TrimBlocks [bool](/builtin#bool)
LStripBlocks [bool](/builtin#bool)}
Options allow you to change the behavior of template-engine. You can change the options before calling the Execute method.
func (opt *Options) Update(other *Options) *Options
Update updates this options from another options.
The parser provides you a comprehensive and easy tool to work with the template document and arguments provided by the user for your custom tag.
The parser works on a token list which will be provided by pongo2. A token is a unit you can work with. Tokens are either of type identifier, string, number, keyword, HTML or symbol.
(See Token's documentation for more about tokens)
func (p *Parser) Consume()
Consume one token. It will be gone forever.
func (p *Parser) ConsumeN(count int)
Consume N tokens. They will be gone forever.
Returns the total token count.
func (p *Parser) Current() *Token
Returns the current token.
func (p *Parser) Error(msg string, token *Token) *Error
Error produces a nice error message and returns an error-object. The 'token'-argument is optional. If provided, it will take the token's position information. If not provided, it will automatically use the CURRENT token's position information.
func (p *Parser) Get(i int) *Token
Returns tokens[i] or NIL (if i >= len(tokens))
func (p *Parser) GetR(shift int) *Token
Returns tokens[current-position + shift] or NIL (if (current-position + i) >= len(tokens))
Returns the CURRENT token if the given type AND value matches. Consumes this token on success.
func (p *Parser) MatchOne(typ TokenType, vals ...string) *Token
Returns the CURRENT token if the given type AND *one* of the given values matches. Consumes this token on success.
func (p *Parser) MatchType(typ TokenType) *Token
Returns the CURRENT token if the given type matches. Consumes this token on success.
func (p *Parser) ParseExpression() (IEvaluator, *Error)
Returns the CURRENT token if the given type AND value matches. It DOES NOT consume the token.
Returns the tokens[current position + shift] token if the given type AND value matches for that token. DOES NOT consume the token.
func (p *Parser) PeekOne(typ TokenType, vals ...string) *Token
Returns the CURRENT token if the given type AND *one* of the given values matches. It DOES NOT consume the token.
func (p *Parser) PeekType(typ TokenType) *Token
Returns the CURRENT token if the given type matches. It DOES NOT consume the token.
func (p *Parser) PeekTypeN(shift int, typ TokenType) *Token
Returns the tokens[current position + shift] token if the given type matches. DOES NOT consume the token for that token.
func (*Parser) Remaining ¶
func (p *Parser) Remaining() int
Returns the UNCONSUMED token count.
func (p *Parser) SkipUntilTag(names ...string) *Error
Skips all nodes between starting tag and "{% endtag %}"
func (p Parser) WrapUntilTag(names ...string) (NodeWrapper, *Parser, *Error)
Wraps all nodes between starting tag and "{% endtag %}" and provides one simple interface to execute the wrapped nodes. It returns a parser to process provided arguments to the tag.
type TagParser func(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error)
This is the function signature of the tag's parser you will have to implement in order to create a new tag.
'doc' is providing access to the whole document while 'arguments' is providing access to the user's arguments to the tag:
{% your_tag_name some "arguments" 123 %}
start_token will be the *Token with the tag's name in it (here: your_tag_name).
Please see the Parser documentation on how to use the parser. See RegisterTag()'s documentation for more information about writing a tag as well.
type Template struct {
Options *[Options](#Options)}
Must panics, if a Template couldn't successfully parsed. This is how you would use it:
var baseTemplate = pongo2.Must(pongo2.FromFile("templates/base.html"))
Executes the template and returns the rendered template as a string
Executes the template and returns the rendered template as a []byte
Executes the template with the given context and writes to writer (io.Writer) on success. Context can be nil. Nothing is written on error; instead the error is being returned.
Same as ExecuteWriter. The only difference between both functions is that this function might already have written parts of the generated template in the case of an execution error because there's no intermediate buffer involved for performance reasons. This is handy if you need high performance template generation or if you want to manage your own pool of buffers.
TemplateLoader allows to implement a virtual file system.
type TemplateSet struct {
Globals [Context](#Context)
Debug [bool](/builtin#bool)
Options *[Options](#Options)}
TemplateSet allows you to create your own group of templates with their own global context (which is shared among all members of the set) and their own configuration. It's useful for a separation of different kind of templates (e. g. web templates vs. mail templates).
NewSet can be used to create sets with different kind of templates (e. g. web from mail templates), with different globals or other configurations.
func (set *TemplateSet) AddLoader(loaders ...TemplateLoader)
BanFilter bans a specific filter for this template set. See more in the documentation for TemplateSet.
BanTag bans a specific tag for this template set. See more in the documentation for TemplateSet.
func (set *TemplateSet) CleanCache(filenames ...string)
CleanCache cleans the template cache. If filenames is not empty, it will remove the template caches of those filenames. Or it will empty the whole template cache. It is thread-safe.
FromBytes loads a template from bytes and returns a Template instance.
FromCache is a convenient method to cache templates. It is thread-safe and will only compile the template associated with a filename once. If TemplateSet.Debug is true (for example during development phase), FromCache() will not cache the template and instead recompile it on any call (to make changes to a template live instantaneously).
FromFile loads a template from a filename and returns a Template instance.
FromString loads a template from string and returns a Template instance.
RenderTemplateBytes is a shortcut and renders template bytes directly.
RenderTemplateFile is a shortcut and renders a template file directly.
RenderTemplateString is a shortcut and renders a template string directly.
func AsSafeValue(i interface{}) *Value
AsSafeValue works like AsValue, but does not apply the 'escape' filter.
func AsValue(i interface{}) *Value
AsValue converts any given value to a pongo2.Value Usually being used within own functions passed to a template through a Context or within filter functions.
Example:
AsValue("my string")
func MustApplyFilter(name string, value *Value, param *Value) *Value
MustApplyFilter behaves like ApplyFilter, but panics on an error.
Bool returns the underlying value as bool. If the value is not bool, false will always be returned. If you're looking for true/false-evaluation of the underlying value, have a look on the IsTrue()-function.
func (v *Value) CanSlice() bool
CanSlice checks whether the underlying value is of type array, slice or string. You normally would use CanSlice() before using the Slice() operation.
func (v *Value) Contains(other *Value) bool
Contains checks whether the underlying value (which must be of type struct, map, string, array or slice) contains of another Value (e. g. used to check whether a struct contains of a specific field or a map contains a specific key).
Example:
AsValue("Hello, World!").Contains(AsValue("World")) == true
func (v *Value) EqualValueTo(other *Value) bool
EqualValueTo checks whether two values are containing the same value or object.
Float returns the underlying value as a float (converts the underlying value, if necessary). If it's not possible to convert the underlying value, it will return 0.0.
func (v *Value) Index(i int) *Value
Index gets the i-th item of an array, slice or string. Otherwise it will return NIL.
Integer returns the underlying value as an integer (converts the underlying value, if necessary). If it's not possible to convert the underlying value, it will return 0.
func (v *Value) Interface() interface{}
Interface gives you access to the underlying value.
IsBool checks whether the underlying value is a bool
func (v *Value) IsFloat() bool
IsFloat checks whether the underlying value is a float
func (v *Value) IsInteger() bool
IsInteger checks whether the underlying value is an integer
IsNil checks whether the underlying value is NIL
func (v *Value) IsNumber() bool
IsNumber checks whether the underlying value is either an integer or a float.
func (v *Value) IsString() bool
IsString checks whether the underlying value is a string
IsTime checks whether the underlying value is a time.Time.
IsTrue tries to evaluate the underlying value the Pythonic-way:
Returns TRUE in one the following cases:
- int != 0
- uint != 0
- float != 0.0
- len(array/chan/map/slice/string) > 0
- bool == true
- underlying value is a struct
Otherwise returns always FALSE.
func (v *Value) Iterate(fn func(idx, count int, key, value *Value) bool, empty func())
Iterate iterates over a map, array, slice or a string. It calls the function's first argument for every value with the following arguments:
idx current 0-index count total amount of items key *Value for the key or item value *Value (only for maps, the respective value for a specific key)
If the underlying value has no items or is not one of the types above, the empty function (function's second argument) will be called.
func (v *Value) IterateOrder(fn func(idx, count int, key, value *Value) bool, empty func(), reverse bool, sorted bool)
IterateOrder behaves like Value.Iterate, but can iterate through an array/slice/string in reverse. Does not affect the iteration through a map because maps don't have any particular order. However, you can force an order using the `sorted` keyword (and even use `reversed sorted`).
Len returns the length for an array, chan, map, slice or string. Otherwise it will return 0.
func (v *Value) Negate() *Value
Negate tries to negate the underlying value. It's mainly used for the NOT-operator and in conjunction with a call to return_value.IsTrue() afterwards.
Example:
AsValue(1).Negate().IsTrue() == false
func (v *Value) Slice(i, j int) *Value
Slice slices an array, slice or string. Otherwise it will return an empty []int.
String returns a string for the underlying value. If this value is not of type string, pongo2 tries to convert it. Currently the following types for underlying values are supported:
- string
- int/uint (any size)
- float (any precision)
- bool
- time.Time
- String() will be called on the underlying value if provided
NIL values will lead to an empty string. Unsupported types are leading to their respective type name.
Time returns the underlying value as time.Time. If the underlying value is not a time.Time, it returns the zero value of time.Time.