pallets / jinja Goto Github PK
View Code? Open in Web Editor NEWA very fast and expressive template engine.
Home Page: https://jinja.palletsprojects.com
License: BSD 3-Clause "New" or "Revised" License
A very fast and expressive template engine.
Home Page: https://jinja.palletsprojects.com
License: BSD 3-Clause "New" or "Revised" License
What the title says.
IMO, jinja2.filters.make_attrgetter should use environment.getattr instead of environment.getitem, which tries Python's getattr first and then falls back to attempting to treat the object as a dict/list.
For context, we ran into an issue when trying to use the sort filter's attribute argument on a list of security-proxied objects; trying to use index notation on them raises an exception that is not caught in environment.getitem.
I've tested this change minor change locally and all of the tests pass.
The groupby builtin filter currently do not support more that one dot.
For instance, if I have articles that I want to group by year, so I need to access item.date.year
in the groupby filter, it is not possible by now, because jinja2 looks for the date.year
attributes which do not exists.
This can probably be fixed by using operator.attrgetter in the filter.
Currently the identifier tracking is very crude and is based on just prefixing variables. The idea would be to keep some unique variable rewriting into unique identifiers that can be reversed as well.
This should make it unnecessary to use locals() all over the code and fix some problems with identifiers over function boundaries.
the current implementation of filters allows us to pipe one value through filters and combine the effect of each step.
I see the "format" filter as an exception.
it filters a format according to values, instead of filtering a value according to a format.
I think the following filter would be more useful:
def do_pyformat(value, format):
"""return float according to format
"""
return soft_unicode("%" + format) % value
you would use it like this:
...] {{ length | float | pyformat("0.1f") }} m [...
this follows the documentation of the old format
filter, as I found it on http://wsgiarea.pocoo.org/jinja/docs/filters.html#format
Create a for loop with an else clause. In the main clause of the for loop, access {{ loop.index }}. In the else clause, put another for loop. When you render the template, you get an exception:
>>> env = jinja2.Environment()
>>> tpl = env.from_string('{% for x in y %}{{ loop.index0 }}{% else %}{% for i in range(3) %}{{ i }}{% endfor %}{% endfor %}')
>>> tpl.render(y=[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/dave/om/trunk/lib/python2.7/site-packages/Jinja2-2.6-py2.7.egg/jinja2/environment.py", line 894, in render
return self.environment.handle_exception(exc_info, True)
File "<template>", line 1, in top-level template code
UnboundLocalError: local variable 'l_loop' referenced before assignment
There are compiled docs als HTML, LaTeX and PDF in the 2.5.4 tarball. The file is almost three times as big as 2.5.3.
Link is down: http://jinja.pocoo.org/2/
I have a template that starts out like this:
When it tries to render I get a seg fault. I switched to an older version of Jinja2 (2.2.1) that the template had previously rendered with and I got this error:
"/usr/local/lib/python2.7/site-packages/Jinja2-2.2.1-py2.7.egg/jinja2/environment.py",
line 839, in from_code
exec code in namespace
File "/var/www/templates/post_alert.html", line 1, in
And I also saw the same traceback but with the exception "ImportError: No module named division" but I'm not sure how to duplicate that. My setup uses a FileSystemLoader with a MemcachedBytecodeCache and autoescape=True, auto_reload=True, line_statement_prefix='#'
I had previously been using Python 2.6 to render this template with no problems using Jinja2 2.2.1.
In any case, my hack to fix this problem was to change the body style: font:13px/1.5
to just: font:13px
Hi,
when I execute this test file :
https://github.com/mitsuhiko/jinja2/blob/master/examples/basic/test.py
I've one error :
Traceback (most recent call last):
File "test.py", line 24, in <module>
tmpl = env.get_template("child.html")
File "/home/harobed/test/jinja2/jinja2/environment.py", line 719, in get_template
return self._load_template(name, self.make_globals(globals))
File "/home/harobed/test/jinja2/jinja2/environment.py", line 693, in _load_template
template = self.loader.load(self, name, globals)
File "/home/harobed/test/jinja2/jinja2/loaders.py", line 127, in load
code = environment.compile(source, name, filename)
File "/home/harobed/test/jinja2/jinja2/environment.py", line 493, in compile
self.handle_exception(exc_info, source_hint=source)
File "<unknown>", line 3, in template
jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got '='
Regards,
Stéphane
I have a Jinja template in a Flask app with something like
{% trans %}here is a <a href="#">link</a>.{% endtrans %}
I'm following the Flask-Babel instructions (including specifying "extensions=jinja2.ext.autoescape" in my babel.cfg), but the message pybabel extracts from this template has the markup escaped.
This is using the latest Jinja2 tip. Tried to provide an excerpt of an interpreter session reproducing this programmatically, but not sure how to. Sorry!
There is a pocoo-libs thread about this at http://goo.gl/0ABXm.
In the section on template inheritance, the base template is structured with nested blocks (title inside head)
{% block head %} <title>{% block title %}{% endblock %} - My Webpage</title> {% endblock %}but in the extension, the blocks appear at the same level:
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
Is this a mistake?
Right now if three templates down the line all import with context the same thing make_module is called a whole bunch of times. That might be worth caching if possible.
Evaluate that and try to figure out if make_module could be improved.
Currently, an environment's extensions are simply stored as an unsorted dict. This is problematic if you are not fully in control of what extensions are added to the environment, and you want to (reliably) override a tag.
In my case, I am using Coffin to integrate Jinja2 with Django, which provides a replica of the "url" tag. I need to replace this default url tag with a custom version, and to do that, I currently need to manually remove the existing url extensions from the environment.extensions dictionary.
If the extensions were stored with order attached, then an extension added later could take preference over one registered earlier.
Using more than one {% extends %}
is not allowed, but the error message and location could be more explicit:
>>> jinja2.Template('{% extends "a" %}{% extends "b" %}')
File "<template>", line 13
SyntaxError: 'yield' outside function (<template>, line 13)
Using jinja2 as part of the tipfy framework, the provided appstats middleware causes a bad interaction with jinja2, resulting in an UndefinedError from jinja2. See http://code.google.com/p/tipfy-ext-appstats/issues/detail?id=1 for details.
I believe that this is weakly a bug on both sides. Appstats should catch the error, but jinja2 should not throw it when the undefined variable is not being used for in-template display. Thus, I think that getattr on runtime.Undefined should raise AttributeError, not UndefinedError, if the attribute is pseudo-private (starts with "_"). Here's the temporary patch I'm using starting at line 460 of runtime.py; please check this patch (Am I using @InternalCode correctly? Do you agree with my reasoning?) and use it if appropriate:
__add__ = __radd__ = __mul__ = __rmul__ = __div__ = __rdiv__ = \
__truediv__ = __rtruediv__ = __floordiv__ = __rfloordiv__ = \
__mod__ = __rmod__ = __pos__ = __neg__ = __call__ = \
__getitem__ = __lt__ = __le__ = __gt__ = __ge__ = \
__int__ = __float__ = __complex__ = __pow__ = __rpow__ = \
_fail_with_undefined_error
@internalcode
def __getattr__(self,attr):
if attr.startswith("_"):
raise AttributeError
else:
self._fail_with_undefined_error()
I think the LRUCache class in Jinja2 has a bug. The problem is that the "getitem" method may mutate the cache, but that method does not acquire the write lock, "_wlock".
For example, here's one scenario:
In my project I've seen the "setitem" method raise a KeyError. I assume that there's a similar execution scenario behind those exceptions, but I could be wrong.
In any case, I think "getitem" clearly needs to acquire "_wlock" before it removes and appends keys.
If {% with %}
blocks are used in a template, the pybabel extractor will not yield any strings for the template.
Minimal example:
{% trans %}Test{% endtrans %}
{% with %}{% endwith %}
This will yield no translation strings. Removing the second line will ("Test").
Encountered with Python 2.7.1, jinja2 2.6, pybabel 0.9.6.
In Jinja 1.2 there was a feature that allows us to override outer scope variables from within a inner scope, by adding an exclamation mark after the set statement.
This feature is somehow missing in Jinja2. However, such feature is often required. Here is a real-world example in stackoverflow:
http://stackoverflow.com/questions/4870346/can-a-jinja-variables-scope-extend-beyond-in-an-inner-block
It would be glad to see such feature back again in Jinja2 ; )
<!-- userprofile does not exist -->
{{ user.userprofile }}
Let's assume that userprofile for given user does not exist. In Django templates, this would give us nothing. In Jinja, this gives me an exception.
I belive that the way how it works in jinja2 is correct and awesome, because it is very easy to catch bugs that would be difficult to find in standard django templates, but at the same time, it'd be nice to be able to test a variable if it raises an exception.
On WinXP SP2 using Python 2.7.2 using the following command line
python -m unittest jinja2.testsuite.suite
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\jinja2\testsuite__init__.py", line 51, in tearDown
self.teardown()
File "C:\Python27\lib\site-packages\jinja2\testsuite\loader.py", line 124, in teardown
os.remove(self.archive)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: 'c:\windows\temp\tmpoyofll.zip'
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\jinja2\testsuite__init__.py", line 51, in tearDown
self.teardown()
File "C:\Python27\lib\site-packages\jinja2\testsuite\loader.py", line 124, in teardown
os.remove(self.archive)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: 'c:\windows\temp\tmps9be2f.zip'
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\jinja2\testsuite__init__.py", line 51, in tearDown
self.teardown()
File "C:\Python27\lib\site-packages\jinja2\testsuite\loader.py", line 124, in teardown
os.remove(self.archive)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: 'c:\windows\temp\tmpe0vzue.zip'
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\jinja2\testsuite__init__.py", line 51, in tearDown
self.teardown()
File "C:\Python27\lib\site-packages\jinja2\testsuite\loader.py", line 124, in teardown
os.remove(self.archive)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: 'c:\windows\temp\tmpxo2zko.zip'
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\jinja2\testsuite__init__.py", line 51, in tearDown
self.teardown()
File "C:\Python27\lib\site-packages\jinja2\testsuite\loader.py", line 124, in teardown
os.remove(self.archive)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: 'c:\windows\temp\tmpf8_oab.zip'
Ran 266 tests in 1.000s
FAILED (errors=5)
If someone traverses the stack with inspect.stack one can get ugly errors like this one: http://paste.pocoo.org/show/398237/ This is caused by inspect.stack which tries to match the current linenumber of the code object to a line in the file that's attached to the code object. Now if Jinja is in the stack the code objects will have the html file as filename, which are usually way smaller than the generated pythoncode which was used to compile this code object -- which causes and IndexError. Not sure if you consider that as inspect.stack bug, but it would be great if jinja could somehow work around this…
http://apolloner.eu/~apollo13/testing.tar is a small django/jinja/django-debug-toolbar project which shows the problem…
jinja2-2.6-py3.2.egg installed by Sphinx fail on Python 3.2. Sphinx 1.1 could not complete docs generation because of exception in Jinja2. The problem was that Python 3.2 does not have xrange global symbol.
xrange was hit in:
After replacing xrange with range Sphinx started running smoothly.
Right now the choice loader and the prefix loader are using get_source to load templates. That's unfortunate because not every loader can provide the source for templates (for example the module loader).
Line statements eat not only the spaces until the beginning of the line as documented at http://jinja.pocoo.org/docs/templates/#whitespace-control , but also all the previous newlines.
As of 2.7-dev, the following code generates no empty lines:
%% for i in range(3)
{{i}}, next line should be empty
%% endfor
This is an issue in languages where newlines matter (generated LaTeX).
This syntax used to work until 2.5.2:
{{ someobj|string[:16] }}
But it gives a syntax error in 2.5.3 and above.
When running jinja2 under IronPython everything works fine, until you have mistakes in your templates. We had a template file with UTF-8 BOM, which causes an exception in jinja2, but this exception can not be processed as expected (i guess it has something to do with the ctypes stuff going on there), all that bubbles up to the IronPython environment is a "AccessViolationException". This is true for all other mistakes in the templates too, so finding errors in templates becomes really painfull.
The problem is caused in debug.py line 313 (brings bad luck doesn' it?):
obj.tb_next = ctypes.POINTER(_Traceback)()
But i dont understand this part of jinja2 ...
Any interest in including something like this:
https://github.com/miracle2k/jinja2utils/blob/master/src/jinja2utils/match.py
I have just written this code a second time, needing it again and not remembering I had already implemented it once.
It seems to fit very well alongside joiner() and cycler(), and presumably is a common usecase.
I'm getting this traceback:
Traceback (most recent call last):
File "/home/watt/src/dawkins/web.py", line 70, in process
content = env.get_template(rsp[0]).render(**rsp[1])
File "/usr/lib64/python2.7/site-packages/jinja2/environment.py", line 894, in render
return self.environment.handle_exception(exc_info, True)
File "/home/watt/src/asimov/templates/reports/symbol.html", line 2, in top-level template code
{% from "reports/contracts.html" import condfmt with context %}
File "/usr/lib64/python2.7/site-packages/jinja2/environment.py", line 938, in make_module
return TemplateModule(self, self.new_context(vars, shared, locals))
File "/usr/lib64/python2.7/site-packages/jinja2/environment.py", line 994, in __init__
self._body_stream = list(template.root_render_func(context))
File "/home/watt/src/asimov/templates/reports/contracts.html", line 4, in top-level template code
{% if val is none %}{% else %}{{ fmt|format(val) }}{% endif %}
File "/home/watt/src/asimov/templates/chrome.html", line 89, in top-level template code
{% block sections %}{% endblock %}
File "/home/watt/src/asimov/templates/reports/contracts.html", line 45, in block "sections"
{% elif info.delta > 0 %}
UndefinedError: 'dict object' has no attribute 'delta'
contracts.html and symbol.html are independent templates, both extending the same root template (chrome.html). symbol.html has this:
{% from "reports/contracts.html" import condfmt with context %}
Both also override the same general block, called "sections". However, the code referenced in the traceback is in the sections block in contracts.html, which shouldn't be called at all! Only the sections block in symbol.html should be executed, with the macro from contracts.html.
The example in http://jinja.pocoo.org/docs/api/#jinja2.ModuleLoader uses ChoiceLoader which doesn't work.
I'm doing just
app.jinja_loader = ModuleLoader('path/to/compiled/templates')
in my code and I'm getting the error at http://paste.pocoo.org/show/475924/
Could you please document intended usage? Thanks in advance.
Obviously poking inside Python objects via ctypes would not work on pypy. It should at least be guarded with "This is obviously CPython". If you really want to achieve true tracebacks with different interface under pypy, use this:
http://codespeak.net/pypy/dist/pypy/doc/objspace-proxies.html#transparent-proxies
However, why not use simply string representation of objects and forget about the whole issue?
Cheers,
fijal
Since python 2.6 os.walk has the 'followlinks' parameter.
Could this be made an option or even a default when using python 2.6 or higher?
Some examples (e.g. examples/basic/translate.py) are not working.
It would be nice to have them all fixed … and in best case included to some regression-testing…
The finalize function seems to be executed on the whole template, not only on variables.
E.g. a function like
def fin(s): print s; return s
dumps the whole template file.
Hi,
in List of Builtin Filters (http://jinja.pocoo.org/docs/templates/#list-of-builtin-filters) I don't found "urlencode" filter. It's a missing ?
I don't understand, in jinja1 this filter exists : http://wsgiarea.pocoo.org/jinja/docs/filters.html
Do you have some comment about that ?
Regards,
Stéphane
Some macros may depend on other macros. Currently if you'd like to manage dependencies across macros, you have to roll your own (a la http://paste.pocoo.org/show/379402/ ).
Django has this really cool tag called {% empty %}, which lets you do this:
{% for item in list %}
<tr><td>{{ item }}</td></tr>
{% empty %}
<tr><td>Nothing to show!</td></tr>
{% endfor %}
which is short for
{% if list %}
{% for item in list %}
<tr><td>{{ item }}</td?</tr>
{% endfor %}
{% else %}
<tr><td>Nothing to show!</td></tr>
{% endif %}
Since switching to jinja, I have really missed this tag :(
The '\n'.join(splitlines()) construct eats the final newline.
Proposed patch at https://gist.github.com/1390994
excerpted from #pocoo just now:
[17:17] oh hey, is there a way to alias "t" to "trans" to save some space in templates?
[17:18] magicbronson: nope, but i wish there was
[17:18] feel free to open an issue on the jinja2 issue tracker
[17:18] but it's not as easy as it sounds as we need a way to also specify if it's endtrans or endt then
[17:18] and that would mean a change in the extension interface
[17:19] mitsuhiko: dumb and happy: don't auto-alias the end tag, make the user specify it explicitly?
[17:20] magicbronson: that does not help with the fact that the extensions currently explicitly search for "endtrans" in this case
[17:20] or, force it as 'endt' for consistency
[17:20] i also wanted to have /if a while ago for people switching from smarty as an option
[17:20] oh. heh.
[17:21] but it's nontrivial to implement without breaking stuff
[17:21] autoupgrading extensions is impossible currently at least
Every time I visit this page, I'm momentarily confused, then realize it's introducing the PackageLoader instead of FileSystemLoader:
http://jinja.pocoo.org/docs/api/
Not only is PackageLoader more difficult to intuit on first reading, but FileSystemLoader is mentioned in the Loaders API as the preferred way to load templates from the file system.
the return value of the slice() filter is interpreted differently than the original list e.g. if mylist is [(1,2), (3,4), (5,6)]
{# works #}
{% for a, b in mylist %}
{# breaks #}
{% for a, b in mylist|slice(3) %}
{# breaks #}
{% set shortlist = mylist|slice(3) %}
{% with a, b in shortlist %}
Sorry if I am missing something but when using Flask/SQLAlchemy to query the database for a list of bookmarks and their categories I get some strange ordering.
<section class="span-12" id="category-bookmarks">
{% for category in category_bookmarks|groupby('category') %}
<h2>{{ category.grouper.title }}</h2>
<ul>
{% for bookmark in category.list %}
<li><img src="static/favicons/{{ bookmark.favicon }}" /><a href="{{ bookmark.url }}">{{ bookmark.title|trim }}</a></li>
{% endfor %}
</ul>
{% endfor %}
</section>
Category is a foreign_key and this does work but every time I reload the page my categories are displayed in what looks to me like a random order. I pull the bookmarks via a SQLAlchemy call:
category_bookmarks = Bookmark.query.order_by(db.desc('created'))
How can I control how groupby orders my results? Putting a |sort after
for category in category_bookmarks|groupby('category')
doesn't seem to effect it.
I've written more about this issue here:
Would love some help with this.
$ easy_install "Jinja2 == 2.6"
Searching for Jinja2==2.6
Reading http://pypi.python.org/simple/Jinja2/
Reading http://jinja.pocoo.org/
No local packages or download links found for Jinja2==2.6
error: Could not find suitable distribution for Requirement.parse('Jinja2==2.6')
$ easy_install "Jinja2 == 2.6-dev"
Searching for Jinja2==2.6-dev
Reading http://pypi.python.org/simple/Jinja2/
Reading http://jinja.pocoo.org/
No local packages or download links found for Jinja2==2.6-dev
error: Could not find suitable distribution for Requirement.parse('Jinja2==2.6-dev')
$ easy_install "Jinja2 == dev"
Searching for Jinja2==dev
Reading http://pypi.python.org/simple/Jinja2/
Reading http://jinja.pocoo.org/
Best match: Jinja2 dev
Downloading http://dev.pocoo.org/hg/jinja2-main/archive/tip.zip#egg=Jinja2-dev
Processing tip.zip
error: Couldn't find a setup script in /var/folders/Y-/Y-Pm+QGfGpGZWZm14l2qW++++TI/-Tmp-/easy_install-TlhvGN/tip.zip
I think if the page at http://pypi.python.org/simple/Jinja2/ linked to the master branch's zipball, instead of to the old hg repository's tip.zip, this would work. For now, I've added this to my setup.py (in case anyone else runs into this problem):
dependency_links=[
'https://github.com/mitsuhiko/jinja2/zipball/master#egg=Jinja2-2.6dev',
]
Hello,
I'm writing to file a minor issue, but it's cause me some grief.
With a contraction such as don't, won't shouldn't, etc. if the |title filter is applied to a string containing these then the characters after the apostrophe are considered a new word and so are capitalized.
So the sentence 'I didn't do it' when pipped through the |title filter we get:
'I Didn'T Do It' with a capital T...
Thank you
(I'll put the Flask view code, as I have no idea reproducing the code only with jinja2)
I have a code that renders some elements that are in a tree fashion distribution, and a recursive loop in jinja2 (listed at the bottom). As I activated the trim_blocks, lines with only tags are removed, rather than left empty. No surpise here.
Following the docs (http://jinja.pocoo.org/docs/templates/#whitespace-control), there is no need to use the minus sign to manually supress the newlines.
But when I use the recursive for (http://jinja.pocoo.org/docs/templates/#list-of-control-structures) the white spaces are not supressed as I would, but I can add the minus sign to supress, so this is a VERY minor issue. Look at the code below.
Is this behaviour correct?
from flask import Flask, render_template
app = Flask(__name__)
app.jinja_env.trim_blocks = True
@app.route('/')
def hello():
data = [['a', 'b'], 'c', [['d', 'e'], 'f']]
return render_template('hello.html', data=data)
Bad
{% for element in data recursive %}
{% if element is string %}
<p>{{ element }}</p>
{% else %}
{{ loop(element) }}
{% endif %}
{% endfor %}
Good
{% for element in data recursive %}
{% if element is string %}
<p>{{ element }}</p>
{% else %}
{{ loop(element) -}}
{% endif %}
{% endfor %}
Apparently Jinja uses the template filename in the cache instead of the full pathname. This leads to "index.html", for example, returning the wrong thing if the template loader path has been changed.
If Jinja caches by the whole path (which makes sense, since you're trying to load a specific template), this will work correctly.
jinja has built in tests for testing if a variable is a string, a unicode string, a sequence, a number, or an iterable, but no built-in test for if an object is a map/dict.
As one of the basic python types, it might make sense to have a builtin test for this type.
When setting the newline_sequence
environment parameter to, say \r\n
, and if the wordwrap
filter is used, the resulting file contains a mix of \n
and \r\n
, which, imo, isn't an acceptable behavior.
I'm not sure if this is a design decision and if there is a rationale behind it. In any case, a patch (sevas/jinja2@218cb643136134da17526e01a42c30a4c71f27ba) is available in the branch 'wordwrap-newline' of my fork.
A pull request has been initiated.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.