github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/flosch/pongo2.v3/README.md (about) 1 # [pongo](https://en.wikipedia.org/wiki/Pongo_%28genus%29)2 2 3 [](https://godoc.org/github.com/flosch/pongo2) 4 [](https://travis-ci.org/flosch/pongo2) 5 [](https://coveralls.io/r/flosch/pongo2?branch=master) 6 [](https://gratipay.com/flosch/) 7 [](https://www.bountysource.com/trackers/3654947-pongo2?utm_source=3654947&utm_medium=shield&utm_campaign=TRACKER_BADGE) 8 9 pongo2 is the successor of [pongo](https://github.com/flosch/pongo), a Django-syntax like templating-language. 10 11 Install/update using `go get` (no dependencies required by pongo2): 12 ``` 13 go get -u github.com/flosch/pongo2 14 ``` 15 16 Please use the [issue tracker](https://github.com/flosch/pongo2/issues) if you're encountering any problems with pongo2 or if you need help with implementing tags or filters ([create a ticket!](https://github.com/flosch/pongo2/issues/new)). If possible, please use [playground](https://www.florian-schlachter.de/pongo2/) to create a short test case on what's wrong and include the link to the snippet in your issue. 17 18 **New**: [Try pongo2 out in the pongo2 playground.](https://www.florian-schlachter.de/pongo2/) 19 20 ## First impression of a template 21 22 ```HTML+Django 23 <html><head><title>Our admins and users</title></head> 24 {# This is a short example to give you a quick overview of pongo2's syntax. #} 25 26 {% macro user_details(user, is_admin=false) %} 27 <div class="user_item"> 28 <!-- Let's indicate a user's good karma --> 29 <h2 {% if (user.karma >= 40) || (user.karma > calc_avg_karma(userlist)+5) %} 30 class="karma-good"{% endif %}> 31 32 <!-- This will call user.String() automatically if available: --> 33 {{ user }} 34 </h2> 35 36 <!-- Will print a human-readable time duration like "3 weeks ago" --> 37 <p>This user registered {{ user.register_date|naturaltime }}.</p> 38 39 <!-- Let's allow the users to write down their biography using markdown; 40 we will only show the first 15 words as a preview --> 41 <p>The user's biography:</p> 42 <p>{{ user.biography|markdown|truncatewords_html:15 }} 43 <a href="/user/{{ user.id }}/">read more</a></p> 44 45 {% if is_admin %}<p>This user is an admin!</p>{% endif %} 46 </div> 47 {% endmacro %} 48 49 <body> 50 <!-- Make use of the macro defined above to avoid repetitive HTML code 51 since we want to use the same code for admins AND members --> 52 53 <h1>Our admins</h1> 54 {% for admin in adminlist %} 55 {{ user_details(admin, true) }} 56 {% endfor %} 57 58 <h1>Our members</h1> 59 {% for user in userlist %} 60 {{ user_details(user) }} 61 {% endfor %} 62 </body> 63 </html> 64 ``` 65 66 ## Development status 67 68 **Latest stable release**: v3.0 (`go get -u gopkg.in/flosch/pongo2.v3` / [`v3`](https://github.com/flosch/pongo2/tree/v3)-branch) [[read the announcement](https://www.florian-schlachter.de/post/pongo2-v3/)] 69 70 **Current development**: v4 (`master`-branch) 71 72 *Note*: With the release of pongo v4 the branch v2 will be deprecated. 73 74 **Deprecated versions** (not supported anymore): v1 75 76 | Topic | Status | 77 | ------------------------------------ | -------------------------------------------------------------------------------------- | 78 | Django version compatibility: | [1.7](https://docs.djangoproject.com/en/1.7/ref/templates/builtins/) | 79 | *Missing* (planned) **filters**: | none ([hints](https://github.com/flosch/pongo2/blob/master/filters_builtin.go#L3)) | 80 | *Missing* (planned) **tags**: | none ([hints](https://github.com/flosch/pongo2/blob/master/tags.go#L3)) | 81 82 Please also have a look on the [caveats](https://github.com/flosch/pongo2#caveats) and on the [official add-ons](https://github.com/flosch/pongo2#official). 83 84 ## Features (and new in pongo2) 85 86 * Entirely rewritten from the ground-up. 87 * [Advanced C-like expressions](https://github.com/flosch/pongo2/blob/master/template_tests/expressions.tpl). 88 * [Complex function calls within expressions](https://github.com/flosch/pongo2/blob/master/template_tests/function_calls_wrapper.tpl). 89 * [Easy API to create new filters and tags](http://godoc.org/github.com/flosch/pongo2#RegisterFilter) ([including parsing arguments](http://godoc.org/github.com/flosch/pongo2#Parser)) 90 * Additional features: 91 * Macros including importing macros from other files (see [template_tests/macro.tpl](https://github.com/flosch/pongo2/blob/master/template_tests/macro.tpl)) 92 * [Template sandboxing](https://godoc.org/github.com/flosch/pongo2#TemplateSet) ([directory patterns](http://golang.org/pkg/path/filepath/#Match), banned tags/filters) 93 94 ## Recent API changes within pongo2 95 96 If you're using the `master`-branch of pongo2, you might be interested in this section. Since pongo2 is still in development (even though there is a first stable release!), there could be (backwards-incompatible) API changes over time. To keep track of these and therefore make it painless for you to adapt your codebase, I'll list them here. 97 98 * Function signature for tag and filter parsing/execution changed (`error` return type changed to `*Error`). 99 * `INodeEvaluator` has been removed and got replaced by `IEvaluator`. You can change your existing tags/filters by simply replacing the interface. 100 * Two new helper functions: [`RenderTemplateFile()`](https://godoc.org/github.com/flosch/pongo2#RenderTemplateFile) and [`RenderTemplateString()`](https://godoc.org/github.com/flosch/pongo2#RenderTemplateString). 101 * `Template.ExecuteRW()` is now [`Template.ExecuteWriter()`](https://godoc.org/github.com/flosch/pongo2#Template.ExecuteWriter) 102 * `Template.Execute*()` functions do now take a `pongo2.Context` directly (no pointer anymore). 103 104 ## How you can help 105 106 * Write [filters](https://github.com/flosch/pongo2/blob/master/filters_builtin.go#L3) / [tags](https://github.com/flosch/pongo2/blob/master/tags.go#L4) (see [tutorial](https://www.florian-schlachter.de/post/pongo2/)) by forking pongo2 and sending pull requests 107 * 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`) 108 * Write/improve template tests (see the `template_tests/` directory) 109 * Write middleware, libraries and websites using pongo2. :-) 110 111 # Documentation 112 113 For a documentation on how the templating language works you can [head over to the Django documentation](https://docs.djangoproject.com/en/dev/topics/templates/). pongo2 aims to be compatible with it. 114 115 You can access pongo2's API documentation on [godoc](https://godoc.org/github.com/flosch/pongo2). 116 117 ## Blog post series 118 119 * [pongo2 v2 released](https://www.florian-schlachter.de/post/pongo2-v2/) 120 * [pongo2 1.0 released](https://www.florian-schlachter.de/post/pongo2-10/) [August 8th 2014] 121 * [pongo2 playground](https://www.florian-schlachter.de/post/pongo2-playground/) [August 1st 2014] 122 * [Release of pongo2 1.0-rc1 + pongo2-addons](https://www.florian-schlachter.de/post/pongo2-10-rc1/) [July 30th 2014] 123 * [Introduction to pongo2 + migration- and "how to write tags/filters"-tutorial.](https://www.florian-schlachter.de/post/pongo2/) [June 29th 2014] 124 125 ## Caveats 126 127 ### Filters 128 129 * **date** / **time**: The `date` and `time` filter are taking the Golang specific time- and date-format (not Django's one) currently. [Take a look on the format here](http://golang.org/pkg/time/#Time.Format). 130 * **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" }}` is `fmt.Sprintf("pi is %.2f", 3.14)`. 131 * **escape** / **force_escape**: Unlike Django's behaviour, the `escape`-filter is applied immediately. Therefore there is no need for a `force_escape`-filter yet. 132 133 ### Tags 134 135 * **for**: All the `forloop` fields (like `forloop.counter`) are written with a capital letter at the beginning. For example, the `counter` can be accessed by `forloop.Counter` and the parentloop by `forloop.Parentloop`. 136 * **now**: takes Go's time format (see **date** and **time**-filter). 137 138 ### Misc 139 140 * **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): 141 `{% 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 %}`. 142 143 # Add-ons, libraries and helpers 144 145 ## Official 146 147 * [ponginae](https://github.com/flosch/ponginae) - A web-framework for Go (using pongo2). 148 * [pongo2-tools](https://github.com/flosch/pongo2-tools) - Official tools and helpers for pongo2 149 * [pongo2-addons](https://github.com/flosch/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. 150 151 ## 3rd-party 152 153 * [beego-pongo2](https://github.com/oal/beego-pongo2) - A tiny little helper for using Pongo2 with [Beego](https://github.com/astaxie/beego). 154 * [beego-pongo2.v2](https://github.com/ipfans/beego-pongo2.v2) - Same as `beego-pongo2`, but for pongo2 v2. 155 * [macaron-pongo2](https://github.com/macaron-contrib/pongo2) - pongo2 support for [Macaron](https://github.com/Unknwon/macaron), a modular web framework. 156 * [ginpongo2](https://github.com/ngerakines/ginpongo2) - middleware for [gin](github.com/gin-gonic/gin) to use pongo2 templates 157 * [pongo2-trans](https://github.com/fromYukki/pongo2trans) - `trans`-tag implementation for internationalization 158 159 Please add your project to this list and send me a pull request when you've developed something nice for pongo2. 160 161 # API-usage examples 162 163 Please see the documentation for a full list of provided API methods. 164 165 ## A tiny example (template string) 166 167 ```Go 168 // Compile the template first (i. e. creating the AST) 169 tpl, err := pongo2.FromString("Hello {{ name|capfirst }}!") 170 if err != nil { 171 panic(err) 172 } 173 // Now you can render the template with the given 174 // pongo2.Context how often you want to. 175 out, err := tpl.Execute(pongo2.Context{"name": "florian"}) 176 if err != nil { 177 panic(err) 178 } 179 fmt.Println(out) // Output: Hello Florian! 180 ``` 181 182 ## Example server-usage (template file) 183 184 ```Go 185 package main 186 187 import ( 188 "github.com/flosch/pongo2" 189 "net/http" 190 ) 191 192 // Pre-compiling the templates at application startup using the 193 // little Must()-helper function (Must() will panic if FromFile() 194 // or FromString() will return with an error - that's it). 195 // It's faster to pre-compile it anywhere at startup and only 196 // execute the template later. 197 var tplExample = pongo2.Must(pongo2.FromFile("example.html")) 198 199 func examplePage(w http.ResponseWriter, r *http.Request) { 200 // Execute the template per HTTP request 201 err := tplExample.ExecuteWriter(pongo2.Context{"query": r.FormValue("query")}, w) 202 if err != nil { 203 http.Error(w, err.Error(), http.StatusInternalServerError) 204 } 205 } 206 207 func main() { 208 http.HandleFunc("/", examplePage) 209 http.ListenAndServe(":8080", nil) 210 } 211 ``` 212 213 # Benchmark 214 215 The benchmarks have been run on the my machine (`Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz`) using the command: 216 217 go test -bench . -cpu 1,2,4,8 218 219 All benchmarks are compiling (depends on the benchmark) and executing the `template_tests/complex.tpl` template. 220 221 The results are: 222 223 BenchmarkExecuteComplexWithSandboxActive 50000 60450 ns/op 224 BenchmarkExecuteComplexWithSandboxActive-2 50000 56998 ns/op 225 BenchmarkExecuteComplexWithSandboxActive-4 50000 60343 ns/op 226 BenchmarkExecuteComplexWithSandboxActive-8 50000 64229 ns/op 227 BenchmarkCompileAndExecuteComplexWithSandboxActive 10000 164410 ns/op 228 BenchmarkCompileAndExecuteComplexWithSandboxActive-2 10000 156682 ns/op 229 BenchmarkCompileAndExecuteComplexWithSandboxActive-4 10000 164821 ns/op 230 BenchmarkCompileAndExecuteComplexWithSandboxActive-8 10000 171806 ns/op 231 BenchmarkParallelExecuteComplexWithSandboxActive 50000 60428 ns/op 232 BenchmarkParallelExecuteComplexWithSandboxActive-2 50000 31887 ns/op 233 BenchmarkParallelExecuteComplexWithSandboxActive-4 100000 22810 ns/op 234 BenchmarkParallelExecuteComplexWithSandboxActive-8 100000 18820 ns/op 235 BenchmarkExecuteComplexWithoutSandbox 50000 56942 ns/op 236 BenchmarkExecuteComplexWithoutSandbox-2 50000 56168 ns/op 237 BenchmarkExecuteComplexWithoutSandbox-4 50000 57838 ns/op 238 BenchmarkExecuteComplexWithoutSandbox-8 50000 60539 ns/op 239 BenchmarkCompileAndExecuteComplexWithoutSandbox 10000 162086 ns/op 240 BenchmarkCompileAndExecuteComplexWithoutSandbox-2 10000 159771 ns/op 241 BenchmarkCompileAndExecuteComplexWithoutSandbox-4 10000 163826 ns/op 242 BenchmarkCompileAndExecuteComplexWithoutSandbox-8 10000 169062 ns/op 243 BenchmarkParallelExecuteComplexWithoutSandbox 50000 57152 ns/op 244 BenchmarkParallelExecuteComplexWithoutSandbox-2 50000 30276 ns/op 245 BenchmarkParallelExecuteComplexWithoutSandbox-4 100000 22065 ns/op 246 BenchmarkParallelExecuteComplexWithoutSandbox-8 100000 18034 ns/op 247 248 Benchmarked on October 2nd 2014.