Skip to content

Commit be5b0ed

Browse files
committed
Add basic Jinja tests
1 parent 6d8e981 commit be5b0ed

35 files changed

+330
-10
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ This package automates the maintenance of UI pattern libraries or styleguides fo
1313
- Create reusable patterns by creating Django templates files as usual.
1414
- All patterns automatically show up in the pattern library’s interface.
1515
- Define data as YAML files for the templates to render with the relevant Django context.
16-
- Override Django templates tags as needed to mock the template’s dependencies.
16+
- Override Django Templates tags as needed to mock the template’s dependencies.
1717
- Document your patterns with Markdown.
18+
- Experimental: support for Jinja templates.
1819

1920
## Why you need this
2021

pattern_library/monkey_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def node_render(context):
126126

127127
def override_jinja_tags():
128128
"""
129-
Overrides jinja extends and include tags for use in your pattern library.
129+
Experimental. Overrides jinja extends and include tags for use in your pattern library.
130130
Call it in your settings to override tags
131131
"""
132132
global jinja_visit_Extends
@@ -136,7 +136,7 @@ def override_jinja_tags():
136136
except ModuleNotFoundError:
137137
ModuleNotFoundError("install jinja2 to override jinja tags")
138138

139-
from .loader_tags import template_new_context, visit_extends
139+
from pattern_library.loader_tags import template_new_context, visit_extends
140140

141141
jinja_visit_Extends = JinjaCodeGenerator.visit_Extends
142142
JinjaTemplate.new_context = template_new_context

pattern_library/utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@ def get_template_ancestors(cls, template_name, context=None, ancestors=None):
307307
context = Context()
308308

309309
pattern_template = get_template(template_name)
310-
# todo - make sure envrionment has context passed in
311310
environment = pattern_template.template.environment
312311
nodelist = environment.parse(pattern_template.template.name)
313312
parent_template_name = nodelist.find(Extends)

tests/jinja/non-patterns/include.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SHOWME
2+
{% if False %}
3+
HIDEME
4+
{% endif %}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
included content from variable
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!doctype html>
2+
<html lang="en-GB">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>{% block title %}Fragment{% endblock %}</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1" />
7+
8+
<link rel="stylesheet" href="{{ static('main.css') }}">
9+
</head>
10+
<body>
11+
<main>
12+
{% block content %}{% endblock %}
13+
</main>
14+
<script src="{{ static('main.js') }}"></script>
15+
</body>
16+
</html>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{% extends 'patterns_jinja/base_jinja.html' %}
2+
3+
{% block title %}{{ page.title }}{% endblock %}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<div class="accordion" data-accordion>
2+
{% for accordion in accordions %}
3+
<div class="accordion__panel" data-accordion-panel>
4+
<h3 class="accordion__title heading heading--4">
5+
<button class="accordion__toggle" type="button" data-accordion-toggle aria-pressed="true" aria-expanded="true" aria-controls="{{ id_prefix }}-content-{{ loop.index }}">
6+
<span class="accordion__title-inner">{{ accordion.title }}</span>
7+
{% set name="chevron-down" %}
8+
{% set classname="accordion__icon" %}
9+
{% include "patterns_jinja/components/icons/icon.html" %}
10+
</button>
11+
</h3>
12+
<div id="{{ id_prefix }}-content-{{ loop.index }}" class="accordion__content" data-accordion-content>
13+
<p>{{ accordion.description }}</p>
14+
</div>
15+
</div>
16+
{% endfor %}
17+
</div>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Accordion (Jinja)
2+
3+
The accordion is a good example of a pattern library component. This one uses [Jinja](https://jinja.palletsprojects.com/).
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
context:
2+
id_prefix: test
3+
accordions:
4+
- title: Title A (Jinja)
5+
description: Description A. Ask for help.
6+
- title: Title B
7+
description: Description B. Ask for help.
8+
- title: Title C
9+
description: Description C. Ask for help.
10+
- title: Title D
11+
description: Description D. Ask for help.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<a href="{% if target_url %}{{ target_url }}{% else %}{{ pageurl(target_page) }}{% endif %}" class="button">
2+
{% if label %}{{ label }}{% else %}{{ target_page.title }}{% endif %}
3+
</a>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
context:
2+
target_page:
3+
title: Get started
4+
tags:
5+
pageurl:
6+
target_page:
7+
raw: /get-started
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<svg class="icon icon--{{ name }}{% if classname %} {{ classname }}{% endif %}" aria-hidden="true" focusable="false">
2+
<use xlink:href="#{{ name }}"></use>
3+
</svg>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
context:
2+
name: close
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<svg style="display: none;">
2+
<symbol id="close" viewBox="0 0 24 24">
3+
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path>
4+
<path d="M0 0h24v24H0z" fill="none"></path>
5+
</symbol>
6+
7+
<symbol id="cancel" viewBox="0 0 11 12">
8+
<rect transform="rotate(45 5.5 6)" x="5" y="-1" width="1" height="14" rx=".5"/>
9+
<rect transform="rotate(135 5.5 6)" x="5" y="-1" width="1" height="14" rx=".5"/>
10+
</symbol>
11+
12+
<symbol id="chevron-down" viewBox="0 0 23 14">
13+
<path d="M.893 1.5L11.5 12.107 22.107 1.5" stroke="currentColor" stroke-width="2" fill="none" vector-effect="non-scaling-stroke" />
14+
</symbol>
15+
16+
<symbol id="checkmark" viewBox="0 0 12 10">
17+
<path d="M1 4.364l3.536 3.535 6.363-6.363" stroke="currentColor" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round"/>
18+
</symbol>
19+
</svg>
20+
{# Show available icons, in pattern library view only #}
21+
{% if is_pattern_library %}
22+
<template>
23+
{% set name="__icon__" %}
24+
{% include "patterns_jinja/components/icons/icon.html" %}
25+
</template>
26+
<script>
27+
const template = document.currentScript.previousElementSibling;
28+
const symbols = [...template.previousElementSibling.querySelectorAll('symbol')];
29+
const list = document.createElement('ul');
30+
list.innerHTML = symbols.map(el => `<li>${el.id}&nbsp;${template.innerHTML.replace(/__icon__/g, el.id)}</li>`).join('');
31+
document.body.appendChild(list);
32+
</script>
33+
{% endif %}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{ atom_var }}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Documentation for test atom - heading 1
2+
3+
**bold text**
4+
5+
*italic text*
6+
7+
## Here's a heading 2
8+
9+
### Here's a heading 3
10+
11+
- here's a list item
12+
- and another
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
context:
2+
atom_var: 'atom_var value from test_atom.yaml'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{% block content %}base content{% endblock %}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{% extends parent_template_name %}
2+
3+
{% block content %}{{ super() }} - extended content{% endblock %}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
context:
2+
parent_template_name: patterns_jinja/components/test_extends/base.html
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{% include 'non-patterns/include.html' %}
2+
{% include variable_include %}
3+
4+
{{ error_tag() }}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
context:
2+
variable_include: non-patterns/variable_include.html
3+
4+
tags:
5+
error_tag:
6+
include:
7+
template_name: 'non-patterns/include.html'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{% include 'patterns_jinja/components/test_atom/test_atom.html' %}
2+
{% set atom_var='atom_var value from test_molecule.html include tag' %}
3+
{% include 'patterns_jinja/components/test_atom/test_atom.html' %}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name: Pretty name for test molecule
2+
3+
context:
4+
atom_var: 'atom_var value from test_molecule.yaml'
5+
utf8_test_var: '你好,世界'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
No context
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{% extends "patterns_jinja/base_jinja.html" %}
2+
3+
{% block content %}
4+
<h1>{% if search_query %}Search results for “{{ search_query }}”{% else %}Search{% endif %}</h1>
5+
6+
{% if search_results %}
7+
{% with count=paginator.count %}
8+
{{ count }} result{{ count|pluralize }} found.
9+
{% endwith %}
10+
11+
{% for result in search_results %}
12+
<h4>{{ result.title }}</h4>
13+
{% endfor %}
14+
15+
{% if paginator.num_pages > 1 %}
16+
<nav aria-label="Pagination">
17+
<ul>
18+
{% if search_results.has_previous %}
19+
<li><a href="#page={{ search_results.previous_page_number() }}{% if search_query %}&amp;query={{ search_query|urlencode }}{% endif %}">previous</a></li>
20+
{% endif %}
21+
22+
<li>{{ search_results.number }}/{{ paginator.num_pages }}</li>
23+
24+
{% if search_results.has_next %}
25+
<li><a href="#page={{ search_results.next_page_number() }}{% if search_query %}&amp;query={{ search_query|urlencode }}{% endif %}">next</a></li>
26+
{% endif %}
27+
</ul>
28+
</nav>
29+
{% endif %}
30+
31+
{% elif search_query %}
32+
No results found.
33+
{% endif %}
34+
{% endblock %}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
context:
2+
search_query: test query
3+
search_results:
4+
- title: First result
5+
- title: Second result
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{% extends 'patterns_jinja/base_page_jinja.html' %}
2+
3+
{% block content %}
4+
<h1>{{ page.title }}</h1>
5+
{{ page.body }}
6+
7+
{% include "patterns_jinja/components/accordion/accordion.html" %}
8+
9+
{% if is_pattern_library %}
10+
<p>is_pattern_library = {{ is_pattern_library }}</p>
11+
{% endif %}
12+
{% endblock %}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
context:
2+
page:
3+
title: Jinja test page
4+
body: >
5+
<p>
6+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
7+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
8+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
9+
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
10+
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
11+
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
12+
</p>

tests/jinja2.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from django.apps import apps
2+
from django.template.context_processors import csrf
3+
from django.template.defaultfilters import (
4+
cut,
5+
date,
6+
linebreaks,
7+
pluralize,
8+
slugify,
9+
truncatewords,
10+
urlencode,
11+
)
12+
from django.contrib.staticfiles.storage import staticfiles_storage
13+
from django.urls import reverse
14+
15+
from jinja2 import Environment
16+
17+
from pattern_library.monkey_utils import override_jinja_tags
18+
19+
20+
if apps.is_installed("pattern_library"):
21+
override_jinja_tags()
22+
23+
24+
def error_tag():
25+
"Just raise an exception, never do anything"
26+
raise Exception("error_tag raised an exception")
27+
28+
29+
def pageurl(page):
30+
"""Approximation of wagtail built-in tag for realistic example."""
31+
return "/page/url"
32+
33+
34+
def environment(**options):
35+
env = Environment(**options)
36+
env.globals.update(
37+
{
38+
"static": staticfiles_storage.url,
39+
"url": reverse,
40+
"csrf": csrf,
41+
"error_tag": error_tag,
42+
"pageurl": pageurl,
43+
}
44+
)
45+
env.filters.update(
46+
{
47+
"cut": cut,
48+
"date": date,
49+
"linebreaks": linebreaks,
50+
"pluralize": pluralize,
51+
"slugify": slugify,
52+
"truncatewords": truncatewords,
53+
"urlencode": urlencode,
54+
}
55+
)
56+
return env

tests/pattern_contexts.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,34 @@ def replicate_pagination(context, request):
3131

3232
# add dummy items to force pagination
3333
for i in range(50):
34-
object_list.append(None)
34+
object_list.append({"title": i})
35+
36+
# paginate and add ListView-like values
37+
paginator = Paginator(object_list, original_length)
38+
context.update(
39+
paginator=paginator,
40+
search_results=paginator.page(10),
41+
is_paginated=True,
42+
object_list=object_list,
43+
)
44+
45+
46+
@register_context_modifier(template="patterns_jinja/pages/search/search.html")
47+
def replicate_pagination_jinja(context, request):
48+
"""
49+
Replace lists of items using the 'page_obj.object_list' key
50+
with a real Paginator page, and add a few other pagination-related
51+
things to the context (like Django's `ListView` does).
52+
"""
53+
object_list = context.pop("search_results", None)
54+
if object_list is None:
55+
return
56+
57+
original_length = len(object_list)
58+
59+
# add dummy items to force pagination
60+
for i in range(50):
61+
object_list.append({"title": i})
3562

3663
# paginate and add ListView-like values
3764
paginator = Paginator(object_list, original_length)

0 commit comments

Comments
 (0)