Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/gobuffalo/velvet
A sweet velvety templating package
https://github.com/gobuffalo/velvet
go golang handlebars template template-engine
Last synced: 3 months ago
JSON representation
A sweet velvety templating package
- Host: GitHub
- URL: https://github.com/gobuffalo/velvet
- Owner: gobuffalo
- License: mit
- Created: 2016-12-29T16:46:57.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2017-03-20T14:41:20.000Z (almost 8 years ago)
- Last Synced: 2024-10-01T00:20:58.551Z (3 months ago)
- Topics: go, golang, handlebars, template, template-engine
- Language: Go
- Size: 32.2 KB
- Stars: 73
- Watchers: 8
- Forks: 11
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
- awesome-go - velvet - A sweet velvety templating package - ★ 62 (Template Engines)
README
# Velvet [![GoDoc](https://godoc.org/github.com/gobuffalo/velvet?status.svg)](https://godoc.org/github.com/gobuffalo/velvet) [![Build Status](https://travis-ci.org/gobuffalo/velvet.svg?branch=master)](https://travis-ci.org/gobuffalo/velvet) [![Code Climate](https://codeclimate.com/github/gobuffalo/velvet/badges/gpa.svg)](https://codeclimate.com/github/gobuffalo/velvet)
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):
```handlebars
{{ name }}
- {{ @value }}
{{#each names}}
{{/each}}
```
Given that string, you can render the template like such:
```go
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:
```html
Mark
- John
- Paul
- George
- Ringo
```
## 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.
```handlebars
{{#if true }}
render this
{{/if}}
```
#### Else Statements
```handlebars
{{#if false }}
won't render this
{{ else }}
render this
{{/if}}
```
#### Unless Statements
```handlebars
{{#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.
```handlebars
- {{ @index }} - {{ @value }}
{{#each names}}
{{/each}}
```
By using "block parameters" you can change the "key" of the element being accessed from `@value` to a key of your choosing.
```handlebars
- {{ name }}
{{#each names as |name|}}
{{/each}}
```
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.
```handlebars
- {{ index }} - {{ name }}
{{#each names as |index, name|}}
{{/each}}
```
#### 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.
```handlebars
- {{ @key }} - {{ @value }}
{{#each users}}
{{/each}}
```
By using "block parameters" you can change the "key" of the element being accessed from `@value` to a key of your choosing.
```handlebars
- {{ @key }} - {{ user }}
{{#each users as |user|}}
{{/each}}
```
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.
```handlebars
- {{ key }} - {{ user }}
{{#each users as |key, user|}}
{{/each}}
```
### 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](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.
```go
func() string {
return ""
}
```
#### `string, error`
Return a `string` and an error. The `string` will be HTML escaped, and deemed "not"-safe.
```go
func() (string, error) {
return "", nil
}
```
#### `template.HTML`
[https://golang.org/pkg/html/template/#HTML](https://golang.org/pkg/html/https://golang.org/pkg/html/template/#HTMLlate/#HTML)
Return a `template.HTML` string. The `template.HTML` will **not** be HTML escaped, and will be deemed safe.
```go
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.
```go
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`](https://godoc.org/github.com/gobuffalo/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
```go
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.
```go
s, err := velvet.Render(`
{{greet "mark"}}
`, velvet.NewContext())if err != nil {
// handle errors
}
fmt.Print(s) //
Hi mark!
```
#### Per Template Helpers
```go
t, err := velvet.Parse(`
{{greet "mark"}}
`)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.
```go
s, err := t.Exec(velvet.NewContext())
if err != nil {
// handle errors
}
fmt.Print(s) //
Hi mark!
```
### 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
```go
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
```