Struct Tera

pub struct Tera { /* private fields */ }

Main point of interaction in this library.

The Tera struct is the primary interface for working with the Tera template engine. It contains parsed templates, registered filters (which can filter data), functions, and testers. It also contains some configuration options, such as a list of suffixes for files that have autoescaping turned on.

It is responsible for:

Example

Basic usage:

use tera::Tera;

let mut tera = Tera::default();
tera.add_raw_template("hello", "Hello, {{ name }}!").unwrap();

// Prepare the context with some data
let mut context = tera::Context::new();
context.insert("name", "World");

// Render the template with the given context
let rendered = tera.render("hello", &context).unwrap();
assert_eq!(rendered, "Hello, World!");

Implementations

impl Tera

fn new() -> Self

Create a new instance of Tera. Equivalent of Tera::default().

fn autoescape_on(&mut self, suffixes: impl IntoIterator<Item = impl Into<Cow<'static, str>>>)

Select which suffix(es) to automatically do HTML escaping on.

By default, autoescaping is performed on .html, .htm and .xml template files. Only call this function if you wish to change the defaults.

Examples

Basic usage:

# use tera::Tera;
let mut tera = Tera::default();
// escape only files ending with `.php.html`
tera.autoescape_on([".php.html"]);
// disable autoescaping completely
tera.autoescape_on(Vec::<&str>::new());
fn set_delimiters(&mut self, delimiters: Delimiters) -> TeraResult<()>

Set custom delimiters for template syntax.

This must be called before adding any templates. Returns an error if any delimiter is empty, if start delimiters conflict or if there are already templates added to the Tera instance.

Example

use tera::{Tera, Delimiters};

let mut tera = Tera::new();
tera.set_delimiters(Delimiters {
    block_start: "<%".into(),
    block_end: "%>".into(),
    variable_start: "<<".into(),
    variable_end: ">>".into(),
    comment_start: "<#".into(),
    comment_end: "#>".into(),
}).unwrap();
tera.add_raw_template("example", "<< name >>").unwrap();
fn set_escape_fn(&mut self, function: EscapeFn)

Set user-defined function that is used to escape content.

Often times, arbitrary data needs to be injected into a template without allowing injection attacks. For this reason, typically escaping is performed on all input. By default, the escaping function will produce HTML escapes, but it can be overridden to produce escapes more appropriate to the language being used.

Inside templates, escaping can be turned off for specific content using the safe filter. For example, the string {{ data }} inside a template will escape data, while {{ data | safe }} will not.

Examples

Basic usage:

# use tera::{Tera, Context};
# use std::io::Write;
// Create new Tera instance
let mut tera = Tera::default();

// Override escape function to escape the letter A, why not
tera.set_escape_fn(|input: &str, output: &mut dyn Write| {
    for byte in input.bytes() {
        match byte {
            b'a' => output.write_all(b"?")?,
            _ => output.write_all(&[byte])?,
        }
    }
    Ok(())
});

// Create template and enable autoescape
tera.add_raw_template("hello.js", "const data = \"{{ content }}\";").unwrap();
tera.autoescape_on(vec!["js"]);

// Create context with some data
let mut context = Context::new();
context.insert("content", &r#"Hello tera"#);

// Render template
let result = tera.render("hello.js", &context).unwrap();
assert_eq!(result, r#"const data = "Hello ter?";"#);
fn reset_escape_fn(&mut self)

Reset escape function to default [escape_html()].

fn register_filter<Func, Arg, Res>(&mut self, name: impl Into<Cow<'static, str>>, filter: Func)
where
    Func: Filter<Arg, Res> + for<'a> Filter<<Arg as ArgFromValue<'a>>::Output, Res>,
    Arg: for<'a> ArgFromValue<'a>,
    Res: FunctionResult,

Register a filter with Tera.

If a filter with that name already exists, it will be overwritten

# use tera::{Tera, Kwargs, State};
let mut tera = Tera::default();
tera.register_filter("double", |x: i64, _: Kwargs, _: &State| x * 2);
fn register_test<Func, Arg, Res>(&mut self, name: impl Into<Cow<'static, str>>, test: Func)
where
    Func: Test<Arg, Res> + for<'a> Test<<Arg as ArgFromValue<'a>>::Output, Res>,
    Arg: for<'a> ArgFromValue<'a>,
    Res: TestResult,

Register a test with Tera.

If a test with that name already exists, it will be overwritten

# use tera::{Tera, Kwargs, State};
let mut tera = Tera::default();
tera.register_test("odd", |x: i64, _: Kwargs, _: &State| x % 2 != 0);
fn register_function<Func, Res>(&mut self, name: impl Into<Cow<'static, str>>, func: Func)
where
    Func: Function<Res>,
    Res: FunctionResult,

Register a function with Tera.

If a function with that name already exists, it will be overwritten

fn register_from(&mut self, other: &Tera)

Register filters, tests, and functions from another Tera instance.

If a filter/test/function with the same name already exists in this instance, it will not be overwritten.

fn get_template_variables(&self, template_name: &str) -> TeraResult<HashSet<&str>>

Does a best-effort to find the top level variables that might be needed to be provided to render the template.

This doesn't do a full analysis and just reports all top level variables that were found. It doesn't care about if statements etc.

fn get_component_definition(&self, name: &str) -> Option<ComponentInfo>

Returns information about a registered component definition.

Returns None if no component with the given name is found.

Examples

# use tera::Tera;
let mut tera = Tera::default();
tera.add_raw_template(
    "components.html",
    r#"{% component Button(label: String, variant="primary") %}<button>{{ label }}</button>{% endcomponent Button %}"#,
).unwrap();

let info = tera.get_component_definition("Button").unwrap();
assert_eq!(info.name(), "Button");
assert_eq!(info.args().len(), 2);
fn contains_component(&self, component_name: &str) -> bool

Lookups a component by name, returning whether it's found or not Returns false if no component with the given name is found.

Examples

# use tera::Tera;
let mut tera = Tera::default();
tera.add_raw_template(
    "components.html",
    r#"{% component Button(label: String, variant="primary") %}<button>{{ label }}</button>{% endcomponent Button %}"#,
).unwrap();

assert!(tera.contains_component("Button"));
fn get_component_names(&self) -> impl Iterator<Item = &str>

Returns an iterator over the names of all registered components in an unspecified order.

Example

use tera::Tera;

let mut tera = Tera::default();
tera.add_raw_template("foo", "{% component hello(name) %}{{ name }}{% endcomponent %}");

let names: Vec<_> = tera.get_component_names().collect();
assert_eq!(names.len(), 1);
assert!(names.contains(&"hello"));
fn add_raw_template(&mut self, name: &str, content: &str) -> TeraResult<()>

Add a single template to the Tera instance.

This will error if there are errors in the inheritance, such as adding a child template without the parent one.

Bulk loading

If you want to add several templates, use add_raw_templates().

Examples

Basic usage:

# use tera::Tera;
let mut tera = Tera::default();
tera.add_raw_template("new.html", "Blabla").unwrap();
fn add_raw_templates<I, N, C>(&mut self, templates: I) -> TeraResult<()>
where
    I: IntoIterator<Item = (N, C)>,
    N: AsRef<str>,
    C: AsRef<str>,

Add all the templates given to the Tera instance

This will error if there are errors in the inheritance, such as adding a child template without the parent one.

# use tera::Tera;
let mut tera = Tera::default();
tera.add_raw_templates(vec![
    ("new.html", "blabla"),
    ("new2.html", "hello"),
]).unwrap();
fn add_template_file<P: AsRef<Path>>(&mut self, path: P, name: Option<&str>) -> TeraResult<()>

Add a single template from a path to the Tera instance. The default name for the template is the path given, but this can be renamed with the name parameter

This will error if the inheritance chain can't be built, such as adding a child template without the parent one. If you want to add several file, use Tera::add_template_files

# use tera::Tera;
let mut tera = Tera::default();
// Rename template with custom name
tera.add_template_file("path/to/template.html", Some("template.html")).unwrap();
// Use path as name
tera.add_template_file("path/to/other.html", None).unwrap();
fn add_template_files<I, P, N>(&mut self, files: I) -> TeraResult<()>
where
    I: IntoIterator<Item = (P, Option<N>)>,
    P: AsRef<Path>,
    N: AsRef<str>,

Add several templates from paths to the Tera instance.

The default name for the template is the path given, but this can be renamed with the second parameter of the tuple

This will error if the inheritance chain can't be built, such as adding a child template without the parent one.

# use tera::Tera;
let mut tera = Tera::default();
tera.add_template_files(vec![
    ("./path/to/template.tera", None), // this template will have the value of path1 as name
    ("./path/to/other.tera", Some("hey")), // this template will have `hey` as name
]);
fn set_fallback_prefixes(&mut self, prefixes: impl IntoIterator<Item = impl Into<Cow<'static, str>>>) -> TeraResult<()>

Set fallback prefixes to try when a template is not found by exact name. This needs to be called before adding templates, it will error otherwise.

When a template is requested (via render, extends, or include) and the exact name is not found, these prefixes are tried in order. The first prefix that produces a match is used.

Prefixes should include any path separator (e.g., "themes/cool/" not "themes/cool").

Example

# use tera::Tera;
let mut tera = Tera::default();
// Templates in "themes/cool/" can be referenced without the prefix
tera.set_fallback_prefixes(["themes/cool/"]).unwrap();
fn contains_template(&self, template_name: &str) -> bool

Lookups a template by name, resolving fallback prefixes if needed, returning whether it's found or not

fn get_template_names(&self) -> impl Iterator<Item = &str>

Returns an iterator over the names of all registered templates in an unspecified order.

Example

use tera::Tera;

let mut tera = Tera::default();
tera.add_raw_template("foo", "{{ hello }}");
tera.add_raw_template("another-one.html", "contents go here");

let names: Vec<_> = tera.get_template_names().collect();
assert_eq!(names.len(), 2);
assert!(names.contains(&"foo"));
assert!(names.contains(&"another-one.html"));
fn render(&self, template_name: &str, context: &Context) -> TeraResult<String>

Renders a Tera template given a Context.

Examples

Basic usage:

# use tera::{Tera, Context};
// Create new tera instance with sample template
let mut tera = Tera::default();
tera.add_raw_template("info", "My age is {{ age }}.");

// Create new context
let mut context = Context::new();
context.insert("age", &18);

// Render template using the context
let output = tera.render("info", &context).unwrap();
assert_eq!(output, "My age is 18.");

To render a template with no context, simply pass a [Context::new()] object.

# use tera::{Tera, Context};
// Create new tera instance with demo template
let mut tera = Tera::default();
tera.add_raw_template("hello.html", "<h1>Hello</h1>");

// Render a template with an empty context
let output = tera.render("hello.html", &Context::new()).unwrap();
assert_eq!(output, "<h1>Hello</h1>");
fn render_to(&self, template_name: &str, context: &Context, write: impl Write) -> TeraResult<()>

Renders a Tera template given a Context to something that implements Write.

The only difference from render() is that this version doesn't convert buffer to a String, allowing to render directly to anything that implements Write. For example, this could be used to write directly to a File.

Any I/O error will be reported in the result.

Examples

Rendering into a Vec<u8>:

# use tera::{Context, Tera};
let mut tera = Tera::default();
tera.add_raw_template("index.html", "<p>{{ name }}</p>");

// Rendering a template to an internal buffer
let mut buffer = Vec::new();
let mut context = Context::new();
context.insert("name", "John Wick");
tera.render_to("index.html", &context, &mut buffer).unwrap();
assert_eq!(buffer, b"<p>John Wick</p>");
fn global_context(&mut self) -> &mut Context

Returns the global context, allowing modifications to it

The global context is automatically included into every template, which is useful for sharing common data.

The global context is not passed if you call render_component.

# use tera::{Tera, Context, context};
let mut tera = Tera::new();
tera.global_context().insert("name", "John Doe");

let content = tera
    .render_str("Hello, {{ name }}!", &Context::new(), false)
    .unwrap();
assert_eq!(content, "Hello, John Doe!".to_string());

let content2 = tera
    .render_str(
        "UserID: {{ id }}, Username: {{ name }}",
        &context! { id => &7489 },
        false,
    )
    .unwrap();
assert_eq!(content2, "UserID: 7489, Username: John Doe");
fn render_str(&self, input: &str, context: &Context, autoescape: bool) -> TeraResult<String>

Renders a one-off template (for example a template coming from a user input) given a Context and using this Tera instance's filters, tests, functions and components.

The only limitation is that it cannot use {% extends %} and therefore blocks.

Any errors will mention the __tera_one_off template: this is the name given to the template by Tera.

# use tera::{Tera, Context, context};
let tera = Tera::new();
let result = tera.render_str(
    "Hello {{ name }}!",
    &context! { name => "world" },
    false,
).unwrap();
assert_eq!(result, "Hello world!");
fn render_str_to(&self, input: &str, context: &Context, autoescape: bool, write: impl Write) -> TeraResult<()>

Renders a one-off template to a writer.

Same as render_str but writes to a Write implementor.

fn one_off(input: &str, context: &Context, autoescape: bool) -> TeraResult<String>

Renders a one off template (for example a template coming from a user input) given a Context

This creates a separate instance of Tera with no possibilities of adding custom filters or testers, parses the template and renders it immediately. Any errors will mention the __tera_one_off template: this is the name given to the template by Tera

# use tera::{Context, Tera};
let mut context = Context::new();
context.insert("greeting", &"hello");
let result = Tera::one_off("{{ greeting }} world", &context, true).unwrap();
assert_eq!(result, "hello world");
fn render_component(&self, component_name: &str, context: &Context, body: Option<&str>, autoescape: bool) -> TeraResult<String>

Renders a component by name with the given context and optional body content.

The context should contain the component's arguments as key-value pairs.

Examples

# use tera::{Tera, Context, context};
let mut tera = Tera::default();
tera.add_raw_template(
    "components.html",
    r#"{% component Button(label) %}<button>{{ label }}</button>{% endcomponent Button %}
{% component Card(title) %}<div><h1>{{ title }}</h1>{{ body }}</div>{% endcomponent Card %}"#,
).unwrap();

// Render a component with arguments
let html = tera.render_component(
    "Button",
    &context! { label => "Click me" },
    None,
    true,
).unwrap();
assert_eq!(html, "<button>Click me</button>");

// Render a component with body content
let html = tera.render_component(
    "Card",
    &context! { title => "My Card" },
    Some("<p>Card content here</p>"),
    true,
).unwrap();
assert_eq!(html, "<div><h1>My Card</h1><p>Card content here</p></div>");
fn render_component_to(&self, component_name: &str, context: &Context, body: Option<&str>, autoescape: bool, write: impl Write) -> TeraResult<()>

Renders a component by name to something that implements Write.

Same as render_component but writes to a Write implementor instead of returning a String.

Examples

# use tera::{Tera, Context, context};
let mut tera = Tera::default();
tera.add_raw_template(
    "components.html",
    r#"{% component Button(label) %}<button>{{ label }}</button>{% endcomponent Button %}"#,
).unwrap();

let mut buffer = Vec::new();
tera.render_component_to(
    "Button",
    &context! { label => "Click me" },
    None,
    true,
    &mut buffer,
).unwrap();
assert_eq!(buffer, b"<button>Click me</button>");
fn render_block(&self, template_name: &str, block_name: &str, context: &Context) -> TeraResult<String>

Renders a block by name with the given context.

Examples

# use tera::{Tera, Context};
// Create new tera instance with demo template
let mut tera = Tera::default();
tera.add_raw_template("hello.html", "<h1>Hello</h1>{% block content %}in block{% endblock %}");

// Render a template with an empty context
let output = tera.render_block("hello.html", "content", &Context::new()).unwrap();
assert_eq!(output, "in block");
fn render_block_to(&self, template_name: &str, block_name: &str, context: &Context, write: impl Write) -> TeraResult<()>

Renders a block by name with the given context to something that implements Write.

Examples

# use tera::{Tera, Context};
let mut tera = Tera::default();
tera.add_raw_template("hello.html", "<h1>Hello</h1>{% block content %}in block{% endblock %}");

let mut buffer = Vec::new();
tera.render_block_to("hello.html", "content", &Context::new(), &mut buffer).unwrap();
assert_eq!(buffer, b"in block");

Trait Implementations

impl Clone for Tera

fn clone(&self) -> Self

impl Debug for Tera

fn fmt(&self, f: &mut Formatter<'_>) -> Result

impl Default for Tera

fn default() -> Self

Auto Trait Implementations

impl !RefUnwindSafe for Tera

impl !UnwindSafe for Tera

impl Freeze for Tera

impl Send for Tera

impl Sync for Tera

impl Unpin for Tera

impl UnsafeUnpin for Tera

Blanket Implementations

impl<T> Any for Tera where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

impl<T> Borrow<T> for Tera where T: ?Sized,

fn borrow(&self) -> &T

impl<T> BorrowMut<T> for Tera where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

impl<T> CloneToUninit for Tera where T: Clone,

unsafe fn clone_to_uninit(&self, dest: *mut u8)

impl<T> From<T> for Tera

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> ToOwned for Tera where T: Clone,

type Owned = T;
fn to_owned(&self) -> T
fn clone_into(&self, target: &mut T)

impl<T, U> Into<U> for Tera where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom<U> for Tera where U: Into<T>,

type Error = never;
fn try_from(value: U) -> Result<T, never>

impl<T, U> TryInto<U> for Tera where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error;
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>