- Notifications
You must be signed in to change notification settings - Fork22
Jinja-like syntax template-engine for Go
License
noirbizarre/gonja
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
gonja
ispongo2
fork intended to be aligned onJinja
template syntax instead of theDjango
one.
Install/update usinggo get
(no dependencies required bygonja
):
go get github.com/noirbizarre/gonja
Please use theissue tracker if you're encountering any problems with gonja or if you need help with implementing tags or filters (create a ticket!).
<html><head><title>Our admins and users</title></head>{# This is a short example to give you a quick overview of gonja's syntax. #}{%macrouser_details(user,is_admin=false)%}<divclass="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 }}<ahref="/user/{{ user.id }}/">read more</a></p>{%ifis_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>{%foradmininadminlist%}{{ user_details(admin, true) }}{%endfor%}<h1>Our members</h1>{%foruserinuserlist%}{{ user_details(user) }}{%endfor%}</body></html>
- Entirely rewritten from the ground-up.
- 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 (seetemplate_tests/macro.tpl)
- Template sandboxing (directory patterns, banned tags/filters)
- Writefilters /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 ongocover.io/github.com/noirbizarre/gonja) - Write/improve template tests (see the
testData/
directory) - Write middleware, libraries and websites using gonja. :-)
For a documentation on how the templating language works you canhead over to the Jinja documentation. gonja aims to be compatible with it.
You can access gonja's API documentation ongodoc.
- format:
format
doesnot 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 Jinja's behaviour, the
escape
-filter is applied immediately. Therefore there is no need for aforce_escape
-filter yet.
Please see the documentation for a full list of provided API methods.
// Compile the template first (i. e. creating the AST)tpl,err:=gonja.FromString("Hello {{ name|capfirst }}!")iferr!=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"})iferr!=nil {panic(err)}fmt.Println(out)// Output: Hello Axel!
package mainimport ("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.vartpl=gonja.Must(gonja.FromFile("example.html"))funcexamplePage(w http.ResponseWriter,r*http.Request) {// Execute the template per HTTP requestout,err:=tpl.Execute(gonja.Context{"query":r.FormValue("query")})iferr!=nil {http.Error(w,err.Error(),http.StatusInternalServerError)}w.WriteString(out)}funcmain() {http.HandleFunc("/",examplePage)http.ListenAndServe(":8080",nil)}
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 thetestData/complex.tpl
template.
The results are:
BenchmarkFromCache 30000 41259 ns/opBenchmarkFromCache-2 30000 42776 ns/opBenchmarkFromCache-4 30000 44432 ns/opBenchmarkFromFile 3000 437755 ns/opBenchmarkFromFile-2 3000 472828 ns/opBenchmarkFromFile-4 2000 519758 ns/opBenchmarkExecute 30000 41984 ns/opBenchmarkExecute-2 30000 48546 ns/opBenchmarkExecute-4 20000 104469 ns/opBenchmarkCompileAndExecute 3000 428425 ns/opBenchmarkCompileAndExecute-2 3000 459058 ns/opBenchmarkCompileAndExecute-4 3000 488519 ns/opBenchmarkParallelExecute 30000 45262 ns/opBenchmarkParallelExecute-2 100000 23490 ns/opBenchmarkParallelExecute-4 100000 24206 ns/op
Benchmarked on August 18th 2019.