1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
use rocket::{Request, State, Outcome};
use rocket::http::Status;
use rocket::request::{self, FromRequest};
use templates::ContextManager;
/// Request guard for dynamiclly querying template metadata.
///
/// # Usage
///
/// The `Metadata` type implements Rocket's [`FromRequest`] trait, so it can be
/// used as a request guard in any request handler.
///
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # #[macro_use] extern crate rocket_contrib;
/// use rocket_contrib::templates::{Template, Metadata};
///
/// #[get("/")]
/// fn homepage(metadata: Metadata) -> Template {
/// # use std::collections::HashMap;
/// # let context: HashMap<String, String> = HashMap::new();
/// // Conditionally render a template if it's available.
/// if metadata.contains_template("some-template") {
/// Template::render("some-template", &context)
/// } else {
/// Template::render("fallback", &context)
/// }
/// }
///
///
/// fn main() {
/// rocket::ignite()
/// .attach(Template::fairing())
/// // ...
/// # ;
/// }
/// ```
pub struct Metadata<'a>(&'a ContextManager);
impl<'a> Metadata<'a> {
/// Returns `true` if the template with the given `name` is currently
/// loaded. Otherwise, returns `false`.
///
/// # Example
///
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// #
/// use rocket_contrib::templates::Metadata;
///
/// #[get("/")]
/// fn handler(metadata: Metadata) {
/// // Returns `true` if the template with name `"name"` was loaded.
/// let loaded = metadata.contains_template("name");
/// }
/// ```
pub fn contains_template(&self, name: &str) -> bool {
self.0.context().templates.contains_key(name)
}
/// Returns `true` if template reloading is enabled.
///
/// # Example
///
/// ```rust
/// # #![feature(proc_macro_hygiene, decl_macro)]
/// # #[macro_use] extern crate rocket;
/// # extern crate rocket_contrib;
/// #
/// use rocket_contrib::templates::Metadata;
///
/// #[get("/")]
/// fn handler(metadata: Metadata) {
/// // Returns `true` if template reloading is enabled.
/// let reloading = metadata.reloading();
/// }
/// ```
pub fn reloading(&self) -> bool {
self.0.is_reloading()
}
}
/// Retrieves the template metadata. If a template fairing hasn't been attached,
/// an error is printed and an empty `Err` with status `InternalServerError`
/// (`500`) is returned.
impl<'a, 'r> FromRequest<'a, 'r> for Metadata<'a> {
type Error = ();
fn from_request(request: &'a Request) -> request::Outcome<Self, ()> {
request.guard::<State<ContextManager>>()
.succeeded()
.and_then(|cm| Some(Outcome::Success(Metadata(cm.inner()))))
.unwrap_or_else(|| {
error_!("Uninitialized template context: missing fairing.");
info_!("To use templates, you must attach `Template::fairing()`.");
info_!("See the `Template` documentation for more information.");
Outcome::Failure((Status::InternalServerError, ()))
})
}
}