sprout

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 3, 2024 License: MIT Imports: 56 Imported by: 5

README

Sprout Logo

[!NOTE] Sprout is an evolved variant of the Masterminds/sprig library, reimagined for modern Go versions. It introduces fresh functionalities and commits to maintaining the library, picking up where Sprig left off. Notably, Sprig had not seen updates for two years and was not compatible beyond Golang 1.13, necessitating the creation of Sprout.

Motivation

Sprout was born out of the need for a modernized, maintained, and performant template function library. Sprig, the predecessor to Sprout, had not seen updates for two years and was not optimized for later versions of Golang. Sprout aims to fill this gap by providing a library that is actively maintained, compatible with the latest Go versions, and optimized for performance.

Roadmap to Sprout v1.0

You can track our progress towards Sprout v1.0 by following the documentation page here.

Table of Contents

Transitioning from Sprig

Sprout is designed to be a drop-in replacement for Sprig in the v1.0, with the same function names and behavior. To use Sprout in your project, simply replace the Sprig import with Sprout:

import (
-  "github.com/Masterminds/sprig/v3"
+  "github.com/42atomys/sprout"
)

tpl := template.Must(
  template.New("base").
-   Funcs(sprig.FuncMap()).
+   Funcs(sprout.FuncMap()).
    ParseGlob("*.tmpl")
)

Usage

To use Sprout in your project, import the library and use the FuncMap function to add the template functions to your template:

import (
  "github.com/42atomys/sprout"
  "text/template"
)

tpl := template.Must(
  template.New("base").
    Funcs(sprout.FuncMap()).
    ParseGlob("*.tmpl")
)

You can customize the behavior of Sprout by creating a FunctionHandler and passing it to the FuncMap function or using the configuration functions provided by Sprout:

handler := sprout.NewFunctionHandler(
  // Add your logger to the handler to log errors and debug information using the
  // standard slog package or any other logger that implements the slog.Logger interface.
  // By default, Sprout uses a slog.TextHandler.
  sprout.WithLogger(slogLogger),
  // Set the error handling behavior for the handler. By default, Sprout returns the default value of the return type without crashes or panics.
  sprout.WithErrHandling(sprout.ErrHandlingReturnDefaultValue),
  // Set the error channel for the handler. By default, Sprout does not use an error channel. If you set an error channel, Sprout will send errors to it.
  // This options is only used when the error handling behavior is set to
  // `ErrHandlingErrorChannel`
  sprout.WithErrorChannel(errChan),
  // Set the alias for a function. By default, Sprout use alias for some functions for backward compatibility with Sprig.
  sprout.WithAlias("hello", "hi"),
)

// Use the handler with the FuncMap function. The handler will be used to handle all template functions.
tpl := template.Must(
  template.New("base").
    Funcs(sprout.FuncMap(sprout.WithFunctionHandler(handler))).
    ParseGlob("*.tmpl")
)

Usage: Logger

Sprout uses the slog package for logging. You can pass your logger to the WithLogger configuration function to log errors and debug information:

// Create a new logger using the slog package.
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))

// Use the handler with the FuncMap function.
tpl := template.Must(
  template.New("base").
    Funcs(sprout.FuncMap(sprout.WithLogger(logger))).
    ParseGlob("*.tmpl")
)

Usage: Alias

Sprout provides the ability to set an alias for a function. This feature is useful for backward compatibility with Sprig. You can set an alias for a function using the WithAlias or WithAliases configuration functions.

See more about the alias in the documentation.

sprout.NewFunctionHandler(
  sprout.WithAlias("hello", "hi"),
)

Usage: Error Handling

Sprout provides three error handling behaviors:

  • ErrHandlingReturnDefaultValue: Sprout returns the default value of the return type without crashes or panics.
  • ErrHandlingPanic: Sprout panics when an error occurs.
  • ErrHandlingErrorChannel: Sprout sends errors to the error channel.

You can set the error handling behavior using the WithErrHandling configuration function:

sprout.NewFunctionHandler(
  sprout.WithErrHandling(sprout.ErrHandlingReturnDefaultValue),
)
Default Value

If you set the error handling behavior to ErrHandlingReturnDefaultValue, Sprout will return the default value of the return type without crashes or panics to ensure a smooth user experience when an error occurs.

Panic

If you set the error handling behavior to ErrHandlingPanic, Sprout will panic when an error occurs to ensure that the error is not ignored and sended back to template execution.

Error Channel

If you set the error handling behavior to ErrHandlingErrorChannel, you can pass an error channel to the WithErrorChannel configuration function. Sprout will send errors to the error channel:

errChan := make(chan error)

sprout.NewFunctionHandler(
  sprout.WithErrHandling(sprout.ErrHandlingErrorChannel),
  sprout.WithErrorChannel(errChan),
)

Performence Benchmarks

To see all the benchmarks, please refer to the benchmarks directory.

Sprig v3.2.3 vs Sprout v0.2

goos: linux
goarch: amd64
pkg: sprout_benchmarks
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkSprig-12              1        3869134593 ns/op        45438616 B/op      24098 allocs/op
BenchmarkSprout-12             1        1814126036 ns/op        38284040 B/op      11627 allocs/op
PASS
ok      sprout_benchmarks       5.910s

Time improvement: 53.1% Memory improvement: 15.7%

So, Sprout v0.2 is approximately 53.1% faster and uses 15.7% less memory than Sprig v3.2.3. 🚀

Development Philosophy (Currently in reflexion to create our)

Our approach to extending and refining Sprout was guided by several key principles:

  • Empowering layout construction through template functions.
  • Designing template functions that avoid returning errors when possible, instead displaying default values for smoother user experiences.
  • Ensuring template functions operate solely on provided data, without external data fetching.
  • Maintaining the integrity of core Go template functionalities without overrides.

Documentation

Overview

package sprout provides template functions for Go.

This package contains a number of utility functions for working with data inside of Go `html/template` and `text/template` files.

To add these functions, use the `template.Funcs()` method:

t := templates.New("foo").Funcs(sprout.FuncMap())

Note that you should add the function map before you parse any template files.

In several cases, sprout reverses the order of arguments from the way they
appear in the standard library. This is to make it easier to pipe
arguments into functions.

See http://masterminds.github.io/sprout/ for more detailed documentation on each of the available functions.

Example
// Set up variables and template.
vars := map[string]interface{}{"Name": "  John Jacob Jingleheimer Schmidt "}
tpl := `Hello {{.Name | trim | lower}}`

// Get the sprout function map.
fmap := TxtFuncMap()
t := template.Must(template.New("test").Funcs(fmap).Parse(tpl))

err := t.Execute(os.Stdout, vars)
if err != nil {
	fmt.Printf("Error during template execution: %s", err)
	return
}
Output:

Hello john jacob jingleheimer schmidt

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func FuncMap

func FuncMap(opts ...FunctionHandlerOption) template.FuncMap

FuncMap returns a template.FuncMap for use with text/template or html/template. It provides backward compatibility with sprig.FuncMap and integrates additional configured functions. FOR BACKWARD COMPATIBILITY ONLY

func GenericFuncMap

func GenericFuncMap() map[string]interface{}

GenericFuncMap returns a copy of the basic function map as a map[string]interface{}.

func HermeticHtmlFuncMap

func HermeticHtmlFuncMap() template.FuncMap

HermeticHtmlFuncMap returns an 'html/template'.Funcmap with only repeatable functions.

func HermeticTxtFuncMap

func HermeticTxtFuncMap() ttemplate.FuncMap

HermeticTxtFuncMap returns a 'text/template'.FuncMap with only repeatable functions.

func HtmlFuncMap

func HtmlFuncMap() template.FuncMap

HtmlFuncMap returns an 'html/template'.Funcmap

func TxtFuncMap

func TxtFuncMap() ttemplate.FuncMap

TxtFuncMap returns a 'text/template'.FuncMap

Types

type DSAKeyFormat

type DSAKeyFormat struct {
	Version       int
	P, Q, G, Y, X *big.Int
}

DSAKeyFormat stores the format for DSA keys. Used by pemBlockForKey

type ErrHandling added in v0.2.0

type ErrHandling int

ErrHandling defines the strategy for handling errors within FunctionHandler. It supports returning default values, panicking, or sending errors to a specified channel.

const (
	// ErrHandlingReturnDefaultValue indicates that a default value should be
	// returned on error (default).
	ErrHandlingReturnDefaultValue ErrHandling = iota + 1
	// ErrHandlingPanic indicates that a panic should be raised on error.
	ErrHandlingPanic
	// ErrHandlingErrorChannel indicates that errors should be sent to an error
	// channel.
	ErrHandlingErrorChannel
)

type FunctionAliasMap added in v0.2.0

type FunctionAliasMap map[string][]string

FunctionAliasMap is a map that stores a list of aliases for each function.

type FunctionHandler added in v0.2.0

type FunctionHandler struct {
	ErrHandling ErrHandling

	Logger *slog.Logger
	// contains filtered or unexported fields
}

FunctionHandler manages function execution with configurable error handling and logging.

func NewFunctionHandler added in v0.2.0

func NewFunctionHandler(opts ...FunctionHandlerOption) *FunctionHandler

NewFunctionHandler creates a new FunctionHandler with the provided options.

func (*FunctionHandler) Hello added in v0.2.0

func (p *FunctionHandler) Hello() string

Hello returns a greeting string.

type FunctionHandlerOption added in v0.2.0

type FunctionHandlerOption func(*FunctionHandler)

FunctionHandlerOption defines a type for functional options that configure FunctionHandler.

func WithAlias added in v0.2.0

func WithAlias(originalFunction string, aliases ...string) FunctionHandlerOption

WithAlias returns a FunctionHandlerOption that associates one or more alias names with an original function name. This allows the function to be called by any of its aliases.

originalFunction specifies the original function name to which aliases will be added. aliases is a variadic parameter that takes one or more strings as aliases for the original function.

The function does nothing if no aliases are provided. If the original function name does not already have associated aliases in the FunctionHandler, a new slice of strings is created to hold its aliases. Each provided alias is then appended to this slice.

This option must be applied to a FunctionHandler using the FunctionHandler's options mechanism for the aliases to take effect.

Example:

handler := NewFunctionHandler(WithAlias("originalFunc", "alias1", "alias2"))

func WithAliases added in v0.2.0

func WithAliases(aliases FunctionAliasMap) FunctionHandlerOption

WithAliases returns a FunctionHandlerOption that configures multiple aliases for function names in a single call. It allows a batch of functions to be associated with their respective aliases, facilitating the creation of aliases for multiple functions at once.

This option must be applied to a FunctionHandler using the FunctionHandler's options mechanism for the aliases to take effect. It complements the WithAlias function by providing a means to configure multiple aliases in one operation, rather than one at a time.

Example:

handler := NewFunctionHandler(WithAliases(sprout.FunctionAliasMap{
    "originalFunc1": {"alias1_1", "alias1_2"},
    "originalFunc2": {"alias2_1", "alias2_2"},
}))

func WithErrHandling added in v0.2.0

func WithErrHandling(eh ErrHandling) FunctionHandlerOption

WithErrHandling sets the error handling strategy for a FunctionHandler.

func WithErrorChannel added in v0.2.0

func WithErrorChannel(ec chan error) FunctionHandlerOption

WithErrorChannel sets the error channel for a FunctionHandler.

func WithFunctionHandler added in v0.2.0

func WithFunctionHandler(new *FunctionHandler) FunctionHandlerOption

WithFunctionHandler updates a FunctionHandler with settings from another FunctionHandler. This is useful for copying configurations between handlers.

func WithLogger added in v0.2.0

func WithLogger(l *slog.Logger) FunctionHandlerOption

WithLogger sets the logger used by a FunctionHandler.

Jump to

Keyboard shortcuts

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