Giter Site home page Giter Site logo

i-love-flamingo / pugtemplate Goto Github PK

View Code? Open in Web Editor NEW
7.0 15.0 1.0 434 KB

A Pug Template engine for Flamingo

License: MIT License

Go 99.03% Makefile 0.01% Perl 0.80% Pug 0.16%
flamingo-module golang hacktoberfest pug-template-engine template-engine

pugtemplate's Introduction

Pug Template

Go Report Card GoDoc Tests

Get Started

In your Flamingo project, run:

mkdir frontend
cd frontend
npm init
npm i flamingo-carotene-core
npm i flamingo-carotene-pug
mkdir -p src/page
echo "h1 hello world" > src/page/index.pug 
npx flamingo-carotene build

Add the index route in config/routes.yml:

- path: /
  name: home
  controller: flamingo.render(tpl="index")

See the folder example for this example.

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 templates.

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, and without the need to rewrite chunks or even learn a new template language.

The static prototype can be used to test/analyze the UI in early project phases, when the backend might not be ready yet.

The way pug.js works is essentially the following:

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

To integrate it in Flamingo, we save the AST (abstract syntax tree) in a JSON representations. Pugtemplate will use a parser to build an in-memory tree of the concrete building blocks. It then will use a renderer to transform these blocks into HTML Go templates as follows:

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

It is possible to view the intermediate result by https://your_flamingo_url/_pugtpl/debug?tpl=home/home

Templating

One feature of pug.js is the possibility to use arbitrary JavaScript in cases where the template syntax does not provide the some functionality. For example, loops can be written as below:

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

In this example the term ['zero', 'one', 'two'] is in JavaScript. Developers will be able to use more advanced code:

- var 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 Go code. While this works for most standard statements and language constructs (default data types such as maps, list, etc), it does not support certain things such as Object Oriented Programming or the JavaScript standard library. Only snippets of JavaScript code can be run.

However, it is possible to recreate such functionalities 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.

Nevertheless, 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 a syntax 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 Data types

- var object = {"key": "value"}
- var array = [1, 2, 3, 4, 5]
- var concat_string = "string" + "another string"
- var add = 1 + 2
- var multiply = 15 * 8

Those types have been reflected in Go in a form structs as Pugjs.Object, Pugjs.Map, Pugjs.Array, Pugjs.String and Pugjs.Number.

Supported prototype functions

Array

The technical documentation of the array struct can be found on GoDoc. As a short summary, the following functions are publicly available:

- var myArray = [1,2,3,4,5]
- myArray.indexOf(3) // returns 2
- myArray.length // return 5
- myArray.join(', ') // joins the values of the array by the given separator: "1, 2, 3, 4, 5"
- myArray.push(6) // returns [1,2,3,4,5,6]
- myArray.pop() // returns 6 and myArray equals [1,2,3,4,5]
- myArray.splice(4) // return [5] and myArray equals [1,2,3,4]
- myArray.slice(2) // returns [1,2]
- myArray.sort() // sorts alphabetically or numerically the array

Note that the splice and slice functions only have a start index.

Objects

Javascript Object have been transcribed as Go Maps. The technical documentation of the objects/Pugjs.Maps struct can be found on GoDoc. As a short summary, the following functions are publicly available:

- var myObject = {"a": 1, "b": 2}
- myObject.keys() // returns an array of keys ["a","b"]
- myObject.assign("c", 3) // assigns a new property by key myObject equals {"a": 1, "b": 2, "c":3}
- myObject.hasMember(a) // True
- myObject.hasMember(z) // False

Strings

The technical documentation of the string struct can be found on GoDoc. As a short summary, the following functions are publicly available:

- var myString = "This is a nice string"
- myString.length // returns 21
- myString.indexOf("h") // returns 1
- myString.charAt(4) // returns "s"
- myString.toUpperCase() // returns "THIS IS A NICE STRING"
- myString.toLowerCase() // returns "this is a nice string"
- myString.replace("is", "was") // returns "this was a nice string" 
- myString.split(" ") // returns ["this","was","a","nice","string"]
- myString.slice(1, 4) // returns "his"

Supported template functions

TODO

Supported Pug

Interpolation

- var a = "this"
p Text #{a} something #{1 + 2}

Conditions

- var user = { description: 'foo bar baz' }
- var authorised = false
if user.description
    p {user.description}
else if authorised
    p Authorised
else
    p Not authorised

Loops

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

Mixins

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

+mymixing("foo")

+mymixin("foo", "bar")

Includes

include /mixin/mymixin

+mymixing("foo")

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 chunk of content from the browser. The partial will still be rendered server side 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 normally 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:

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

If you call the template function 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
    }
}

Loading mechanism

In production mode, all templates are loaded at once on application startup. Incoming requests are blocked until the loading process has finished.

This module registers a route /pugjs/ready on the systemendpoint which gives an HTTP 200 response only if the template loading has finished. This endpoint can for example be used as kubernetes Startup probe.

In Flamingo's debug mode (flamingo.debug.mode: true), all templates are loaded on demand on each render request. This setting should be used when working on templates locally.

pugtemplate's People

Contributors

annabadsi avatar bastianccm avatar carstendietrich avatar d-p-dev avatar danielpoe avatar dependabot[bot] avatar dmnkdmnt avatar github-actions[bot] avatar ivanmaidurov avatar jadhub avatar karstenkoehler avatar mathiasschopmans avatar ompluscator avatar panzerfahrer avatar patrickschaper avatar renovate[bot] avatar tessig avatar tlayh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

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

Forkers

songyue

pugtemplate's Issues

False boolean in attribute overwrites values

We discovered that falsy booleans are interpreted quite weirdly by the compiler. When writing something like the following:

- var classVariable = false
.className(class=classVariable)

One could expect to keep the className class in the rendered HTML afterwards, indeed there are snippets of code that intend to do that (runtime.go line 149 to 155). But in effect this div won't receive any classes.

is:
<div></div>
instead of:
<div class="className"></div>

Because of all the reflections in this place I couldn't really find what was going on.

First of all what is the behaviour should we expect for attributes with values that are either false or null? If the expected behaviour I described above is the correct one, what would be the best way to keep track of the various ways of attaching attributes or to have falsy booleans not be reflected as "no attribute" in HTML?

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/main.yml
  • actions/checkout v4
  • actions/setup-go v5
  • actions/checkout v4
  • actions/setup-go v5
.github/workflows/semanticore.yml
  • actions/checkout v4
  • actions/setup-go v5
gomod
go.mod
  • go 1.21
  • go 1.21.6
  • flamingo.me/dingo v0.2.10
  • flamingo.me/flamingo/v3 v3.8.0
  • github.com/go-sourcemap/sourcemap v2.1.3+incompatible
  • github.com/go-test/deep v1.1.0
  • github.com/pkg/errors v0.9.1
  • github.com/spf13/cobra v1.8.0
  • github.com/stretchr/testify v1.8.4
  • go.uber.org/goleak v1.3.0
  • golang.org/x/net v0.23.0
  • golang.org/x/sync v0.6.0
npm
example/frontend/package.json
  • flamingo-carotene-core ^8.0.0
  • flamingo-carotene-pug ^8.0.0

  • Check this box to trigger a request for Renovate to run again on this repository

dependencies: fix vunlerability

Hello friends,
when running Nancy on pugtemplate it detects a vulnerable dependency.

Approach
I am on pugtemplate master and execute:

go list -json -m all | docker run --rm -i sonatypecommunity/nancy:latest sleuth

Output

Checking for updates...
Already up-to-date.
pkg:golang/golang.org/x/[email protected]
1 known vulnerabilities affecting installed version
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ [CVE-2019-11840]  Use of Insufficiently Random Values                                                                                                                                                                       ┃
┣━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ Description        ┃ An issue was discovered in supplementary Go cryptography libraries, aka                                                                                                                                ┃
┃                    ┃ golang-googlecode-go-crypto, before 2019-03-20. A flaw was found in the                                                                                                                                ┃
┃                    ┃ amd64 implementation of golang.org/x/crypto/salsa20 and                                                                                                                                                ┃
┃                    ┃ golang.org/x/crypto/salsa20/salsa. If more than 256 GiB of keystream is                                                                                                                                ┃
┃                    ┃ generated, or if the counter otherwise grows greater than 32 bits, the                                                                                                                                 ┃
┃                    ┃ amd64 implementation will first generate incorrect output, and then cycle                                                                                                                              ┃
┃                    ┃ back to previously generated keystream. Repeated keystream bytes can lead                                                                                                                              ┃
┃                    ┃ to loss of confidentiality in encryption applications, or to predictability                                                                                                                            ┃
┃                    ┃ in CSPRNG applications.                                                                                                                                                                                ┃
┣━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ OSS Index ID       ┃ 5121f5ff-9831-44a6-af2e-24f7301d1df7                                                                                                                                                                   ┃
┣━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ CVSS Score         ┃ 5.9/10 (Medium)                                                                                                                                                                                        ┃
┣━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ CVSS Vector        ┃ CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N                                                                                                                                                           ┃
┣━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ Link for more info ┃ https://ossindex.sonatype.org/vuln/5121f5ff-9831-44a6-af2e-24f7301d1df7?component-type=golang&component-name=golang.org%2Fx%2Fcrypto&utm_source=nancy-client&utm_medium=integration&utm_content=1.0.15 ┃
┗━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

1 Vulnerable Packages

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Summary                       ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━┫
┃ Audited Dependencies    ┃ 103 ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━┫
┃ Vulnerable Dependencies ┃ 1   ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━┛

Pushing numbers to array fails

It is not possible to push numbers to an array. If we do so:

- var min = 1
- var max = 99
- var i = min
- var array = []
while i < max
 - array.push(i)
 - i++

We get the following error

executing "mixin_cart" at <$n>: wrong type for value; expected pugjs.Object; got int

This is of because Array.Push only takes an object as parameter, and those initialized numbers aren't really of pugjs.Object type at that time.

However if we have something like the following

- var object = {
 min: 1,
 max: 99
}
- var i = object.min
- var array = []
while i < object.max
 - array.push(i)
 - i++

It would work perfectly, because the type of object.min assigned to i, is a valid Object.

Problem of scoping in loops

In an each loop, the scoping of variables is not really handled. If a variable is declared in one iteration of the loop, it's value is kept in the following iterations

In the following example, the variable newVariable will be set to test from the beginning until the end of the loop iteration

- var array = [1,2,3,4]
each value, index in array
  if index === 0
    - var newVariable = 'test'

Is this a known issue?

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.