Plain is headed towards 1.0! Subscribe for development updates →

 1# plain.elements
 2
 3**Use HTML tags to include HTML template components.**
 4
 5Elements are an alternative to Jinja [`{% include %}`](https://jinja.palletsprojects.com/en/stable/templates/#include) or [macros](https://jinja.palletsprojects.com/en/stable/templates/#macros) and flow better with existing HTML by using a compatible syntax. They are distinguished from built-in HTML tags by using a capitalized tag name (so `<Button>` doesn't clash with `<button>`).
 6
 7To make a `<Submit>` element, for example, you would create a template named `templates/elements/Submit.html`.
 8
 9```html
10<!-- templates/elements/Submit.html -->
11<button type="submit" class="btn">
12    {{ children }}
13</button>
14```
15
16An element can be used in any other template by enabling them with `{% use_elements %}` and then using the caplitalized tag name.
17
18```html
19{% extends "admin/base.html" %}
20
21{% use_elements %}
22
23{% block content %}
24<form method="post">
25    {{ csrf_input }}
26    <!-- Form fields here -->
27    <Submit>Save</Submit>
28</form>
29{% endblock %}
30```
31
32## Installation
33
34Install [`plain.elements` from PyPI](https://pypi.org/project/plain.elements/) and add it to your `INSTALLED_PACKAGES` setting. That's it! The Jinja extension will be enabled automatically.
35
36```python
37# settings.py
38INSTALLED_PACKAGES = [
39    # ...
40    "plain.elements",
41]
42```
43
44## Element attributes
45
46Attributes will be passed through using regular strings or single braces `{}` for Python variables.
47
48```html
49{% extends "admin/base.html" %}
50
51{% use_elements %}
52
53{% block content %}
54<form method="post">
55    {{ csrf_input }}
56    <FormInput field={form.username} placeholder="Username" label="Username" />
57    <Submit>Save</Submit>
58</form>
59{% endblock %}
60```
61
62The attributes are passed to the element as named variables. By default in Plain, you will get an error if you try to use an undefined variable, so Jinja features like [`|default`](https://jinja.palletsprojects.com/en/stable/templates/#jinja-filters.default) and [`is defined`](https://jinja.palletsprojects.com/en/stable/templates/#jinja-tests.defined) are useful for optional attributes.
63
64```html
65<!-- templates/elements/FormInput.html -->
66<label for="{{ field.html_id }}">
67    {{ label }}
68</label>
69<input
70    id="{{ field.html_id }}"
71    type="{{ type|default('text') }}"
72    name="{{ field.html_name }}"
73    value="{{ field.value() or '' }}"
74    placeholder="{{ placeholder }}"
75    {% if field.field.required %}required{% endif %}
76    />
77```
78
79## Namespaced elements
80
81Especially for reusable packages, it can be useful to namespace your elements by putting them in a subdirectory of `templates/elements/`. To use namespaced elements, you need to include the full dot-separated path in your HTML tag.
82
83For example, an element in `templates/elements/admin/Submit.html` would be used like this:
84
85```html
86{% use_elements %}
87
88{% block content %}
89<form method="post">
90    {{ csrf_input }}
91    <admin.Submit>Save</admin.Submit>
92</form>
93{% endblock %}
94```