Sprout Template Function Library

repository·main·Indexed 42 days ago

https://github.com/go-sprout/sprout

A 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.

Tokens
44.3K
Snippets
220
Records
252
Agent score
50%

What's inside Sprout

  1. Overview of Sprout

    main
    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.
  2. What is a Registry in Sprout?

    main

    A 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.
  3. How RegistryGroup simplifies registry management

    main

    A RegistryGroup is 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 a Handler.

    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.

  4. Understand Sprout registries and 'must' versions

    main
    In 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.
  5. Understand the Handler interface

    main

    The Handler interface 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.
  6. How the `dig` function differs from Sprig

    main

    The dig function has two major behavioral differences in Sprout:

    1. Argument Order/Default Value: In Sprig, the default value is the second-to-last argument. In Sprout, use the pipe syntax and the default filter separately.
    2. 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 to dig "a" "b").
    // Sprig
    {{ dig "key1" "key2" "default" $dict }}
    
    // Sprout
    {{ $dict | dig "key1" "key2" | default "default" }}
  7. Use the Strings registry for string manipulation

    main
    The Strings registry 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.
  8. How Sprout Handlers work

    main

    A Handler is the central component in Sprout responsible for managing function registries and functions. The DefaultHandler is the primary implementation. You use a handler to organize functions into registries and eventually build a FuncMap compatible with Go's text/template or html/template engines.

    import "github.com/go-sprout/sprout"
    
    handler := sprout.New()
  9. Modify lists using append and prepend

    main

    The append and prepend functions 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 -}}
  10. Naming conventions for Registries and UIDs

    main

    When creating registries, follow these naming rules:

    • Package Names: Use short, concise, singular nouns (e.g., util instead of utils). Exceptions include strings, slices, and maps to maintain consistency with the Go standard library.
    • UIDs: The Unique Identifier (UID) for a repository must be in camelCase and 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.
  11. Use Info, Debug, and Deprecated notices

    main

    Sprout provides three types of notices via NoticeKind, each mapped to a specific slog level:

    Info

    Linked to slog.InfoLevel. Used for purely informational messages.

    Debug

    Linked to slog.DebugLevel. Useful for template debugging. You can use the $out placeholder 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")
  12. Use the Slices registry for slice transformations

    main
    The Slices registry 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.