|
1 | 1 | # Introduction |
2 | 2 |
|
3 | | -## ⭐ Features |
4 | | - |
5 | | -- Use HTML-like elements in Django templates, e.g. `<dj-some-partial />` instead of `{% include 'some-partial.html' %}` |
6 | | -- Can be sprinkled in as needed to enhance existing Django functionality |
7 | | -- Since it looks like HTML, syntax highlighting mostly "just works" |
8 | | -- Wraps components in a custom HTML element for easier debugging and targeted CSS styling |
9 | | -- Support for the [Shadow DOM](https://dj-angles.adamghill.com/en/latest/components/#css-scoping) to encapsulate component styles |
10 | | -- Error boundaries to catch and display template errors |
11 | | -- Lightweight way to submit forms via AJAX and swap in the resulting HTML |
12 | | - |
13 | | -### Third-party package integrations |
14 | | - |
15 | | -- Support for Django 6.0 [template partials](https://docs.djangoproject.com/en/stable/ref/templates/language/#template-partials) |
16 | | -- [django-compressor](https://django-compressor.readthedocs.io) |
17 | | -- [django-components](https://django-components.github.io/django-components/) |
18 | | -- [django-viewcomponent](https://github.com/rails-inspire-django/django-viewcomponent) |
19 | | -- [django-bird](https://django-bird.readthedocs.io) |
20 | | -- [django-template-partials](https://github.com/carltongibson/django-template-partials) |
21 | | - |
22 | | -### Template tags |
23 | | - |
24 | | -- [`call`](https://dj-angles.adamghill.com/en/latest/template-tags/call/): call functions in a template |
25 | | -- [`model`](https://dj-angles.adamghill.com/en/latest/template-tags/model/): call a model in a template |
26 | | -- [`template`](https://dj-angles.adamghill.com/en/latest/template-tags/template/): inline template |
27 | | -- [`view`](https://dj-angles.adamghill.com/en/latest/template-tags/view/): render a view in a template |
28 | | - |
29 | | -### Filters |
30 | | - |
31 | | -- [`dateformat`](https://dj-angles.adamghill.com/en/latest/filters/dateformat/): use Python [`strftime`](https://strftime.org) format for formatting dates as a string |
32 | | - |
33 | | -## 💥 Examples |
34 | | - |
35 | | -```html |
36 | | -<!-- base.html --> |
37 | | -<dj-block name="content"> <!-- {% block content %} --> |
38 | | -</dj-block> <!-- {% endblock content %} --> |
39 | | -``` |
40 | | - |
41 | | -```html |
42 | | -<!-- template-tags.html --> |
43 | | -<dj-extends parent="base.html" /> <!-- {% extends "base.html" %} --> |
44 | | - |
45 | | -<dj-block name="content"> <!-- {% block content %} --> |
46 | | - <!-- components --> |
47 | | - <dj-some-partial /> <!-- {% include "test-partial.html" %} --> |
48 | | - <dj-include template="test-partial.html" /> <!-- {% include "test-partial.html" %} --> |
49 | | - |
50 | | - <dj-verbatim> <!-- {% verbatim %} --> |
51 | | - This is verbatim: {% include %} |
52 | | - </dj-verbatim> <!-- {% endverbatim %} --> |
53 | | - |
54 | | - <dj-comment> <!-- {% comment %} --> |
55 | | - this is a comment |
56 | | - </dj-comment> <!-- {% endcomment %} --> |
57 | | - |
58 | | - <dj-autoescape-on> <!-- {% autoescape-on %} --> |
59 | | - This is escaped |
60 | | - </dj-autoescape-on> <!-- {% endautoescape %} --> |
61 | | - |
62 | | - <dj-autoescape-off> <!-- {% autoescape off %} --> |
63 | | - This is not escaped |
64 | | - </dj-autoescape-off> <!-- {% endautoescape %} --> |
65 | | - |
66 | | - <dj-csrf /> <!-- {% csrf_token %} --> |
67 | | - |
68 | | - <dj-debug /> <!-- {% debug %} --> |
69 | | -</dj-block> <!-- {% endblock content %} --> |
70 | | -``` |
71 | | - |
72 | | -```html |
73 | | -<!-- static-helpers.html --> |
74 | | -<dj-image src="img/django.jpg" /> <!-- <img src="{% static 'img/django.jpg' %}" /> --> |
75 | | -<dj-css href="css/styles.css" /> <!-- <link href="{% static 'css/styles.css' %}" rel="stylesheet" /> --> |
76 | | -``` |
77 | | - |
78 | | -```html |
79 | | -<!-- call-code-from-template.html --> |
80 | | -<dj-call code="slugify('Hello Goodbye')" as="variable_name" /> <!-- {% call slugify("Hello Goodbye") as variable_name %} --> |
81 | | -<dj-model code="Book.objects.filter(id=1)" as="book" /> <!-- {% model Book.objects.filter(id=1) as book %} --> |
82 | | -<dj-view name="some-view" /> <!-- {% view "some-view" %} --> |
83 | | -``` |
84 | | - |
85 | | -```html |
86 | | -<!-- django-compressor.html --> |
87 | | -<dj-compress css> <!-- {% compress css %} --> |
88 | | - <style>.critical { color: red; }</style> |
89 | | -</dj-compress> <!-- {% endcompress %} --> |
| 3 | +```{include} ../../README.md |
| 4 | +:start-after: <!-- readme-features-start --> |
| 5 | +:end-before: <!-- readme-features-end --> |
90 | 6 | ``` |
91 | 7 |
|
92 | | -```html |
93 | | -<!-- third-party-component-libraries.html --> |
94 | | - |
95 | | -<!-- django-components --> |
96 | | -<dj-component name="button">Click me</dj-component> <!-- {% component "button" %}Click me{% endcomponent %} --> |
97 | | - |
98 | | -<!-- django-viewcomponent --> |
99 | | -<dj-viewcomponent name="button">Click me</dj-viewcomponent> <!-- {% viewcomponent "button" %}Click me{% endviewcomponent %} --> |
100 | | - |
101 | | -<!-- django-bird --> |
102 | | -<dj-bird template="button" class="btn">Click me</dj-bird> <!-- {% bird "button" class="btn" %}Click me{% endbird %} --> |
103 | | - |
104 | | -<!-- django-template-partials --> |
105 | | -<dj-partial name="sidebar"> <!-- {% partialdef sidebar %} --> |
106 | | - <p>Sidebar content</p> |
107 | | -</dj-partial> <!-- {% endpartialdef %} --> |
108 | | - |
109 | | -<dj-partial name="sidebar" /> <!-- {% partial sidebar %} --> |
| 8 | +```{include} ../../README.md |
| 9 | +:start-after: <!-- readme-examples-start --> |
| 10 | +:end-before: <!-- readme-examples-end --> |
110 | 11 | ``` |
111 | 12 |
|
112 | | -```html |
113 | | -<!-- inline-expressions.html --> |
114 | | -{{ request.user.username or request.user.email }} <!-- {% if request.user.username %}{{ request.user.username }}{% else %}{{ request.user.email }}{% endif %} --> |
115 | | -{{ request.user.username if request.user.is_authenticated else "Unknown" }} <!-- {% if request.user.is_authenticated %}{{ request.user.username }}{% else %}Unknown{% endif %} --> |
| 13 | +```{include} ../../README.md |
| 14 | +:start-after: <!-- readme-inspiration-start --> |
| 15 | +:end-before: <!-- readme-inspiration-end --> |
116 | 16 | ``` |
117 | 17 |
|
118 | | -```html |
119 | | -<!-- error-boundaries.html --> |
120 | | -<dj-block name="content" error-boundary> |
121 | | - <dj-include template="missing-template.html" /> |
122 | | -</dj-block> |
123 | | - |
124 | | -<dj-error-boundary> |
125 | | - <dj-include template="missing-template.html" /> |
126 | | -</dj-error-boundary> |
127 | | -``` |
128 | | - |
129 | | -```html |
130 | | -<!-- ajax-form-submission.html --> |
131 | | -<dj-form action="/submit" method="POST" swap="outerHTML" ajax csrf> <!-- <ajax-form><form action="/submit" method="POST">{% csrf_token %} --> |
132 | | - <button type="submit">Submit</button> |
133 | | -</dj-form><!-- </form></ajax-form> --> |
134 | | -``` |
135 | | - |
136 | | -```html |
137 | | -<!-- conditional-attributes.html --> |
138 | | -<div dj-if="True"> <!-- {% if True %}<div> --> |
139 | | - If |
140 | | -</div> |
141 | | -<div dj-elif="False"> <!-- {% elif False %}<div> --> |
142 | | - Elif |
143 | | -</div> |
144 | | -<div dj-else> <!-- {% else %}<div> --> |
145 | | - Else |
146 | | -</div> <!-- </div>{% endif %} --> |
147 | | -``` |
148 | | - |
149 | | -## ✨ Inspiration |
150 | | - |
151 | | -- [Web Components](https://web.dev/learn/html/template) |
152 | | -- [Cotton](https://django-cotton.com) by [wrabit](https://github.com/wrabit) |
153 | | - |
154 | 18 | ```{toctree} |
155 | 19 | :maxdepth: 2 |
156 | 20 | :hidden: |
|
0 commit comments