aboutsummaryrefslogtreecommitdiffstats
path: root/askama_shared/src/path.rs
diff options
context:
space:
mode:
authorLibravatar mash <mashedcode@users.noreply.github.com>2018-07-04 15:41:58 +0000
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2018-07-10 14:29:29 +0100
commitb5b1589093b96efdb8a80d6045dcfb4950d2632c (patch)
tree4f11c5e0937c122968ff03a94c8b468dc7df7bcb /askama_shared/src/path.rs
parent953df2b3f3afe5c4a357a4353a4c9e8657b96114 (diff)
downloadaskama-b5b1589093b96efdb8a80d6045dcfb4950d2632c.tar.gz
askama-b5b1589093b96efdb8a80d6045dcfb4950d2632c.tar.bz2
askama-b5b1589093b96efdb8a80d6045dcfb4950d2632c.zip
Add complete support for multiple template dirs
Diffstat (limited to 'askama_shared/src/path.rs')
-rw-r--r--askama_shared/src/path.rs106
1 files changed, 63 insertions, 43 deletions
diff --git a/askama_shared/src/path.rs b/askama_shared/src/path.rs
index 37fb261..6b3ed0c 100644
--- a/askama_shared/src/path.rs
+++ b/askama_shared/src/path.rs
@@ -5,9 +5,18 @@ use std::path::{Path, PathBuf};
use toml;
+fn search_template_in_dirs<'a>(dirs: &'a [PathBuf], path: &Path) -> Option<&'a PathBuf> {
+ dirs.iter().find(|dir| dir.join(path).exists())
+}
+
pub fn get_template_source(tpl_path: &Path) -> String {
- let mut path = template_dir();
- path.push(tpl_path);
+ let dirs = template_dirs();
+ let path = search_template_in_dirs(&dirs, tpl_path)
+ .map(|dir| dir.join(tpl_path))
+ .expect(&format!(
+ "template file '{}' does not exist",
+ tpl_path.to_str().unwrap()
+ ));
let mut f = match File::open(&path) {
Err(_) => {
let msg = format!("unable to open template file '{}'", &path.to_str().unwrap());
@@ -24,66 +33,77 @@ pub fn get_template_source(tpl_path: &Path) -> String {
}
pub fn find_template_from_path(path: &str, start_at: Option<&Path>) -> PathBuf {
- let root = template_dir();
+ let dirs = template_dirs();
if let Some(rel) = start_at {
- let mut fs_rel_path = root.clone();
- fs_rel_path.push(rel);
- fs_rel_path = fs_rel_path.with_file_name(path);
+ let root = search_template_in_dirs(&dirs, rel).expect(&format!(
+ "unable to find previously available template file '{}'",
+ rel.to_str().unwrap()
+ ));
+ let fs_rel_path = root.join(rel).with_file_name(path);
if fs_rel_path.exists() {
return fs_rel_path.strip_prefix(&root).unwrap().to_owned();
}
}
- let mut fs_abs_path = root.clone();
let path = Path::new(path);
- fs_abs_path.push(Path::new(path));
- if fs_abs_path.exists() {
- path.to_owned()
- } else {
- panic!(format!(
- "template {:?} not found at {:?}",
- path.to_str().unwrap(),
- fs_abs_path
- ));
- }
+ search_template_in_dirs(&dirs, &path).expect(&format!(
+ "template {:?} not found in directories {:?}",
+ path.to_str().unwrap(),
+ dirs
+ ));
+ path.to_owned()
}
-pub fn template_dir() -> PathBuf {
- let mut path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
- path.push("templates");
- path
-}
+static CONFIG_FILE_NAME: &str = "askama.toml";
#[derive(Deserialize)]
-struct Config {
+struct RawConfig {
dirs: Option<Vec<String>>,
}
-pub fn template_dirs() -> Vec<PathBuf> {
- let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
- let askama = root.join("askama.toml");
- let default = vec![root.join("templates")];
- if askama.exists() {
- let mut contents = String::new();
- File::open(askama).unwrap().read_to_string(&mut contents).unwrap();
- let config: Config = toml::from_str(&contents).unwrap();
- if let Some(dirs) = config.dirs {
- let paths: Vec<PathBuf> = dirs.into_iter().map(|directory| {
- root.join(directory)
- }).collect();
- if paths.len() > 0 {
- paths
- } else {
- default
- }
+struct Config {
+ dirs: Vec<PathBuf>,
+}
+
+impl RawConfig {
+ fn from_file(filename: &PathBuf) -> Option<RawConfig> {
+ if filename.exists() {
+ let mut contents = String::new();
+ File::open(filename)
+ .unwrap()
+ .read_to_string(&mut contents)
+ .unwrap();
+ Some(toml::from_str(&contents).unwrap())
} else {
- default
+ None
}
- } else {
- vec![root.join("templates")]
}
}
+impl Config {
+ fn from_file() -> Config {
+ let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
+ let filename = root.join(CONFIG_FILE_NAME);
+ RawConfig::from_file(&filename).map_or_else(
+ || Config {
+ dirs: vec![root.join("templates")],
+ },
+ |config| Config {
+ dirs: config
+ .dirs
+ .unwrap_or_else(|| Vec::new())
+ .into_iter()
+ .map(|directory| root.join(directory))
+ .collect(),
+ },
+ )
+ }
+}
+
+pub fn template_dirs() -> Vec<PathBuf> {
+ Config::from_file().dirs
+}
+
#[cfg(test)]
mod tests {
use super::Path;