Create advanced HTML components using Django Tags.
Project description
Create advanced HTML components using Django Tags.
Description
The goal of this project is to use Django Template Tags and create a new way of writing reusable html components compatible with the current template infrastructure. This new way should fit the Django standards of creating classes, like Models and Forms, also it should require as little boilerplate code and be simple to write.
Some features:
Class based template tags.
Template tag argument parser.
Declarative component attributes.
Extendable components.
Slot components.
Requirements
Requires Django 2.2 or newer, and is tested against Python 3.7 and PyPy.
Quick Start
First, install the library:
pip3 install django-component-tags
Add it to INSTALLED_APPS.
INSTALLED_APPS = [
...
'component_tags',
...
]
Assuming that we already have an application called foo, lets create a new component tag:
# foo/templatetags/foo_tags.py
from component_tags import template
register = template.Library()
@register.tag
class Link(template.Component):
href = template.Attribute(default='#')
class Meta:
template_name = 'tags/link.html'
Next step, creating the component template:
# foo/templates/foo/tags/link.html
<a {{ attributes }}>
{{ nodelist }}
</a>
Here we defined a couple of variables that we can use inside a component template:
attributes: component template/class attributes (formatted).
nodelist: the content created between {% link %} and {% endlink %} will be rendered here.
Finally, we can use it as follows:
# foo/templates/foo/index.html
{% load foo_tags %}
{% link %}
Link 1
{% endlink %}
Output:
# foo/templates/foo/index.html
<a href="#">
Link 1
</a>
This is the simplest way to start, there is a lot of different settings that you can combine to create complex html components.
Examples
Adding css classes
Lets create a html component using the bootstrap framework
# foo/templatetags/foo_tags.py
from component_tags import template
register = template.Library()
@register.tag
class Link(template.Component):
class ColorChoices(template.AttributeChoices):
primary = 'btn btn-primary'
secondary = 'btn btn-secondary'
success = 'btn btn-success'
danger = 'btn btn-danger'
warning = 'btn btn-warning'
info = 'btn btn-info'
color = template.Attribute(choices=TypeChoices, default=TypeChoices.submit, as_class=True)
href = template.Attribute(default='#')
class Meta:
template_name = 'tags/link.html'
Rendering the component:
# foo/templates/foo/index.html
{% load foo_tags %}
{% link color="primary" class="foo-bar" %}
Link 1
{% endlink %}
Also we added the class argument to the component tag, so even if the components strictly have class attributes, you will always have a flexible way to customize your components any time in different scenarios.
Output:
# foo/templates/foo/index.html
<a class="btn btn-primary foo-bar" href="#">
Link 1
</a>
Note that it was merged with all attribute classes previously declared.
Using slot components
Lets make another html component using the bootstrap framework, this one is going to be a Card component.
# foo/templatetags/foo_tags.py
from component_tags import template
register = template.Library()
@register.tag
class Card(template.Component):
title = template.Attribute(as_context=True)
class Meta:
template_name = 'tags/card.html'
Create the component template:
# foo/templates/foo/tags/card.html
<div class="card" style="width: 18rem;">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{ title }}</h5>
<div class="card-text">
{{ nodelist }}
</div>
{% if slot_footer %}
<div class="card-footer">
{{ slot_footer }}
</div>
{% endif %}
</div>
</div>
Rendering the component:
# foo/templates/foo/index.html
{% load foo_tags %}
{% card title='foo' %}
Some quick example text to build on the card title and make up the bulk of the card's content.
{% slot 'footer' %}
<a href="#" class="btn btn-primary">Go somewhere</a>
{% endslot %}
{% endcard %}
Output:
# foo/templates/foo/index.html
<div class="card" style="width: 18rem;">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">foo</h5>
<div class="card-text">
Some quick example text to build on the card title and make up the bulk of the card's content.
</div>
<div class="card-footer">
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
Adding extra context
By default, all components used isolated context to work with. If you want to pass global context to the component tag it is required to use the with argument.
# foo/views.py
def foo(request, object_id=None):
return render(request, 'foo/index.html', {
'object_id': object_id
})
# foo/templates/foo/index.html
{% load foo_tags %}
{% link color="primary" with id=object_id %}
Link {{ id }}
{% endlink %}
Assuming that the request of the page will be something like http://localhost:8000/foo/1/, the output will be:
# foo/templates/foo/index.html
<a class="btn btn-primary" href="#">
Link 1
</a>
Note
This project has been set up using PyScaffold 4.0rc2. For details and usage information on PyScaffold see https://pyscaffold.org/.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django_component_tags-0.0.4.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | f2d5b732e9bb0cacd63f9e37a4bc06e51b966de20b6573129cdd50596d7a816e |
|
MD5 | d06dda2afdc5b9e22fb197f217885dfe |
|
BLAKE2b-256 | 2099e88585b2b8ba77e75392d38fa363c7a750d8afd8670564e82e286e594e8a |
Hashes for django_component_tags-0.0.4-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e25b7b100ebdbca5be58b223e8b57d5b58ca274396c4e16f072c841453eade73 |
|
MD5 | 3373bcf4d9e06e444f727619bbf87669 |
|
BLAKE2b-256 | 93798a52ab6f44aa1ca2e64548ca18ca4fab0fc45f00c6bb13eca4f747e164ee |