Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I could not give relative path to template on linux but can give on windows #932

Open
Necoo33 opened this issue Dec 12, 2023 · 7 comments
Open

Comments

@Necoo33
Copy link

Necoo33 commented Dec 12, 2023

Hello, my project structure from beginning of the root directory like this:

the file which template struct exist:

routemodels -> src -> lib.rs

the folder that actual templates exist:

pages

and i create a template struct and give path of a template like that:

#[derive(Template)]
#[template(path = "../../pages/contact.html")]
pub struct ContactTemplate {
    pub data1: String,
    pub route: String,
    pub layer: i8
}

Now, the problem is it's totally fine for windows, it compiles and works but it doesn't work on linux. That usage is so practical and easy, but i cant compile it on ubuntu, i take this error:

error: template "../../pages/contact.html" not found in directories ["/home/neco/calculate-measures/routemodels/templates"]
--> routemodels/src/lib.rs:79:10
|
79 | #[derive(Template)]
| ^^^^^^^^
|
= note: this error originates in the derive macro Template (in Nightly builds, run with -Z macro-backtrace for more info)

So, how can i get rid of this error? I don't want to change my project structure. Why it doesn't force you to put your files on "templates" folder on windows and forces you to put that on linux?

Can you make that path platform agnostic(in my case at least for windows and linux) and make support relative paths on linux? It will make your crate way more maintainable.

@djc
Copy link
Owner

djc commented Dec 12, 2023

It is intended to be platform-agnostic, so this might just be a bug? (Could be a bug on the Windows side, though...)

I don't know exactly what's going on here, but maybe have a look at the Config::find_template() code and debug what it's doing with your setup?

@Necoo33
Copy link
Author

Necoo33 commented Dec 12, 2023

It is intended to be platform-agnostic, so this might just be a bug? (Could be a bug on the Windows side, though...)

I don't know exactly what's going on here, but maybe have a look at the Config::find_template() code and debug what it's doing with your setup?

What happens in windows side is ideal behavior imo. Giving a relative path is way more easy. So i think you should apply this behavior for linux on future versions. Strictly defining folder and place of that folder of the templates is not good for development experience.

@vallentin
Copy link
Collaborator

vallentin commented Apr 16, 2024

Duplicate of #383

I explained why it occurs in that issue #383 (comment).

In short, it has to do with how paths are resolved. Your path is actually templates/../../pages/contact.html, so if templates/ doesn't exist, then it fails. This is because on Unix templates might be a symlink, so it has to resolve templates first. If it doesn't exist, then you get an error.

The workaround is that instead of starting your paths with ../, then instead create a askama.toml file and add:

[general]
dirs = ["path/to/pages"]

The dirs path you can use ../ e.g. ../pages. Since here .. is relative to the crate/directory that askama.toml is in, and that directory definitely exists.

@djc
Copy link
Owner

djc commented Apr 17, 2024

@vallentin do you think it makes sense for us to document this behavior in the Askama book?

@vallentin
Copy link
Collaborator

@djc Yes, I'll look into it. Since I'm already documenting other stuff

@vallentin
Copy link
Collaborator

So I was thinking more about this. We could also specialize this case, where the template path starts with ../.

So when resolving the template path, say the path is ../path/to/template and dirs is ["template", "a/b", "c/d"], then they would be tested in this order:

  • [root]/template/../path/to/template
  • [root]/path/to/template
  • [root]/a/b/../path/to/template
  • [root]/a/to/template
  • [root]/c/d/../path/to/template
  • [root]/c/to/template

Testing like this, would ensure that even if someone actually symlinked templates/, thus templates/../path/to/template actually be valid, then we aren't breaking anything.

I just want to point out again, that the/my original issue #383. This issue only exists on Unix and macOS. The behavior works as expected on Windows, given that there's no symlinks to resolve in the first place. Which funnily enough meant that I first triggered the issue myself, when I attempted to build on a separate system.

To be very clear, I'm only suggesting special casing a path starting with ../. I'm not suggesting resolving any other .. in the path. So the implementation should be super simple, e.g. dir.parent() if path starts with Component::ParentDir.


Of course we should still recommend in the book, that people actually use askama.toml and [dirs]. But this seems like something that catches people off-guard. Especially considering that this just works on Windows.


The main question is, should it resolve in the previous order, or this order:

  • [root]/template/../path/to/template
  • [root]/a/b/../path/to/template
  • [root]/c/d/../path/to/template
  • [root]/path/to/template
  • [root]/a/path/to/template
  • [root]/c/path/to/template

What do you think @djc?

@djc
Copy link
Owner

djc commented Apr 23, 2024

If the goal is to more closely match the behavior on Windows, we should probably also try to match the order that Windows ends up with?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants