Mercurial > piecrust2
changeset 65:071cc99b1779
Jinja templating now has `spaceless`, `|keys` and `|values`.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 29 Aug 2014 08:06:43 -0700 |
parents | 9ae3237365eb |
children | e4a24512b814 |
files | piecrust/templating/jinjaengine.py |
diffstat | 1 files changed, 62 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/piecrust/templating/jinjaengine.py Fri Aug 29 08:06:17 2014 -0700 +++ b/piecrust/templating/jinjaengine.py Fri Aug 29 08:06:43 2014 -0700 @@ -5,7 +5,9 @@ from jinja2 import Environment, FileSystemLoader, TemplateNotFound from jinja2.exceptions import TemplateSyntaxError from jinja2.ext import Extension, Markup +from jinja2.lexer import Token, describe_token from jinja2.nodes import CallBlock, Const +from compressinja.html import HtmlCompressor, StreamProcessContext from pygments import highlight from pygments.formatters import HtmlFormatter from pygments.lexers import get_lexer_by_name, guess_lexer @@ -69,7 +71,8 @@ loader = FileSystemLoader(self.app.templates_dirs) extensions = [ PieCrustHighlightExtension, - PieCrustCacheExtension] + PieCrustCacheExtension, + PieCrustSpacelessExtension] if autoescape: extensions.append('jinja2.ext.autoescape') self.env = PieCrustEnvironment( @@ -86,6 +89,8 @@ self.globals.update({ 'fail': raise_exception}) self.filters.update({ + 'keys': get_dict_keys, + 'values': get_dict_values, 'paginate': self._paginate, 'formatwith': self._formatWith, 'markdown': lambda v: self._formatWith(v, 'markdown'), @@ -140,6 +145,18 @@ raise Exception(msg) +def get_dict_keys(value): + if isinstance(value, list): + return [i[0] for i in value] + return value.keys() + + +def get_dict_values(value): + if isinstance(value, list): + return [i[1] for i in value] + return value.values() + + def add_no_cache_parameter(value, param_name='t', param_value=None): if not param_value: param_value = time.time() @@ -251,7 +268,7 @@ class PieCrustCacheExtension(Extension): - tags = set(['pccache']) + tags = set(['pccache', 'cache']) def __init__(self, environment): super(PieCrustCacheExtension, self).__init__(environment) @@ -273,7 +290,8 @@ # now we parse the body of the cache block up to `endpccache` and # drop the needle (which would always be `endpccache` in that case) - body = parser.parse_statements(['name:endpccache'], drop_needle=True) + body = parser.parse_statements(['name:endpccache', 'name:endcache'], + drop_needle=True) # now return a `CallBlock` node that calls our _cache_support # helper method on this extension. @@ -294,6 +312,47 @@ return rv +class PieCrustSpacelessExtension(HtmlCompressor): + """ A re-implementation of `SelectiveHtmlCompressor` so that we can + both use `strip` or `spaceless` in templates. + """ + def filter_stream(self, stream): + ctx = StreamProcessContext(stream) + strip_depth = 0 + while 1: + if stream.current.type == 'block_begin': + for tk in ['strip', 'spaceless']: + change = self._processToken(ctx, stream, tk) + if change != 0: + strip_depth += change + if strip_depth < 0: + ctx.fail('Unexpected tag end%s' % tk) + break + if strip_depth > 0 and stream.current.type == 'data': + ctx.token = stream.current + value = self.normalize(ctx) + yield Token(stream.current.lineno, 'data', value) + else: + yield stream.current + next(stream) + + def _processToken(self, ctx, stream, test_token): + change = 0 + if (stream.look().test('name:%s' % test_token) or + stream.look().test('name:end%s' % test_token)): + stream.skip() + if stream.current.value == test_token: + change = 1 + else: + change = -1 + stream.skip() + if stream.current.type != 'block_end': + ctx.fail('expected end of block, got %s' % + describe_token(stream.current)) + stream.skip() + return change + + def php_format_to_strftime_format(fmt): replacements = { 'd': '%d',