Skip to content

Commit

Permalink
Load templates from relative paths
Browse files Browse the repository at this point in the history
Templates can now be placed directly next to the source file that they
are defined in as a default. This relies on an unstable rust compiler
feature, which exposes the source file to proc macros. See
<rust-lang/rust#54725> for more info.

This requires the nightly compiler to run, and enabling the
proc_macro_span and procmacro2_semver_exempt cfg flags. To build / test:

```shell
RUSTFLAGS='--cfg proc_macro_span --cfg procmacro2_semver_exempt' \
  cargo +nightly build
```
Fixes: <https://github.com/djc/askama/issues/877>
  • Loading branch information
joshka committed Dec 3, 2024
1 parent 704f8f1 commit b6106c5
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 1 deletion.
6 changes: 6 additions & 0 deletions askama/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ with-axum = ["askama_derive/with-axum"]
with-rocket = ["askama_derive/with-rocket"]
with-warp = ["askama_derive/with-warp"]

## Enables the ability to put templates in a directory relative to the source file that uses them.
## Requires a nightly compiler and adding:
## RUSTFLAGS='--cfg proc_macro_span --cfg procmacro2_semver_exempt'
## to your cargo build command.
relative-paths = ["askama_derive/relative-paths"]

[dependencies]
askama_derive = { version = "0.13", path = "../askama_derive" }
askama_escape = { version = "0.11", path = "../askama_escape" }
Expand Down
18 changes: 18 additions & 0 deletions askama/tests/relative_paths.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#[cfg(feature = "relative-paths")]
mod relative_paths {
use askama::Template;

#[derive(Template)]
#[template(path = "relative_paths.txt")]
struct RelativePathTemplate {
name: String,
}

#[test]
fn test_relative_paths() {
let t = RelativePathTemplate {
name: "world".to_string(),
};
assert_eq!(t.render().unwrap(), "Hello, world!");
}
}
1 change: 1 addition & 0 deletions askama/tests/relative_paths.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello, {{ name }}!
6 changes: 6 additions & 0 deletions askama_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ with-axum = []
with-rocket = []
with-warp = []

## Enables the ability to put templates in a directory relative to the source file that uses them.
## Requires a nightly compiler and adding:
## RUSTFLAGS='--cfg proc_macro_span --cfg procmacro2_semver_exempt'
## to your cargo build command.
relative-paths = []

[dependencies]
parser = { package = "askama_parser", version = "0.3.1", path = "../askama_parser" }
mime = "0.3"
Expand Down
17 changes: 16 additions & 1 deletion askama_derive/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,22 @@ impl<'a> Config<'a> {
template_whitespace: Option<&str>,
) -> std::result::Result<Config<'a>, CompileError> {
let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let default_dirs = vec![root.join("templates")];
let root_path = root.join("templates");
let default_dirs;
#[cfg(feature = "relative-paths")]
{
let source = proc_macro2::Span::call_site().source_file();
default_dirs = if source.is_real() {
let relative_path = source.path().parent().unwrap().to_path_buf();
vec![relative_path, root_path]
} else {
vec![root_path]
};
}
#[cfg(not(feature = "relative-paths"))]
{
default_dirs = vec![root_path];
}

let mut syntaxes = BTreeMap::new();
syntaxes.insert(DEFAULT_SYNTAX_NAME.to_string(), Syntax::default());
Expand Down

0 comments on commit b6106c5

Please sign in to comment.