Django Simple Components is a small package to easily create components inside your templates without saving them in the templates folder.
To get started, install the package from pypi:
pip install django-simple-components
Now you can add simple_components
to your django project. Change your INSTALLED_APPS
setting like this:
INSTALLED_APPS = [
...,
"simple_components",
]
Optionally, you can specify simple_components
as builtins and this will be available in any of your templates without additionally specifying {% load simple_components %}
:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
"builtins": ["simple_components.templatetags.simple_components"],
},
},
]
If you choose not use it as a built-in, you will need to add {% load simple_components %}
to the top of your template whenever you want to use simple components.
You can define a base component that can be reused later. For example:
{% load simple_components %}
{% #set_component "card" %}
<div class="card">
<h3>{{ title }}</h3>
<p>{{ description }}</p>
</div>
{% /set_component %}
<div class="card-list">
{% component "card" title="Post 1" description="..." %}
{% component "card" title="Post 2" description="..." %}
{% component "card" title="Post 3" description="..." %}
</div>
You can also use named slots to change the contents of a component as quickly as possible:
{% load simple_components %}
{% #set_component "profile" %}
<div class="profile">
<div class="avatar">
{% @set_slot "avatar" %}
<!-- fallback username as bdage -->
<span class="badge">{{ username.0 }}</span>
{% /set_slot %}
</div>
<div class="info">
{{ username }}
</div>
</div>
{% /set_component %}
{% #set_component "card" %}
<div class="card">
{% set_slot "image" %}
<h3>{{ title }}</h3>
<p>{{ description }}</p>
</div>
{% /set_component %}
<div class="page">
{% component "profile" username="Default" %}
<div class="card-list">
{% #component "card" title="Post 1" description="..." %}
{% @slot "image" %}
<img src="..." alt="slot image" />
{% /slot %}
{% /component %}
</div>
</div>
To define a component you need to use the Django tag {# set_component name %}
where name is the name of the component,
listed in quotes. This is a paired tag, which means it needs to be closed:
{% #set_component "card" %}
<p>{{ title }}</p>
{% /set_component %}
In the example above, we defined the "card" component and specified a variable that will be used during rendering later. Now, to use this component, you just need to write:
{% component "card" title="Post" %}
Components can also render children - anything specified between the opening and closing component
tags:
{% #set_component "card" %}
<div class="c1 c2 c3 c4 c5">
<p>{{ title }}</p>
{{ children }}
</div>
{% /set_component %}
{% #component "card" title="Post" %}
<p>Simple</p>
<p>Content</p>
{% /component %}
Slots are a powerful opportunity to upgrade your components! Slots can accept any content. Each slot has a name, and is specified inside the set_component tag:
{% #set_component "card" %}
<div class="card">
<div class="card-header">
<h3>{{ title }}</h3>
</div>
<div class="card-body">
{% set_slot "body" %}
</div>
</div>
{% /set_component %}
Any slot can have a fallback template, which will be displayed if this slot was not passed to the component.
Otherwise, a SlotNotFoundError
will be raised:
{% @set_slot "custom" %}
fallback
{% /set_slot %}
To use slots in components, you need to pass the slot when rendering where it is needed:
{% #set_component "card" %}
<div class="card">
...
<div class="card-body">
{% set_slot "body" %}
</div>
</div>
{% /set_component %}
{% #component "card" %}
{% @slot "body" %}
render slot inside card-body class
{% /slot %}
{% /component %}
All paired tags in simple components close with %{ /tag %}
, where tag
can be set_component
, set_slot
, component
.
There are {% component %}
and {% set_slot %}
which can be defined on the same line. For the component,
this means that it cannot use slots and children. For set_slot
this means that the fallback template is not specified:
{% component "card" title="Post" description="..." %}
{% set_slot "avatar" %}
To define a component or use it, you can specify #
at the beginning of the tag (only for closable tags):
{% #set_component name="simple" %}
{{ children }}
{% /set_component %}
{% #component name="simple" %}
component with children content
{% /component %}
To define a slot or use it, you can specify @
at the beginning of the tag (only for closable tags):
{% @set_slot "custom" %}
fallback
{% /set_slot %}
{% @slot "custom" %}
render slot
{% /slot %}
If you would like to suggest a new feature, you can create an issue on the GitHub repository for this project. Also you can fork the repository and submit a pull request with your changes.
This project is licensed under the MIT License. See the LICENSE file for more information.