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))] #[cfg_attr(feature = "json", macro_reexport(json_internal))]
extern crate serde_json; extern crate serde_json;
#[cfg(feature = "handlebars_templates")]
pub extern crate handlebars;
#[cfg(feature = "tera_templates")]
pub extern crate tera;
#[cfg(feature = "json")] #[cfg(feature = "json")]
#[cfg_attr(feature = "json", macro_use)] #[cfg_attr(feature = "json", macro_use)]
#[doc(hidden)] #[doc(hidden)]

View File

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

View File

@ -158,9 +158,35 @@ impl Template {
/// } /// }
/// ``` /// ```
pub fn fairing() -> impl Fairing { pub fn fairing() -> impl Fairing {
AdHoc::on_attach(|rocket| { Template::custom(|_| {})
let mut template_root = rocket.config() }
.root_relative(DEFAULT_TEMPLATE_DIR);
/// 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") { match rocket.config().get_str("template_dir") {
Ok(dir) => template_root = rocket.config().root_relative(dir), Ok(dir) => template_root = rocket.config().root_relative(dir),
@ -172,7 +198,10 @@ impl Template {
}; };
match Context::initialize(template_root) { 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) None => Err(rocket)
} }
}) })

View File

@ -10,6 +10,7 @@ extern crate rocket;
use rocket::Request; use rocket::Request;
use rocket::response::Redirect; use rocket::response::Redirect;
use rocket_contrib::Template; use rocket_contrib::Template;
use rocket_contrib::handlebars::{Helper, Handlebars, RenderContext, RenderError, JsonRender};
#[derive(Serialize)] #[derive(Serialize)]
struct TemplateContext { struct TemplateContext {
@ -42,7 +43,21 @@ fn not_found(req: &Request) -> Template {
fn rocket() -> rocket::Rocket { fn rocket() -> rocket::Rocket {
rocket::ignite() rocket::ignite()
.mount("/", routes![index, get]) .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]) .catch(catchers![not_found])
} }

View File

@ -14,5 +14,6 @@
</ul> </ul>
<p>Try going to <a href="/hello/YourName">/hello/YourName</a></p> <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> </body>
</html> </html>