Skip to content

Go: simple plain Go template renderer with layout and partials support

Notifications You must be signed in to change notification settings

Zoktog/wutrender

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wutrender

Simple Go templates rendering (wut = web utils).

API Reference

Usage

wutrender uses Go's html/template package to render templates.

// main.go
package main

import (
  "github.com/8protons/wutrender"
)

func main() {
  // Init default Renderer with default options
  wutrender.Init()

  // Init default Renderer with custom options
  wutrender.Init(wutrender.Options{
    Directory: "app/templates",
    Layout:    "layout",
  })

  // return (*bytes.Buffer, error)
  wutrender.HTML("sessions/new", map[string]interface{}{ "hello": "world" })
}

// ..
// WriteHTML is an easy way to write to ResponseWriter
func IndexHandler(w http.ResponseWriter, r *http.Request) {
  data := map[string]interface{}{}
  data["counter"] = 5

  wutrender.WriteHTML(w, 200, "hello", data)
}
// ..
<!-- templates/hello.html.tmpl -->
<h2>Hello {{.}}!</h2>

Options

wutrender.Renderer can be configurated by several options:

// ...
wutrender.New(wutrender.Options{
  Directory: "templates", // Specify a path to a folder which contains templates
  Layout: "layout", // Specify a layout template
  Extensions: []string{".tmpl"}, // Specify extensions for templates
  Delims: render.Delims{"{{{", "}}}"}, // Override default delimiters
  Funcs: []template.FuncMap{AppHelpers}, // Specify helper function
})
// ...

Loading Templates and Formats

By default the wutrender.Renderer will load templates with *.tmpl extension from the "templates" directory.

It uses filepath/filename.{format}.{extension} scheme to distinguish folders and content formats.

For example, this templates folder:

templates/
  |
  |__ users/
  |      |
  |      |__ new.html.tmpl
  |      |
  |      |__ edit.html.tmpl
  |      |
  |      |__ update.js.tmpl
  |      |
  |      |__ user.json.tmpl
  |
  |__ layout.html.tmpl

Will provide the following templates:

users/new.html
users/edit.html
users/update.js
users/user.json
layout.html

We can render it as:

// HTML format function - render "users/new.html"
wutrender.HTML("users/new", nil)
wutrender.HTML("users/edit", map[string]interface{}{"answer": 42})

// write HTML to ResponseWriter
wutrender.WriteHTML(w, 200, "users/new", nil)

// JS format function - render "users/update.js"
wutrender.JS("users/update", nil)

// or with standalone Render function
wutrender.RenderFormat("js", "users/update", nil)
wutrender.RenderFormat("html", "users/new", nil)

It may be useful when you want to render a JavaScript file back to client:

// templates/users/update.js.tmpl
jGrowl("User sucessfuly updated");

$('.user-form').hide();

or even if you want to render a complex JSON file:

{{/* templates/users/user.json.tmpl */}}
{
  "id": "{{ .User.Id }}",
  "profile": {
    "name": "{{ .User.Name }}"
  }
}

Development and Production

wutrender.Renderer uses wutenv package to detect current application environment (by GO_ENV or GO_FLAVOR):

  // Recompile template
  if wutenv.IsDev {
    tc = r.compile()
  } else {
    tc, _ = r.t.Clone()
  }

In development mode, it will recompile all templates each time, so no need to restart server if something's changed.

In production mode, it will just use Clone() function from html/template package.

*TemplateCopy

Everytime we want to render a template - we create a copy.

wutrender.Renderer has the Copy() method which return *TemplateCopy struct (it provides all rendering functions - HTML, JS, WriteHTML, etc.).

This guarantees cleanness of the source templates and also allows us to use per template functions and, for example, different layouts:

wutrender.Copy().SetFuncs(PerTemplateFuncs).SetLayout("company").HTML("hello", nil)

wutrender.HTML(...) method does this, for example: DefaultRenderer.Copy().HTML(...)

Layouts

wutrender has the yield function for layouts which render current template:

// ...
wutrender.Init(wutrender.Options{
  Layout: "layout",
})
// ...
<!-- templates/layout.html.tmpl -->
<html>
  <head>
    <title>Layout |::| wut!</title>
  </head>
  <body>
    <!-- Render the current template here -->
    {{ yield }}
  </body>
</html>

Partials

partial function takes name argument, transforms it to {filepath}/_{filename}.html and renders this template with the provided binding.

Example: users/user becomes users/_user.html

Binding can be:

  • Empty: {{ partial "users/user" }}
  • Simple object: {{ partial "users/user" . }} (full binding from the parent template) or partial "users/user" .User (one object from the parent template)
  • Key-Value pairs: {{ partial "users/user" "user" .User "isEdit" true }} - first argument is a string key, second is an interface{} value (idea from Gorilla Mux - URL)
<div class="container">
    <!-- Render "users/_user.html" template here without binding -->
    {{ partial "users/user" }}

    <!-- Render "users/_user.html" template here and pass current binding to it -->
    {{ partial "users/user" . }}

    <!-- Render "users/_user.html" template here and pass a map binding: {user: .user, isEdit: true} -->
    {{ partial "users/user" "user" .User "isEdit" true }}
</div>

Loop example:

<div class="container">
    <!-- Example partial rendering with loop -->
    {{ range .channels }}
      {{ partial "channels/channel" . }}
    {{ end }}
</div>

<!-- templates/channels/_channel.html.tmpl  -->
<div class="channel">
  {{ .Name }}
</div>

Authors

About

Go: simple plain Go template renderer with layout and partials support

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages