An open API service indexing awesome lists of open source software.

https://github.com/noirbizarre/gonja

Jinja-like syntax template-engine for Go
https://github.com/noirbizarre/gonja

golang golang-library jinja jinja2 template template-engine template-language

Last synced: 3 months ago
JSON representation

Jinja-like syntax template-engine for Go

Awesome Lists containing this project

README

          

# Gonja

[![GoDoc](https://godoc.org/github.com/noirbizarre/gonja?status.svg)](https://godoc.org/github.com/noirbizarre/gonja)
[![Build Status](https://travis-ci.org/noirbizarre/gonja.svg?branch=master)](https://travis-ci.org/noirbizarre/gonja)
[![Coverage Status](https://codecov.io/gh/noirbizarre/gonja/branch/master/graph/badge.svg)](https://codecov.io/gh/noirbizarre/gonja)

`gonja` is [`pongo2`](https://github.com/flosch/pongo2) fork intended to be aligned on `Jinja` template syntax instead of the `Django` one.

Install/update using `go get` (no dependencies required by `gonja`):
```
go get github.com/noirbizarre/gonja
```

Please use the [issue tracker](https://github.com/noirbizarre/gonja/issues) if you're encountering any problems with gonja or if you need help with implementing tags or filters ([create a ticket!](https://github.com/noirbizarre/gonja/issues/new)).

## First impression of a template

```HTML+Django
Our admins and users
{# This is a short example to give you a quick overview of gonja's syntax. #}

{% macro user_details(user, is_admin=false) %}



= 40) || (user.karma > calc_avg_karma(userlist)+5) %}
class="karma-good"{% endif %}>


{{ user }}


This user registered {{ user.register_date|naturaltime }}.




The user's biography:


{{ user.biography|markdown|truncatewords_html:15 }}
read more



{% if is_admin %}

This user is an admin!

{% endif %}

{% endmacro %}



Our admins


{% for admin in adminlist %}
{{ user_details(admin, true) }}
{% endfor %}

Our members


{% for user in userlist %}
{{ user_details(user) }}
{% endfor %}

```

## Features (and new in gonja)

* Entirely rewritten from the ground-up.
* [Advanced C-like expressions](https://github.com/noirbizarre/gonja/blob/master/template_tests/expressions.tpl).
* [Complex function calls within expressions](https://github.com/noirbizarre/gonja/blob/master/template_tests/function_calls_wrapper.tpl).
* [Easy API to create new filters and tags](http://godoc.org/github.com/noirbizarre/gonja#RegisterFilter) ([including parsing arguments](http://godoc.org/github.com/noirbizarre/gonja#Parser))
* Additional features:
* Macros including importing macros from other files (see [template_tests/macro.tpl](https://github.com/noirbizarre/gonja/blob/master/template_tests/macro.tpl))
* [Template sandboxing](https://godoc.org/github.com/noirbizarre/gonja#TemplateSet) ([directory patterns](http://golang.org/pkg/path/filepath/#Match), banned tags/filters)

## How you can help

* Write [filters](https://github.com/noirbizarre/gonja/blob/master/builtins/filters.go#L3) / [statements](https://github.com/noirbizarre/gonja/blob/master/builtins/statements.go#L4)
* Write/improve code tests (use the following command to see what tests are missing: `go test -v -cover -covermode=count -coverprofile=cover.out && go tool cover -html=cover.out` or have a look on [gocover.io/github.com/noirbizarre/gonja](http://gocover.io/github.com/noirbizarre/gonja))
* Write/improve template tests (see the `testData/` directory)
* Write middleware, libraries and websites using gonja. :-)

# Documentation

For a documentation on how the templating language works you can [head over to the Jinja documentation](https://jinja.palletsprojects.com). gonja aims to be compatible with it.

You can access gonja's API documentation on [godoc](https://godoc.org/github.com/noirbizarre/gonja).

## Caveats

### Filters

* **format**: `format` does **not** take Python's string format syntax as a parameter, instead it takes Go's. Essentially `{{ 3.14|stringformat:"pi is %.2f" }}` is `fmt.Sprintf("pi is %.2f", 3.14)`.
* **escape** / **force_escape**: Unlike Jinja's behaviour, the `escape`-filter is applied immediately. Therefore there is no need for a `force_escape`-filter yet.

# API-usage examples

Please see the documentation for a full list of provided API methods.

## A tiny example (template string)

```Go
// Compile the template first (i. e. creating the AST)
tpl, err := gonja.FromString("Hello {{ name|capfirst }}!")
if err != nil {
panic(err)
}
// Now you can render the template with the given
// gonja.Context how often you want to.
out, err := tpl.Execute(gonja.Context{"name": "axel"})
if err != nil {
panic(err)
}
fmt.Println(out) // Output: Hello Axel!
```

## Example server-usage (template file)

```Go
package main

import (
"github.com/noirbizarre/gonja"
"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 tpl = gonja.Must(gonja.FromFile("example.html"))

func examplePage(w http.ResponseWriter, r *http.Request) {
// Execute the template per HTTP request
out, err := tpl.Execute(gonja.Context{"query": r.FormValue("query")})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
w.WriteString(out)
}

func main() {
http.HandleFunc("/", examplePage)
http.ListenAndServe(":8080", nil)
}
```

# Benchmark

The benchmarks have been run on the my machine (`Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz`) using the command:

go test -bench . -cpu 1,2,4,8

All benchmarks are compiling (depends on the benchmark) and executing the `testData/complex.tpl` template.

The results are:

BenchmarkFromCache 30000 41259 ns/op
BenchmarkFromCache-2 30000 42776 ns/op
BenchmarkFromCache-4 30000 44432 ns/op
BenchmarkFromFile 3000 437755 ns/op
BenchmarkFromFile-2 3000 472828 ns/op
BenchmarkFromFile-4 2000 519758 ns/op
BenchmarkExecute 30000 41984 ns/op
BenchmarkExecute-2 30000 48546 ns/op
BenchmarkExecute-4 20000 104469 ns/op
BenchmarkCompileAndExecute 3000 428425 ns/op
BenchmarkCompileAndExecute-2 3000 459058 ns/op
BenchmarkCompileAndExecute-4 3000 488519 ns/op
BenchmarkParallelExecute 30000 45262 ns/op
BenchmarkParallelExecute-2 100000 23490 ns/op
BenchmarkParallelExecute-4 100000 24206 ns/op

Benchmarked on August 18th 2019.