def test_no_jinja_autoescape(): val = 'some double quote: " and a <' tpl = '{{ val }}' ctx = {'val': val} template = jingo.get_env().from_string(tpl) assert template.render(ctx) == 'some double quote: " and a <' with no_jinja_autoescape(): template = jingo.get_env().from_string(tpl) assert template.render(ctx) == 'some double quote: " and a <'
def ready(self): """ Bootstrapping stuff """ # Install gettext translations # Note: we'll remove these things with django-jinja import jingo from django.utils import translation jingo.get_env().install_gettext_translations(translation, newstyle=True) jingo.load_helpers()
def send_html_mail_jinja(subject, html_template, text_template, context, *args, **kwargs): """Sends HTML mail using a Jinja template with autoescaping turned off.""" # Get a jinja environment so we can override autoescaping for text emails. with no_jinja_autoescape(): html_template = get_env().get_template(html_template) text_template = get_env().get_template(text_template) msg = send_mail(subject, text_template.render(context), html_message=html_template.render(context), *args, **kwargs) return msg
def test_compiled_css(open_mock, subprocess_mock, getmtime_mock, time_mock): jingo.get_env().from_string("{{ css('compiled', debug=True) }}").render() eq_(subprocess_mock.Popen.mock_calls, [call(['lessc-bin', 'static/css/less.less'], stdout=ANY), call(['sass-bin', 'static/css/sass.sass'], stdout=ANY), call(['sass-bin', 'static/css/scss.scss'], stdout=ANY)]) subprocess_mock.call.assert_called_with( 'stylus-bin --include-css --include ' 'static/css < static/css/stylus.styl > static/css/stylus.styl.css', shell=True)
def test_no_links(): s = 'a <a href="http://url.link">http://example.com</a>, http://text.link' eq_(jingo.get_env().from_string('{{ s|no_links }}').render({'s': s}), 'a http://example.com, http://text.link') # Bad markup. s = '<http://bad.markup.com' eq_(jingo.get_env().from_string('{{ s|no_links }}').render({'s': s}), '') # Bad markup. s = 'some text <http://bad.markup.com' eq_(jingo.get_env().from_string('{{ s|no_links }}').render({'s': s}), 'some text')
def test_compiled_css(open_mock, subprocess_mock, getmtime_mock, time_mock): jingo.get_env().from_string("{{ css('compiled', debug=True) }}").render() eq_(subprocess_mock.Popen.mock_calls, [ call(['lessc-bin', 'static/css/less.less'], stdout=ANY), call(['sass-bin', 'static/css/sass.sass'], stdout=ANY), call(['sass-bin', 'static/css/scss.scss'], stdout=ANY) ]) subprocess_mock.call.assert_called_with( 'stylus-bin --include-css --include ' 'static/css < static/css/stylus.styl > static/css/stylus.styl.css', shell=True)
def rendered_content(self): template = self.template_name if 'user' not in self.context_data: self.context_data['user'] = self._request.user context_instance = self.resolve_context(self.context_data) # Gross, let's figure out if we're in the admin. if getattr(self._request, 'current_app', None) == 'admin': source = loader.render_to_string( template, RequestContext(self._request, context_instance)) template = jingo.get_env().from_string(source) # This interferes with our media() helper. if 'media' in self.context_data: del self.context_data['media'] # ``render_to_string`` only accepts a Template instance or a template name, # not a list. if isinstance(template, (list, tuple)): template = loader.select_template(template) if isinstance(template, Template): template = template.template return jingo.render_to_string(self._request, template, self.context_data)
def collection_widgets(context, collection, condensed=False): """Displays collection widgets""" c = dict(context.items()) if collection: c.update({'condensed': condensed, 'c': collection}) template = get_env().get_template('bandwagon/collection_widgets.html') return jinja2.Markup(template.render(c))
def rendered_content(self): template = self.template_name if 'user' not in self.context_data: self.context_data['user'] = self._request.user context_instance = self.resolve_context(self.context_data) # Gross, let's figure out if we're in the admin. if getattr(self._request, 'current_app', None) == 'admin': source = loader.render_to_string( template, RequestContext(self._request, context_instance)) template = jingo.get_env().from_string(source) # This interferes with our media() helper. if 'media' in self.context_data: del self.context_data['media'] # ``render_to_string`` only accepts a Template instance or a template name, # not a list. if isinstance(template, (list, tuple)): template = loader.select_template(template) if isinstance(template, Template): template = template.template return jingo.render_to_string( self._request, template, self.context_data)
def no_jinja_autoescape(): """Disable Jinja2 autoescape.""" env = get_env() autoescape_orig = env.autoescape env.autoescape = False yield env.autoescape = autoescape_orig
def generate_video(v, params=[]): """Takes a video object and returns HTML markup for embedding it.""" sources = [] if v.webm: sources.append({'src': _get_video_url(v.webm), 'type': 'webm'}) if v.ogv: sources.append({'src': _get_video_url(v.ogv), 'type': 'ogg'}) data_fallback = '' # Flash fallback if v.flv: data_fallback = _get_video_url(v.flv) return jingo.get_env().get_template('wikiparser/hook_video.html').render({ 'fallback': data_fallback, 'sources': sources, 'params': params, 'video': v, 'height': settings.WIKI_VIDEO_HEIGHT, 'width': settings.WIKI_VIDEO_WIDTH })
def get_embed_html(self): """ Return suitable initial HTML for embedding this file in an article, generated from a template. The template searching is from most specific to least specific, based on mime-type. For example, an attachment with mime-type 'image/png' will try to load the following templates, in order, and use the first one found: * attachments/attachments/image_png.html * attachments/attachments/image.html * attachments/attachments/generic.html """ rev = self.current_revision env = jingo.get_env() t = env.select_template([ 'attachments/attachments/%s.html' % rev.mime_type.replace('/', '_'), 'attachments/attachments/%s.html' % rev.mime_type.split('/')[0], 'attachments/attachments/generic.html' ]) return t.render({'attachment': rev})
def user_collection_list(collections=None, heading='', id='', link=None): """list of collections, as used on the user profile page""" if collections is None: collections = [] c = {'collections': collections, 'heading': heading, 'link': link, 'id': id} template = get_env().get_template('bandwagon/users/collection_list.html') return jinja2.Markup(template.render(c))
def test_app_in_fragment_cache_key(cache_mock): cache_mock.return_value = '' request = mock.Mock() request.APP.id = '<app>' request.user.is_authenticated.return_value = False template = jingo.get_env().from_string('{% cache 1 %}{% endcache %}') render(request, template) assert cache_mock.call_args[0][0].endswith('<app>')
def impala_reviews_link(addon, collection_uuid=None, link_to_list=False): t = jingo.get_env().get_template('reviews/impala/reviews_link.html') return jinja2.Markup( t.render({ 'addon': addon, 'link_to_list': link_to_list, 'collection_uuid': collection_uuid }))
def render(self): c = { 'pager': self.pager, 'num_pages': self.num_pages, 'count': self.count } t = get_env().get_template('amo/paginator.html').render(c) return jinja2.Markup(t)
def test_app_in_fragment_cache_key(cache_mock): cache_mock.return_value = "" request = mock.Mock() request.APP.id = "<app>" request.user.is_authenticated.return_value = False template = jingo.get_env().from_string("{% cache 1 %}{% endcache %}") render(request, template) assert cache_mock.call_args[0][0].endswith("<app>")
def test_truncate_purified_field_xss(): """Truncating should not introduce xss issues.""" s = 'safe <script>alert("omg")</script>' t = PurifiedTranslation(localized_string=s) env = jingo.get_env() actual = env.from_string('{{ s|truncate(100) }}').render({'s': t}) assert actual == 'safe <script>alert("omg")</script>' actual = env.from_string('{{ s|truncate(5) }}').render({'s': t}) assert actual == 'safe ...'
def test_tag_no_match(self): addon = Addon.objects.get() tag = Tag.objects.create(tag_text='http://foo.com') amo.log(amo.LOG.ADD_TAG, addon, tag) log = ActivityLog.objects.get() env = jingo.get_env() text = env.from_string('<p>{{ log }}</p>').render({'log': log}) # There should only be one a, the link to the addon, but no tag link. assert len(pq(text)('a')) == 1
def test_app_in_fragment_cache_key(cache_mock): cache_mock.return_value = '' request = mock.Mock() request.APP.id = '<app>' request.user.is_authenticated.return_value = False request.groups = [] template = jingo.get_env().from_string('{% cache 1 %}{% endcache %}') render(request, template) assert cache_mock.call_args[0][0].endswith('<app>')
def test_tag_no_match(self): addon = Addon.objects.get() tag = Tag.objects.create(tag_text='http://foo.com') ActivityLog.create(amo.LOG.ADD_TAG, addon, tag) log = ActivityLog.objects.get() env = jingo.get_env() text = env.from_string('<p>{{ log }}</p>').render({'log': log}) # There should only be one a, the link to the addon, but no tag link. assert len(pq(text)('a')) == 1
def user_vcard(context, user, table_class='person-info', is_profile=False): c = dict(context.items()) c.update({ 'profile': user, 'table_class': table_class, 'is_profile': is_profile }) t = get_env().get_template('users/vcard.html').render(c) return jinja2.Markup(t)
def test_truncate_purified_field_xss(): """Truncating should not introduce xss issues.""" s = 'safe <script>alert("omg")</script>' t = PurifiedTranslation(localized_string=s) env = jingo.get_env() actual = env.from_string('{{ s|truncate(100) }}').render({'s': t}) eq_(actual, 'safe <script>alert("omg")</script>') actual = env.from_string('{{ s|truncate(5) }}').render({'s': t}) eq_(actual, 'safe ...')
def _hook_button(self, parser, space, btn_type): btn_type, params = build_hook_params(btn_type, self.locale) if btn_type == 'refresh': template = 'wikiparser/hook_refresh_button.html' else: return _lazy(u'Button of type "%s" does not exist.') % btn_type return jingo.get_env().get_template(template).render({'params': params})
def stars(num, large=False): # check for 0.0 incase None was cast to a float. Should # be safe since lowest rating you can give is 1.0 if num is None or num == 0.0: return _('Not yet rated') else: num = min(5, int(round(num))) t = jingo.get_env().get_template('reviews/impala/reviews_rating.html') # These are getting renamed for contextual sense in the template. return jinja2.Markup(t.render({'rating': num, 'detailpage': large}))
def send_mail_jinja(subject, template, context, *args, **kwargs): """Sends mail using a Jinja template with autoescaping turned off. Jinja is especially useful for sending email since it has whitespace control. """ with no_jinja_autoescape(): template = get_env().get_template(template) msg = send_mail(subject, template.render(context), *args, **kwargs) return msg
def all_locales(addon, field_name, nl2br=False, prettify_empty=False): field = getattr(addon, field_name, None) if not addon or field is None: return trans = field.__class__.objects.filter(id=field.id, localized_string__isnull=False) ctx = dict(addon=addon, field=field, field_name=field_name, translations=trans, nl2br=nl2br, prettify_empty=prettify_empty) t = jingo.get_env().get_template('translations/all-locales.html') return jinja2.Markup(t.render(ctx))
def _hook_button(self, parser, space, btn_type): btn_type, params = build_hook_params(btn_type, self.locale) if btn_type == 'refresh': template = 'wikiparser/hook_refresh_button.html' else: return _lazy(u'Button of type "%s" does not exist.') % btn_type return jingo.get_env().get_template(template).render( {'params': params})
def test_gettext_translations(): env = jingo.get_env() ok_('jinja2.ext.i18n' in env.extensions or 'jinja2.ext.InternationalizationExtension' in env.extensions) gettext = getattr(translation, 'ugettext', None) ok_(gettext) eq_(env.globals['gettext'], gettext) ngettext = getattr(translation, 'ungettext', None) ok_(ngettext) eq_(env.globals['ngettext'], ngettext)
def test_template_substitution_crash(): translation.activate('xx') env = get_env() # The localized string has the wrong variable name in it s = '{% trans string="heart" %}Broken {{ string }}{% endtrans %}' template = env.from_string(s) rendered = render_to_string(sentinel.request, template, {}) eq_(rendered, 'Broken heart')
def test_added_lang_files(self): """ Lang files specified in the template should be added to the defaults. """ template = get_env().get_template('some_lang_files.html') # make a dummy object capable of having arbitrary attrs assigned request = type('request', (), {})() template.render({'request': request}) eq_(request.langfiles, ['dude', 'walter', 'main', 'download_button'])
def test_template_substitution_crash(): translation.activate('xx') env = get_env() # The localized string has the wrong variable name in it s = '{% trans string="heart" %}Broken {{ string }}{% endtrans %}' template = env.from_string(s) rendered = jingo.render_to_string(Mock(), template, {}) eq_(rendered, 'Broken heart')
def test_inclusion_tag(): @jingo.register.inclusion_tag('xx.html') def tag(x): return {'z': x} env = jingo.get_env() with patch.object(env, 'get_template') as mock_get_template: temp = jinja2.environment.Template('<{{ z }}>') mock_get_template.return_value = temp t = env.from_string('{{ tag(1) }}') eq_('<1>', t.render())
def test_l10n_block_locales(self): """ Parsing an l10n block with locales info should put that info on the node. """ tree = get_env().parse("""{% l10n dude locales=ru,es-ES,fr 20121212 %} This stuff is totally translated. {% endl10n %}""") l10n_block = tree.find(Block) self.assertEqual(l10n_block.locales, ['ru', 'es-ES', 'fr']) self.assertEqual(l10n_block.version, 20121212)
def report_menu(context, request, report, obj=None): """Reports Menu. navigation for the various statistic reports.""" if obj: if isinstance(obj, Addon): has_privs = False if (request.user.is_authenticated() and (acl.action_allowed(request, amo.permissions.STATS_VIEW) or obj.has_author(request.user))): has_privs = True t = get_env().get_template('stats/addon_report_menu.html') c = {'addon': obj, 'has_privs': has_privs} return jinja2.Markup(t.render(c)) if isinstance(obj, Collection): t = get_env().get_template('stats/collection_report_menu.html') c = { 'collection': obj, } return jinja2.Markup(t.render(c)) t = get_env().get_template('stats/global_report_menu.html') return jinja2.Markup(t.render())
def _make_message(title=None, message=None, title_safe=False, message_safe=False): c = { 'title': title, 'message': message, 'title_safe': title_safe, 'message_safe': message_safe } t = get_env().get_template('message_content.html').render(c) return DoubleSafe(t)
def test_no_links(): env = jingo.get_env().from_string('{{ s|no_links }}') s = 'a <a href="http://url.link">http://example.com</a>, http://text.link' assert env.render({'s': s}) == 'a http://example.com, http://text.link' # Bad markup. s = '<http://bad.markup.com' assert env.render({'s': s}) == '' # Bad markup. s = 'some text <http://bad.markup.com' assert env.render({'s': s}) == 'some text'
def send_mail(request, template, subject, emails, context, perm_setting=None): # Get a jinja environment so we can override autoescaping for text emails. env = jingo.get_env() env.autoescape = False # Link to our newfangled "Account Settings" page. manage_url = absolutify(reverse('account.settings')) + '#notifications' template = env.get_template(template) amo_send_mail(subject, jingo.render_to_string(request, template, context), recipient_list=emails, from_email=settings.NOBODY_EMAIL, use_blacklist=False, perm_setting=perm_setting, manage_url=manage_url, headers={'Reply-To': settings.MKT_REVIEWERS_EMAIL})
def file_tree(files, selected): depth = 0 output = ['<ul class="root">'] t = get_env().get_template('files/node.html') for k, v in files.items(): if v['depth'] > depth: output.append('<ul class="js-hidden">') elif v['depth'] < depth: output.extend(['</ul>' for x in range(v['depth'], depth)]) output.append(t.render({'value': v, 'selected': selected})) depth = v['depth'] output.extend(['</ul>' for x in range(depth, -1, -1)]) return jinja2.Markup('\n'.join(output))
def test_js(getmtime, time): getmtime.return_value = 1 time.return_value = 1 env = jingo.get_env() t = env.from_string("{{ js('common', debug=True) }}") s = t.render() expected = "\n".join( ['<script src="%s?build=1"></script>' % (settings.STATIC_URL + j) for j in settings.MINIFY_BUNDLES['js']['common']]) eq_(s, expected)
def test_inline_css_helper(): env = jingo.get_env() t = env.from_string("{{ inline_css('common', debug=True) }}") s = t.render() eq_(s, '<style type="text/css" media="screen,projection,tv">' 'body {\n color: #999;\n}\n</style>') t = env.from_string("{{ inline_css('common', debug=False) }}") s = t.render() eq_(s, '<style type="text/css" media="screen,projection,tv">body' '{color:#999}</style>')
def test_inline_css(monkeypatch): jingo.load_helpers() env = jingo.get_env() t = env.from_string("{{ inline_css('zamboni/mobile', debug=True) }}") # Monkeypatch settings.LESS_BIN to not call the less compiler. We don't # need nor want it in tests. monkeypatch.setattr(settings, 'LESS_BIN', 'ls') # Monkeypatch jingo_minify.helpers.is_external to counter-effect the # autouse fixture in conftest.py. monkeypatch.setattr(amo.helpers, 'is_external', lambda css: False) s = t.render() assert 'background-image: url(/static/img/icons/stars.png);' in s
def test_css(getmtime, time): getmtime.return_value = 1 time.return_value = 1 env = jingo.get_env() t = env.from_string("{{ css('common', debug=True) }}") s = t.render() expected = "\n".join( ['<link rel="stylesheet" media="screen,projection,tv" ' 'href="%s?build=1" />' % (settings.STATIC_URL + j) for j in settings.MINIFY_BUNDLES['css']['common']]) eq_(s, expected)
def test_inline_css_helper_external_url(): env = jingo.get_env() t = env.from_string("{{ inline_css('common_url', debug=True) }}") s = t.render() eq_(s, '<link rel="stylesheet" media="screen,projection,tv" ' 'href="http://example.com/test.css" />') t = env.from_string("{{ inline_css('common_url', debug=False) }}") s = t.render() eq_(s, '<style type="text/css" media="screen,projection,tv">' 'body{color:#999}</style>')