pub struct TemplateRegistry { /* private fields */ }Expand description
Registry for template resolution from multiple sources.
The registry maintains a unified view of templates from:
- Inline strings (highest priority)
- Multiple filesystem directories
- Embedded content (for release builds)
§Resolution Order
When looking up a template name:
- Check inline templates first
- Check file-based templates in registration order
- Return error if not found
§Thread Safety
The registry is not thread-safe. For concurrent access, wrap in appropriate synchronization primitives.
§Example
let mut registry = TemplateRegistry::new();
// Add inline template (highest priority)
registry.add_inline("header", "{{ title }}");
// Add from directory
registry.add_template_dir("./templates")?;
// Resolve and get content
let content = registry.get_content("header")?;Implementations§
Source§impl TemplateRegistry
impl TemplateRegistry
Sourcepub fn add_inline(
&mut self,
name: impl Into<String>,
content: impl Into<String>,
)
pub fn add_inline( &mut self, name: impl Into<String>, content: impl Into<String>, )
Adds an inline template with the given name.
Inline templates have the highest priority and will shadow any file-based templates with the same name.
§Arguments
name- The template name for resolutioncontent- The template content
§Example
registry.add_inline("header", "{{ title | style(\"title\") }}");Sourcepub fn add_template_dir<P: AsRef<Path>>(
&mut self,
path: P,
) -> Result<(), RegistryError>
pub fn add_template_dir<P: AsRef<Path>>( &mut self, path: P, ) -> Result<(), RegistryError>
Adds a template directory to search for files.
Templates in the directory are resolved by their relative path without
extension. For example, with directory ./templates:
"config"→./templates/config.jinja"todos/list"→./templates/todos/list.jinja
§Errors
Returns an error if the directory doesn’t exist.
Sourcepub fn add_from_files(
&mut self,
files: Vec<TemplateFile>,
) -> Result<(), RegistryError>
pub fn add_from_files( &mut self, files: Vec<TemplateFile>, ) -> Result<(), RegistryError>
Adds templates discovered from a directory scan.
This method processes a list of TemplateFile entries, typically
produced by walk_template_dir, and registers them for resolution.
§Resolution Names
Each file is registered under two names:
- Without extension:
"config"forconfig.jinja - With extension:
"config.jinja"forconfig.jinja
§Extension Priority
If multiple files share the same base name with different extensions
(e.g., config.jinja and config.j2), the higher-priority extension wins
for the extensionless name. Both can still be accessed by full name.
§Collision Detection
If a template name conflicts with one from a different source directory, an error is returned with details about both files.
§Arguments
files- Template files discovered during directory walking
§Errors
Returns RegistryError::Collision if templates from different
directories resolve to the same name.
Sourcepub fn add_embedded(&mut self, templates: HashMap<String, String>)
pub fn add_embedded(&mut self, templates: HashMap<String, String>)
Adds pre-embedded templates (for release builds).
Embedded templates are treated as inline templates, stored directly in memory without filesystem access.
§Arguments
templates- Map of template name to content
Sourcepub fn add_framework(
&mut self,
name: impl Into<String>,
content: impl Into<String>,
)
pub fn add_framework( &mut self, name: impl Into<String>, content: impl Into<String>, )
Adds framework templates (lowest priority fallback).
Framework templates are provided by the standout framework and serve as defaults that can be overridden by user templates with the same name. They are checked last during resolution.
Framework templates typically use the standout/ namespace to avoid
accidental collision with user templates (e.g., standout/list-view).
§Arguments
name- The template name (e.g.,"standout/list-view")content- The template content
§Example
registry.add_framework("standout/list-view", include_str!("templates/list-view.jinja"));Sourcepub fn add_framework_entries(&mut self, entries: &[(&str, &str)])
pub fn add_framework_entries(&mut self, entries: &[(&str, &str)])
Adds multiple framework templates from embedded entries.
This is similar to [from_embedded_entries] but adds templates to the
framework (lowest priority) tier instead of inline (highest priority).
§Arguments
entries- Slice of(name_with_ext, content)pairs
Sourcepub fn clear_framework(&mut self)
pub fn clear_framework(&mut self)
Clears all framework templates.
This is useful when you want to disable all framework-provided defaults and require explicit template configuration.
Sourcepub fn from_embedded_entries(entries: &[(&str, &str)]) -> Self
pub fn from_embedded_entries(entries: &[(&str, &str)]) -> Self
Creates a registry from embedded template entries.
This is the primary entry point for compile-time embedded templates,
typically called by the embed_templates! macro.
§Arguments
entries- Slice of(name_with_ext, content)pairs wherename_with_extis the relative path including extension (e.g.,"report/summary.jinja")
§Processing
This method applies the same logic as runtime file loading:
- Extension stripping:
"report/summary.jinja"→"report/summary" - Extension priority: When multiple files share a base name, the
higher-priority extension wins (see
TEMPLATE_EXTENSIONS) - Dual registration: Each template is accessible by both its base name and its full name with extension
§Example
use standout::TemplateRegistry;
// Typically generated by embed_templates! macro
let entries: &[(&str, &str)] = &[
("list.jinja", "Hello {{ name }}"),
("report/summary.jinja", "Report: {{ title }}"),
];
let registry = TemplateRegistry::from_embedded_entries(entries);
// Access by base name or full name
assert!(registry.get("list").is_ok());
assert!(registry.get("list.jinja").is_ok());
assert!(registry.get("report/summary").is_ok());Sourcepub fn get(&self, name: &str) -> Result<ResolvedTemplate, RegistryError>
pub fn get(&self, name: &str) -> Result<ResolvedTemplate, RegistryError>
Looks up a template by name.
Names can be specified with or without extension:
"config"resolves toconfig.jinja(or highest-priority extension)"config.jinja"resolves to exactly that file
§Resolution Priority
Templates are resolved in this order:
- Inline templates (highest priority)
- File-based templates from
add_from_files - Directory-based templates from
add_template_dir - Framework templates (lowest priority)
This allows user templates to override framework defaults.
§Errors
Returns RegistryError::NotFound if the template doesn’t exist.
Sourcepub fn get_content(&self, name: &str) -> Result<String, RegistryError>
pub fn get_content(&self, name: &str) -> Result<String, RegistryError>
Gets the content of a template, reading from disk if necessary.
For inline templates, returns the stored content directly. For file templates, reads the file from disk (enabling hot reload).
§Errors
Returns an error if the template is not found or cannot be read from disk.
Sourcepub fn refresh(&mut self) -> Result<(), RegistryError>
pub fn refresh(&mut self) -> Result<(), RegistryError>
Refreshes the registry from registered directories.
This re-walks all registered template directories and rebuilds the resolution map. Call this if:
- You’ve added template directories after the first render
- Template files have been added/removed from disk
§Panics
Panics if a collision is detected (same name from different directories).
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of registered templates.
Note: This counts both extensionless and with-extension entries, so it may be higher than the number of unique template files.
Sourcepub fn names(&self) -> impl Iterator<Item = &str>
pub fn names(&self) -> impl Iterator<Item = &str>
Returns an iterator over all registered template names.
Sourcepub fn has_framework_templates(&self) -> bool
pub fn has_framework_templates(&self) -> bool
Returns true if the registry has framework templates.
Sourcepub fn framework_names(&self) -> impl Iterator<Item = &str>
pub fn framework_names(&self) -> impl Iterator<Item = &str>
Returns an iterator over framework template names.
Trait Implementations§
Source§impl Default for TemplateRegistry
impl Default for TemplateRegistry
Source§impl From<EmbeddedSource<TemplateResource>> for TemplateRegistry
impl From<EmbeddedSource<TemplateResource>> for TemplateRegistry
Source§fn from(source: EmbeddedTemplates) -> Self
fn from(source: EmbeddedTemplates) -> Self
Converts embedded templates into a TemplateRegistry.
In debug mode, if the source path exists, templates are loaded from disk (enabling hot-reload). Otherwise, embedded content is used.