Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
Latest commit 9d63bc9 Apr 12, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
puganalyse adjust templatecheck Aug 28, 2018
pugjs Add [].sort() May 15, 2019
templatefunctions
.gitlab-ci.yml add ssh key Mar 15, 2019
LICENSE add license and go.mod Apr 2, 2019
Readme.md document pug partials Mar 31, 2019
debug.go update to flamingo v3 Feb 14, 2019
go.mod add license and go.mod Apr 2, 2019
go.sum add license and go.mod Apr 2, 2019
module.go block directory listing Mar 26, 2019

Readme.md

Pug Template

pug.js

Pug is a JavaScript template rendering engine.

Flamingo Pug Template

The Flamingo flamingo.me/pugtemplate package is a flamingo template module to use pug.js templates.

Basically pug.js is by default compiled to JavaScript, and executed as HTML.

This mechanism is used to render static prototypes for the templates, so the usual HTML prototype is just a natural artifact of this templating, instead of an extra workflow step or custom tool.

This allows frontend developers to start templating very early with very few backend support, yet without the need to rewrite everything or even learn a new template language.

Also the static prototype can be used to test/analyze the UI in early project phases, while the backend might not be done yet.

The way pug.js works is essentially this:

template -[tokenizer]-> tokens -[parser]-> AST -[compiler]-> JavaScript -[runtime]-> HTML

To integrate this with Flamingo we save the AST (abstract syntax tree) in a json representation. pug_template will use a parser to build an internal in-memory tree of the concrete building blocks, and then use a render to transform these blocks into actual go template with HTML.

AST -[parser]-> Block tree -[render]-> go template -[go-template-runtime]-> HTML

(You can also view the intermediate result under https://flamingoURL/_pugtpl/debug?tpl=home/home)

One of the features of pug.js is the possibility to use arbitrary JavaScript in case the template syntax does not provide the correct functions. This is used for example in loops like

ul
  each val, index in ['zero', 'one', 'two']
    li= index + ': ' + val

The term ['zero', 'one', 'two'] is actual JavaScript, and a developer is able to use more advanced code like

- prefix = 'foo'
ul
  each val, index in [prefix+'zero', prefix+'one', prefix+'two']
    li= index + ': ' + val

The pug_template module takes this JavaScript and uses the go-based JS engine otto to parse the JavaScript and transpile it into actual go code. While this works for some standard statements and language constructs (default datatypes such as maps, list, etc), this does not support certain things such as OOP or the JS stdlib.

It is, however, possible to recreate such functionality in a third-party module via Flamingo's template functions. For example pug_template itself has a substitute for the JavaScript Math library with the min, max and ceil functions. Please note that these function have to use reflection and it's up to the implementation to properly reflect the functionality and handle different inputs correctly.

After all extensive usage of JavaScript is not advised.

Dynamic JavaScript

The Pug Template engine compiles a subset of JavaScript (ES2015) to Go templates. This allows frontend developers to use known workflows and techniques, instead of learning a complete new template engine.

To make this possible Flamingo rewrites the JavaScript to go, on the fly.

Supported JavaScript

Standard Datatypes

{"key": "value"}

"string" + "another string"

1 + 2

15 * 8

[1, 2, 3, 4, 5]

Support Pug

Interpolation

p Text #{variable} something #{1 + 2}

Mixins

mixin mymixin(arg1, arg2="default)
  p.something(id=arg2)= arg1
  
+mymixing("foo")

+mymixin("foo", "bar")

Loops

each value, index in  ["a", "b", "c"]
  p value #{value} at #{index}

Debugging

Templates can be debugged via /_pugtpl/debug?tpl=pages/product/view

Partials Rendering

The template engine supports rendering of partials. The idea of partials is to support progressive enhancement by being able to request just a part (partial) of the content from the browser. The partial will still be rendered serverside and should be requested by an ajax call from the browser.

Partials are requested by setting the http Header X-Partial

The requested partials are searched in a subfolder "{templatename}.partials"

So if you have a response that will normaly render like this:

return cc.responder.Render("folder/template")

And you request that page with the Header X-Partial: foo,bar

The engine will search for partials in folder/template.partials/foo.pug and folder/template.partials/bar.pug and just render them and return them wrapped in a JSON response like this:

{
    "partials": {
        "foo": "content rendered",
        "bar": "content rendered"
    }
}

If you call setPartialData in this templates, you can add additional data to the json response. For example:

setPartialData("cartamount", 4)

Will result in this response:

{
    "partials": {
        "foo": "content rendered",
        "bar": "content rendered"
    },
    "data" : {
        "key": 4
    }
}
You can’t perform that action at this time.