Documentation
¶
Overview ¶
Package templates provides a secure, file-system-based Go template engine built on Google's safehtml/template library.
Core Concepts ¶
This engine organizes templates into a specific directory structure:
- layouts/: specific wrapper templates that define the document structure (e.g. <html>...</html>).
- pages/: individual page templates that render inside a layout.
- blocks/: reusable partials (e.g. forms, navigational elements) that can be included in pages or layouts.
Safety ¶
Using safehtml/template ensures that your output is free from XSS vulnerabilities by default. Context-aware escaping is applied automatically. For cases where you strictly trust the input (e.g. from a CMS), special helper functions `trusted_*` are provided.
Rapid Prototyping and HTMX ¶
If the strictness of safehtml is an obstacle during development or for projects using libraries like HTMX where security models might differ, it can be disabled via the DisableSafeHTML configuration. In this mode, the engine falls back to the standard library's text/template (producing literal output), and trusted_* functions return objects as-is.
Logging for trusted helper usage can also be disabled via DisableTrustedLog to reduce noise in projects that use them frequently.
Index ¶
- Variables
- func Locals(args ...any) map[string]any
- func References(args ...any) map[string]any
- type LayoutContextKey
- type Option
- type Templates
- func (t *Templates) AddDynamicBlockCtxToFuncMap()
- func (t *Templates) AddDynamicBlockToFuncMap()
- func (t *Templates) AddFuncMapHelpers()
- func (t *Templates) AddLocalsToFuncMap()
- func (t *Templates) AddReferencesToFuncMap()
- func (t *Templates) ExecuteTemplate(w io.Writer, r *http.Request, templateName string, data interface{}) error
- func (t *Templates) ExecuteTemplateAsText(r *http.Request, templateName string, data interface{}) (string, error)
- func (t *Templates) GetParsedTemplates() []string
- func (t *Templates) HandlerRenderWithData(templateName string, data interface{}) func(w http.ResponseWriter, r *http.Request)
- func (t *Templates) HandlerRenderWithDataFromContext(templateName string, contextKey interface{}) func(w http.ResponseWriter, r *http.Request)
- func (t *Templates) MustParseTemplates()
- func (t *Templates) ParseTemplates() error
- func (t *Templates) RenderBlockAsHTMLString(name string, data interface{}) (any, error)
- func (t *Templates) RenderBlockAsHTMLStringWithContext(ctx context.Context, blockname string, payload interface{}) (any, error)
Constants ¶
This section is empty.
Variables ¶
var ( // ErrTemplateNotFound is returned when a requested template or layout is not in the parsed map. ErrTemplateNotFound = errors.New("template not found") // ErrBlockNotFound is returned when a requested block is not found. ErrBlockNotFound = errors.New("block not found") // ErrInvalidBlockName is returned when a block name does not adhere to naming conventions (e.g. must start with '_'). ErrInvalidBlockName = errors.New("invalid block name") )
Functions ¶
func Locals ¶
Locals is a template helper function that creates a map[string]any from a sequence of key-value pairs. This is useful for passing named arguments to templates. The arguments must be in pairs, e.g., `locals "key1", "value1", "key2", 2`.
func References ¶ added in v1.0.4
References is a template helper function that creates a map[string]any from a sequence of key-value pairs. Unlike Locals, it ensures that every value in the map is a pointer. If a value is already a pointer, it is used as is. If it is not a pointer, a new pointer to the value is created.
Types ¶
type LayoutContextKey ¶
type LayoutContextKey struct{}
LayoutContextKey is the key used to store and retrieve the desired layout name from a request's context. A middleware can set this value to dynamically change the layout for a request.
type Option ¶ added in v1.0.4
type Option func(*Templates)
Option defines a functional option for configuring the Templates engine.
func WithDisableSafeHTML ¶ added in v1.0.5
WithDisableSafeHTML enables or disables the use of safehtml/template. When disabled, the standard library's text/template is used for literal output.
func WithDisableTrustedLog ¶ added in v1.0.5
WithDisableTrustedLog enables or disables INFO logs for trusted helpers.
func WithFileSystem ¶ added in v1.0.4
WithFileSystem sets the filesystem and root path for templates. The rootPath argument specifies the directory within the filesystem where templates are stored. If fs is nil, it uses the OS filesystem rooted at the given path.
func WithFuncMap ¶ added in v1.0.4
WithFuncMap adds custom functions to the template engine.
func WithLogger ¶ added in v1.0.4
WithLogger sets a custom logger.
func WithReload ¶ added in v1.0.4
WithReload enables or disables always reloading parsing templates on execution.
type Templates ¶
type Templates struct {
// If true, templates will be re-parsed on every ExecuteTemplate call.
// This is highly recommended for development to see changes without restarting
// the application, but should be disabled in production for performance.
AlwaysReloadAndParseTemplates bool
// If true, disables the use of safehtml/template and uses standard text/template instead.
// This is useful for rapid prototyping or for projects where safehtml is not required.
// When true, NO auto-escaping occurs, and trusted_* functions return objects as-is.
DisableSafeHTML bool
// If true, suppresses the INFO log message normally generated when a
// trusted_*_ctx helper function is used.
DisableTrustedLog bool
// The name of the default layout file (without extension) to use when a
// layout is not explicitly specified in the template name.
// Defaults to "application".
DefaultLayout string
// The file extension for template files. Defaults to ".gohtml".
TemplateFileExtension string
// The trusted source path for templates, used by the underlying safehtml/template
// library for security checks.
TemplatesPath template.TrustedSource
// The subdirectory within the templates path for layout files.
// Defaults to "layouts".
LayoutsPath string
// The subdirectory within the templates path for page files.
// Defaults to "pages".
PagesPath string
// The subdirectory within the templates path for reusable block files.
// Defaults to "blocks".
BlocksPath string
// If true, automatically adds helper functions like `d_block`, `locals`,
// `references` and `trusted_*` to the template function map. Defaults to true.
AddHeadlessCMSFuncMapHelpers bool
// The logger to use for internal errors and debug messages.
// Defaults to slog.Default().
Logger *slog.Logger
// contains filtered or unexported fields
}
Templates is the core engine for managing, parsing, and executing templates. It holds the parsed templates, configuration, and the underlying filesystem.
func New ¶
New creates a new Templates instance configured with the provided options.
By default, it looks for templates in "files/templates" within the OS filesystem. You can change this using `WithFileSystem` or `WithRoot`.
func (*Templates) AddDynamicBlockCtxToFuncMap ¶ added in v1.0.4
func (t *Templates) AddDynamicBlockCtxToFuncMap()
AddDynamicBlockCtxToFuncMap adds 'd_block_ctx' to the FuncMap.
func (*Templates) AddDynamicBlockToFuncMap ¶
func (t *Templates) AddDynamicBlockToFuncMap()
AddDynamicBlockToFuncMap adds the 'd_block' function to the FuncMap. This powerful helper allows templates to render blocks dynamically by name, which is ideal for pages whose structure is determined by an API response (e.g., from a headless CMS). Usage in template: `{{ d_block "block_name_from_variable" .Data }}`
func (*Templates) AddFuncMapHelpers ¶
func (t *Templates) AddFuncMapHelpers()
AddFuncMapHelpers populates the template function map with the default helpers if `AddHeadlessCMSFuncMapHelpers` is true. It will panic if a function name is already in use.
func (*Templates) AddLocalsToFuncMap ¶
func (t *Templates) AddLocalsToFuncMap()
AddLocalsToFuncMap adds the 'locals' function to the FuncMap. This helper provides a convenient way to create a `map[string]any` inside a template, which is useful for passing structured data to blocks. Usage: `{{ block "_myblock" (locals "key1" "value1" "key2" 2) }}`
func (*Templates) AddReferencesToFuncMap ¶ added in v1.0.4
func (t *Templates) AddReferencesToFuncMap()
AddReferencesToFuncMap adds the 'references' function to the FuncMap. This helper provides a convenient way to create a `map[string]any` inside a template, where all values are pointers. Usage: `{{ block "_myblock" (references "key1" "value1" "key2" 2) }}`
func (*Templates) ExecuteTemplate ¶
func (t *Templates) ExecuteTemplate(w io.Writer, r *http.Request, templateName string, data interface{}) error
ExecuteTemplate renders a template by name to the given writer.
The `templateName` parameter supports several syntaxes:
- "page_name": Renders the page within the default layout (or a layout from context).
- "layout_name:page_name": Renders the page within a specific layout.
- ":page_name": Renders the page without any layout.
- "_block_name": Renders a specific block by itself.
Parameters:
- w: The io.Writer to write the output to (e.g., an http.ResponseWriter).
- r: The *http.Request for the current request. Can be nil, but if provided, the engine will check its context for a LayoutContextKey to override the layout.
- templateName: The name of the template to execute.
- data: The data to pass to the template.
func (*Templates) ExecuteTemplateAsText ¶
func (t *Templates) ExecuteTemplateAsText(r *http.Request, templateName string, data interface{}) (string, error)
ExecuteTemplateAsText is a testing helper that renders a template to a string.
func (*Templates) GetParsedTemplates ¶
GetParsedTemplates returns a sorted slice of the names of all parsed templates. This is primarily intended for debugging and testing purposes.
func (*Templates) HandlerRenderWithData ¶
func (t *Templates) HandlerRenderWithData(templateName string, data interface{}) func(w http.ResponseWriter, r *http.Request)
HandlerRenderWithData returns a http.HandlerFunc that renders a template with the provided static data.
func (*Templates) HandlerRenderWithDataFromContext ¶
func (t *Templates) HandlerRenderWithDataFromContext(templateName string, contextKey interface{}) func(w http.ResponseWriter, r *http.Request)
HandlerRenderWithDataFromContext returns a http.HandlerFunc that renders a template, taking its data from the request's context via the provided context key.
func (*Templates) MustParseTemplates ¶
func (t *Templates) MustParseTemplates()
MustParseTemplates parses all template files from the configured filesystem. It will panic if any error occurs during parsing, making it suitable for application initialization.
func (*Templates) ParseTemplates ¶
ParseTemplates reads and parses all template files from the configured layouts, pages, and blocks directories. It populates the internal template map. This method is safe for concurrent use.
func (*Templates) RenderBlockAsHTMLString ¶
RenderBlockAsHTMLString renders a specific block to a safehtml.HTML string (or raw string if safehtml is disabled). This is useful for rendering partials inside other logic. The block name must start with an underscore "_".
func (*Templates) RenderBlockAsHTMLStringWithContext ¶ added in v1.0.4
func (t *Templates) RenderBlockAsHTMLStringWithContext(ctx context.Context, blockname string, payload interface{}) (any, error)
RenderBlockAsHTMLStringWithContext renders a block to HTML string and logs errors with the provided context. Registered as 'd_block_ctx'.