The powerful template system that Go needs

Overview

Plush Build Status GoDoc

Plush is the templating system that Go both needs and deserves. Powerful, flexible, and extendable, Plush is there to make writing your templates that much easier.

Introduction Video

Installation

$ go get -u github.com/gobuffalo/plush

Usage

Plush allows for the embedding of dynamic code inside of your templates. Take the following example:

<!-- input -->
<p><%= "plush is great" %></p>

<!-- output -->
<p>plush is great</p>

Controlling Output

By using the <%= %> tags we tell Plush to dynamically render the inner content, in this case the string plush is great, into the template between the <p></p> tags.

If we were to change the example to use <% %> tags instead the inner content will be evaluated and executed, but not injected into the template:

<!-- input -->
<p><% "plush is great" %></p>

<!-- output -->
<p></p>

By using the <% %> tags we can create variables (and functions!) inside of templates to use later:

<!-- does not print output -->
<%
let h = {name: "mark"}
let greet = fn(n) {
  return "hi " + n
}
%>
<!-- prints output -->
<h1><%= greet(h["name"]) %></h1>

Full Example:

html := `<html>
<%= if (names && len(names) > 0) { %>
	<ul>
		<%= for (n) in names { %>
			<li><%= capitalize(n) %></li>
		<% } %>
	</ul>
<% } else { %>
	<h1>Sorry, no names. :(</h1>
<% } %>
</html>`

ctx := plush.NewContext()
ctx.Set("names", []string{"john", "paul", "george", "ringo"})

s, err := plush.Render(html, ctx)
if err != nil {
  log.Fatal(err)
}

fmt.Print(s)
// output: <html>
// <ul>
// 		<li>John</li>
// 		<li>Paul</li>
// 		<li>George</li>
// 		<li>Ringo</li>
// 		</ul>
// </html>

Comments

You can add comments like this:

<%# This is a comment %>

If/Else Statements

The basic syntax of if/else if/else statements is as follows:

<%
if (true) {
  # do something
} else if (false) {
  # do something
} else {
  # do something else
}
%>

When using if/else statements to control output, remember to use the <%= %> tag to output the result of the statement:

<%= if (true) { %>
  <!-- some html here -->
<% } else { %>
  <!-- some other html here -->
<% } %>

Operators

Complex if statements can be built in Plush using "common" operators:

  • == - checks equality of two expressions
  • != - checks that the two expressions are not equal
  • ~= - checks a string against a regular expression (foo ~= "^fo")
  • < - checks the left expression is less than the right expression
  • <= - checks the left expression is less than or equal to the right expression
  • > - checks the left expression is greater than the right expression
  • >= - checks the left expression is greater than or equal to the right expression
  • && - requires both the left and right expression to be true
  • || - requires either the left or right expression to be true

Grouped Expressions

<%= if ((1 < 2) && (someFunc() == "hi")) { %>
  <!-- some html here -->
<% } else { %>
  <!-- some other html here -->
<% } %>

Maps

Maps in Plush will get translated to the Go type map[string]interface{} when used. Creating, and using maps in Plush is not too different than in JSON:

<% let h = {key: "value", "a number": 1, bool: true} %>

Would become the following in Go:

map[string]interface{}{
  "key": "value",
  "a number": 1,
  "bool": true,
}

Accessing maps is just like access a JSON object:

<%= h["key"] %>

Using maps as options to functions in Plush is incredibly powerful. See the sections on Functions and Helpers to see more examples.

Arrays

Arrays in Plush will get translated to the Go type []interface{} when used.

<% let a = [1, 2, "three", "four", h] %>
[]interface{}{ 1, 2, "three", "four", h }

For Loops

There are three different types that can be looped over: maps, arrays/slices, and iterators. The format for them all looks the same:

<%= for (key, value) in expression { %>
  <%= key %> <%= value %>
<% } %>

The values inside the () part of the statement are the names you wish to give to the key (or index) and the value of the expression. The expression can be an array, map, or iterator type.

Arrays

Using Index and Value

<%= for (i, x) in someArray { %>
  <%= i %> <%= x %>
<% } %>

Using Just the Value

<%= for (val) in someArray { %>
  <%= val %>
<% } %>

Maps

Using Index and Value

<%= for (k, v) in someMap { %>
  <%= k %> <%= v %>
<% } %>

Using Just the Value

<%= for (v) in someMap { %>
  <%= v %>
<% } %>

Iterators

type ranger struct {
	pos int
	end int
}

func (r *ranger) Next() interface{} {
	if r.pos < r.end {
		r.pos++
		return r.pos
	}
	return nil
}

func betweenHelper(a, b int) Iterator {
	return &ranger{pos: a, end: b - 1}
}
html := `<%= for (v) in between(3,6) { return v } %>`

ctx := plush.NewContext()
ctx.Set("between", betweenHelper)

s, err := plush.Render(html, ctx)
if err != nil {
  log.Fatal(err)
}
fmt.Print(s)
// output: 45

Helpers

For a full list, and documentation of, all the Helpers included in Plush, see github.com/gobuffalo/helpers.

Custom Helpers

html := `<p><%= one() %></p>
<p><%= greet("mark")%></p>
<%= can("update") { %>
<p>i can update</p>
<% } %>
<%= can("destroy") { %>
<p>i can destroy</p>
<% } %>
`

ctx := NewContext()

// one() #=> 1
ctx.Set("one", func() int {
  return 1
})

// greet("mark") #=> "Hi mark"
ctx.Set("greet", func(s string) string {
  return fmt.Sprintf("Hi %s", s)
})

// can("update") #=> returns the block associated with it
// can("adsf") #=> ""
ctx.Set("can", func(s string, help HelperContext) (template.HTML, error) {
  if s == "update" {
    h, err := help.Block()
    return template.HTML(h), err
  }
  return "", nil
})

s, err := Render(html, ctx)
if err != nil {
  log.Fatal(err)
}
fmt.Print(s)
// output: <p>1</p>
// <p>Hi mark</p>
// <p>i can update</p>

Special Thanks

This package absolutely 100% could not have been written without the help of Thorsten Ball's incredible book, Writing an Interpeter in Go.

Not only did the book make understanding the process of writing lexers, parsers, and asts, but it also provided the basis for the syntax of Plush itself.

If you have yet to read Thorsten's book, I can't recommend it enough. Please go and buy it!

Issues
  • Cannot get the **_User_** value.

    Cannot get the **_User_** value.

    type Order struct {
    	ID          uuid.UUID `json:"id" db:"id"`
    	CreatedAt   time.Time `json:"created_at" db:"created_at"`
    	UpdatedAt   time.Time `json:"updated_at" db:"updated_at"`
    	UserID      uuid.UUID `json:"user_id" db:"user_id"`
    	Num         string    `json:"num" db:"num"`
    	Status      string    `json:"status" db:"status"`
    	TotalMoney  float64   `json:"total_money" db:"total_money"`
    	Money       float64   `json:"money" db:"money"`
    	Description string    `json:"description" db:"description"`
    	User        User      `json:"user" db:"-"`
    	Goods       []Good    `json:"goods" db:"-"`
    }
    
    type User struct {
    	ID                   uuid.UUID `json:"id" db:"id"`
    	CreatedAt            time.Time `json:"created_at" db:"created_at"`
    	UpdatedAt            time.Time `json:"updated_at" db:"updated_at"`
    	Mobile               string    `json:"mobile" db:"mobile"`
    	Role                 string    `json:"role" db:"role"`
    	Addr                 string    `json:"addr" db:"addr"`
    	PasswordHash         string    `json:"-" db:"password_hash"`
    	Password             string    `json:"-" db:"-"`
    	PasswordConfirmation string    `json:"-" db:"-"`
    }
    

    index.html:

     <%= for (order) in orders { %>
       <%= order.User.Mobile %>
      <% } %>
    

    Cannot get the User value.

    opened by ghost 15
  • Add markdown file support in partials

    Add markdown file support in partials

    This is a fix for https://github.com/gobuffalo/gobuffalo/issues/404, but not necessarily a good one:

    What is bad?

    In contrast to the js support in partial_helper.go#47, the markdown support activates if the content type includes markdown or if the file ends in .md (JS support requires both to be true). This is inconsistent and might lead to confusion.

    Why did I still do it this way?

    Concluding from my tests, buffalo doesn't set a markdown content type but uses text/html. I could not yet find the place to change this in buffalo. I'm not sure if buffalo can change the content type for markdown files as r.HTML seems to define it on initialization where the file type might not yet be clear: https://gobuffalo.io/en/docs/rendering#automatic-extensions

    Solution

    To be honest, I don't think this really is a big deal. If someone can give me some pointers on how to fix it in buffalo though, I'd be happy to give it a try and make this fix a bit better.

    opened by lukasschlueter 13
  • Fix invalid if condition parameter

    Fix invalid if condition parameter

    Fixes issue 115

    The new pull requests confirm the validity of the If condition parameter during parsing and compiling. It checks for syntax error and if the evaluated If condition is of a type Bool or nil

    During Parsing:

    We check if the expression. Condition implements ast.Comparable. If not, then a syntax error is returned. If the type of expression. Condition is of type ast.InflixExpression then we also check the Left and Right expressions do implement ast.Comparable recursively.

    During Compilation:

    We confirm the evaluated type return of the if condition to be either bool or nil.

    opened by Mido-sys 10
  • Memory leak issue potentially caused by rendering authenticity_token in meta tag

    Memory leak issue potentially caused by rendering authenticity_token in meta tag

    Description

    Memory usage in heap is increasing proportionately to the volume of access caused by the following memory allocations. pprof report shows as follows.

    With 10000 access 
    $ go tool pprof -top  http://127.0.0.1:6060/debug/pprof/heap
          flat  flat%   sum%        cum   cum%
    30285.50kB 92.21% 92.21% 30285.50kB 92.21%  bytes.(*Buffer).String (inline)
    
    With 20000 access 
    $ go tool pprof -top  http://127.0.0.1:6060/debug/pprof/heap
          flat  flat%   sum%        cum   cum%
       57.15MB 85.65% 85.65%    57.15MB 85.65%  bytes.(*Buffer).String (inline)
    

    After many trials, I found that the issue doesn't happen by removing following meta tag in application.plush.html

    <meta name="csrf-token" content="<%= authenticity_token %>" />
    

    Steps to Reproduce the Problem

    1. Create new buffalo project
    $ buffalo new buffalonew
    
    1. Prepare postgres database
    2. Add following code for pprof in main.go
    import (
    	"fmt"
    	"net/http"
    	_ "net/http/pprof"
    
    	"github.com/gobuffalo/envy"
    )
    
    func init() {
    	go func() {
    		if envy.Get("GO_ENV", "development") == "development" {
    			fmt.Println("start pprof on :6060")
    			log.Println(http.ListenAndServe("127.0.0.1:6060", nil))
    		}
    	}()
    }
    
    1. Launch the project
    $ cd buffalonew
    $ buffalo dev
    
    1. Confirm it's running image

    2. Run pprof report

    $ go tool pprof -top  http://127.0.0.1:6060/debug/pprof/heap   
    
    1. Generate dummy access with ab command
    $ ab -n 10000 -c 100 http://127.0.0.1:3000/
    
    1. Run pprof report again and compare with step gobuffalo/buffalo#6
    $ go tool pprof -top  http://127.0.0.1:6060/debug/pprof/heap   
    
    1. After a few hours later, try pprof again. The memory allocation is still there...

    Expected Behavior

    The memory allocation with bytes.(*Buffer).String will be cleaned up in heap after decent durations

    Actual Behavior

    The memory allocation with bytes.(*Buffer).String is not cleaned up until killing the buffalo process

    Info

    • This leak seems to be caused by line 62 in plush/compiler It can be traced by pprof graphical report. https://github.com/gobuffalo/plush/blob/master/compiler.go

    Environment

    • macOS Big Sur Version 11.0.1
    • go version go1.15.5 darwin/amd64
    • Buffalo version is: v0.16.17

    Question

    Our real application seems working properly with removing authenticity_token in header. Forms are working with the token generated in input tag. Do you think if there are any issues with removing the token in header meta?

    Please feel free to contact me for additional info. Thanks!

    opened by segakazzz 8
  • Support `else if`

    Support `else if`

    To learn more about Go I thought it would be cool to implement else if support.

    What do you think about this approach?

    Codeclimate is failing, but I can fix that later if I know I'm on the right track.

    opened by ruudk 8
  • catch out of bounds slice/array index access

    catch out of bounds slice/array index access

    An error will return to the user if they try to access an index that doesn't exist.

    Example: array index out of bounds, got index 5, while array size is 5

    opened by Mido-sys 7
  • Rendering with backslash in template before <%=var%> fails

    Rendering with backslash in template before <%=var%> fails

    Following unit test

    func Test_Issue_With_Backslash(t *testing.T) {
    	r := require.New(t)
    	input := `c:\\temp\\<%=subfolder%>`
    	s, err := Render(input, NewContextWith(map[string]interface{}{
    		"subfolder": "test",
    	}))
    	r.NoError(err)
    	r.Equal(`c:\\temp\\test`, s)
    }
    

    fails with:

    Not equal: 
    	            	expected: "c:\\\\temp\\\\test"
    	            	received: "c:\\\\temp\\<%!=(MISSING)subfolder%!>(MISSING)"
    

    (While the following unit test runs fine:

    func Test_With_Slash(t *testing.T) {
    	r := require.New(t)
    	input := `c:/temp/<%=subfolder%>`
    	s, err := Render(input, NewContextWith(map[string]interface{}{
    		"subfolder": "test",
    	}))
    	r.NoError(err)
    	r.Equal(`c:/temp/test`, s)
    

    )

    opened by pvelder 6
  • return doesn't exit the block

    return doesn't exit the block

    If we use return somewhere (like in a conditional) execution does not exit the block as expected. Instead, it continues and future return statements seem to overwrite the previous returns.

    For a real failing test example, see https://github.com/gobuffalo/plush/pull/52

    opened by matryer 5
  • failure to get struct field when having map[string]struct in context

    failure to get struct field when having map[string]struct in context

    This unit test works fine:

    type address struct {
    	Street string
    }
    
    func Test_Render_Struct_Field(t *testing.T) {
    	r := require.New(t)
    
    	input := `<p><%= a.Street %></p>`
    	s, err := Render(input, NewContextWith(map[string]interface{}{
    		"a": address{Street: "avenue des nations-unies"},
    	}))
    	r.NoError(err)
    	r.Equal(`<p>avenue des nations-unies</p>`, s)
    }
    

    But when extending it to a map[string]address :

    func Test_Render_Map_Struct_Field(t *testing.T) {
    	r := require.New(t)
    
    	input := `<p><%= a["myaddress"].Street %></p>`
    	s, err := Render(input, NewContextWith(map[string]interface{}{
    		"a": map[string]address{
    			"myaddress": address{Street: "avenue des nations-unies"},
    		},
    	}))
    	r.NoError(err)
    	r.Equal(`<p>avenue des nations-unies</p>`, s)
    }
    

    It shows following error:

    Received unexpected error:
    	
    line 1: no prefix parse function for DOT found
    github.com/gobuffalo/plush.(*Template).Parse
        /Users/pdv/dev/src/github.com/gobuffalo/plush/template.go:41
    
    opened by pvelder 5
  • Better Helper Errors

    Better Helper Errors

    If you pass a non-existent param into a Helper, you will get:

    <nil> (<nil>) is an invalid value - evalCallExpression

    This issue is to track enhancing this behavior to output more descriptive details around where the error is occuring.

    opened by gose 5
  • plush DefaultTimeFormat not working in plush/v4

    plush DefaultTimeFormat not working in plush/v4

    Hi,

    In the earlier versions of plush i have been using the following to set the default formatting for dates in my web applications.

    plush.DefaultTimeFormat = "02 Jan 2006"
    

    But in the resent release github.com/gobuffalo/plush/v4 this is no longer working. I am using plush from buffalo (version v0.16.21).

    I have tried setting the DefaultTimeFormat in the func App() *buffalo.App function and in a buffalo.MiddlewareFunc. Non of these seems to work as expected.

    Has this feature been deprecated or am I missing something?

    opened by mogensen 4
  • Can't evaluated if conditions properly with an undefined variable

    Can't evaluated if conditions properly with an undefined variable

    Plush evaluates undefined variables in if conditions without throwing an error; however, it becomes an issue with this example.

    	r := require.New(t)
    	type page struct {
    		PageTitle string
    	}
    	g := &page{"cafe"}
    	ctx := NewContext()
    	ctx.Set("pages", g)
    	ctx.Set("path", "home")
    
    	input := `<%= if ( path != "pagePath" || (page && page.PageTitle != "cafe") ) { %>hi<%} %>`
    
    	s, err := Render(input, ctx)
    	r.NoError(err)
    	r.Equal("hi", s)
    
    

    Currently, this should return "hi" as one of the conditions path != "pagePath" is true; however, it returns an empty string because the if condition values on the right of the or return an error, so it bubbles back up and results in evaluating the condition as false.

    This behaviour is inconsistent because this condition evaluates as true <%= if ( path != "pagePath" || !page) { %>hi<%} %>

    opened by Mido-sys 1
  • Chaining function result ends in error

    Chaining function result ends in error

    Similar to the arrays issue when trying to call a member of the result of a function call plush errors.

    Code:

    ...
    <p class="mr-2">
        Employees will be reminded on 
        <date class="font-semibold">
            <%= period.EmployeeReviewReminderDate().Format("Jan 2, 2006") %>
        </date>.
    </p>
    ...
    

    Error:

    no prefix parse function for DOT found
    

    It would be good to support this.

    cc @Mido-sys

    opened by paganotoni 7
  • Custom Block Helpers not working

    Custom Block Helpers not working

    Custom block helpers are not working for me. I am following the documentation found here: https://gobuffalo.io/en/docs/custom-helpers/#block-helpers

    If I try the exact block helper example shown in the document I get the following compile error:

    actions/render.go:39:27: cannot use strings.ToUpper(s) (type string) as type "html/template".HTML in return argument
    

    the original helper code

    func upblock(help plush.HelperContext) (template.HTML, error) {
      s, err := help.Block()
      if err != nil {
        return "", err
      }
      return strings.ToUpper(s), nil
    }
    

    That is obviously caused by a bug in the example code where it is expecting a template.HTML response, but the example code is only returning a plain string. So I changed the upblock function to return a string instead, but now I get the following error:

    reflect: Call using plush.HelperContext as type plush.HelperContext
    

    Any idea what is going wrong? I have also tried the reverse of leaving the return value as template.HTML and converting the output to use a buffalo tag, but that still has the same error.

    My code looks like this:

    render.go

    func init() {
    	r = render.New(render.Options{
    		// HTML layout to be used for all HTML requests:
    		HTMLLayout: "application.plush.html",
    
    		// Box containing all of the templates:
    		TemplatesBox: packr.New("app:templates", "../templates"),
    		AssetsBox:    assetsBox,
    
    		// Add template helpers here:
    		Helpers: render.Helpers{
    			// for non-bootstrap form helpers uncomment the lines
    			// below and import "github.com/gobuffalo/helpers/forms"
    			// forms.FormKey:     forms.Form,
    			// forms.FormForKey:  forms.FormFor,
    			"upblock": func(help plush.HelperContext) (string, error) {
    				s, err := help.Block()
    				if err != nil {
    					return "", err
    				}
    				return strings.ToUpper(s), nil
    			},
    		},
    	})
    }
    

    index.plush.html

    <%= upblock() { %>
      hello world
    <% } %>
    

    go.mod

    module myapp
    
    go 1.13
    
    require (
    	github.com/aws/aws-sdk-go v1.30.13
    	github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 // indirect
    	github.com/benbjohnson/clock v1.0.1 // indirect
    	github.com/casbin/casbin/v2 v2.2.2
    	github.com/gobuffalo/buffalo v0.16.8
    	github.com/gobuffalo/buffalo-pop v1.23.1
    	github.com/gobuffalo/envy v1.9.0
    	github.com/gobuffalo/events v1.4.1
    	github.com/gobuffalo/mw-csrf v1.0.0
    	github.com/gobuffalo/mw-forcessl v0.0.0-20200131175327-94b2bd771862
    	github.com/gobuffalo/mw-i18n v1.1.0
    	github.com/gobuffalo/mw-paramlogger v1.0.0
    	github.com/gobuffalo/nulls v0.4.0
    	github.com/gobuffalo/packr/v2 v2.8.0
    	github.com/gobuffalo/plush v3.8.3+incompatible
    	github.com/gobuffalo/pop v4.13.1+incompatible
    	github.com/gobuffalo/suite v2.8.2+incompatible
    	github.com/gobuffalo/tags v2.1.7+incompatible
    	github.com/gobuffalo/validate v2.0.4+incompatible
    	github.com/gobuffalo/x v0.0.0-20190224155809-6bb134105960
    	github.com/gofrs/uuid v3.2.0+incompatible
    	github.com/guregu/dynamo v1.7.0
    	github.com/markbates/goth v1.64.0
    	github.com/pkg/errors v0.9.1
    	github.com/unrolled/secure v1.0.7
    	gopkg.in/auth0.v4 v4.3.6
    )
    
    

    go version

    ✗ go version
    go version go1.13.6 darwin/amd64
    
    opened by r3ap3r2004 3
  • Double-quoted string with space is not correctly handled in template

    Double-quoted string with space is not correctly handled in template

    I want to populate an input inside a form, with data coming from the handler, and not from the user. But the problem is that when I declare the html property as an string, and bind it to the variable inside the html, everything goes wrong, and the output gives only a string with some extra double quotes at the beginning, and the rest of the output is broken.

    I tried to escape the " in the string, but this doesnt work.

    My theory is that this comes from the parser from Plush, but this is only a personal theory.

    In example.go

    func (context buffalo.Context) error {
         val := `value="Hello World"`
    
         context.Set("inputvalue", val)
    
         return context.Render(200, MyOwnContext(c).REngine.HTML("form.html"))
    }
    

    In form.html

    <form action="" method="post" novalidate>
            <label><b>My value : </b></label>
            <input class="form-control" type="text" <%= inputvalue %>>
    </form>
    

    The Final output inside the input:

    "Hello
    

    Does someone have the same problem when testing the same code.?

    Thank you for all your answers!

    go.sum

    github.com/gobuffalo/plush v3.8.3+incompatible h1:kzvUTnFPhwyfPEsx7U7LI05/IIslZVGnAlMA1heWub8=
    github.com/gobuffalo/plush v3.8.3+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
    

    go.mod

    github.com/gobuffalo/buffalo v0.15.4
    
    opened by suppadeliux 0
  • Result of SECOND call to partial from r.JavaScript(...) will be escaped content!?

    Result of SECOND call to partial from r.JavaScript(...) will be escaped content!?

    As what described here Naming partial example, We able to use partial as below(One leve partial call): t1.html that use partial _t1.html:

    <h1>Create New User</h1>
    
    <%= partial("t1.html") %>
    

    _t1.html:

    <form action="/users">
    <!-- form stuff here  -->
    <form>
    

    That will get us:

    <h1>Create New User</h1>
    
    <form action="/users">
    <!-- form stuff here  -->
    <form>
    

    That's good, but what I`m try to do: t1.js

    $("#app-content").replaceWith('<%= partial("t1.html") %>');
    

    _t1.html:

    <main class="app-content" id="app-content">
      <h1>Create New User</h1>
      <%= partial("person/_t1.form.html") %>
    </main
    

    _t1.form.html

    <div> FORM? </div>
    

    And in action (GO)(templateing and rendering with plush)

    c.Render(200, r.JavaScript("t1.js")
    

    get me somthing like this:

    <main class="app-content" id="app-content">
      <h1>Create New User</h1>
      \x3Cdiv\x3E FORM? \x3C/div\x3E\u000A
    </main>
    

    AND what expected:

    <main class="app-content" id="app-content">
      <h1>Create New User</h1>
    <div> FORM? </div>
    </main>
    

    Did I missed something, or can be it done?

    opened by MaMrEzO 1
Releases(v4.1.12)
Owner
Buffalo - The Go Web Eco-System
Buffalo - The Go Web Eco-System
Simple system for writing HTML/XML as Go code. Better-performing replacement for html/template and text/template

Simple system for writing HTML as Go code. Use normal Go conditionals, loops and functions. Benefit from typing and code analysis. Better performance than templating. Tiny and dependency-free.

Nelo Mitranim 4 Apr 13, 2022
A handy, fast and powerful go template engine.

Hero Hero is a handy, fast and powerful go template engine, which pre-compiles the html templates to go code. It has been used in production environme

Lime 1.5k Jul 4, 2022
The world’s most powerful template engine and Go embeddable interpreter.

The world’s most powerful template engine and Go embeddable interpreter

Open2b 335 Jun 26, 2022
Wrapper package for Go's template/html to allow for easy file-based template inheritance.

Extemplate Extemplate is a small wrapper package around html/template to allow for easy file-based template inheritance. File: templates/parent.tmpl <

Danny van Kooten 50 Jun 23, 2022
Goview is a lightweight, minimalist and idiomatic template library based on golang html/template for building Go web application.

goview Goview is a lightweight, minimalist and idiomatic template library based on golang html/template for building Go web application. Contents Inst

foolin 284 Jun 21, 2022
A template to build dynamic web apps quickly using Go, html/template and javascript

gomodest-template A modest template to build dynamic web apps in Go, HTML and sprinkles and spots of javascript. Why ? Build dynamic websites using th

Adnaan Badr 80 Jun 27, 2022
Made from template temporalio/money-transfer-project-template-go

Temporal Go Project Template This is a simple project for demonstrating Temporal with the Go SDK. The full 20 minute guide is here: https://docs.tempo

MarkGorewicz 0 Jan 6, 2022
Go-project-template - Template for a golang project

This is a template repository for golang project Usage Go to github: https://git

KyberNetwork 2 Jan 18, 2022
Go-api-template - A rough template to give you a starting point for your API

Golang API Template This is only a rough template to give you a starting point f

Only Tunes Radio 3 Jan 14, 2022
Api-go-template - A simple Go API template that uses a controller-service based model to build its routes

api-go-template This is a simple Go API template that uses a controller-service

Pedro Espíndula 1 Feb 18, 2022
⚗ The most advanced CLI template on earth! Featuring automatic releases, website generation and a custom CI-System out of the box.

cli-template ✨ ⚗ A template for beautiful, modern, cross-platform compatible CLI tools written with Go! Getting Started | Wiki This template features

null 33 Jun 21, 2022
HTML template engine for Go

Ace - HTML template engine for Go Overview Ace is an HTML template engine for Go. This is inspired by Slim and Jade. This is a refinement of Gold. Exa

Keiji Yoshida 817 May 31, 2022
Package damsel provides html outlining via css-selectors and common template functionality.

Damsel Markup language featuring html outlining via css-selectors, extensible via pkg html/template and others. Library This package expects to exist

Daniel Skinner 25 Jan 24, 2022
Simple and fast template engine for Go

fasttemplate Simple and fast template engine for Go. Fasttemplate performs only a single task - it substitutes template placeholders with user-defined

Aliaksandr Valialkin 609 Jun 29, 2022
Jet template engine

Jet Template Engine for Go Jet is a template engine developed to be easy to use, powerful, dynamic, yet secure and very fast. simple and familiar synt

null 937 Jun 24, 2022
A complete Liquid template engine in Go

Liquid Template Parser liquid is a pure Go implementation of Shopify Liquid templates. It was developed for use in the Gojekyll port of the Jekyll sta

Oliver Steele 160 Jun 21, 2022
The mustache template language in Go

Overview mustache.go is an implementation of the mustache template language in Go. It is better suited for website templates than Go's native pkg/temp

Michael Hoisie 1k Jun 30, 2022
Useful template functions for Go templates.

Sprig: Template functions for Go templates The Go language comes with a built-in template language, but not very many template functions. Sprig is a l

null 3k Jul 4, 2022
comparing the performance of different template engines

goTemplateBenchmark comparing the performance of different template engines full featured template engines Ace Amber Go Handlebars removed - Kasia Mus

null 206 Jun 29, 2022