# README
pongo2
pongo2 is a Django-syntax like templating-language (official website).
Install/update using go get
(no dependencies required by pongo2):
go get -u github.com/flosch/pongo2/v6
Please use the issue tracker if you're encountering any problems with pongo2 or if you need help with implementing tags or filters (create a ticket!).
First impression of a template
<html>
<head>
<title>Our admins and users</title>
</head>
{# This is a short example to give you a quick overview of pongo2's syntax. #}
{% macro user_details(user, is_admin=false) %}
<div class="user_item">
<!-- Let's indicate a user's good karma -->
<h2 {% if (user.karma>= 40) || (user.karma > calc_avg_karma(userlist)+5) %} class="karma-good"{% endif %}>
<!-- This will call user.String() automatically if available: -->
{{ user }}
</h2>
<!-- Will print a human-readable time duration like "3 weeks ago" -->
<p>This user registered {{ user.register_date|naturaltime }}.</p>
<!-- Let's allow the users to write down their biography using markdown;
we will only show the first 15 words as a preview -->
<p>The user's biography:</p>
<p>
{{ user.biography|markdown|truncatewords_html:15 }}
<a href="/user/{{ user.id }}/">read more</a>
</p>
{% if is_admin %}
<p>This user is an admin!</p>
{% endif %}
</div>
{% endmacro %}
<body>
<!-- Make use of the macro defined above to avoid repetitive HTML code
since we want to use the same code for admins AND members -->
<h1>Our admins</h1>
{% for admin in adminlist %} {{ user_details(admin, true) }} {% endfor %}
<h1>Our members</h1>
{% for user in userlist %} {{ user_details(user) }} {% endfor %}
</body>
</html>
Features
- Syntax- and feature-set-compatible with Django 1.7
- Advanced C-like expressions.
- Complex function calls within expressions.
- Easy API to create new filters and tags (including parsing arguments)
- Additional features:
- Macros including importing macros from other files (see template_tests/macro.tpl)
- Template sandboxing (directory patterns, banned tags/filters)
Caveats
Filters
- date / time: The
date
andtime
filter are taking the Golang specific time- and date-format (not Django's one) currently. Take a look on the format here. - stringformat:
stringformat
does not take Python's string format syntax as a parameter, instead it takes Go's. Essentially{{ 3.14|stringformat:"pi is %.2f" }}
isfmt.Sprintf("pi is %.2f", 3.14)
. - escape / force_escape: Unlike Django's behaviour, the
escape
-filter is applied immediately. Therefore there is no need for aforce_escape
-filter yet.
Tags
- for: All the
forloop
fields (likeforloop.counter
) are written with a capital letter at the beginning. For example, thecounter
can be accessed byforloop.Counter
and the parentloop byforloop.Parentloop
. - now: takes Go's time format (see date and time-filter).
Misc
- not in-operator: You can check whether a map/struct/string contains a key/field/substring by using the in-operator (or the negation of it):
{% if key in map %}Key is in map{% else %}Key not in map{% endif %}
or{% if !(key in map) %}Key is NOT in map{% else %}Key is in map{% endif %}
.
Add-ons, libraries and helpers
Official
- pongo2-addons - Official additional filters/tags for pongo2 (for example a markdown-filter). They are in their own repository because they're relying on 3rd-party-libraries.
3rd-party
- beego-pongo2 - A tiny little helper for using Pongo2 with Beego.
- beego-pongo2.v2 - Same as
beego-pongo2
, but for pongo2 v2. - macaron-pongo2 - pongo2 support for Macaron, a modular web framework.
- ginpongo2 - middleware for gin to use pongo2 templates
- Build'n support for Iris' template engine
- pongo2gin - alternative renderer for gin to use pongo2 templates
- pongo2-trans -
trans
-tag implementation for internationalization - tpongo2 - pongo2 support for Tango, a micro-kernel & pluggable web framework.
- p2cli - command line templating utility based on pongo2
- pongorenderer - minimal pongo2 renderer for Echo web framework
- pongo2gcloud - Google Cloud Storage loader for pongo2 template files
Please add your project to this list and send me a pull request when you've developed something nice for pongo2.
Who's using pongo2
I'm compiling a list of pongo2 users. Add your project or company!
API-usage examples
Please see the documentation for a full list of provided API methods.
A tiny example (template string)
// 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": "florian"})
if err != nil {
panic(err)
}
fmt.Println(out) // Output: Hello Florian!
Example server-usage (template file)
package main
import (
"github.com/flosch/pongo2/v6"
"net/http"
)
// Pre-compiling the templates at application startup using the
// little Must()-helper function (Must() will panic if FromFile()
// or FromString() will return with an error - that's it).
// It's faster to pre-compile it anywhere at startup and only
// execute the template later.
var tplExample = pongo2.Must(pongo2.FromFile("example.html"))
func examplePage(w http.ResponseWriter, r *http.Request) {
// Execute the template per HTTP request
err := tplExample.ExecuteWriter(pongo2.Context{"query": r.FormValue("query")}, w)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func main() {
http.HandleFunc("/", examplePage)
http.ListenAndServe(":8080", nil)
}
# Functions
ApplyFilter applies a filter to a given value using the given parameters.
AsSafeValue works like AsValue, but does not apply the 'escape' filter.
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.
FilterExists returns true if the given filter is already registered.
Must panics, if a Template couldn't successfully parsed.
MustApplyFilter behaves like ApplyFilter, but panics on an error.
MustNewHttpFileSystemLoader creates a new HttpFilesystemLoader instance and panics if there's any error during instantiation.
MustNewLocalFileSystemLoader creates a new LocalFilesystemLoader instance and panics if there's any error during instantiation.
NewHttpFileSystemLoader creates a new HttpFileSystemLoader and allows templates to be loaded from the virtual filesystem.
NewLocalFileSystemLoader creates a new LocalFilesystemLoader and allows templatesto be loaded from disk (unrestricted).
NewSandboxedFilesystemLoader creates a new sandboxed local file system instance.
NewSet can be used to create sets with different kind of templates (e.
RegisterFilter registers a new filter.
Registers a new tag.
ReplaceFilter replaces an already registered filter with a new implementation.
Replaces an already registered tag with a new implementation.
# Variables
DefaultLoader allows the default un-sandboxed access to the local file system and is being used by the DefaultSet.
DefaultSet is a set created for you for convinience reasons.
Methods on the default set.
Globals for the default set.
Available keywords in pongo2.
Available symbols in pongo2 (within filters/tag).
# Structs
The Error type is being used to address an error during lexing, parsing or execution.
ExecutionContext contains all data important for the current rendering state.
FSLoader supports the fs.FS interface for loading templates.
HttpFilesystemLoader supports loading templates from an http.FileSystem - useful for using one of several file-to-code generators that packs static files into a go binary (ex: https://github.com/jteeuwen/go-bindata).
LocalFilesystemLoader represents a local filesystem loader with basic BaseDirectory capabilities.
Options allow you to change the behavior of template-engine.
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.
SandboxedFilesystemLoader is still WIP.
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.
# Interfaces
TemplateLoader allows to implement a virtual file system.
# Type aliases
A Context type provides constants, variables, instances or functions to a template.
FilterFunction is the type filter functions must fulfil.
This is the function signature of the tag's parser you will have to implement in order to create a new tag.