Skip to content

Joker/jade

Repository files navigation

Jade.go - template engine for Go (golang)

Package jade (github.com/Joker/jade) is a simple and fast template engine implementing Jade/Pug template.
Jade precompiles templates to Go code or generates html/template.
Now Jade-lang is renamed to Pug template engine.

GoDoc Go Report Card

Jade/Pug syntax

example:

//-  :go:func Index(pageTitle string, youAreUsingJade bool)

mixin for(golang)
    #cmd Precompile jade templates to #{golang} code.

doctype html
html(lang="en")
    head
        title= pageTitle
        script(type='text/javascript').
            if(question){
                answer(40 + 2)
            }
    body
        h1 Jade - template engine
            +for('Go')

        #container.col
            if youAreUsingJade
                p You are amazing
            else
                p Get on it!
            p.
                Jade/Pug is a terse and simple
                templating language with
                a #[strong focus] on performance 
                and powerful features.

becomes

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Jade.go</title>
        <script type="text/javascript">
            if(question){
                answer(40 + 2)
            }
        </script>
    </head>
    <body>
        <h1>Jade - template engine
            <div id="cmd">Precompile jade templates to Go code.</div>
        </h1>
        <div id="container" class="col">
            <p>You are amazing</p>
            <p>
                Jade/Pug is a terse and simple
                templating language with
                a <strong>focus</strong> on performance 
                and powerful features.
            </p>
        </div>
    </body>
</html>

Here are additional examples and test cases.

Installation

Install jade compiler

go install github.com/Joker/jade/cmd/jade@latest

or github.com/Joker/jade package

go get -u github.com/Joker/jade

Example usage

jade compiler

jade -writer -pkg=main hello.jade

jade command1 precompiles hello.jade to hello.jade.go

hello.jade

:go:func(arg) word string
doctype 5
html
    body
        p Hello #{word}!

hello.jade.go

// Code generated by "jade.go"; DO NOT EDIT.
package main

import "io"

const (
    hello__0 = `<!DOCTYPE html><html><body><p>Hello `
    hello__1 = `!</p></body></html>`
)
func Jade_hello(word string, wr io.Writer) {
    buffer := &WriterAsBuffer{wr}
    buffer.WriteString(hello__0)
    WriteEscString(word, buffer)
    buffer.WriteString(hello__1)
}

main.go

package main
//go:generate jade -pkg=main -writer hello.jade

import "net/http"

func main() {
    http.HandleFunc("/", func(wr http.ResponseWriter, req *http.Request) {
        Jade_hello("jade", wr)
    })
    http.ListenAndServe(":8080", nil)
}

output at localhost:8080

<!DOCTYPE html><html><body><p>Hello jade!</p></body></html>

github.com/Joker/jade package

generate html/template at runtime (This case is slightly slower and doesn't support2 all features of Jade.go)

package main

import (
    "fmt"
    "html/template"
    "net/http"

    "github.com/Joker/hpp" // Prettify HTML
    "github.com/Joker/jade"
)

func handler(w http.ResponseWriter, r *http.Request) {
    jadeTpl, _ := jade.Parse("jade", []byte("doctype 5\n html: body: p Hello #{.Word} !"))
    goTpl, _ := template.New("html").Parse(jadeTpl)

    fmt.Printf("output:%s\n\n", hpp.PrPrint(jadeTpl))
    goTpl.Execute(w, struct{ Word string }{"jade"})
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

console output

<!DOCTYPE html>
<html>
    <body>
        <p>Hello {{.Word}} !</p>
    </body>
</html>

output at localhost:8080

<!DOCTYPE html><html><body><p>Hello jade !</p></body></html>

Performance

The data of chart comes from SlinSo/goTemplateBenchmark. chart

Custom filter :go

This filter is used as helper for command line tool
(to set imports, function name and parameters).
Filter may be placed at any nesting level.
When Jade used as library :go filter is not needed.

Nested filter :func

:go:func
    CustomNameForTemplateFunc(any []int, input string, args map[string]int)

:go:func(name)
    OnlyCustomNameForTemplateFunc

:go:func(args)
    (only string, input float32, args uint)

Nested filter :import

:go:import
    "github.com/Joker/jade"
    github.com/Joker/hpp

note

Footnotes

  1. Usage: ./jade [OPTION]... [FILE]...

    -basedir string
            base directory for templates (default "./")
    -d string
            directory for generated .go files (default "./")
    -fmt
            HTML pretty print output for generated functions
    -inline
            inline HTML in generated functions
    -pkg string
            package name for generated files (default "jade")
    -stdbuf
            use bytes.Buffer  [default bytebufferpool.ByteBuffer]
    -stdlib
            use stdlib functions
    -writer
            use io.Writer for output
    
  2. Runtime html/template generation doesn't support the following features:
    => means it generate the folowing template

    for                =>  "{{/* %s, %s */}}{{ range %s }}"
    for if             =>  "{{ if gt len %s 0 }}{{/* %s, %s */}}{{ range %s }}"
    
    multiline code     =>  "{{/* %s */}}"
    inheritance block  =>  "{{/* block */}}"
    
    case statement     =>  "{{/* switch %s */}}"
    when               =>  "{{/* case %s: */}}"
    default            =>  "{{/* default: */}}"
    

    You can change this behaviour in config.go file.
    Partly this problem can be solved by custom functions.