Skip to content

Commit

Permalink
Started working on refactoring Jinja integration
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Jul 4, 2010
1 parent a154c87 commit 7599046
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Codename to be decided, release date to be announced.
- fixed a bug with subdomains that was caused by the inability to
specify the server name. The server name can now be set with
the `SERVER_NAME` config key.
- autoescaping is no longer active for all templates. Instead it
is only active for ``.html``, ``.htm``, ``.xml`` and ``.xhtml``.
Inside templates this behaviour can be changed with the
``autoescape`` tag.

Version 0.4
-----------
Expand Down
7 changes: 7 additions & 0 deletions docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,13 @@ Markup(u'<blink>hacker</blink>')
>>> Markup('<em>Marked up</em> &raquo; HTML').striptags()
u'Marked up \xbb HTML'

.. versionchanged:: 0.5

Autoescaping is no longer enabled for all templates. The following
extensions for templates trigger autoescaping: ``.html``, ``.htm``,
``.xml``, ``.xhtml``. Templates loaded from string will have
autoescaping disabled.

.. [#] Unsure what that :class:`~flask.g` object is? It's something you
can store information on yourself, check the documentation of that
object (:class:`~flask.g`) and the :ref:`sqlite3` for more
Expand Down
42 changes: 34 additions & 8 deletions flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,15 @@ def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self))


def _select_autoescape(filename):
"""Returns `True` if autoescaping should be active for the given
template name.
"""
if filename is None:
return False
return filename.endswith(('.html', '.htm', '.xml', '.xhtml'))


class Flask(_PackageBoundObject):
"""The flask object implements a WSGI application and acts as the central
object. It is passed the name of the module or package of the
Expand Down Expand Up @@ -920,7 +929,7 @@ class Flask(_PackageBoundObject):

#: Options that are passed directly to the Jinja2 environment.
jinja_options = ImmutableDict(
autoescape=True,
autoescape=_select_autoescape,
extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_']
)

Expand Down Expand Up @@ -1018,13 +1027,8 @@ def __init__(self, import_name):
#: The Jinja2 environment. It is created from the
#: :attr:`jinja_options` and the loader that is returned
#: by the :meth:`create_jinja_loader` function.
self.jinja_env = Environment(loader=self.create_jinja_loader(),
**self.jinja_options)
self.jinja_env.globals.update(
url_for=url_for,
get_flashed_messages=get_flashed_messages
)
self.jinja_env.filters['tojson'] = _tojson_filter
self.jinja_env = self.create_jinja_environment()
self.init_jinja_globals()

@property
def logger(self):
Expand Down Expand Up @@ -1061,6 +1065,15 @@ def emit(x, record):
self._logger = logger
return logger

def create_jinja_environment(self):
"""Creates the Jinja2 environment based on :attr:`jinja_options`
and :meth:`create_jinja_loader`.
.. versionadded:: 0.5
"""
return Environment(loader=self.create_jinja_loader(),
**self.jinja_options)

def create_jinja_loader(self):
"""Creates the Jinja loader. By default just a package loader for
the configured package is returned that looks up templates in the
Expand All @@ -1071,6 +1084,19 @@ def create_jinja_loader(self):
return FileSystemLoader(os.path.join(self.root_path, 'templates'))
return PackageLoader(self.import_name)

def init_jinja_globals(self):
"""Callde directly after the environment was created to inject
some defaults (like `url_for`, `get_flashed_messages` and the
`tojson` filter.
.. versionadded:: 0.5
"""
self.jinja_env.globals.update(
url_for=url_for,
get_flashed_messages=get_flashed_messages
)
self.jinja_env.filters['tojson'] = _tojson_filter

def update_template_context(self, context):
"""Update the template context with some commonly used variables.
This injects request, session and g into the template context.
Expand Down
8 changes: 8 additions & 0 deletions tests/flask_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,14 @@ def index():
'<p>Hello World!'
]

def test_no_escaping(self):
app = flask.Flask(__name__)
with app.test_request_context():
assert flask.render_template_string('{{ foo }}',
foo='<test>') == '<test>'
assert flask.render_template('mail.txt', foo='<test>') \
== '<test> Mail'

def test_macros(self):
app = flask.Flask(__name__)
with app.test_request_context():
Expand Down
1 change: 1 addition & 0 deletions tests/templates/mail.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ foo}} Mail

0 comments on commit 7599046

Please sign in to comment.