temple

package
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2017 License: MIT Imports: 15 Imported by: 4

README

Humble/Temple

GoDoc

Version 0.1.3

A library and a command line tool for sanely managing go templates, with the ability to share them between client and server. The library and code generated by the cli are both compatible with gopherjs, so you can compile to javascript and run in the browser. Temple works great as a stand-alone package or in combination with other packages in the Humble Framework.

This README is specific to the library, which offers helper functions and methods for managing templates and rendering them in the DOM. The README for the command line tool can be found at github.com/go-humble/temple.

What Does the Library Do?

The temple library can be used on its own or in conjunction with code generated by the command line tool. It offers some utility functions for organizing templates into distinct categories: regular templates, partials, and layouts. It also lets you load templates from files or load inline templates from the DOM, and provides helper methods for rendering to the DOM.

Temple uses the builtin html/template package. If you are not already familiar with go's builtin templates, it is highly recommended that you read the documentation for them before continuing.

Browser Support

Temple is regularly tested with IE9+ and the latest versions of Chrome, Safari, and Firefox.

Javascript code generated with gopherjs uses typed arrays, so in order to work with IE9, you will need a polyfill for typed arrays.

Installation

Install the temple library with the following.

go get github.com/go-humble/temple/temple`

You may also need to install gopherjs. The latest version is recommended. Install gopherjs with:

go get -u github.com/gopherjs/gopherjs

Quickstart Guide

Loading Templates

All templates, partials, and layouts must belong to a group. To create a new group, use the NewGroup function:

g := NewGroup()
From a String

To add template to the group, you can use the AddTemplate method. It takes two arguments, the name of the template and the source.

if err := g.AddTemplate("home", "<h2>Home</h2>"); err != nil {
	// Handle err
}
From a File

To add a template file, you can use the AddTemplateFile method, which takes the name of the template and the path to the file as an argument.

if err := g.AddTemplateFile("home", "templates/home.tmpl"); err != nil {
	// Handle err
}
From a Directory

You can also add multiple files in a directory at once with the AddTemplateFiles method. When you use this method, the templates created from the files will automatically get a name based on the filename and location relative to the given directory. So for example, if you had a template file located at templates/people/show.tmpl and passed templates as the dir argument, the name assigned to the template would be "people/show".

if err := g.AddTemplateFiles("templates"); err != nil {
	// Handle err
}
From the DOM

Finally, if you compile to javascript with gopherjs, you can load inline templates from the DOM with the AddInlineTemplate method.

if err := g.AddInlineTemplate(document.QuerySelector("script[type='text/template']#home")); err != nil {
	// Handle err
}

The method expects a dom.Element from the gopherjs dom bindings as an argument. Typically this would be a script tag that looks something like:

<script type="text/template" id="home">
	<h2>Home</h2>
</script>

The AddInlineTemplate method will use the id property of the element as the template name, and the innerHTML of the given element as the template source.

You can also load multiple inline templates (as well as partials and layouts) at once with the AddAllInline method, which scans the DOM for script tags with a type attribute of "text/template".

if err := g.AddAllInline(); err != nil {
	// Handle err
}

It uses the id property as the template name, and the special data-kind attribute to distinguish between regular templates, partials, and layouts.

Getting Templates

Once a template has been added to a group, you can get it with the GetTemplate method:

homeTmpl, err := g.GetTemplate("home")
if err != nil {
	// Handle error
}

This returns a pointer to a temple.Template, which is merely a wrapper around the template.Template type from the builtin html/template package. temple.Template has all the same methods as a builtin template, and also introduces an ExecuteEl method for rendering the template to the DOM.

In some cases, you just want to fail fast if a template is not found. You can use the MustGetTemplate method, which will panic instead of returning an error. This is analogous to the Temlate.Must method in the text/template and html/template packages in the standard library, and is useful for variable declarations.

var (
	homeTmpl = g.MustGetTemplate("home")
	indexTmpl = g.MustGetTemplate("index")
	todoTmpl = g.MustGetTemplate("todo")
)
Rendering Templates
To an io.Writer

To render a template to an io.Writer, you can just use the Execute method. Since http.ResponseWriter implements io.Writer it is common to render templates this way on the server:

func HomeHandler(res http.ResponseWriter, req *http.Request) {
	homeTmpl, err := g.GetTemplate("home")
	if err != nil {
		// Handle error
	}
	if err := homeTmpl.Execute(res, nil); err != nil {
		// Handle error
	}
}

The second argument to Execute is the data that will be passed into the template.

To an Element in the DOM

You can also render a template to an element in the DOM with the ExecuteEl method. This is the most common way to render templates for code which has been compiled to javascript with gopherjs and is running in the browser.

homeTmpl, err := g.GetTemplate("home")
if err != nil {
	// Handle error
}
if err := homeTmpl.ExecuteEl(document.QuerySelector("body"), nil); err != nil {
	// Handle err
}
Partials and Layouts

Temple uses two optional groups called "partials" and "layouts" to help organize templates. To add partials or layouts, use the same methods for adding templates, but replace the word Template with Partial or Layout (e.g. AddLayout, AddInlinePartials, AddLayoutFile).

Before continuing, it is recommended that you read the documentation for the text/template and html/template packages. In addition, this article about template inheritence in go will help explain some of the concepts that temple uses.

Partials

Partials are templates which typically represent only part of a full page. For example, you might have a partial for rendering a single model or a partial for the head section of your html. Partials are associated with (i.e., added to the parse tree of) all other partials, in addition to layouts and regular templates. That means you can render a partial inside of a regular template or layout with the template action. PartialsPrefix is added to the template name of all partials, which by default is simply "partials/".

So for example, you could have partials located in the my-partials directory and add them to a group with g.AddPartialFiles("my-partials"). Let's say you have the following partial file located at my-partials/head.tmpl:

<head>
	<title>Example Humble Application</title>
	<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
</head>

Let's also say that you have regular template files located in the my-templates directory, which you have added to the same group with g.AddTemplateFiles("my-templates"). And the following regular template located at my-templates/index.tmpl:

<!doctype html>
<html>
	{{ template "partials/head" }}
	<body>
	</body>
</html>

Then, if you rendered the template with the following code:

indexTmpl, err := g.GetTemplate("index")
if err != nil {
	// Handle error
}
if err := indexTmpl.Execute(os.Stdout, nil); err != nil {
	// Handle err
}

You would see the following output:

<!doctype html>
<html>
	<head>
		<title>Example Humble Application</title>
		<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
	</head>
	<body>
	</body>
</html>

Check out the partials in go-humble/examples/people for a more in-depth example.

Layouts

Layouts are templates which define the structure for a page and require another template to fill in the details. Typically, layouts will use one or more template actions to render partials or regular templates inside of some structure. Layouts are associated with (i.e., added to the parse tree of) all regular templates and have access to partials. That means you can render layouts inside of a regular template, typically after declaring some sub-template that the layout expects to be defined. LayoutsPrefix is added to the template name of all layouts, which by default is simply "layouts/".

So for example, you could have layouts located in the my-layouts directory, and add them to a group with g.AddLayoutFiles("my-layouts"). Let's say you have the following layout file located at my-layouts/app.tmpl:

<!doctype html>
<html>
	<head>
		<title>Example Humble Application</title>
	</head>
	<body>
		{{ template "content" . }}
	</body>
</html>

Let's also say that you have regular template files located in the my-templates directory, which you have added to the same group with g.AddTemplateFiles("my-templates"). And the following regular template located at my-templates/hello.tmpl:

{{ define "content" }}
	Hello, {{ . }}!
{{ end }}
{{ template "layouts/app" . }}

Notice that we used the . in both the {{ template "content" . }} and the {{ template "layouts/app" . }} expressions to pass in the template data from the regular template to the layout. If you rendered the template with the following code:

helloTmpl, err := g.GetTemplate("hello")
if err != nil {
	// Handle error
}
if err := helloTmpl.Execute(os.Stdout, "World"); err != nil {
	// Handle err
}

You would see output that looked like this:

<!doctype html>
<html>
	<head>
		<title>Example Humble Application</title>
	</head>
	<body>
		Hello, World!
	</body>
</html>

Check out the layouts in go-humble/examples/people for a more in-depth example.

Testing

Temple uses regular go testing, so you can run the all the tests with go test ..

Contributing

See CONTRIBUTING.md

License

Temple is licensed under the MIT License. See the LICENSE file for more information.

Documentation

Overview

Package temple is a library for managing go templates which supports sharing templates between a client and server. It is the library that powers the temple command line tool. Temple provides lets you load templates from files or load inline templates from the DOM. It also optionally organizes templates into regular templates, partials, and layouts, associating each template with other templates depending on which category it belongs to. Temple is compatible with gopherjs and can be compiled to javascript and run in a browser.

Version 0.1.3

Index

Constants

This section is empty.

Variables

View Source
var (
	// PartialPrefix is added to the name of all partials.
	PartialPrefix = "partials/"
	// LayoutPrefix is added to the name of all layouts.
	LayoutPrefix = "layouts/"
)

Functions

func Build

func Build(src, dest, partials, layouts, packageName string) error

Build is the function called when you run the build sub-command in the command line tool. It compiles all the templates in the src directory and generates go code in the dest file. If partials and/or layouts are provided, it will add them to the generated file with calls to AddPartial and AddLayout. If packageName is an empty string, the package name will be the directory of the dest file.

func ExecuteEl

func ExecuteEl(e Executor, el dom.Element, data interface{}) error

ExecuteEl executes an Executor with the given data and then writes the result to the innerHTML of el. It only works if you have compiled this code to javascript with gopherjs and it is running in a browser.

Types

type Executor

type Executor interface {
	Execute(wr io.Writer, data interface{}) error
}

Executor represents some type of template that is capable of executing (i.e. rendering) to an io.Writer with some data. It is satisfied by Template, Partial, and Layout as well as the builtin template.Template.

type Group

type Group struct {

	// Funcs is a map of function names to functions. All functions in the
	// FuncMap are accessible by all templates, partials, and layouts for
	// this Group.
	Funcs template.FuncMap
	// contains filtered or unexported fields
}

A Group represents a set of associated templates, partials, and layouts. Each Group also gets its own template.FuncMap called Funcs.

func NewGroup

func NewGroup() *Group

NewGroup creates, initializes, and returns a new Group

func (*Group) AddAllFiles

func (g *Group) AddAllFiles(templatesDir, partialsDir, layoutsDir string) error

AddAllFiles adds the .tmpl files located in templatesDir, partialsDir, and layoutsDir to the group as regular templates, partials, and layouts, respectively. It also adds the needed associations. The name assigned to each template, partial, or layout is based on the filename and the path relative to dir, just as it is in AddTemplateFiles, AddPartialFiles, and AddLayoutFiles, respectively.

func (*Group) AddAllInline

func (g *Group) AddAllInline() error

AddAllInline scans the DOM for inline templates which must be script tags with the type "text/template". The id property will be used for the name of each template, and the special property "data-kind" can be used to distinguish between regular templates, partials, and layouts. So, to declare an inline partial for use with the AddAllInline method, use an opening script tag that looks like:

<script type="text/template" id="todo" data-kind="partial">

func (*Group) AddFunc

func (g *Group) AddFunc(name string, f interface{})

AddFunc adds f to the FuncMap for the group under the given name. You must call AddFunc before adding any templates, partials, or layouts. Once added, all templates can call the function directly. See http://golang.org/pkg/text/template/ for more information about the FuncMap type and how to call functions from inside templates.

func (*Group) AddInlineLayout

func (g *Group) AddInlineLayout(el dom.Element) error

AddInlineLayout adds the inline template el to the group as a layout. It uses the id property as the template name and the innerHTML as the template source. LayoutsPrefix will be added to the name, which by default is "layouts/". Typically inline templates will be in script tags that look like:

<script type="text/template" id="app">

which would correspond to a template with the name "layouts/app".

func (*Group) AddInlinePartial

func (g *Group) AddInlinePartial(el dom.Element) error

AddInlinePartial adds the inline template el to the group as a partial. It uses the id property as the template name and the innerHTML as the template source. PartialsPrefix will be added to the name, which by default is "partials/". Typically inline templates will be in script tags that look like:

<script type="text/template" id="todo">

which would correspond to a template with the name "partials/todo".

func (*Group) AddInlineTemplate

func (g *Group) AddInlineTemplate(el dom.Element) error

AddInlineTemplate adds the inline template el to the group as a regular template. It uses the id property as the template name and the innerHTML as the template source. Typically inline templates will be in script tags that look like:

<script type="text/template" id="home">

func (*Group) AddLayout

func (g *Group) AddLayout(name, src string) error

AddLayout adds a layout to the group with the given name and source.

func (*Group) AddLayoutFile

func (g *Group) AddLayoutFile(name, filename string) error

AddLayoutFile reads the contents of filename and adds a layout to the group using the given name and the contents of the file as the source.

func (*Group) AddLayoutFiles

func (g *Group) AddLayoutFiles(dir string) error

AddLayoutFiles recursively adds all the .tmpl files in dir and its subdirectories to the group. The name assigned to each layout is based on the filename and the path relative to dir. LayoutsPrefix is prepended to the name, which by default is "layouts/". So if dir is `my-layouts`, the file located at `my-layouts/app.tmpl` will be given the name "layouts/app".

func (*Group) AddPartial

func (g *Group) AddPartial(name, src string) error

AddPartial adds a partial to the group with the given name and source.

func (*Group) AddPartialFile

func (g *Group) AddPartialFile(name, filename string) error

AddPartialFile reads the contents of filename and adds a partial to the group using the given name and the contents of the file as the source.

func (*Group) AddPartialFiles

func (g *Group) AddPartialFiles(dir string) error

AddPartialFiles recursively adds all the .tmpl files in dir and its subdirectories to the group. The name assigned to each partial is based on the filename and the path relative to dir. PartialsPrefix is prepended to the name, which by default is "partials/". So if dir is `my-partials`, the file located at `my-partials/head.tmpl` will be given the name "partials/head".

func (*Group) AddTemplate

func (g *Group) AddTemplate(name, src string) error

AddTemplate adds a regular template to the group with the given name and source.

func (*Group) AddTemplateFile

func (g *Group) AddTemplateFile(name, filename string) error

AddTemplateFile reads the contents of filename and adds a template to the group using the given name and the contents of the file as the source.

func (*Group) AddTemplateFiles

func (g *Group) AddTemplateFiles(dir string) error

AddTemplateFiles recursively adds all the .tmpl files in dir and its subdirectories to the group. The name assigned to each template is based on the filename and the path relative to dir. So if dir is `templates`, the file located at `templates/people/show.tmpl` will be given the name "people/show".

func (Group) GetLayout added in v0.1.0

func (g Group) GetLayout(name string) (*Layout, error)

GetLayout returns the layout identified by name, or an error if the layout could not be found.

func (Group) GetPartial added in v0.1.0

func (g Group) GetPartial(name string) (*Partial, error)

GetPartial returns the partial identified by name, or an error if the partial could not be found.

func (Group) GetTemplate added in v0.1.0

func (g Group) GetTemplate(name string) (*Template, error)

GetTemplate returns the template identified by name, or an error if the template could not be found.

func (Group) MustGetLayout added in v0.1.0

func (g Group) MustGetLayout(name string) *Layout

MustGetLayout works like GetLayout, except that it panics instead of returning an error if the layout could not be found.

func (Group) MustGetPartial added in v0.1.0

func (g Group) MustGetPartial(name string) *Partial

MustGetPartial works like GetPartial, except that it panics instead of returning an error if the partial could not be found.

func (Group) MustGetTemplate added in v0.1.0

func (g Group) MustGetTemplate(name string) *Template

MustGetTemplate works like GetTemplate, except that it panics instead of returning an error if the template could not be found.

type Layout

type Layout struct {
	*template.Template
}

Layout is a lightweight wrapper around template.Template from the builtin html/template package. It has all the same methods, plus some additional ones. Layouts are assiciated with all regular temlates, and partials are associated with layouts. That means you can render a partial inside of a lyout with the `template` action. You can also render a layout from inside a regular template with the `template` action. See http://golang.org/pkg/text/template/ for more information about nested templates and the `template` action.

func (*Layout) ExecuteEl

func (l *Layout) ExecuteEl(el dom.Element, data interface{}) error

ExecuteEl executes the layout with the given data and then writes the result to the innerHTML of el. It only works if you have compiled this code to javascript with gopherjs and it is running in a browser.

func (Layout) PrefixedName

func (l Layout) PrefixedName() string

PrefixedName returns the name of the layout with LayoutsPrefix included. By default, LayoutsPrefix is "layouts/". Each layout can be rendered by any template using the `template` action with the prefixed name as the first argument.

type Partial

type Partial struct {
	*template.Template
}

Partial is a lightweight wrapper around template.Template from the builtin html/template package. It has all the same methods, plus some additional ones. Partials are associated with all other partials, as well as with regular templates and layouts. That means you can render partials inside of templates, layouts, or other partials with the `template` action. See http://golang.org/pkg/text/template/ for more information about nested templates and the `template` action.

func (*Partial) ExecuteEl

func (p *Partial) ExecuteEl(el dom.Element, data interface{}) error

ExecuteEl executes the partial with the given data and then writes the result to the innerHTML of el. It only works if you have compiled this code to javascript with gopherjs and it is running in a browser.

func (Partial) PrefixedName

func (p Partial) PrefixedName() string

PrefixedName returns the name of the partial with PartialsPrefix included. By default, PartialsPrefix is "partials/". Each partial can be rendered inside any template, layout, or other partial using the `template` action with the prefixed name as the first argument.

type Template

type Template struct {
	*template.Template
}

Template is a lightweight wrapper around template.Template from the builtin html/template package. It has all the same methods, plus some additional ones. All partials and layouts are associated with all templates, i.e. added to the parse tree for all templates. So you can render partials and layouts inside of a template with the `template` action. See http://golang.org/pkg/text/template/ for more information about nested templates and the `template` action.

func (*Template) ExecuteEl

func (t *Template) ExecuteEl(el dom.Element, data interface{}) error

ExecuteEl executes the template with the given data and then writes the result to the innerHTML of el. It only works if you have compiled this code to javascript with gopherjs and it is running in a browser.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL