velvet

package module
Version: v0.0.0-...-d97471b Latest Latest
Warning

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

Go to latest
Published: Mar 20, 2017 License: MIT Imports: 13 Imported by: 34

README

Velvet GoDoc Build Status Code Climate

Velvet is a templating package for Go. It bears a striking resemblance to "handlebars" based templates, there are a few small changes/tweaks, that make it slightly different.

General Usage

If you know handlebars, you basically know how to use Velvet.

Let's assume you have a template (a string of some kind):

<!-- some input -->
<h1>{{ name }}</h1>
<ul>
  {{#each names}}
    <li>{{ @value }}</li>
  {{/each}}
</ul>

Given that string, you can render the template like such:

ctx := velvet.NewContext()
ctx.Set("name", "Mark")
ctx.Set("names", []string{"John", "Paul", "George", "Ringo"})
s, err := velvet.Render(input, ctx)
if err != nil {
  // handle errors
}

Which would result in the following output:

<h1>Mark</h1>
<ul>
  <li>John</li>
  <li>Paul</li>
  <li>George</li>
  <li>Ringo</li>
</ul>

Helpers

If Statements

What to do? Should you render the content, or not? Using Velvet's built in if, else, and unless helpers, let you figure it out for yourself.

{{#if true }}
  render this
{{/if}}
Else Statements
{{#if false }}
  won't render this
{{ else }}
  render this
{{/if}}
Unless Statements
{{#unless true }}
  won't render this
{{/unless}}
Each Statements

Into everyone's life a little looping must happen. We can't avoid the need to write loops in applications, so Velvet helps you out by coming loaded with an each helper to iterate through arrays, slices, and maps.

Arrays

When looping through arrays or slices, the block being looped through will be access to the "global" context, as well as have four new variables available within that block:

  • @first [bool] - is this the first pass through the iteration?
  • @last [bool] - is this the last pass through the iteration?
  • @index [int] - the counter of where in the loop you are, starting with 0.
  • @value - the current element in the array or slice that is being iterated over.
<ul>
  {{#each names}}
    <li>{{ @index }} - {{ @value }}</li>
  {{/each}}
</ul>

By using "block parameters" you can change the "key" of the element being accessed from @value to a key of your choosing.

<ul>
  {{#each names as |name|}}
    <li>{{ name }}</li>
  {{/each}}
</ul>

To change both the key and the index name you can pass two "block parameters"; the first being the new name for the index and the second being the name for the element.

<ul>
  {{#each names as |index, name|}}
    <li>{{ index }} - {{ name }}</li>
  {{/each}}
</ul>
Maps

Looping through maps using the each helper is also supported, and follows very similar guidelines to looping through arrays.

  • @first [bool] - is this the first pass through the iteration?
  • @last [bool] - is this the last pass through the iteration?
  • @key - the key of the pair being accessed.
  • @value - the value of the pair being accessed.
<ul>
  {{#each users}}
    <li>{{ @key }} - {{ @value }}</li>
  {{/each}}
</ul>

By using "block parameters" you can change the "key" of the element being accessed from @value to a key of your choosing.

<ul>
  {{#each users as |user|}}
    <li>{{ @key }} - {{ user }}</li>
  {{/each}}
</ul>

To change both the key and the value name you can pass two "block parameters"; the first being the new name for the key and the second being the name for the value.

<ul>
  {{#each users as |key, user|}}
    <li>{{ key }} - {{ user }}</li>
  {{/each}}
</ul>
Other Builtin Helpers
  • json - returns a JSON marshaled string of the value passed to it.
  • js_escape - safely escapes a string to be used in a JavaScript bit of code.
  • html_escape - safely escapes a string to be used in an HTML bit of code.
  • upcase - upper cases the entire string passed to it.
  • downcase - lower cases the entire string passed to it.
  • markdown - converts markdown to HTML.
  • len - returns the length of an array or slice

Velvet also imports all of the helpers found https://github.com/markbates/inflect/blob/master/helpers.go

Custom Helpers

No templating package would be complete without allowing for you to build your own, custom, helper functions.

Return Values

The first thing to understand about building custom helper functions is their are a few "valid" return values:

string

Return just a string. The string will be HTML escaped, and deemed "not"-safe.

func() string {
  return ""
}
string, error

Return a string and an error. The string will be HTML escaped, and deemed "not"-safe.

func() (string, error) {
  return "", nil
}
template.HTML

https://golang.org/pkg/html/template/#HTML

Return a template.HTML string. The template.HTML will not be HTML escaped, and will be deemed safe.

func() template.HTML {
  return template.HTML("")
}
template.HTML, error

Return a template.HTML string and an error. The template.HTML will not be HTML escaped, and will be deemed safe.

func() ( template.HTML, error ) {
  return template.HTML(""), error
}
Input Values

Custom helper functions can take any type, and any number of arguments. There is an option last argument, velvet.HelperContext, that can be received. It's quite useful, and I would recommend taking it, as it provides you access to things like the context of the call, the block associated with the helper, etc...

Registering Helpers

Custom helpers can be registered in one of two different places; globally and per template.

Global Helpers
err := velvet.Helpers.Add("greet", func(name string) string {
  return fmt.Sprintf("Hi %s!", name)
})
if err != nil {
  // handle errors
}

The greet function is now available to all templates that use Velvet.

s, err := velvet.Render(`<h1>{{greet "mark"}}</h1>`, velvet.NewContext())
if err != nil {
  // handle errors
}
fmt.Print(s) // <h1>Hi mark!</h1>
Per Template Helpers
t, err := velvet.Parse(`<h1>{{greet "mark"}}</h1>`)
if err != nil {
  // handle errors
}
t.Helpers.Add("greet", func(name string) string {
  return fmt.Sprintf("Hi %s!", name)
})
if err != nil {
  // handle errors
}

The greet function is now only available to the template it was added to.

s, err := t.Exec(velvet.NewContext())
if err != nil {
  // handle errors
}
fmt.Print(s) // <h1>Hi mark!</h1>
Block Helpers

Like the if and each helpers, block helpers take a "block" of text that can be evaluated and potentially rendered, manipulated, or whatever you would like. To write a block helper, you have to take the velvet.HelperContext as the last argument to your helper function. This will give you access to the block associated with that call.

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

s, err := velvet.Render(`{{#upblock}}hi{{/upblock}}`, velvet.NewContext())
if err != nil {
  // handle errors
}
fmt.Print(s) // HI

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Helpers = HelperMap{
	// contains filtered or unexported fields
}

Helpers contains all of the default helpers for velvet. These will be available to all templates. You should add any custom global helpers to this list.

Functions

func BuffaloRenderer

func BuffaloRenderer(input string, data map[string]interface{}, helpers map[string]interface{}) (string, error)

BuffaloRenderer implements the render.TemplateEngine interface allowing velvet to be used as a template engine for Buffalo

func IsTrue

func IsTrue(obj interface{}) bool

IsTrue returns true if obj is a truthy value.

func Render

func Render(input string, ctx *Context) (string, error)

Render a string using the given the context.

Types

type Context

type Context struct {
	// contains filtered or unexported fields
}

Context holds all of the data for the template that is being rendered.

func NewContext

func NewContext() *Context

NewContext returns a fully formed context ready to go

func NewContextWith

func NewContextWith(data map[string]interface{}) *Context

NewContextWith returns a fully formed context using the data provided.

func (*Context) Get

func (c *Context) Get(key string) interface{}

Get a value from the context, or it's parent's context if one exists.

func (*Context) Has

func (c *Context) Has(key string) bool

Has checks the existence of the key in the context.

func (*Context) New

func (c *Context) New() *Context

New context containing the current context. Values set on the new context will not be set onto the original context, however, the original context's values will be available to the new context.

func (*Context) Options

func (c *Context) Options() map[string]interface{}

Options are the values passed into a helper.

func (*Context) Set

func (c *Context) Set(key string, value interface{})

Set a value onto the context

type HTMLer

type HTMLer interface {
	HTML() template.HTML
}

HTMLer generates HTML source

type HelperContext

type HelperContext struct {
	Context *Context
	Args    []interface{}
	// contains filtered or unexported fields
}

HelperContext is an optional context that can be passed as the last argument to helper functions.

func (HelperContext) Block

func (h HelperContext) Block() (string, error)

Block executes the block of template associated with the helper, think the block inside of an "if" or "each" statement.

func (HelperContext) BlockWith

func (h HelperContext) BlockWith(ctx *Context) (string, error)

BlockWith executes the block of template associated with the helper, think the block inside of an "if" or "each" statement. It takes a new context with which to evaluate the block.

func (HelperContext) ElseBlock

func (h HelperContext) ElseBlock() (string, error)

ElseBlock executes the "inverse" block of template associated with the helper, think the "else" block of an "if" or "each" statement.

func (HelperContext) ElseBlockWith

func (h HelperContext) ElseBlockWith(ctx *Context) (string, error)

ElseBlockWith executes the "inverse" block of template associated with the helper, think the "else" block of an "if" or "each" statement. It takes a new context with which to evaluate the block.

func (HelperContext) Get

func (h HelperContext) Get(key string) interface{}

Get is a convenience method that calls the underlying Context.

func (HelperContext) Helpers

func (h HelperContext) Helpers() *HelperMap

Helpers returns a HelperMap containing all of the known helpers

type HelperMap

type HelperMap struct {
	// contains filtered or unexported fields
}

HelperMap holds onto helpers and validates they are properly formed.

func NewHelperMap

func NewHelperMap() (HelperMap, error)

NewHelperMap containing all of the "default" helpers from "velvet.Helpers".

func (*HelperMap) Add

func (h *HelperMap) Add(key string, helper interface{}) error

Add a new helper to the map. New Helpers will be validated to ensure they meet the requirements for a helper:

func(...) (string) {}
func(...) (string, error) {}
func(...) (template.HTML) {}
func(...) (template.HTML, error) {}

func (*HelperMap) AddMany

func (h *HelperMap) AddMany(helpers map[string]interface{}) error

AddMany helpers at the same time.

func (HelperMap) Helpers

func (h HelperMap) Helpers() map[string]interface{}

Helpers returns the underlying list of helpers from the map

type Template

type Template struct {
	Input   string
	Helpers HelperMap
	// contains filtered or unexported fields
}

Template represents an input and helpers to be used to evaluate and render the input.

func NewTemplate

func NewTemplate(input string) (*Template, error)

NewTemplate from the input string. Adds all of the global helper functions from "velvet.Helpers".

func Parse

func Parse(input string) (*Template, error)

Parse an input string and return a Template.

func (*Template) Clone

func (t *Template) Clone() *Template

Clone a template. This is useful for defining helpers on per "instance" of the template.

func (*Template) Exec

func (t *Template) Exec(ctx *Context) (string, error)

Exec the template using the content and return the results

func (*Template) Parse

func (t *Template) Parse() error

Parse the template this can be called many times as a successful result is cached and is used on subsequent uses.

Jump to

Keyboard shortcuts

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