Sprout Template Function Library
repository·main·Indexed 42 days ago
https://github.com/go-sprout/sproutA modernized, high-performance template function library for Go, designed as an evolved successor to the Masterminds/sprig library. Sprout provides a flexible system for managing function registries and building FuncMaps compatible with Go's text/template and html/template engines. It includes a compatibility layer via the sprigin package for drop-in replacement of Sprig behavior and supports a wide range of function categories including String, Math, JSON, and Crypto.
What's inside Sprout
- Sprout is a library that originated as a fork of Sprig. It is designed to provide more responsive dependency updates and a continuous delivery of new functionalities compared to the original Sprig repository. It serves as an evolution of Sprig, aimed at fostering a dynamic and collaborative development environment for template function extensions.
What is a Registry in Sprout?
mainA Registry is a modular collection of functions designed to improve build efficiency and maintainability. Instead of importing a monolithic library, you can use registries to:
- Optimize Build Time: Only include the specific functions you need, reducing binary size.
- Promote Reusability: Share function collections across multiple projects as Go packages.
- Enable Collaboration: Easily incorporate registries contributed by other developers.
- Manage Versioning: Treat registries as versioned Go packages to ensure consistency.
How RegistryGroup simplifies registry management
mainA
RegistryGroupis a struct that allows you to group multiple registries together. This enables you to manage collections of registries as a single unit, promoting modularity and cleaner code organization within aHandler.Warning: When using
RegistryGroup, ensure you review the functions contained within each registry in the group to avoid registering undesired functions or causing unexpected behavior due to conflicts.Understand Sprout registries and 'must' versions
mainIn Sprout, every function is categorized into a specific registry. Some functions include a 'must' version (e.g.,must_something). These 'must' versions utilize Go's native template error handling to manage errors that occur during the execution of the method, rather than returning an error value to the template pipeline.Understand the Handler interface
mainThe
Handlerinterface is the core abstraction in Sprout used to manage function registries, logging, and error handling. To create a custom handler, you must implement the following methods:Logger() *slog.Logger: Returns the logger instance used for logging.AddRegistry(registry Registry) error: Adds a single registry to the handler.AddRegistries(registries ...Registry) error: Adds multiple registries to the handler.RawFunctions() FunctionMap: Returns the map of registered functions.RawAliases() FunctionAliasMap: Returns the map of function aliases.Build() FunctionMap: Builds and returns the complete function map, ready to be used in templates.
How the `dig` function differs from Sprig
mainThe
digfunction has two major behavioral differences in Sprout:- Argument Order/Default Value: In Sprig, the default value is the second-to-last argument. In Sprout, use the pipe syntax and the
defaultfilter separately. - Key Resolution: In Sprig, dots in keys are treated literally (e.g.,
dig "a.b"looks for a key named exactly"a.b"). In Sprout, keys are split on dots (e.g.,dig "a.b"is equivalent todig "a" "b").
// Sprig {{ dig "key1" "key2" "default" $dict }} // Sprout {{ $dict | dig "key1" "key2" | default "default" }}- Argument Order/Default Value: In Sprig, the default value is the second-to-last argument. In Sprout, use the pipe syntax and the
Use the Strings registry for string manipulation
mainTheStringsregistry provides a comprehensive set of functions for common string operations, such as formatting, splitting, joining, and case manipulation. It is used to access a collection of string-related utility functions within the Sprout ecosystem.How Sprout Handlers work
mainA
Handleris the central component in Sprout responsible for managing function registries and functions. TheDefaultHandleris the primary implementation. You use a handler to organize functions into registries and eventually build aFuncMapcompatible with Go'stext/templateorhtml/templateengines.import "github.com/go-sprout/sprout" handler := sprout.New()Modify lists using append and prepend
mainThe
appendandprependfunctions add elements to a list.Important: These functions do not modify the original list in place; they return a new list. When using them within a loop (like a
range), you must assign the result back to your variable to accumulate changes.// To accumulate in a range, assign the result back: {{- $stages := list -}} {{- range .Stages -}} {{- $stages = $stages | append .Name -}} {{- end -}}Naming conventions for Registries and UIDs
mainWhen creating registries, follow these naming rules:
- Package Names: Use short, concise, singular nouns (e.g.,
utilinstead ofutils). Exceptions includestrings,slices, andmapsto maintain consistency with the Go standard library. - UIDs: The Unique Identifier (UID) for a repository must be in
camelCaseand prefixed with your name or organization, separated by a dot (e.g.,42atomys.myRegistry). - Documentation: Every package must include a README or a comment providing a brief overview of its purpose.
- Package Names: Use short, concise, singular nouns (e.g.,
Use Info, Debug, and Deprecated notices
mainSprout provides three types of notices via
NoticeKind, each mapped to a specificsloglevel:Info
Linked to
slog.InfoLevel. Used for purely informational messages.Debug
Linked to
slog.DebugLevel. Useful for template debugging. You can use the$outplaceholder in the message, which will be replaced by the actual output of the function.Deprecated
Indicates a function should be replaced. When triggered, it writes to the warning logger with a message indicating the function is deprecated and suggesting an alternative.
// Info notice sprout.NewInfoNotice("toLower", "This is an informative notice") // Debug notice with $out placeholder sprout.NewDebugNotice("toLower", "toLower result are $out") // Deprecated notice sprout.NewDeprecatedNotice("int", "please use `toInt` instead")Use the Slices registry for slice transformations
mainTheSlicesregistry provides a collection of utility functions designed for working with slice data structures. It includes operations for filtering, sorting, transforming, and manipulating slices (such as appending, prepending, chunking, and flattening) in a flexible manner. These utilities are intended to be used within the Sprout framework's registry system to handle slice-based data processing tasks.