Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

some documentation improvements, jinja escapes " and ' now, both into…

… charpoints and no named entities for html 3.2 support ;-)

--HG--
branch : trunk
  • Loading branch information...
commit f35e28154f6ee9269beec6864136dbb9f230af7d 1 parent c2f3a3b
@mitsuhiko authored
View
3  docs/_static/print.css
@@ -1,6 +1,5 @@
div.header, div.relnav, #toc { display: none; }
#contentwrapper { padding: 0; margin: 0; border: none; }
body { color: black; background-color: white; }
-div.footer { text-align: right; border-top: 1px solid #888; color: #888;
- margin-top: 1cm; }
+div.footer { border-top: 1px solid #888; color: #888; margin-top: 1cm; }
div.footer a { text-decoration: none; }
View
21 docs/_static/style.css
@@ -8,10 +8,10 @@ body {
}
div.footer {
- border-top: 1px solid #111;
+ border-top: 1px solid black;
padding: 8px;
font-size: 11px;
- text-align: center;
+ text-align: right;
}
div.footer a {
@@ -26,7 +26,7 @@ div.header {
div.relnav {
border-bottom: 1px solid #ACACAC;
background: url(navigation.png);
- padding: 2px 20px 0 38px;
+ padding: 2px 20px 0 28px;
line-height: 25px;
color: #aaa;
font-size: 12px;
@@ -56,18 +56,27 @@ h1 {
}
h1.heading {
- margin: 0 0 0 20px;
+ margin: 0;
padding: 0;
height: 80px;
- background: url(jinjabanner.png) no-repeat;
+}
+
+h1.heading:hover {
+ background: #222;
}
h1.heading a {
+ background: url(jinjabanner.png) no-repeat 20px 0;
display: block;
- width: 200px;
+ width: 100%;
height: 80px;
}
+h1.heading a:focus {
+ -moz-outline: none;
+ outline: none;
+}
+
h1.heading span {
display: none;
}
View
BIN  docs/_static/watermark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
3  docs/_templates/layout.html
@@ -45,7 +45,8 @@
<body>
<div id="content">
<div class="header">
- <h1 class="heading"><a href="{{ pathto('index') }}"><span>Jinja</span></a></h1>
+ <h1 class="heading"><a href="{{ pathto('index') }}"
+ title="back to the documentation overview"><span>Jinja</span></a></h1>
</div>
<div class="relnav">
{%- if prev %}
View
2  docs/api.rst
@@ -124,7 +124,7 @@ The Context
-----------
.. autoclass:: jinja2.runtime.Context
- :members: super, get, get_exported, get_all
+ :members: resolve, get_exported, get_all
.. attribute:: parent
View
89 docs/templates.rst
@@ -126,6 +126,95 @@ yourself::
{% endfor %}
#}
+
+Whitespace Control
+------------------
+
+In the default configuration whitespace is not further modified by the
+template engine, so each whitespace (spaces, tabs, newlines etc.) is returned
+unchanged. If the application configures Jinja to `trim_blocks` the first
+newline after a a template tag is removed automatically (like in PHP).
+
+But you can also strip whitespace in templates by hand. If you put an minus
+sign (``-``) to the start or end of an block (for example a for tag), a
+comment or variable expression you can remove the whitespaces after or before
+that block::
+
+ {% for item in seq -%}
+ {{ item }}
+ {%- endfor %}
+
+This will yield all elements without whitespace between them. If `seq` was
+a list of numbers from ``1`` to ``9`` the output would be ``123456789``.
+
+Note that you must not use a whitespace between the tag and the minus sign:
+
+ valid:
+ {%- if foo -%}...{% endif %}
+
+ invalid:
+
+ {% - if foo - %}...{% endif %}
+
+If :ref:`line-statements` are enabled they strip leading whitespace
+automatically up to the beginning of the line.
+
+
+Escaping
+--------
+
+It is sometimes desirable or even necessary to have Jinja ignore parts it
+would otherwise handle as variables or blocks. For example if the default
+syntax is used and you want to use ``{{`` as raw string in the template and
+not start a variable you have to use a trick.
+
+The easiest way is to output the variable delimiter (``{{``) by using a
+variable expression::
+
+ {{ '{{' }}
+
+For bigger sections it makes sense to mark a block `raw`. For example to
+put Jinja syntax as example into a template you can use this snippet::
+
+ {% raw %}
+ <ul>
+ {% for item in seq %}
+ <li>{{ item }}</li>
+ {% endfor %}
+ </ul>
+ {% endraw %}
+
+
+.. _line-statements:
+
+Line Statements
+---------------
+
+If line statements are enabled by the application it's possible to mark a
+line as a statement. For example if the line statement prefix is configured
+to ``#`` the following two examples are equivalent::
+
+ <ul>
+ # for item in seq
+ <li>{{ item }}</li>
+ # endfor
+ </ul>
+
+ <ul>
+ {% for item in seq %}
+ <li>{{ item }}</li>
+ {% endfor %}
+ </ul>
+
+The line statement prefix can appear anywhere on the line as long as no text
+precedes it. For better readability statements that start a block (such as
+`for`, `if`, `elif` etc.) may end with a colon::
+
+ # for item in seq:
+ ...
+ # endif
+
+
.. _template-inheritance:
Template Inheritance
View
42 jinja2/_speedups.c
@@ -23,20 +23,20 @@ static Py_UNICODE *escaped_chars_repl[ESCAPED_CHARS_TABLE_SIZE];
static int
init_constants(void)
{
- memset(escaped_chars_delta_len, 0, sizeof (escaped_chars_delta_len));
-
- escaped_chars_delta_len['"'] = 5;
- escaped_chars_repl['"'] = UNICHR("&quot;");
-
- escaped_chars_delta_len['&'] = 4;
+ /* happing of characters to replace */
+ escaped_chars_repl['"'] = UNICHR("&#34;");
+ escaped_chars_repl['\''] = UNICHR("&#39;");
escaped_chars_repl['&'] = UNICHR("&amp;");
-
- escaped_chars_delta_len['<'] = 3;
escaped_chars_repl['<'] = UNICHR("&lt;");
-
- escaped_chars_delta_len['>'] = 3;
escaped_chars_repl['>'] = UNICHR("&gt;");
+
+ /* lengths of those characters when replaced - 1 */
+ memset(escaped_chars_delta_len, 0, sizeof (escaped_chars_delta_len));
+ escaped_chars_delta_len['"'] = escaped_chars_delta_len['\''] = \
+ escaped_chars_delta_len['&'] = 4;
+ escaped_chars_delta_len['<'] = escaped_chars_delta_len['>'] = 3;
+ /* import markup type so that we can mark the return value */
PyObject *module = PyImport_ImportModule("jinja2.utils");
if (!module)
return 0;
@@ -109,16 +109,6 @@ escape_unicode(PyUnicodeObject *in)
static PyObject*
-soft_unicode(PyObject *self, PyObject *s)
-{
- if (!PyUnicode_Check(s))
- return PyObject_Unicode(s);
- Py_INCREF(s);
- return s;
-}
-
-
-static PyObject*
escape(PyObject *self, PyObject *text)
{
PyObject *s = NULL, *rv = NULL;
@@ -156,6 +146,16 @@ escape(PyObject *self, PyObject *text)
}
+static PyObject*
+soft_unicode(PyObject *self, PyObject *s)
+{
+ if (!PyUnicode_Check(s))
+ return PyObject_Unicode(s);
+ Py_INCREF(s);
+ return s;
+}
+
+
static PyObject *
tb_set_next(PyObject *self, PyObject *args)
{
@@ -187,7 +187,7 @@ static PyMethodDef module_methods[] = {
{"escape", (PyCFunction)escape, METH_O,
"escape(s) -> markup\n\n"
"Convert the characters &, <, >, and \" in string s to HTML-safe\n"
- "sequences. Use this if you need to display text that might contain\n"
+ "sequences. Use this if you need to display text that might contain\n"
"such characters in HTML. Marks return value as markup string."},
{"soft_unicode", (PyCFunction)soft_unicode, METH_O,
"soft_unicode(object) -> string\n\n"
View
2  jinja2/compiler.py
@@ -461,7 +461,7 @@ def touch_comma():
def pull_locals(self, frame):
"""Pull all the references identifiers into the local scope."""
for name in frame.identifiers.undeclared:
- self.writeline('l_%s = context[%r]' % (name, name))
+ self.writeline('l_%s = context.resolve(%r)' % (name, name))
def pull_dependencies(self, nodes):
"""Pull all the dependencies."""
View
2  jinja2/environment.py
@@ -103,7 +103,7 @@ class Environment(object):
`line_statement_prefix`
If given and a string, this will be used as prefix for line based
- statements.
+ statements. See also :ref:`line-statements`.
`trim_blocks`
If this is set to ``True`` the first newline after a block is
View
37 jinja2/runtime.py
@@ -51,8 +51,10 @@ class Context(object):
and are allowed to access the context read-only.
The template context supports read only dict operations (`get`,
- `__getitem__`, `__contains__`) however `__getitem__` doesn't fail with
- a `KeyError` but returns an :attr:`Undefined` object.
+ `keys`, `values`, `items`, `iterkeys`, `itervalues`, `iteritems`,
+ `__getitem__`, `__contains__`). Additionally there is a :meth:`resolve`
+ method that doesn't fail with a `KeyError` but returns an
+ :class:`Undefined` object for missing variables.
"""
def __init__(self, environment, parent, name, blocks):
@@ -95,11 +97,20 @@ def get(self, key, default=None):
"""Returns an item from the template context, if it doesn't exist
`default` is returned.
"""
+ try:
+ return self[key]
+ except KeyError:
+ return default
+
+ def resolve(self, key):
+ """Looks up a variable like `__getitem__` or `get` but returns an
+ :class:`Undefined` object with the name of the name looked up.
+ """
if key in self.vars:
return self.vars[key]
if key in self.parent:
return self.parent[key]
- return default
+ return self.environment.undefined(name=key)
def get_exported(self):
"""Get a new dict with the exported variables."""
@@ -111,15 +122,29 @@ def get_all(self):
"""
return dict(self.parent, **self.vars)
+ def _all(meth):
+ def proxy(self):
+ return getattr(self.get_all(), meth)()
+ proxy.__doc__ = getattr(dict, meth).__doc__
+ proxy.__name__ = meth
+ return proxy
+
+ keys = _all('keys')
+ values = _all('values')
+ items = _all('items')
+ iterkeys = _all('iterkeys')
+ itervalues = _all('itervalues')
+ iteritems = _all('iteritems')
+ del _all
+
def __contains__(self, name):
return name in self.vars or name in self.parent
def __getitem__(self, key):
+ """Lookup a variable or raise `KeyError`."""
if key in self.vars:
return self.vars[key]
- if key in self.parent:
- return self.parent[key]
- return self.environment.undefined(name=key)
+ return self.parent[key]
def __repr__(self):
return '<%s %s of %r>' % (
View
13 jinja2/utils.py
@@ -303,6 +303,14 @@ def striptags(self):
stripped = u' '.join(_striptags_re.sub('', self).split())
return Markup(stripped).unescape()
+ @classmethod
+ def escape(cls, s):
+ """Escape the string. Works like :func:`escape`."""
+ rv = escape(s)
+ if rv.__class__ is not cls:
+ return cls(rv)
+ return rv
+
def make_wrapper(name):
orig = getattr(unicode, name)
def func(self, *args, **kwargs):
@@ -478,8 +486,8 @@ def __reversed__(self):
from jinja2._speedups import escape, soft_unicode
except ImportError:
def escape(s):
- """Convert the characters &, <, >, and " in string s to HTML-safe
- sequences. Use this if you need to display text that might contain
+ """Convert the characters &, <, >, ' and " in string s to HTML-safe
+ sequences. Use this if you need to display text that might contain
such characters in HTML. Marks return value as markup string.
"""
if hasattr(s, '__html__'):
@@ -488,6 +496,7 @@ def escape(s):
.replace('&', '&amp;')
.replace('>', '&gt;')
.replace('<', '&lt;')
+ .replace("'", '&#39;')
.replace('"', '&quot;')
)
View
2  tests/test_filters.py
@@ -110,7 +110,7 @@ def test_slice(env):
def test_escape(env):
tmpl = env.from_string(ESCAPE)
out = tmpl.render()
- assert out == '&lt;&quot;&gt;&amp;'
+ assert out == '&lt;&#34;&gt;&amp;'
def test_striptags(env):
Please sign in to comment.
Something went wrong with that request. Please try again.