Add 'Template::custom()' to customize templating engines.

This commit is contained in:
Ning Sun 2017-09-16 13:34:33 +08:00 committed by Sergio Benitez
parent 4be75accf7
commit d79cb9d8f0
5 changed files with 58 additions and 7 deletions

View File

@ -48,6 +48,12 @@ extern crate serde;
#[cfg_attr(feature = "json", macro_reexport(json_internal))]
extern crate serde_json;
#[cfg(feature = "handlebars_templates")]
pub extern crate handlebars;
#[cfg(feature = "tera_templates")]
pub extern crate tera;
#[cfg(feature = "json")]
#[cfg_attr(feature = "json", macro_use)]
#[doc(hidden)]

View File

@ -15,9 +15,9 @@ pub trait Engine: Send + Sync + 'static {
pub struct Engines {
#[cfg(feature = "tera_templates")]
tera: Tera,
pub tera: Tera,
#[cfg(feature = "handlebars_templates")]
handlebars: Handlebars,
pub handlebars: Handlebars,
}
impl Engines {

View File

@ -158,9 +158,35 @@ impl Template {
/// }
/// ```
pub fn fairing() -> impl Fairing {
AdHoc::on_attach(|rocket| {
let mut template_root = rocket.config()
.root_relative(DEFAULT_TEMPLATE_DIR);
Template::custom(|_| {})
}
/// Returns a fairing that intializes and maintains templating state.
///
/// This method allows you to configure the template context via the
/// closure.
///
/// # Example
///
/// ```rust
/// extern crate rocket;
/// extern crate rocket_contrib;
///
/// use rocket_contrib::Template;
///
/// fn main() {
/// rocket::ignite()
/// // ...
/// .attach(Template::custom(|engines| {
/// // engines.handlebars.register_helper ...
/// }))
/// // ...
/// # ;
/// }
/// ```
pub fn custom<F>(f: F) -> impl Fairing where F: Fn(&mut Engines) + Send + Sync + 'static {
AdHoc::on_attach(move |rocket| {
let mut template_root = rocket.config().root_relative(DEFAULT_TEMPLATE_DIR);
match rocket.config().get_str("template_dir") {
Ok(dir) => template_root = rocket.config().root_relative(dir),
@ -172,7 +198,10 @@ impl Template {
};
match Context::initialize(template_root) {
Some(ctxt) => Ok(rocket.manage(ctxt)),
Some(mut ctxt) => {
f(&mut ctxt.engines);
Ok(rocket.manage(ctxt))
}
None => Err(rocket)
}
})

View File

@ -10,6 +10,7 @@ extern crate rocket;
use rocket::Request;
use rocket::response::Redirect;
use rocket_contrib::Template;
use rocket_contrib::handlebars::{Helper, Handlebars, RenderContext, RenderError, JsonRender};
#[derive(Serialize)]
struct TemplateContext {
@ -42,7 +43,21 @@ fn not_found(req: &Request) -> Template {
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![index, get])
.attach(Template::fairing())
.attach(Template::custom(|engines| {
engines.handlebars.register_helper(
"echo", Box::new(|h: &Helper,
_: &Handlebars,
rc: &mut RenderContext| -> Result<(), RenderError> {
if let Some(p0) = h.param(0) {
rc.writer.write(p0.value()
.render()
.into_bytes()
.as_ref())?;
}
Ok(())
}));
}))
.catch(catchers![not_found])
}

View File

@ -14,5 +14,6 @@
</ul>
<p>Try going to <a href="/hello/YourName">/hello/YourName</a></p>
<p>You can define custom helper like <b>{{echo "this"}}</b>.</p>
</body>
</html>