1 # -*- coding: utf-8 -*-
8 :copyright: (c) 2010 by the Jinja Team.
9 :license: BSD, see LICENSE for more details.
15 from thread import allocate_lock
17 from dummy_thread import allocate_lock
18 from collections import deque
19 from itertools import imap
22 _word_split_re = re.compile(r'(\s+)')
23 _punctuation_re = re.compile(
24 '^(?P<lead>(?:%s)*)(?P<middle>.*?)(?P<trail>(?:%s)*)$' % (
25 '|'.join(imap(re.escape, ('(', '<', '<'))),
26 '|'.join(imap(re.escape, ('.', ',', ')', '>', '\n', '>')))
29 _simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$')
30 _striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
31 _entity_re = re.compile(r'&([^;]+);')
32 _letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
33 _digits = '0123456789'
35 # special singleton representing missing values for the runtime
36 missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})()
42 # concatenate a list of strings and convert them to unicode.
43 # unfortunately there is a bug in python 2.4 and lower that causes
44 # unicode.join trash the traceback.
48 raise TypeError(_test_gen_bug)
50 _concat(_test_gen_bug())
51 except TypeError, _error:
52 if not _error.args or _error.args[0] is not _test_gen_bug:
55 return _concat(list(gen))
57 # this hack is needed so that the current frame
58 # does not show up in the traceback.
59 exc_type, exc_value, tb = sys.exc_info()
60 raise exc_type, exc_value, tb.tb_next
63 del _test_gen_bug, _error
66 # for python 2.x we create outselves a next() function that does the
67 # basics without exception catching.
75 # if this python version is unable to deal with unicode filenames
76 # when passed to encode we let this function encode it properly.
77 # This is used in a couple of places. As far as Jinja is concerned
78 # filenames are unicode *or* bytestrings in 2.x and unicode only in
79 # 3.x because compile cannot handle bytes
80 if sys.version_info < (3, 0):
81 def _encode_filename(filename):
82 if isinstance(filename, unicode):
83 return filename.encode('utf-8')
86 def _encode_filename(filename):
87 assert filename is None or isinstance(filename, str), \
88 'filenames must be strings'
91 from keyword import iskeyword as is_python_keyword
94 # common types. These do exist in the special types module too which however
95 # does not exist in IronPython out of the box. Also that way we don't have
96 # to deal with implementation specific stuff here
98 def method(self): pass
101 FunctionType = type(_func)
102 GeneratorType = type(_func())
103 MethodType = type(_C.method)
104 CodeType = type(_C.method.func_code)
108 _tb = sys.exc_info()[2]
109 TracebackType = type(_tb)
110 FrameType = type(_tb.tb_frame)
114 def contextfunction(f):
115 """This decorator can be used to mark a function or method context callable.
116 A context callable is passed the active :class:`Context` as first argument when
117 called from the template. This is useful if a function wants to get access
118 to the context or functions provided on the context object. For example
119 a function that returns a sorted list of template variables the current
120 template exports could look like this::
123 def get_exported_names(context):
124 return sorted(context.exported_vars)
126 f.contextfunction = True
130 def evalcontextfunction(f):
131 """This decoraotr can be used to mark a function or method as an eval
132 context callable. This is similar to the :func:`contextfunction`
133 but instead of passing the context, an evaluation context object is
136 .. versionadded:: 2.4
138 f.evalcontextfunction = True
142 def environmentfunction(f):
143 """This decorator can be used to mark a function or method as environment
144 callable. This decorator works exactly like the :func:`contextfunction`
145 decorator just that the first argument is the active :class:`Environment`
148 f.environmentfunction = True
153 """Marks the function as internally used"""
154 internal_code.add(f.func_code)
158 def is_undefined(obj):
159 """Check if the object passed is undefined. This does nothing more than
160 performing an instance check against :class:`Undefined` but looks nicer.
161 This can be used for custom filters or tests that want to react to
162 undefined variables. For example a custom default filter can look like
165 def default(var, default=''):
166 if is_undefined(var):
170 from jinja2.runtime import Undefined
171 return isinstance(obj, Undefined)
174 def consume(iterable):
175 """Consumes an iterable without doing anything with it."""
176 for event in iterable:
181 """Jinja2 keeps internal caches for environments and lexers. These are
182 used so that Jinja2 doesn't have to recreate environments and lexers all
183 the time. Normally you don't have to care about that but if you are
184 messuring memory consumption you may want to clean the caches.
186 from jinja2.environment import _spontaneous_environments
187 from jinja2.lexer import _lexer_cache
188 _spontaneous_environments.clear()
192 def import_string(import_name, silent=False):
193 """Imports an object based on a string. This use useful if you want to
194 use import paths as endpoints or something similar. An import path can
195 be specified either in dotted notation (``xml.sax.saxutils.escape``)
196 or with a colon as object delimiter (``xml.sax.saxutils:escape``).
198 If the `silent` is True the return value will be `None` if the import
201 :return: imported object
204 if ':' in import_name:
205 module, obj = import_name.split(':', 1)
206 elif '.' in import_name:
207 items = import_name.split('.')
208 module = '.'.join(items[:-1])
211 return __import__(import_name)
212 return getattr(__import__(module, None, None, [obj]), obj)
213 except (ImportError, AttributeError):
218 def open_if_exists(filename, mode='rb'):
219 """Returns a file descriptor for the filename if that file exists,
223 return open(filename, mode)
225 if e.errno not in (errno.ENOENT, errno.EISDIR):
229 def pformat(obj, verbose=False):
230 """Prettyprint an object. Either use the `pretty` library or the
234 from pretty import pretty
235 return pretty(obj, verbose=verbose)
237 from pprint import pformat
241 def urlize(text, trim_url_limit=None, nofollow=False):
242 """Converts any URLs in text into clickable links. Works on http://,
243 https:// and www. links. Links can have trailing punctuation (periods,
244 commas, close-parens) and leading punctuation (opening parens) and
245 it'll still do the right thing.
247 If trim_url_limit is not None, the URLs in link text will be limited
248 to trim_url_limit characters.
250 If nofollow is True, the URLs in link text will get a rel="nofollow"
253 trim_url = lambda x, limit=trim_url_limit: limit is not None \
254 and (x[:limit] + (len(x) >=limit and '...'
256 words = _word_split_re.split(unicode(escape(text)))
257 nofollow_attr = nofollow and ' rel="nofollow"' or ''
258 for i, word in enumerate(words):
259 match = _punctuation_re.match(word)
261 lead, middle, trail = match.groups()
262 if middle.startswith('www.') or (
263 '@' not in middle and
264 not middle.startswith('http://') and
266 middle[0] in _letters + _digits and (
267 middle.endswith('.org') or
268 middle.endswith('.net') or
269 middle.endswith('.com')
271 middle = '<a href="http://%s"%s>%s</a>' % (middle,
272 nofollow_attr, trim_url(middle))
273 if middle.startswith('http://') or \
274 middle.startswith('https://'):
275 middle = '<a href="%s"%s>%s</a>' % (middle,
276 nofollow_attr, trim_url(middle))
277 if '@' in middle and not middle.startswith('www.') and \
278 not ':' in middle and _simple_email_re.match(middle):
279 middle = '<a href="mailto:%s">%s</a>' % (middle, middle)
280 if lead + middle + trail != word:
281 words[i] = lead + middle + trail
282 return u''.join(words)
285 def generate_lorem_ipsum(n=5, html=True, min=20, max=100):
286 """Generate some lorem impsum for the template."""
287 from jinja2.constants import LOREM_IPSUM_WORDS
288 from random import choice, randrange
289 words = LOREM_IPSUM_WORDS.split()
293 next_capitalized = True
294 last_comma = last_fullstop = 0
299 # each paragraph contains out of 20 to 100 words.
300 for idx, _ in enumerate(xrange(randrange(min, max))):
307 word = word.capitalize()
308 next_capitalized = False
310 if idx - randrange(3, 8) > last_comma:
314 # add end of sentences
315 if idx - randrange(10, 20) > last_fullstop:
316 last_comma = last_fullstop = idx
318 next_capitalized = True
321 # ensure that the paragraph ends with a dot.
325 elif not p.endswith('.'):
330 return u'\n\n'.join(result)
331 return Markup(u'\n'.join(u'<p>%s</p>' % escape(x) for x in result))
334 class Markup(unicode):
335 r"""Marks a string as being safe for inclusion in HTML/XML output without
336 needing to be escaped. This implements the `__html__` interface a couple
337 of frameworks and web applications use. :class:`Markup` is a direct
338 subclass of `unicode` and provides all the methods of `unicode` just that
339 it escapes arguments passed and always returns `Markup`.
341 The `escape` function returns markup objects so that double escaping can't
342 happen. If you want to use autoescaping in Jinja just enable the
343 autoescaping feature in the environment.
345 The constructor of the :class:`Markup` class can be used for three
346 different things: When passed an unicode object it's assumed to be safe,
347 when passed an object with an HTML representation (has an `__html__`
348 method) that representation is used, otherwise the object passed is
349 converted into a unicode string and then assumed to be safe:
351 >>> Markup("Hello <em>World</em>!")
352 Markup(u'Hello <em>World</em>!')
353 >>> class Foo(object):
354 ... def __html__(self):
355 ... return '<a href="#">foo</a>'
358 Markup(u'<a href="#">foo</a>')
360 If you want object passed being always treated as unsafe you can use the
361 :meth:`escape` classmethod to create a :class:`Markup` object:
363 >>> Markup.escape("Hello <em>World</em>!")
364 Markup(u'Hello <em>World</em>!')
366 Operations on a markup string are markup aware which means that all
367 arguments are passed through the :func:`escape` function:
369 >>> em = Markup("<em>%s</em>")
371 Markup(u'<em>foo & bar</em>')
372 >>> strong = Markup("<strong>%(text)s</strong>")
373 >>> strong % {'text': '<blink>hacker here</blink>'}
374 Markup(u'<strong><blink>hacker here</blink></strong>')
375 >>> Markup("<em>Hello</em> ") + "<foo>"
376 Markup(u'<em>Hello</em> <foo>')
380 def __new__(cls, base=u'', encoding=None, errors='strict'):
381 if hasattr(base, '__html__'):
382 base = base.__html__()
384 return unicode.__new__(cls, base)
385 return unicode.__new__(cls, base, encoding, errors)
390 def __add__(self, other):
391 if hasattr(other, '__html__') or isinstance(other, basestring):
392 return self.__class__(unicode(self) + unicode(escape(other)))
393 return NotImplemented
395 def __radd__(self, other):
396 if hasattr(other, '__html__') or isinstance(other, basestring):
397 return self.__class__(unicode(escape(other)) + unicode(self))
398 return NotImplemented
400 def __mul__(self, num):
401 if isinstance(num, (int, long)):
402 return self.__class__(unicode.__mul__(self, num))
403 return NotImplemented
406 def __mod__(self, arg):
407 if isinstance(arg, tuple):
408 arg = tuple(imap(_MarkupEscapeHelper, arg))
410 arg = _MarkupEscapeHelper(arg)
411 return self.__class__(unicode.__mod__(self, arg))
415 self.__class__.__name__,
416 unicode.__repr__(self)
420 return self.__class__(unicode.join(self, imap(escape, seq)))
421 join.__doc__ = unicode.join.__doc__
423 def split(self, *args, **kwargs):
424 return map(self.__class__, unicode.split(self, *args, **kwargs))
425 split.__doc__ = unicode.split.__doc__
427 def rsplit(self, *args, **kwargs):
428 return map(self.__class__, unicode.rsplit(self, *args, **kwargs))
429 rsplit.__doc__ = unicode.rsplit.__doc__
431 def splitlines(self, *args, **kwargs):
432 return map(self.__class__, unicode.splitlines(self, *args, **kwargs))
433 splitlines.__doc__ = unicode.splitlines.__doc__
436 r"""Unescape markup again into an unicode string. This also resolves
437 known HTML4 and XHTML entities:
439 >>> Markup("Main » <em>About</em>").unescape()
440 u'Main \xbb <em>About</em>'
442 from jinja2.constants import HTML_ENTITIES
445 if name in HTML_ENTITIES:
446 return unichr(HTML_ENTITIES[name])
448 if name[:2] in ('#x', '#X'):
449 return unichr(int(name[2:], 16))
450 elif name.startswith('#'):
451 return unichr(int(name[1:]))
455 return _entity_re.sub(handle_match, unicode(self))
458 r"""Unescape markup into an unicode string and strip all tags. This
459 also resolves known HTML4 and XHTML entities. Whitespace is
462 >>> Markup("Main » <em>About</em>").striptags()
465 stripped = u' '.join(_striptags_re.sub('', self).split())
466 return Markup(stripped).unescape()
470 """Escape the string. Works like :func:`escape` with the difference
471 that for subclasses of :class:`Markup` this function would return the
475 if rv.__class__ is not cls:
479 def make_wrapper(name):
480 orig = getattr(unicode, name)
481 def func(self, *args, **kwargs):
482 args = _escape_argspec(list(args), enumerate(args))
483 _escape_argspec(kwargs, kwargs.iteritems())
484 return self.__class__(orig(self, *args, **kwargs))
485 func.__name__ = orig.__name__
486 func.__doc__ = orig.__doc__
489 for method in '__getitem__', 'capitalize', \
490 'title', 'lower', 'upper', 'replace', 'ljust', \
491 'rjust', 'lstrip', 'rstrip', 'center', 'strip', \
492 'translate', 'expandtabs', 'swapcase', 'zfill':
493 locals()[method] = make_wrapper(method)
496 if hasattr(unicode, 'partition'):
497 partition = make_wrapper('partition'),
498 rpartition = make_wrapper('rpartition')
501 if hasattr(unicode, 'format'):
502 format = make_wrapper('format')
505 if hasattr(unicode, '__getslice__'):
506 __getslice__ = make_wrapper('__getslice__')
508 del method, make_wrapper
511 def _escape_argspec(obj, iterable):
512 """Helper for various string-wrapped functions."""
513 for key, value in iterable:
514 if hasattr(value, '__html__') or isinstance(value, basestring):
515 obj[key] = escape(value)
519 class _MarkupEscapeHelper(object):
520 """Helper for Markup.__mod__"""
522 def __init__(self, obj):
525 __getitem__ = lambda s, x: _MarkupEscapeHelper(s.obj[x])
526 __str__ = lambda s: str(escape(s.obj))
527 __unicode__ = lambda s: unicode(escape(s.obj))
528 __repr__ = lambda s: str(escape(repr(s.obj)))
529 __int__ = lambda s: int(s.obj)
530 __float__ = lambda s: float(s.obj)
533 class LRUCache(object):
534 """A simple LRU Cache implementation."""
536 # this is fast for small capacities (something below 1000) but doesn't
537 # scale. But as long as it's only used as storage for templates this
540 def __init__(self, capacity):
541 self.capacity = capacity
543 self._queue = deque()
547 # alias all queue methods for faster lookup
548 self._popleft = self._queue.popleft
549 self._pop = self._queue.pop
550 if hasattr(self._queue, 'remove'):
551 self._remove = self._queue.remove
552 self._wlock = allocate_lock()
553 self._append = self._queue.append
555 def _remove(self, obj):
556 """Python 2.4 compatibility."""
557 for idx, item in enumerate(self._queue):
562 def __getstate__(self):
564 'capacity': self.capacity,
565 '_mapping': self._mapping,
566 '_queue': self._queue
569 def __setstate__(self, d):
570 self.__dict__.update(d)
573 def __getnewargs__(self):
574 return (self.capacity,)
577 """Return an shallow copy of the instance."""
578 rv = self.__class__(self.capacity)
579 rv._mapping.update(self._mapping)
580 rv._queue = deque(self._queue)
583 def get(self, key, default=None):
584 """Return an item from the cache dict or `default`"""
590 def setdefault(self, key, default=None):
591 """Set `default` if the key is not in the cache otherwise
592 leave unchanged. Return the value of this key.
601 """Clear the cache."""
602 self._wlock.acquire()
604 self._mapping.clear()
607 self._wlock.release()
609 def __contains__(self, key):
610 """Check if a key exists in this cache."""
611 return key in self._mapping
614 """Return the current size of the cache."""
615 return len(self._mapping)
619 self.__class__.__name__,
623 def __getitem__(self, key):
624 """Get an item from the cache. Moves the item up so that it has the
625 highest priority then.
627 Raise an `KeyError` if it does not exist.
629 rv = self._mapping[key]
630 if self._queue[-1] != key:
634 # if something removed the key from the container
635 # when we read, ignore the ValueError that we would
641 def __setitem__(self, key, value):
642 """Sets the value for an item. Moves the item up so that it
643 has the highest priority then.
645 self._wlock.acquire()
647 if key in self._mapping:
651 # __getitem__ is not locked, it might happen
653 elif len(self._mapping) == self.capacity:
654 del self._mapping[self._popleft()]
656 self._mapping[key] = value
658 self._wlock.release()
660 def __delitem__(self, key):
661 """Remove an item from the cache dict.
662 Raise an `KeyError` if it does not exist.
664 self._wlock.acquire()
666 del self._mapping[key]
670 # __getitem__ is not locked, it might happen
673 self._wlock.release()
676 """Return a list of items."""
677 result = [(key, self._mapping[key]) for key in list(self._queue)]
682 """Iterate over all items."""
683 return iter(self.items())
686 """Return a list of all values."""
687 return [x[1] for x in self.items()]
690 """Iterate over all values."""
691 return iter(self.values())
694 """Return a list of all keys ordered by most recent usage."""
698 """Iterate over all keys in the cache dict, ordered by
699 the most recent usage.
701 return reversed(tuple(self._queue))
705 def __reversed__(self):
706 """Iterate over the values in the cache dict, oldest items
709 return iter(tuple(self._queue))
714 # register the LRU cache as mutable mapping if possible
716 from collections import MutableMapping
717 MutableMapping.register(LRUCache)
722 class Cycler(object):
723 """A cycle helper for templates."""
725 def __init__(self, *items):
727 raise RuntimeError('at least one item has to be provided')
732 """Resets the cycle."""
737 """Returns the current item."""
738 return self.items[self.pos]
741 """Goes one item ahead and returns it."""
743 self.pos = (self.pos + 1) % len(self.items)
747 class Joiner(object):
748 """A joining helper for templates."""
750 def __init__(self, sep=u', '):
761 # we have to import it down here as the speedups module imports the
762 # markup type which is define above.
764 from jinja2._speedups import escape, soft_unicode
767 """Convert the characters &, <, >, ' and " in string s to HTML-safe
768 sequences. Use this if you need to display text that might contain
769 such characters in HTML. Marks return value as markup string.
771 if hasattr(s, '__html__'):
773 return Markup(unicode(s)
774 .replace('&', '&')
775 .replace('>', '>')
776 .replace('<', '<')
777 .replace("'", ''')
778 .replace('"', '"')
782 """Make a string unicode if it isn't already. That way a markup
783 string is not converted back to unicode.
785 if not isinstance(s, unicode):
792 from functools import partial
794 class partial(object):
795 def __init__(self, _func, *args, **kwargs):
798 self._kwargs = kwargs
799 def __call__(self, *args, **kwargs):
800 kwargs.update(self._kwargs)
801 return self._func(*(self._args + args), **kwargs)