Documentation ¶
Overview ¶
Package tal implements the TAL template language for generating HTML5 output.
TAL templates are HTML5 documents containing additional attributes that, using the TALES expression language, change the structure and content of the resulting document.
Here is a basic example (without error handling) that prints "<html><h1>Raising Steam</h1> by Author: Terry Pratchett"
type Book struct { Title string Author string } book := Book{"Raising Steam", "Terry Pratchett"} tmpl, _ := tal.CompileTemplate(strings.NewReader(`<html><h1 tal:content="title">Title goes here</h1> by <b tal:replace="string: Author: $Author"></b>`)) tmpl.Render(book, os.Stdout)
The tal package also supports METAL macros as described later on.
TAL Commands ¶
The tal package supports all TAL commands defined by Zope (see http://docs.zope.org/zope2/zope2book/AppendixC.html).
Define ¶
tal:define sets a local or global variable:
tal:define="[local | global] name expression [; define-expression...]
Description: Sets the value of "name" to "expression". By default the name will be applicable in the "local" scope, which consists of this tag, and all other tags nested inside this tag. If the "global" keyword is used then this name will keep its value for the rest of the document.
If the expression evaluates to nil, the variable will be set to the value nil.
Example:
<div tal:define="global title book/theTitle; local chapterTitle book/chapter/theTitle">
Condition ¶
tal:condition makes output of an element conditional:
tal:condition="expression"
Description: If the expression evaluates to true then this tag and all its children will be output. If the expression evaluates to false then this tag and all its children will not be included in the output.
An expression is considered false if it is not found, evaluates to nil, is an empty string, is zero or is a boolean false. All other values are treated as true.
Example:
<h1 tal:condition="user/firstLogin">Welcome to this page!</h1>
Repeat ¶
tal:repeat replicates an element a number of times:
tal:repeat="name expression"
Description: Evaluates "expression", and if it is a slice or array, repeats this tag and all children once for each item in the sequence. The "name" will be set to the value of the item in the current iteration, and is also the name of the repeat variable. The repeat variable is accessible using the TAL path: repeat/name and has the following properties:
index - Iteration number starting from zero number - Iteration number starting from one even - True if this is an even iteration odd - True if this is an odd iteration start - True if this is the first item in the sequence end - True if this is the last item in the sequence length - The length of the sequence letter - The lower case letter for this iteration, starting at "a" Letter - Upper case version of letter roman - Iteration number in Roman numerals, starting at i Roman - Upper case version of roman
The "first" and "last" properties are not supported.
If the expression evaluates to tal.Default, the contents of the template will be kept as-is with no repeat variable set. If the expression evaluates to an object other than a slice or array, or the slice or array is empty, the element and it's children are removed.
Example:
<table> <tr tal:repeat="fruit basket"> <td tal:content="repeat/fruit/number"></td> <td tal:content="fruit/name"></td> </tr> </table>
Content ¶
tal:content replaces the content of an element:
tal:content="[text | structure] expression"
Description: Replaces the contents of the tag with the value of "expression". By default, and if the "text" keyword is present, then the value of the expression will be escaped as required (i.e. characters "&<> will be escaped). If the "structure" keyword is present then the value will be output with no escaping performed.
If the expression evaluates to tal.Default then the template content is kept as is. If the expression evaluates to nil then the child contents of the tag will be empty.
Example:
<h1 tal:content="user/firstName"></h1>
Replace ¶
tal:replace replaces the whole element:
tal:replace="[text | structure] expression"
Description: Behaves identically to tal:content, except that the tag is removed from the output (as if tal:omit-tag had been used).
Example:
<h1>Welcome <b tal:replace="user/firstName"></b></h1>
Attributes ¶
tal:attributes sets or removes attributes on the element:
tal:attributes="name expression[;attributes-expression]"
Description: Evaluates each "expression" and replaces the tag's attribute "name". If the expression evaluates to nil then the attribute is removed from the tag. If the expression evaluates to default then the original tag's attribute is kept. If the attribute is a HTML5 boolean attribute then it will be removed if the expression is not found, evaluates to nil, is an empty string, is zero or is a boolean false. All other expression values are treated as true and the attribute value is set to equal to the attribute name.
If the "expression" requires a semi-colon then it must be escaped by using ";;".
Example:
<a tal:attributes="href user/homepage;title user/fullname">Your Homepage</a>
Omit Tag ¶
tal:omit-tag removes the start and end tags:
tal:omit-tag="expression"
Description: Removes the tag (leaving the tags content) if the expression evaluates to true. If expression is empty then it is taken as true.
An expression is considered false if it is not found, evaluates to nil, is an empty string, is zero or is a boolean false. All other values are treated as true.
Example:
<p><b tal:omit-tag="not:user/firstVisit">Welcome</b> to this page!</h1>
TALES Expressions ¶
The expressions used in TAL are called TALES expressions. The simplest TALES expression is a path which references a value, e.g. page/body references the body property of the page object. Objects are passed as the first argument of the Render method on a compiled template and must be either a struct, pointer to a struct or a map with strings as keys.
The tal package does not support the python: and nocall: expression types.
Path ¶
path: provides access to properties on objects.
Syntax: [path:]string[|TALES Expression]
Description: A path, optionally starting with the modifier 'path:', references a property of an object. The '/' delimiter is used to end the name of an object and start of the property name. Properties themselves may be objects that in turn have properties. The '|' ("or") character is used to find an alternative value to a path if the first path evaluates to nil or does not exist.
Example:
<p tal:content="book/chapter/title | string:Untitled"></p>
There are several built in variables that can be used in paths:
nothing - acts as nil in Go default - keeps the existing value of the node (tag content or attribute value), the same value as tal.Default repeat - access to repeat variables (see tal:repeat) attrs - a dictionary of original attributes of the current tag
Path Variables ¶
Path variables allow for indirection in paths.
Syntax: [path:]object/?attribute
Description: The "attribute" is evaluated as a local or global variable, and it's value is used as the attribute name to lookup on the object. Useful for accessing the contents of a map within a loop:
Example:
<div tal:content="myMap/?loopValue"/>
Exists ¶
exists: Tests whether a path exists.
Syntax: exists:path
Description: Returns true if the path exists, false otherwise. Particularly useful for eliminating entire subtrees if a particular object is not available.
Example:
<div tal:condition="exists:book">...</div>
Not ¶
not: Returns the inverse boolean value of a path.
Syntax: not:tales-path
Description: Returns the inverse of the tales-path. If the path returns true, not:path will return false.
Example:
<p tal:condition="not: user/firstLogin">Welcome to the site!</p>
String ¶
string: Basic string substitution
Syntax: string:text
Description: Evaluates to a string with value text while substituting variables with the form ${pathName} and $pathName
Example:
<b tal:content="string:Welcome ${user/name}!"></b>
METAL Macro Language ¶
METAL is a macro language commonly used with TAL & TALES. METAL allows part of a template to be used as a macro in later parts of the template, or shared across templates.
Macros defined in a template can be retrieved from a compiled template and added to the context by calling the Macros() method.
Define Macro ¶
metal:define-macro marks an element and it's subtree as being a reusable macro.
Syntax: metal:define-macro="name"
Description: Defines a new macro that can be reference later as "name".
Example:
<div metal:define-macro="footer">Copyright <span tal:content="page/lastModified">2004</span></div>
Use Macro ¶
metal:use-macro expands a macro into the template.
Syntax: metal:use-macro="expression"
Description: Evaluates "expression" and uses this as a macro.
Example:
<div metal:use-macro="macros/footer"></div>
Define Slot ¶
metal:define-slot creates a customisation point within a macro.
Syntax: metal:define-slot="name"
Description: Defines a customisation point in a macro with the given name.
Example:
<div metal:define-macro="footer"> <b>Standard disclaimer for the site.</b> <i metal:define-slot="Contact">Contact admin@site.com</i> </div>
Fill Slot ¶
metal:fill-slot overwrites the contents of a slot when using a macro.
Syntax: metal:fill-slot="name"
Description: Replaces the content of a slot with this element.
Example:
<div metal:use-macro="macros/footer"> <i metal:fill-slot="Contact">Contact someone else</i> </div>
Notes On HTML ¶
The tal package supports html5 output. Void elements (such as <img>) are supported and will correctly suppress end tags. Templates must have balanced start and end tags for non-void elements. Even though HTML5 elements defines several elements as supporting optional end tags, for tal templates end tags must be provided.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var Default interface{} = struct{ Name string }{"Default"}
Default is a special value used by TAL to indicate that the default template content should be used in tal:content, etc.
Use the top level TALES variable "default" for the default value in a path.
For None use the path "nothing" and in Go use nil.
Functions ¶
This section is empty.
Types ¶
type CompileError ¶
type CompileError struct { // LastToken is the last parsed HTML token seen. LastToken string // NextData contains some of the unparsed data that happens after the error. NextData string // ErrorType specifies the kind of compilation error that has occured. ErrorType CompileErrorKind }
CompileErrors are returned from CompileTemplate for compilation errors.
func (*CompileError) Error ¶
func (err *CompileError) Error() string
Error returns a text description of the compilation error.
type CompileErrorKind ¶
type CompileErrorKind int
CompileErrorKind indicates the kind of error encountered while compiling
const ( // ErrUnexpectedCloseTag is if a close tag is encountered for which an open tag was not seen. ErrUnexpectedCloseTag CompileErrorKind = iota // ErrUnknownTalCommand is if a tal: or metal: command is not one of the supported commands. ErrUnknownTalCommand // ErrExpressionMalformed is for expressions that don't match the tal command they are on. ErrExpressionMalformed // ErrExpressionMissing is if an expression is missing where one is expected. ErrExpressionMissing // ErrSlotOutsideMacro is if a metal:fill-slot is outside of a use-macro. ErrSlotOutsideMacro )
type RenderConfig ¶
type RenderConfig func(t *Template, rc *renderContext)
A RenderConfig function is one that can be passed as an option to Render.
func RenderDebugLogging ¶
func RenderDebugLogging(logger func(fmt string, args ...interface{})) RenderConfig
RenderDebugLogging uses the given logger for debug output when rendering the template.
To use the standard log library pass RenderDebugLogging(log.Printf) to the Render method.
type TalesValue ¶
type TalesValue interface { /* TalesValue handles all property lookups on the object. All fields & methods that would normally be automatically found by tal will instead be passed to TalesValue for handling. If the property is not supported by this object, nil should be returned. */ TalesValue(property string) (result interface{}) }
TalesValue provide a method allowing properties to be resolved to a value.
TalesValue can be used to provide custom lookups for resolving the last entry in a path.
Example ¶
package main import ( "os" "strings" ) type Person struct { name string } func (p *Person) TalesValue(property string) interface{} { switch property { case "Name": return p.name case "upper": return strings.ToUpper(p.name) case "lower": return strings.ToLower(p.name) } return nil } func main() { vals := make(map[string]interface{}) vals["person"] = &Person{"Alice"} tmpl, _ := CompileTemplate(strings.NewReader(`<b tal:content="person/Name"></b> and <b tal:content="person/upper"></b> and <b tal:content="person/lower"></b>`)) tmpl.Render(vals, os.Stdout) }
Output: <b>Alice</b> and <b>ALICE</b> and <b>alice</b>
type Template ¶
type Template struct {
// contains filtered or unexported fields
}
Template holds the compiled version of a TAL template.
Once the Template has been compiled it is immutable and can be used by multiple goroutines simultaneously.
func CompileTemplate ¶
CompileTemplate reads the template in and compiles it ready for execution.
If a compilation error (rather than IO error) occurs, the returned error will be a CompileError object.
The io.Reader must provide a stream of UTF-8 encoded text. Templates render into UTF-8, so any conversion to or from other character sets must be carried out in the io.Reader and io.Writer used.
func (*Template) Render ¶
func (t *Template) Render(context interface{}, out io.Writer, config ...RenderConfig) error
Render a template contents with the given context to the io.Writer.
The Context object should be either a struct or a map with string keys. Resolution of TAL paths is done in the following order:
1 - nothing and default: built-in variables 2 - attrs: access to the original attributes on the element 3 - repeat: access to the repeat variables 4 - local variables 5 - global variables 6 - User provided context
When looking for a property on local, global and user provided context the following lookup rules are followed:
1 - If a map, look for a value with the property name as the key. 2 - If a struct or pointer to a struct: a) Look for an exported field with this name b) Look for a Pointer Method with this name and call it c) Look for a Value Method with this name and call it
If a value found in either a map or struct field is a function, it will be called. Functions and methods are called with no arguments and the first value returned is used as the resulting value.
A RenderConfig option can be provided to set debug logging.
Example ¶
vals := make(map[string]interface{}) vals["colours"] = []string{"Red", "Green", "Blue"} vals["name"] = "Alice" vals["age"] = 21 tmpl, _ := CompileTemplate(strings.NewReader(` <html> <body> <h1 tal:content="name">Name Here</h1> <p tal:content="string: Age: ${age}">Age</p> <ul> <li tal:repeat="colour colours" tal:content="colour">Colours</li> </ul> </body> </html>`)) tmpl.Render(vals, os.Stdout) /* Output: <html> <body> <h1>Alice</h1> <p>Age: 21</p> <ul> <li>Red</li><li>Green</li><li>Blue</li> </ul> </body> </html> */
Output: <html> <body> <h1>Alice</h1> <p>Age: 21</p> <ul> <li>Red</li><li>Green</li><li>Blue</li> </ul> </body> </html>
func (*Template) TalesValue ¶
Templates are a TalesValue that provides its macros as properties.
A Templates own macros are made available to it under the "macros" object.
Example ¶
vals := make(map[string]interface{}) macroTemplate, _ := CompileTemplate(strings.NewReader(`<html><body><h2 metal:define-macro="author">Author Name</h2></body></html>`)) vals["sharedmacros"] = macroTemplate tmpl, _ := CompileTemplate(strings.NewReader(` <html><body> <p metal:define-macro="boiler">Boiler Plate Message</p> <h2 metal:use-macro="sharedmacros/author"></h2> <p metal:use-macro="macros/boiler"></p> </body></html>`)) tmpl.Render(vals, os.Stdout) /* Output: <html><body> <p>Boiler Plate Message</p> <h2>Author Name</h2> <p>Boiler Plate Message</p> </body></html> */
Output: <html><body> <p>Boiler Plate Message</p> <h2>Author Name</h2> <p>Boiler Plate Message</p> </body></html>