soy

package module
v0.0.0-...-c50f1b6 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2024 License: MIT Imports: 15 Imported by: 4

README

soy

GoDoc Build Status Go Report Card

Go implementation for Soy templates aka Google Closure Templates. See godoc for more details and usage examples.

This project requires Go 1.12 or higher due to one of the transitive dependencies requires it as a minimum version; otherwise, Go 1.11 would suffice for go mod support.

Be sure to set the env var GO111MODULE=on to use the go mod dependency versioning when building and testing this project.

Documentation

Overview

Package soy is an implementation of Google's Closure Templates, which are data-driven templates for generating HTML.

Compared to html/template, Closure Templates have a few advantages

  • Intuitive templating language that supports simple control flow, expressions and arithmetic.
  • The same templates may be used from Go, Java, and Javascript.
  • Internationalization is built in

and specific to this implementation:

  • High performance (> 3x faster than html/template in BenchmarkSimpleTemplate)
  • Hot reload for templates
  • Parse a directory tree of templates

Refer to the official language spec for details:

https://developers.google.com/closure/templates/

Template example

Here is Hello World

{namespace examples.simple}

/**
 * Says hello to the world.
 */
{template .helloWorld}
  Hello world!
{/template}

Here is a more customized version that addresses us by name and can use greetings other than "Hello".

/**
 * Greets a person using "Hello" by default.
 * @param name The name of the person.
 * @param? greetingWord Optional greeting word to use instead of "Hello".
 */
{template .helloName}
  {if not $greetingWord}
    Hello {$name}!
  {else}
    {$greetingWord} {$name}!
  {/if}
{/template}

This last example renders a greeting for each person in a list of names.

It demonstrates a [foreach] loop with an [ifempty] command. It also shows how to call other templates and insert their output using the [call] command. Note that the [data="all"] attribute in the call command passes all of the caller's template data to the callee template.

/**
 * Greets a person and optionally a list of other people.
 * @param name The name of the person.
 * @param additionalNames The additional names to greet. May be an empty list.
 */
{template .helloNames}
  // Greet the person.
  {call .helloName data="all" /}<br>
  // Greet the additional people.
  {foreach $additionalName in $additionalNames}
    {call .helloName}
      {param name: $additionalName /}
    {/call}
    {if not isLast($additionalName)}
      <br>  // break after every line except the last
    {/if}
  {ifempty}
    No additional people to greet.
  {/foreach}
{/template}

This example is from https://developers.google.com/closure/templates/docs/helloworld_java.

Many more examples of Soy language features/commands may be seen here: https://github.com/robfig/soy/blob/master/testdata/features.soy

Usage example

These are the high level steps:

  • Create a soy.Bundle and add templates to it (the literal template strings, files, or directories).
  • Compile the bundle of templates, resulting in a "Tofu" instance. It provides access to all your soy.
  • Render a HTML template from Tofu by providing the template name and a data object.

Typically in a web application you have a directory containing views for all of your pages. For example:

app/views/
app/views/account/
app/views/feed/
...

This code snippet will parse a file of globals, all Soy templates within app/views, and provide back a Tofu intance that can be used to render any declared template. Additionally, if "mode == dev", it will watch the Soy files for changes and update your compiled templates in the background (or log compile errors to soy.Logger). Error checking is omitted.

On startup:

tofu, _ := soy.NewBundle().
    WatchFiles(true).                     // watch Soy files, reload on changes
    AddGlobalsFile("views/globals.txt").  // parse a file of globals
    AddTemplateDir("views").              // load *.soy in all sub-directories
    CompileToTofu()

To render a page:

var obj = map[string]interface{}{
  "user":    user,
  "account": account,
}
tofu.Render(resp, "acme.account.overview", obj)

Structs may be used as the data context too, but keep in mind that they are converted to data maps -- unlike html/template, the context is pure data, and you can not call methods on it.

var obj = HomepageContext{
  User:    user,
  Account: account,
}
tofu.Render(resp, "acme.account.overview", obj)

See soyhtml.StructOptions for knobs to control how your structs get converted to data maps.

Project Status

The goal is full compatibility and feature parity with the official Closure Templates project.

The server-side templating functionality is well tested and nearly complete, except for two notable areas: contextual autoescaping and internationalization/bidi support. Contributions welcome.

The Javascript generation is early and lacks many generation options, but it successfully passes the server-side template test suite. Note that it is possible to run the official Soy compiler to generate your javascript templates at build time, even if you use this package for server-side templates.

Please see the TODO file for features that have yet to be implemented.

Please open a Github Issue for any bugs / problems / comments, or if you find a template that renders differently than with the official compiler.

Index

Constants

This section is empty.

Variables

View Source
var Logger = log.New(os.Stderr, "[soy] ", 0)

Logger is used to print notifications and compile errors when using the "WatchFiles" feature.

Functions

func ParseGlobals

func ParseGlobals(input io.Reader) (data.Map, error)

ParseGlobals parses the given input, expecting the form:

<global_name> = <primitive_data>

Furthermore:

  • Empty lines and lines beginning with '//' are ignored.
  • <primitive_data> must be a valid template expression literal for a primitive type (null, boolean, integer, float, or string)

Types

type Bundle

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

Bundle is a collection of Soy content (templates and globals). It acts as input for the Soy compiler.

func NewBundle

func NewBundle() *Bundle

NewBundle returns an empty bundle.

func (*Bundle) AddGlobalsFile

func (b *Bundle) AddGlobalsFile(filename string) *Bundle

AddGlobalsFile opens and parses the given filename for Soy globals, and adds the resulting data map to the bundle.

func (*Bundle) AddGlobalsMap

func (b *Bundle) AddGlobalsMap(globals data.Map) *Bundle

func (*Bundle) AddParsePass

func (b *Bundle) AddParsePass(f func(template.Registry) error) *Bundle

AddParsePass adds a function to the bundle that will be called after the Soy is parsed.

func (*Bundle) AddTemplateDir

func (b *Bundle) AddTemplateDir(root string) *Bundle

AddTemplateDir adds all *.soy files found within the given directory (including sub-directories) to the bundle.

func (*Bundle) AddTemplateFile

func (b *Bundle) AddTemplateFile(filename string) *Bundle

AddTemplateFile adds the given Soy template file text to this bundle. If WatchFiles is on, it will be subsequently watched for updates.

func (*Bundle) AddTemplateString

func (b *Bundle) AddTemplateString(filename, soyfile string) *Bundle

AddTemplateString adds the given template to the bundle. The name is only used for error messages - it does not need to be provided nor does it need to be a real filename.

func (*Bundle) Compile

func (b *Bundle) Compile() (*template.Registry, error)

Compile parses all of the Soy files in this bundle, verifies a number of rules about data references, and returns the completed template registry.

func (*Bundle) CompileToTofu

func (b *Bundle) CompileToTofu() (*soyhtml.Tofu, error)

CompileToTofu returns a soyhtml.Tofu object that allows you to render soy templates to HTML.

func (*Bundle) SetRecompilationCallback

func (b *Bundle) SetRecompilationCallback(c func(*template.Registry)) *Bundle

SetRecompilationCallback assigns the bundle a function to call after recompilation. This is called before updating the in-use registry.

func (*Bundle) WatchFiles

func (b *Bundle) WatchFiles(watch bool) *Bundle

WatchFiles tells Soy to watch any template files added to this bundle, re-compile as necessary, and propagate the updates to your tofu. It should be called once, before adding any files.

Directories

Path Synopsis
Package ast contains definitions for the in-memory representation of a Soy template.
Package ast contains definitions for the in-memory representation of a Soy template.
Package data contains the definitions for the Soy data types.
Package data contains the definitions for the Soy data types.
Package parse converts a Soy template into its in-memory representation (AST)
Package parse converts a Soy template into its in-memory representation (AST)
Package parsepasses contains routines that validate or rewrite a Soy AST.
Package parsepasses contains routines that validate or rewrite a Soy AST.
Package soyhtml renders a compiled set of Soy to HTML.
Package soyhtml renders a compiled set of Soy to HTML.
Package soyjs compiles Soy to javascript.
Package soyjs compiles Soy to javascript.
pomsg
Package pomsg provides a PO file implementation for Soy message bundles
Package pomsg provides a PO file implementation for Soy message bundles
pomsg/xgettext-soy
xgettext-soy is a tool to extract messages from Soy templates in the PO (gettext) file format.
xgettext-soy is a tool to extract messages from Soy templates in the PO (gettext) file format.
Package soyweb is a simple development server that serves the given template.
Package soyweb is a simple development server that serves the given template.
Package template provides convenient access to groups of parsed Soy files.
Package template provides convenient access to groups of parsed Soy files.

Jump to

Keyboard shortcuts

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