Coder Social home page Coder Social logo

gonja's Introduction

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.

gonja's People

Contributors

noirbizarre avatar nvartolomei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

gonja's Issues

gonja CLI ?

Is there a gonja CLI I can use. Just asking before potentially writing it myself.

Unable to Execute template

example code

package main

import (
    "fmt"
    "github.com/noirbizarre/gonja"
)

func main() {
    // 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!
}

Run after build abnormal

Unable to Execute template: Unable to render expression 'FilteredExpression(Expression=Name(Val=name Line=1 Col=10) Line=1 Col=10)': Unable to evaluate filter &{<Token[Name] Val='capfirst' Pos=14 Line=1 Col=15> capfirst [] map[]}: Filte
r "capfirst" not found

Thanks !!

Thank you for writing this library. I took me sometime to find this library. I am playing around with it.

Doesn't support Jinja's for...else syntax

func TestJinja(t *testing.T) {
	jsonStr := `{"search": "yeno"}`
	c := map[string]interface{}{}
	err := json.Unmarshal([]byte(jsonStr), &c)
	if err != nil {
		fmt.Println(err.Error())
		t.FailNow()
	}
	tmpl := `
{%- set keywords = ['yes', 'hello'] -%}
{%- for w in keywords if w in search -%}
{%- if loop.first -%}
match
{%- endif -%}
{%- else -%}
no match
{%- endfor -%}
`
	tpl, err := gonja.FromString(tmpl)
	if err != nil {
		return
	}
	out, err := tpl.Execute(c)
	if err != nil {
		fmt.Println(err.Error())
		t.FailNow()
	}
	fmt.Println("output:", out)
}

The above code tests whether an input string contains any string (as substring) in a list predefined inside a Jinja template. However, going into the else branch produces an empty output whereas "no match" is expected. The "match" case works though.

https://jinja.palletsprojects.com/en/3.1.x/templates/#for

template str `a is defined and a == 'x'` cannot execute

code

func TestGonja(t *testing.T) {
	tpl, err := gonja.FromString("{{ a is defined and a == 'x' }}")
	if err != nil {
		t.Log(err)
		return
	}
	out, err := tpl.Execute(gonja.Context{"a": "x"})
	if err != nil {
		t.Log(err)
		return
	}
	t.Log(out)
}

error

TestGonja: util_test.go:34: '}}' expected here (Line: 1 Col: 21, near "a")

How fix,Could anyone give me some suggestions?

[Bug] Issue with parsing {%- endraw %}

The following file isn't parsable:

{%- raw -%}
123
{%- endraw -%}

The parser gives this error:

Unable to parse statement "raw": Unexpected EOF, expected tag endraw. (Line: 0 Col: 0, near "Unable to find raw closing statement"

But this file is:

{%- raw -%}
123
{% endraw -%}

I'm not sure why {% endraw -%} works but {%- endraw -%} doesn't. But figured I should open a bug report in case its an easy fix to somoene who knows the source code..

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.