• Stars
    star
    100
  • Rank 340,703 (Top 7 %)
  • Language
    Go
  • License
    MIT License
  • Created about 5 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Jinja-like syntax template-engine for Go

Gonja

GoDoc Build Status Coverage Status

gonja is 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 if you're encountering any problems with gonja 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 gonja'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 (and new in gonja)

How you can help

  • Write filters / statements
  • 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)
  • 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. gonja aims to be compatible with it.

You can access gonja's API documentation on godoc.

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)

// 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)

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.

More Repositories

1

flask-restplus

Fully featured framework for fast, easy and documented API development with Flask
Python
2,734
star
2

django.js

Javascript tools for Django
JavaScript
180
star
3

django-eztables

Easy integration between jQuery DataTables and Django.
JavaScript
97
star
4

django-ember

Django Ember.js integration
JavaScript
58
star
5

django-absolute

Easy full absolute URLs for Django
Python
36
star
6

bumpr

Bump'R: Bump and release versions
Python
32
star
7

flask-fs

Simple and easy file storages for Flask
Python
31
star
8

pelican-microdata

Microdata semantic markups support for Pelican Blog Generator
Python
17
star
9

pdm-dockerize

Help generating docker images from PDM projects
Python
12
star
10

pytest-copier

A Copier plugin for pytest to help testing Copier templates
Python
8
star
11

pelican-frontmark

A Pelican CommonMark/Front Matter reader
Python
7
star
12

pelican-social

Social directives for Pelican static blog generator.
Python
6
star
13

airorm

An Active Record ORM for Flex/AIR
ActionScript
6
star
14

splashes

Elasticsearch loader and playground for SIRENE dataset
Python
5
star
15

minibench

A really simple benchmark tool
Python
4
star
16

pelican-drafts

Add a browsable drafts listing to your Pelican website
Python
4
star
17

ezwall-plugin

A Jenkins plugin that simply add a button to display a fullscreen buildwall on each view.
JavaScript
4
star
18

setuptools-meta

Easily store custom metadata with setuptools.
Python
3
star
19

umfactory

Factories for uMongo
Python
2
star
20

description-column

Jenkins Description Column Plugin
Java
1
star
21

gookie

A command-line utility to create projects (or parts of) using templates
1
star
22

git-doc

Illustrated git documentation
Python
1
star
23

json4humans

Python tools for JSONC and JSON5 (aka. JSON for humans)
Python
1
star
24

strello

Extract some statistics from Trello JSON dump
Python
1
star
25

slides-paris.py

Python Packaging Paris.py Meetup slides
JavaScript
1
star
26

pyss

Python CSS Compiler
1
star
27

virtualenvwrapper.tools

Some virtualenvwrapper extensions
Python
1
star
28

pelican-data

Data and collections management for Pelican
Python
1
star
29

need-checks

Expect or wait status checks for a commit
Python
1
star
30

config.nvim

My personal NeoViM configuration
Lua
1
star