Improve documentation on accessing templating engines.

This commit is contained in:
Sergio Benitez 2017-12-28 22:55:17 -08:00
parent 9f9971f4cf
commit f7e5c105ee
3 changed files with 83 additions and 20 deletions

View File

@ -73,7 +73,7 @@ pub use msgpack::{MsgPack, MsgPackError};
mod templates;
#[cfg(feature = "templates")]
pub use templates::Template;
pub use templates::{Template, Engines};
#[cfg(feature = "uuid")]
mod uuid;

View File

@ -13,20 +13,61 @@ pub trait Engine: Send + Sync + 'static {
fn render<C: Serialize>(&self, name: &str, context: C) -> Option<String>;
}
/// A structure exposing access to templating engines.
///
/// Calling methods on the exposed template engine types may require importing
/// types from the respective templating engine library. These types should be
/// imported from the reexported crate at the root of `rocket_contrib` to avoid
/// version mismatches. For instance, when registering a Tera filter, the
/// [`tera::Value`] and [`tera::Result`] types are required. Import them from
/// `rocket_contrib::tera`. The example below illustrates this:
///
/// ```rust
/// use std::collections::HashMap;
///
/// use rocket_contrib::{Template, Engines};
/// use rocket_contrib::tera::{self, Value};
///
/// fn my_filter(value: Value, _: HashMap<String, Value>) -> tera::Result<Value> {
/// # /*
/// ...
/// # */ unimplemented!();
/// }
///
/// Template::custom(|engines: &mut Engines| {
/// engines.tera.register_filter("my_filter", my_filter);
/// });
/// ```
///
/// [`tera::Value`]: https://docs.rs/tera/0.10.10/tera/enum.Value.html
/// [`tera::Result`]: https://docs.rs/tera/0.10.10/tera/type.Result.html
pub struct Engines {
#[cfg(feature = "tera_templates")]
/// A [`Tera`] structure. This field is only available when the
/// `tera_templates` feature is enabled. When calling methods on the `Tera`
/// instance, ensure you use types imported from `rocket_contrib::tera` to
/// avoid version mismatches.
///
/// [`Tera`]: https://docs.rs/tera/0.10.10/tera/struct.Tera.html
pub tera: Tera,
/// A [`Handlebars`] structure. This field is only available when the
/// `handlebars_templates` feature is enabled. When calling methods on the
/// `Tera` instance, ensure you use types
/// imported from `rocket_contrib::handlebars` to avoid version mismatches.
///
/// [`Handlebars`]:
/// https://docs.rs/handlebars/0.29.1/handlebars/struct.Handlebars.html
#[cfg(feature = "handlebars_templates")]
pub handlebars: Handlebars,
}
impl Engines {
pub const ENABLED_EXTENSIONS: &'static [&'static str] = &[
pub(crate) const ENABLED_EXTENSIONS: &'static [&'static str] = &[
#[cfg(feature = "tera_templates")] Tera::EXT,
#[cfg(feature = "handlebars_templates")] Handlebars::EXT,
];
pub fn init(templates: &HashMap<String, TemplateInfo>) -> Option<Engines> {
pub(crate) fn init(templates: &HashMap<String, TemplateInfo>) -> Option<Engines> {
fn inner<E: Engine>(templates: &HashMap<String, TemplateInfo>) -> Option<E> {
let named_templates = templates.iter()
.filter(|&(_, i)| i.extension == E::EXT)
@ -50,20 +91,23 @@ impl Engines {
})
}
pub fn render<C>(&self, name: &str, info: &TemplateInfo, c: C) -> Option<String>
where C: Serialize
{
pub(crate) fn render<C: Serialize>(
&self,
name: &str,
info: &TemplateInfo,
context: C
) -> Option<String> {
#[cfg(feature = "tera_templates")]
{
if info.extension == Tera::EXT {
return Engine::render(&self.tera, name, c);
return Engine::render(&self.tera, name, context);
}
}
#[cfg(feature = "handlebars_templates")]
{
if info.extension == Handlebars::EXT {
return Engine::render(&self.handlebars, name, c);
return Engine::render(&self.handlebars, name, context);
}
}

View File

@ -7,7 +7,9 @@ extern crate glob;
mod engine;
mod context;
use self::engine::{Engine, Engines};
pub use self::engine::Engines;
use self::engine::Engine;
use self::context::Context;
use self::serde::Serialize;
use self::serde_json::{Value, to_value};
@ -61,11 +63,10 @@ const DEFAULT_TEMPLATE_DIR: &'static str = "templates";
/// extensions should look like: `.html.hbs`, `.html.tera`, `.xml.hbs`, etc.
///
/// Template discovery is actualized by the template fairing, which itself is
/// created via the
/// [`Template::fairing()`](/rocket_contrib/struct.Template.html#method.fairing)
/// method. In order for _any_ templates to be rendered, the template fairing
/// must be [attached](/rocket/struct.Rocket.html#method.attach) to the running
/// Rocket instance.
/// created via the [`Template::fairing()`] or [`Template::custom()`] method. In
/// order for _any_ templates to be rendered, the template fairing _must_ be
/// [attached](/rocket/struct.Rocket.html#method.attach) to the running Rocket
/// instance. Failure to do so will result in an error.
///
/// Templates are rendered with the `render` method. The method takes in the
/// name of a template and a context to render the template with. The context
@ -114,6 +115,15 @@ const DEFAULT_TEMPLATE_DIR: &'static str = "templates";
/// Template::render("index", &context)
/// }
/// ```
///
/// # Customizing
///
/// You can use the [`Template::custom()`] method to construct a fairing with
/// customized templating engines. Among other things, this method allows you to
/// register template helpers and register templates from strings.
///
/// [`Template::custom()`]: /rocket_contrib/struct.Template.html#method.custom
/// [`Template::fairing()`]: /rocket_contrib/struct.Template.html#method.fairing
#[derive(Debug)]
pub struct Template {
name: Cow<'static, str>,
@ -133,10 +143,16 @@ pub struct TemplateInfo {
impl Template {
/// Returns a fairing that intializes and maintains templating state.
///
/// This fairing _must_ be attached to any `Rocket` instance that wishes to
/// render templates. Failure to attach this fairing will result in a
/// "Uninitialized template context: missing fairing." error message when a
/// template is attempted to be rendered.
/// This fairing, or the one returned by [`Template::custom()`], _must_ be
/// attached to any `Rocket` instance that wishes to render templates.
/// Failure to attach this fairing will result in a "Uninitialized template
/// context: missing fairing." error message when a template is attempted to
/// be rendered.
///
/// If you wish to customize the internal templating engines, use
/// [`Template::custom()`] instead.
///
/// [`Template::custom()`]: /rocket_contrib/struct.Template.html#method.custom
///
/// # Example
///
@ -163,8 +179,11 @@ impl Template {
/// Returns a fairing that intializes and maintains templating state.
///
/// This method allows you to configure the template context via the
/// closure.
/// Unlike [`Template::fairing()`], this method allows you to configure
/// templating engines via the parameter `f`. Note that only the enabled
/// templating engines will be accessible from the `Engines` type.
///
/// [`Template::fairing()`]: /rocket_contrib/struct.Template.html#method.fairing
///
/// # Example
///