Skip to content

Commit 36fbd49

Browse files
committed
Add missing docs and tests for API endpoint
1 parent e3cd9a4 commit 36fbd49

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed

docs/recipes/api-rendering.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# API rendering
2+
3+
For additional flexibility, django-pattern-library supports rendering patterns via an API endpoint.
4+
This can be useful when implementing a custom UI while still using the pattern library’s Django rendering features.
5+
6+
The API endpoint is available at `api/v1/render-pattern`. It accepts POST requests with a JSON payload containing the following fields:
7+
8+
- `template_name` – the path of the template to render
9+
- `config` – the configuration for the template, with the same data structure as the configuration files (`context` and `tags`).
10+
11+
Here is an example, with curl:
12+
13+
```bash
14+
echo '{"template_name": "patterns/molecules/button/button.html", "config": {"context": {"target_page": {"title": "API"}}, "tags": {"pageurl":{"target_page":{"raw": "/hello-api"}}}}}' | curl -d @- http://localhost:8000/api/v1/render-pattern
15+
```
16+
17+
The response will be the pattern’s rendered HTML:
18+
19+
```html
20+
<a href="/hello-api" class="button">
21+
API
22+
</a>
23+
```
24+
25+
Note compared to iframe rendering, this API always renders the pattern’s HTML standalone, never within a base template.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ nav:
5050
- 'Inclusion tags': 'recipes/inclusion-tags.md'
5151
- 'Looping for tags': 'recipes/looping-for-tags.md'
5252
- 'Pagination': 'recipes/pagination.md'
53+
- 'API rendering': 'recipes/api-rendering.md'
5354
- 'Reference':
5455
- 'API and settings': 'reference/api.md'
5556
- 'Concepts': 'reference/concepts.md'

pattern_library/monkey_utils.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ def node_render(context):
3030
tag_overridden = False
3131
result = ""
3232

33-
# Load pattern's config
34-
current_template_name = parser.origin.template_name
33+
# Get overriden tag config.
3534
tag_overrides = context.get("__pattern_library_tag_overrides", {})
3635

3736
# Extract values for lookup from the token
@@ -87,7 +86,7 @@ def node_render(context):
8786
logger.warning(
8887
'No default or stub data defined for the "%s" tag in the "%s" template',
8988
tag_name,
90-
current_template_name,
89+
parser.origin.template_name,
9190
)
9291

9392
return original_node_render(context)

tests/tests/test_views.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,32 @@ def test_fragment_extended_from_variable(self):
116116
),
117117
"base content - extended content",
118118
)
119+
120+
121+
class APIViewsTestCase(SimpleTestCase):
122+
def test_renders_with_tag_overrides(self):
123+
api_endpoint = reverse("pattern_library:render_pattern_api")
124+
response = self.client.post(
125+
api_endpoint,
126+
content_type="application/json",
127+
data={
128+
"template_name": "patterns/molecules/button/button.html",
129+
"config": {
130+
"context": {"target_page": {"title": "API"}},
131+
"tags": {"pageurl": {"target_page": {"raw": "/hello-api"}}},
132+
},
133+
},
134+
)
135+
self.assertContains(response, '/hello-api')
136+
137+
def test_404(self):
138+
api_endpoint = reverse("pattern_library:render_pattern_api")
139+
response = self.client.post(
140+
api_endpoint,
141+
content_type="application/json",
142+
data={
143+
"template_name": "doesnotexist.html",
144+
"config": {},
145+
},
146+
)
147+
self.assertEqual(response.status_code, 404)

0 commit comments

Comments
 (0)