From 69e12dbb951fad8bfb7e92b8b3060aff288b5b98 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 12 May 2008 09:00:03 +0200 Subject: [PATCH] improved variable exporting, added TODO file --HG-- branch : trunk --- TODO | 57 ++++++++++++++++++++++++++++++++++++++++++++++ docs/jinjaext.py | 9 +++++--- docs/tricks.rst | 4 ++-- jinja2/compiler.py | 22 +++++++++++++++--- jinja2/ext.py | 10 ++++---- jinja2/nodes.py | 34 +++++++++++++++++++++++++++ 6 files changed, 123 insertions(+), 13 deletions(-) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 0000000..6881b76 --- /dev/null +++ b/TODO @@ -0,0 +1,57 @@ +Todo Before Release +=================== + +This has to be implemented before the release: + +Drop special casing template globals +------------------------------------ + +The idea some time ago was to partially evaluate templates at compile time. +For that we decided to not allow globals being overridden by locals as the +static compiler could have changed semantics. Turns out that the static +compiler blows up the complexity to something nobody wants to support which +means that this restriction is kinda pointless. + +That should go for good. + +Pull Attributes Onces +--------------------- + +Imagine the following template:: + + {% if foo.bar %} + {{ baz(foo.bar) }} + {% endif %} + +Problem with that is that it compiles to this:: + + if environment.subscribe(l_foo, 'bar'): + if 0: yield None + yield u'\n %s\n' % ( + l_baz(environment.subscribe(l_foo, 'bar')), + ) + +As `environment.subscribe` is more expensive then regular attribute lookups +(it tries getitem/getattr and in sandbox mode also permissions) multiple +lookups with the same parameters in the same scope should get local aliases. +The result we have is that one:: + + t1 = environment.subscribe(l_foo, 'bar') + if t1: + if 0: yield None + yield u'\n %s\n' % ( + l_baz(t1), + ) + +However that should only happen if the attribute is accessed multiple times +unlike locals and filters/tests which are always pulled. We're not doing that +for filters/tests/locals as nested scopes may access it and testing is too +complicated for the tiny performance improvement but easy for attribute +lookups, keeping the complexity of the whole thing in mind. + +Use `set` for Assignments +------------------------- + +The keyword-less way to assign variabeles is a left-over from the days when +it was possible to use Jinja2 like a regular programming language without +necessary template end/start delimiters to group statements. diff --git a/docs/jinjaext.py b/docs/jinjaext.py index 78a45ec..1ed6d35 100644 --- a/docs/jinjaext.py +++ b/docs/jinjaext.py @@ -168,14 +168,17 @@ def jinja_nodes(dirname, arguments, options, content, lineno, if node.abstract: members = [] for key, name in node.__dict__.iteritems(): - if not key.startswith('_') and callable(name): + if not key.startswith('_') and \ + not hasattr(node.__base__, key) and callable(name): members.append(key) if members: members.sort() doc.append('%s :members: %s' % (p, ', '.join(members)), '') - else: + if node.__base__ != object: doc.append('', '') - doc.append(p + ' :Node type: :class:`%s`' % node.__base__.__name__, '') + doc.append('%s :Node type: :class:`%s`' % + (p, node.__base__.__name__), '') + # XXX: sphinx bug? Expr gives a rst warning doc.append('', '') children = node.__subclasses__() children.sort(key=lambda x: x.__name__.lower()) diff --git a/docs/tricks.rst b/docs/tricks.rst index 6029ec5..1cfdaa8 100644 --- a/docs/tricks.rst +++ b/docs/tricks.rst @@ -65,12 +65,12 @@ child template:: The layout template can then access `active_page`. Additionally it makes sense to defined a default for that variable:: - {% navigation_bar = [ + {% set navigation_bar = [ ('/', 'index', 'Index'), ('/downloads/', 'downloads', 'Downloads'), ('/about/', 'about', 'About') ] -%} - {% active_page = active_page|default('index') -%} + {% set active_page = active_page|default('index') -%} ...