diff --git a/contrib/src/templates/mod.rs b/contrib/src/templates/mod.rs index e8d4888e..9f296f70 100644 --- a/contrib/src/templates/mod.rs +++ b/contrib/src/templates/mod.rs @@ -14,9 +14,9 @@ use self::serde_json::{Value, to_value}; use self::glob::glob; use std::borrow::Cow; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; -use rocket::State; +use rocket::{Rocket, State}; use rocket::request::Request; use rocket::fairing::{Fairing, AdHoc}; use rocket::response::{self, Content, Responder}; @@ -187,7 +187,6 @@ impl Template { pub fn custom(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), Err(ConfigError::NotFound) => { /* ignore missing configs */ } @@ -230,40 +229,55 @@ impl Template { Template { name: name.into(), value: to_value(context).ok() } } - /// Render the template named `name` located at the path `root` with the - /// context `context` into a `String`. This method is _very slow_ and should - /// **not** be used in any running Rocket application. This method should - /// only be used during testing to validate `Template` responses. For other - /// uses, use [`render`](#method.render) instead. + /// Render the template named `name` with the context `context` into a + /// `String`. This method should **not** be used in any running Rocket + /// application. This method should only be used during testing to + /// validate `Template` responses. For other uses, use + /// [`render`](#method.render) instead. /// /// The `context` can be of any type that implements `Serialize`. This is - /// typically a `HashMap` or a custom `struct`. The path `root` can be - /// relative, in which case it is relative to the current working directory, - /// or absolute. + /// typically a `HashMap` or a custom `struct`. /// /// Returns `Some` if the template could be rendered. Otherwise, returns /// `None`. If rendering fails, error output is printed to the console. + /// `None` is also returned if a `Template` fairing has not been attached. /// /// # Example /// /// ```rust + /// # extern crate rocket; + /// # extern crate rocket_contrib; /// use std::collections::HashMap; + /// /// use rocket_contrib::Template; + /// use rocket::local::Client; /// - /// // Create a `context`. Here, just an empty `HashMap`. - /// let mut context = HashMap::new(); + /// fn main() { + /// let rocket = rocket::ignite().attach(Template::fairing()); + /// let client = Client::new(rocket).expect("valid rocket"); /// - /// # context.insert("test", "test"); - /// # #[allow(unused_variables)] - /// let template = Template::show("templates/", "index", context); + /// // Create a `context`. Here, just an empty `HashMap`. + /// let mut context = HashMap::new(); + /// + /// # context.insert("test", "test"); + /// # #[allow(unused_variables)] + /// let template = Template::show(client.rocket(), "index", context); + /// } + /// ``` #[inline] - pub fn show(root: P, name: S, context: C) -> Option - where P: AsRef, S: Into>, C: Serialize + pub fn show(rocket: &Rocket, name: S, context: C) -> Option + where S: Into>, C: Serialize { - let root = root.as_ref().to_path_buf(); - Context::initialize(root).and_then(|ctxt| { - Template::render(name, context).finalize(&ctxt).ok().map(|v| v.0) - }) + let ctxt = match rocket.state::() { + Some(ctxt) => ctxt, + None => { + warn!("Uninitialized template context: missing fairing."); + info!("To use templates, you must attach `Template::fairing()`."); + info!("See the `Template` documentation for more information."); + return None; + } + }; + Template::render(name, context).finalize(&ctxt).ok().map(|v| v.0) } #[inline(always)] diff --git a/contrib/tests/templates.rs b/contrib/tests/templates.rs index abf1de48..1c24028d 100644 --- a/contrib/tests/templates.rs +++ b/contrib/tests/templates.rs @@ -1,17 +1,29 @@ +extern crate rocket; extern crate rocket_contrib; use std::env; use std::path::PathBuf; +use rocket::Rocket; +use rocket::config::{Config, Environment}; +use rocket_contrib::Template; + fn template_root() -> PathBuf { let cwd = env::current_dir().expect("current working directory"); cwd.join("tests").join("templates") } +fn rocket() -> Rocket { + let config = Config::build(Environment::Development) + .extra("template_dir", template_root().to_str().expect("template directory")) + .expect("valid configuration"); + + rocket::custom(config, true).attach(Template::fairing()) +} + #[cfg(feature = "tera_templates")] mod tera_tests { use super::*; - use rocket_contrib::Template; use std::collections::HashMap; const UNESCAPED_EXPECTED: &'static str @@ -21,16 +33,17 @@ mod tera_tests { #[test] fn test_tera_templates() { + let rocket = rocket(); let mut map = HashMap::new(); map.insert("title", "_test_"); map.insert("content", "