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  [![GoDoc](https://godoc.org/github.com/flosch/pongo2?status.png)](https://godoc.org/github.com/flosch/pongo2)
     4  [![Build Status](https://travis-ci.org/flosch/pongo2.svg?branch=master)](https://travis-ci.org/flosch/pongo2)
     5  [![Coverage Status](https://coveralls.io/repos/flosch/pongo2/badge.png?branch=master)](https://coveralls.io/r/flosch/pongo2?branch=master)
     6  [![gratipay](http://img.shields.io/badge/gratipay-support%20pongo-brightgreen.svg)](https://gratipay.com/flosch/)
     7  [![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=3654947)](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.