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

Any built-in filter that concatenates paths in a way similar to the os.path.join()? #367

Closed
kohaugustine opened this issue Sep 12, 2014 · 5 comments

Comments

@kohaugustine
Copy link

Dear All,

I'm looking to improve on a script through using Jinja2's templating engine to allow us to render new files (lua script files) from a given template stored in a text file. One filter that we would need to have is a filter that concatenates paths (which are embedded as variables within the original template), and although the 'join' filter does fulfill this requirement somewhat as we can specify for it to connect paths with either a / or a , this would make our code platform bounded (if we tell the join filter to use a / , then we can only run our code on a Unix-based platform; if a , then only windows).

Is there any built-in filter in Jinja2 that has a behavior similar to that of python's standard os.path.join, and that will know when it should use a / or a \ depending on the platform it is running in?

Otherwise, we might have to define our own filter, but I have not been able to find any documentation on that from the official Jinja2 website thus far; could someone point me to where the documentation is?

Thank you!

Best,
Augustine

@Naddiseo
Copy link
Contributor

To answer your question: there's no built-in filter.

There are two ways I can think of doing this

  • First would be to create a filter with os.path.join, something like: jinja_env.filters['path_join'] = os.path.join
  • The second would be to always use just use '/'.join() which afaik works on windows too.

@kohaugustine
Copy link
Author

Dear Naddiseo,

Thank you for your response! Yes the methods you have suggested sound good, especially the first one. However, I'm afraid I dont quite understand what you mean by the seond. Do you mean that I should put '/'.join as a filter in the jinja2 template that I will be rendering from?

Best,
Augustine

@Naddiseo
Copy link
Contributor

You can use plain python methods in jinja templates:

<div>Path: {{ '/'.join(path_parts) }}</div>

And as far as I know (and wikipedia seems to agree), windows allows the use of forward slashes, so the use of os.path.join is moot in a lot of cases.

@kohaugustine
Copy link
Author

Dear Naddiseo,

Thanks for your suggestion, but we have decided we'd like to go with os.path.join anyways, just to be safe. I think most windows apps still use the \ even though / is allowed on windows, so it'll still be safer to go with the convention and have os.path.join adapt according to the platform to avoid any issues.

Somehow jinja_env.filters['path_join'] = os.path.join didn't work; eventually we figured out specifying this custom filter as:

jinja_env.filters['path_join'] = lambda paths: os.path.join(*paths)

essentially specify a lambda function that serves to invoke the os.path.join. This worked for us. Is Jinja2's filters method unable to accept whole functions/methods directly to use them as filters?

Thank you.

Best,
Augustine

@Naddiseo
Copy link
Contributor

Filters only accept a single argument (ignoring context), which is the left-hand side of the filter expression.

Is Jinja2's filters method unable to accept whole functions/methods directly to use them as filters?

It can take plain functions as long as they only need a single argument.
a|b is converted into b(a) so using your first approach would only work if os.path.join took an iterable as its only argument, instead it takes an *args argument, and so you, correctly, specified the filter with a lambda.

@davidism davidism closed this as completed Jul 5, 2017
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants