Source code for cookiecutter.extensions

"""Jinja2 extensions."""

import json
import string
import uuid
from secrets import choice

import arrow
from jinja2 import nodes
from jinja2.ext import Extension
from slugify import slugify as pyslugify


[docs] class JsonifyExtension(Extension): """Jinja2 extension to convert a Python object to JSON.""" def __init__(self, environment): """Initialize the extension with the given environment.""" super().__init__(environment) def jsonify(obj): return json.dumps(obj, sort_keys=True, indent=4) environment.filters['jsonify'] = jsonify
[docs] class RandomStringExtension(Extension): """Jinja2 extension to create a random string.""" def __init__(self, environment): """Jinja2 Extension Constructor.""" super().__init__(environment) def random_ascii_string(length, punctuation=False): if punctuation: corpus = "".join((string.ascii_letters, string.punctuation)) else: corpus = string.ascii_letters return "".join(choice(corpus) for _ in range(length)) environment.globals.update(random_ascii_string=random_ascii_string)
[docs] class SlugifyExtension(Extension): """Jinja2 Extension to slugify string.""" def __init__(self, environment): """Jinja2 Extension constructor.""" super().__init__(environment) def slugify(value, **kwargs): """Slugifies the value.""" return pyslugify(value, **kwargs) environment.filters['slugify'] = slugify
[docs] class UUIDExtension(Extension): """Jinja2 Extension to generate uuid4 string.""" def __init__(self, environment): """Jinja2 Extension constructor.""" super().__init__(environment) def uuid4(): """Generate UUID4.""" return str(uuid.uuid4()) environment.globals.update(uuid4=uuid4)
[docs] class TimeExtension(Extension): """Jinja2 Extension for dates and times.""" tags = {'now'} def __init__(self, environment): """Jinja2 Extension constructor.""" super().__init__(environment) environment.extend(datetime_format='%Y-%m-%d') def _datetime(self, timezone, operator, offset, datetime_format): d = arrow.now(timezone) # parse shift params from offset and include operator shift_params = {} for param in offset.split(','): interval, value = param.split('=') shift_params[interval.strip()] = float(operator + value.strip()) d = d.shift(**shift_params) if datetime_format is None: datetime_format = self.environment.datetime_format return d.strftime(datetime_format) def _now(self, timezone, datetime_format): if datetime_format is None: datetime_format = self.environment.datetime_format return arrow.now(timezone).strftime(datetime_format)
[docs] def parse(self, parser): """Parse datetime template and add datetime value.""" lineno = next(parser.stream).lineno node = parser.parse_expression() if parser.stream.skip_if('comma'): datetime_format = parser.parse_expression() else: datetime_format = nodes.Const(None) if isinstance(node, nodes.Add): call_method = self.call_method( '_datetime', [node.left, nodes.Const('+'), node.right, datetime_format], lineno=lineno, ) elif isinstance(node, nodes.Sub): call_method = self.call_method( '_datetime', [node.left, nodes.Const('-'), node.right, datetime_format], lineno=lineno, ) else: call_method = self.call_method( '_now', [node, datetime_format], lineno=lineno, ) return nodes.Output([call_method], lineno=lineno)