Name | django-components JSON |
Version |
0.141.2
JSON |
| download |
home_page | None |
Summary | A way to create simple reusable template components in Django. |
upload_time | 2025-07-20 22:13:23 |
maintainer | None |
docs_url | None |
author | None |
requires_python | <4.0,>=3.8 |
license | MIT |
keywords |
django
components
css
js
html
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# <img src="https://raw.githubusercontent.com/django-components/django-components/master/logo/logo-black-on-white.svg" alt="django-components" style="max-width: 100%; background: white; color: black;">
[](https://pypi.org/project/django-components/) [](https://pypi.org/project/django-components/) [](https://github.com/django-components/django-components/blob/master/LICENSE/) [](https://pypistats.org/packages/django-components) [](https://github.com/django-components/django-components/actions/workflows/tests.yml) [](https://django-components.github.io/django-components/latest/benchmarks/)
### <table><td>[Read the full documentation](https://django-components.github.io/django-components/latest/)</td></table>
`django-components` is a modular and extensible UI framework for Django.
It combines Django's templating system with the modularity seen
in modern frontend frameworks like Vue or React.
With `django-components` you can support Django projects small and large without leaving the Django ecosystem.
## Quickstart
A component in django-components can be as simple as a Django template and Python code to declare the component:
```django
{# components/calendar/calendar.html #}
<div class="calendar">
Today's date is <span>{{ date }}</span>
</div>
```
```py
# components/calendar/calendar.py
from django_components import Component, register
@register("calendar")
class Calendar(Component):
template_file = "calendar.html"
```
Or a combination of Django template, Python, CSS, and Javascript:
```django
{# components/calendar/calendar.html #}
<div class="calendar">
Today's date is <span>{{ date }}</span>
</div>
```
```css
/* components/calendar/calendar.css */
.calendar {
width: 200px;
background: pink;
}
```
```js
/* components/calendar/calendar.js */
document.querySelector(".calendar").onclick = () => {
alert("Clicked calendar!");
};
```
```py
# components/calendar/calendar.py
from django_components import Component, register
@register("calendar")
class Calendar(Component):
template_file = "calendar.html"
js_file = "calendar.js"
css_file = "calendar.css"
def get_template_data(self, args, kwargs, slots, context):
return {"date": kwargs["date"]}
```
Use the component like this:
```django
{% component "calendar" date="2024-11-06" %}{% endcomponent %}
```
And this is what gets rendered:
```html
<div class="calendar-component">
Today's date is <span>2024-11-06</span>
</div>
```
Read on to learn about all the exciting details and configuration possibilities!
(If you instead prefer to jump right into the code, [check out the example project](https://github.com/django-components/django-components/tree/master/sampleproject))
## Features
### Modern and modular UI
- Create self-contained, reusable UI elements.
- Each component can include its own HTML, CSS, and JS, or additional third-party JS and CSS.
- HTML, CSS, and JS can be defined on the component class, or loaded from files.
```python
from django_components import Component
@register("calendar")
class Calendar(Component):
template = """
<div class="calendar">
Today's date is
<span>{{ date }}</span>
</div>
"""
css = """
.calendar {
width: 200px;
background: pink;
}
"""
js = """
document.querySelector(".calendar")
.addEventListener("click", () => {
alert("Clicked calendar!");
});
"""
# Additional JS and CSS
class Media:
js = ["https://cdn.jsdelivr.net/npm/htmx.org@2/dist/htmx.min.js"]
css = ["bootstrap/dist/css/bootstrap.min.css"]
# Variables available in the template
def get_template_data(self, args, kwargs, slots, context):
return {
"date": kwargs["date"]
}
```
### Composition with slots
- Render components inside templates with
[`{% component %}`](https://django-components.github.io/django-components/latest/reference/template_tags#component) tag.
- Compose them with [`{% slot %}`](https://django-components.github.io/django-components/latest/reference/template_tags#slot)
and [`{% fill %}`](https://django-components.github.io/django-components/latest/reference/template_tags#fill) tags.
- Vue-like slot system, including [scoped slots](https://django-components.github.io/django-components/latest/concepts/fundamentals/slots/#slot-data).
```django
{% component "Layout"
bookmarks=bookmarks
breadcrumbs=breadcrumbs
%}
{% fill "header" %}
<div class="flex justify-between gap-x-12">
<div class="prose">
<h3>{{ project.name }}</h3>
</div>
<div class="font-semibold text-gray-500">
{{ project.start_date }} - {{ project.end_date }}
</div>
</div>
{% endfill %}
{# Access data passed to `{% slot %}` with `data` #}
{% fill "tabs" data="tabs_data" %}
{% component "TabItem" header="Project Info" %}
{% component "ProjectInfo"
project=project
project_tags=project_tags
attrs:class="py-5"
attrs:width=tabs_data.width
/ %}
{% endcomponent %}
{% endfill %}
{% endcomponent %}
```
### Extended template tags
`django-components` is designed for flexibility, making working with templates a breeze.
It extends Django's template tags syntax with:
<!-- TODO - Document literal lists and dictionaries -->
- Literal lists and dictionaries in the template
- [Self-closing tags](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#self-closing-tags) `{% mytag / %}`
- [Multi-line template tags](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#multiline-tags)
- [Spread operator](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#spread-operator) `...` to dynamically pass args or kwargs into the template tag
- [Template tags inside literal strings](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#template-tags-inside-literal-strings) like `"{{ first_name }} {{ last_name }}"`
- [Pass dictonaries by their key-value pairs](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#pass-dictonary-by-its-key-value-pairs) `attr:key=val`
```django
{% component "table"
...default_attrs
title="Friend list for {{ user.name }}"
headers=["Name", "Age", "Email"]
data=[
{
"name": "John"|upper,
"age": 30|add:1,
"email": "john@example.com",
"hobbies": ["reading"],
},
{
"name": "Jane"|upper,
"age": 25|add:1,
"email": "jane@example.com",
"hobbies": ["reading", "coding"],
},
],
attrs:class="py-4 ma-2 border-2 border-gray-300 rounded-md"
/ %}
```
You too can define template tags with these features by using
[`@template_tag()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.template_tag)
or [`BaseNode`](https://django-components.github.io/django-components/latest/reference/api/#django_components.BaseNode).
Read more on [Custom template tags](https://django-components.github.io/django-components/latest/concepts/advanced/template_tags/).
### Full programmatic access
When you render a component, you can access everything about the component:
- Component input: [args, kwargs, slots and context](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#component-inputs)
- Component's template, CSS and JS
- Django's [context processors](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#request-and-context-processors)
- Unique [render ID](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#component-id)
```python
class Table(Component):
js_file = "table.js"
css_file = "table.css"
template = """
<div class="table">
<span>{{ variable }}</span>
</div>
"""
def get_template_data(self, args, kwargs, slots, context):
# Access component's ID
assert self.id == "djc1A2b3c"
# Access component's inputs and slots
assert self.args == [123, "str"]
assert self.kwargs == {"variable": "test", "another": 1}
footer_slot = self.slots["footer"]
some_var = self.context["some_var"]
# Access the request object and Django's context processors, if available
assert self.request.GET == {"query": "something"}
assert self.context_processors_data['user'].username == "admin"
return {
"variable": kwargs["variable"],
}
# Access component's HTML / JS / CSS
Table.template
Table.js
Table.css
# Render the component
rendered = Table.render(
kwargs={"variable": "test", "another": 1},
args=(123, "str"),
slots={"footer": "MY_FOOTER"},
)
```
### Granular HTML attributes
Use the [`{% html_attrs %}`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/) template tag to render HTML attributes.
It supports:
- Defining attributes as whole dictionaries or keyword arguments
- Merging attributes from multiple sources
- Boolean attributes
- Appending attributes
- Removing attributes
- Defining default attributes
```django
<div
{% html_attrs
attrs
defaults:class="default-class"
class="extra-class"
%}
>
```
[`{% html_attrs %}`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/) offers a Vue-like granular control for
[`class`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/#merging-class-attributes)
and [`style`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/#merging-style-attributes)
HTML attributes,
where you can use a dictionary to manage each class name or style property separately.
```django
{% html_attrs
class="foo bar"
class={
"baz": True,
"foo": False,
}
class="extra"
%}
```
```django
{% html_attrs
style="text-align: center; background-color: blue;"
style={
"background-color": "green",
"color": None,
"width": False,
}
style="position: absolute; height: 12px;"
%}
```
Read more about [HTML attributes](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/).
### HTML fragment support
`django-components` makes integration with HTMX, AlpineJS or jQuery easy by allowing components to be rendered as [HTML fragments](https://django-components.github.io/django-components/latest/concepts/advanced/html_fragments/):
- Components's JS and CSS files are loaded automatically when the fragment is inserted into the DOM.
- Components can be [exposed as Django Views](https://django-components.github.io/django-components/latest/concepts/fundamentals/component_views_urls/) with `get()`, `post()`, `put()`, `patch()`, `delete()` methods
- Automatically create an endpoint for a component with [`Component.View.public`](https://django-components.github.io/django-components/latest/concepts/fundamentals/component_views_urls/#register-urls-automatically)
```py
# components/calendar/calendar.py
@register("calendar")
class Calendar(Component):
template_file = "calendar.html"
class View:
# Register Component with `urlpatterns`
public = True
# Define handlers
def get(self, request, *args, **kwargs):
page = request.GET.get("page", 1)
return self.component.render_to_response(
request=request,
kwargs={
"page": page,
},
)
def get_template_data(self, args, kwargs, slots, context):
return {
"page": kwargs["page"],
}
# Get auto-generated URL for the component
url = get_component_url(Calendar)
# Or define explicit URL in urls.py
path("calendar/", Calendar.as_view())
```
### Provide / Inject
`django-components` supports the provide / inject pattern, similarly to React's [Context Providers](https://react.dev/learn/passing-data-deeply-with-context) or Vue's [provide / inject](https://vuejs.org/guide/components/provide-inject):
- Use the [`{% provide %}`](https://django-components.github.io/django-components/latest/reference/template_tags/#provide) tag to provide data to the component tree
- Use the [`Component.inject()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.Component.inject) method to inject data into the component
Read more about [Provide / Inject](https://django-components.github.io/django-components/latest/concepts/advanced/provide_inject).
```django
<body>
{% provide "theme" variant="light" %}
{% component "header" / %}
{% endprovide %}
</body>
```
```djc_py
@register("header")
class Header(Component):
template = "..."
def get_template_data(self, args, kwargs, slots, context):
theme = self.inject("theme").variant
return {
"theme": theme,
}
```
### Input validation and static type hints
Avoid needless errors with [type hints and runtime input validation](https://django-components.github.io/django-components/latest/concepts/fundamentals/typing_and_validation/).
To opt-in to input validation, define types for component's args, kwargs, slots, and more:
```py
from typing import NamedTuple, Optional
from django.template import Context
from django_components import Component, Slot, SlotInput
class Button(Component):
class Args(NamedTuple):
size: int
text: str
class Kwargs(NamedTuple):
variable: str
another: int
maybe_var: Optional[int] = None # May be omitted
class Slots(NamedTuple):
my_slot: Optional[SlotInput] = None
another_slot: SlotInput
def get_template_data(self, args: Args, kwargs: Kwargs, slots: Slots, context: Context):
args.size # int
kwargs.variable # str
slots.my_slot # Slot[MySlotData]
```
To have type hints when calling
[`Button.render()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.Component.render) or
[`Button.render_to_response()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.Component.render_to_response),
wrap the inputs in their respective `Args`, `Kwargs`, and `Slots` classes:
```py
Button.render(
# Error: First arg must be `int`, got `float`
args=Button.Args(
size=1.25,
text="abc",
),
# Error: Key "another" is missing
kwargs=Button.Kwargs(
variable="text",
),
)
```
### Extensions
Django-components functionality can be extended with [Extensions](https://django-components.github.io/django-components/latest/concepts/advanced/extensions/).
Extensions allow for powerful customization and integrations. They can:
- Tap into lifecycle events, such as when a component is created, deleted, or registered
- Add new attributes and methods to the components
- Add custom CLI commands
- Add custom URLs
Some of the extensions include:
- [Component caching](https://github.com/django-components/django-components/blob/master/src/django_components/extensions/cache.py)
- [Django View integration](https://github.com/django-components/django-components/blob/master/src/django_components/extensions/view.py)
- [Component defaults](https://github.com/django-components/django-components/blob/master/src/django_components/extensions/defaults.py)
- [Pydantic integration (input validation)](https://github.com/django-components/djc-ext-pydantic)
Some of the planned extensions include:
- AlpineJS integration
- Storybook integration
- Component-level benchmarking with asv
### Caching
- [Components can be cached](https://django-components.github.io/django-components/latest/concepts/advanced/component_caching/) using Django's cache framework.
- Caching rules can be configured on a per-component basis.
- Components are cached based on their input. Or you can write custom caching logic.
```py
from django_components import Component
class MyComponent(Component):
class Cache:
enabled = True
ttl = 60 * 60 * 24 # 1 day
def hash(self, *args, **kwargs):
return hash(f"{json.dumps(args)}:{json.dumps(kwargs)}")
```
### Simple testing
- Write tests for components with [`@djc_test`](https://django-components.github.io/django-components/latest/concepts/advanced/testing/) decorator.
- The decorator manages global state, ensuring that tests don't leak.
- If using `pytest`, the decorator allows you to parametrize Django or Components settings.
- The decorator also serves as a stand-in for Django's [`@override_settings`](https://docs.djangoproject.com/en/5.2/topics/testing/tools/#django.test.override_settings).
```python
from django_components.testing import djc_test
from components.my_table import MyTable
@djc_test
def test_my_table():
rendered = MyTable.render(
kwargs={
"title": "My table",
},
)
assert rendered == "<table>My table</table>"
```
### Debugging features
- **Visual component inspection**: Highlight components and slots directly in your browser.
- **Detailed tracing logs to supply AI-agents with context**: The logs include component and slot names and IDs, and their position in the tree.
<div style="text-align: center;">
<img src="https://github.com/django-components/django-components/blob/master/docs/images/debug-highlight-slots.png?raw=true" alt="Component debugging visualization showing slot highlighting" width="500" style="margin: auto;">
</div>
### Sharing components
- Install and use third-party components from PyPI
- Or publish your own "component registry"
- Highly customizable - Choose how the components are called in the template (and more):
```django
{% component "calendar" date="2024-11-06" %}
{% endcomponent %}
{% calendar date="2024-11-06" %}
{% endcalendar %}
```
## Documentation
[Read the full documentation here](https://django-components.github.io/django-components/latest/).
... or jump right into the code, [check out the example project](https://github.com/django-components/django-components/tree/master/sampleproject).
## Performance
Our aim is to be at least as fast as Django templates.
As of `0.130`, `django-components` is ~4x slower than Django templates.
| | Render time|
|----------|----------------------|
| django | 68.9±0.6ms |
| django-components | 259±4ms |
See the [full performance breakdown](https://django-components.github.io/django-components/latest/benchmarks/) for more information.
## Release notes
Read the [Release Notes](https://github.com/django-components/django-components/tree/master/CHANGELOG.md)
to see the latest features and fixes.
## Community examples
One of our goals with `django-components` is to make it easy to share components between projects. If you have a set of components that you think would be useful to others, please open a pull request to add them to the list below.
- [django-htmx-components](https://github.com/iwanalabs/django-htmx-components): A set of components for use with [htmx](https://htmx.org/).
- [djc-heroicons](https://pypi.org/project/djc-heroicons/): A component that renders icons from [Heroicons.com](https://heroicons.com/).
## Contributing and development
Get involved or sponsor this project - [See here](https://django-components.github.io/django-components/dev/overview/contributing/)
Running django-components locally for development - [See here](https://django-components.github.io/django-components/dev/overview/development/)
Raw data
{
"_id": null,
"home_page": null,
"name": "django-components",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": "django, components, css, js, html",
"author": null,
"author_email": "Emil Stenstr\u00f6m <emil@emilstenstrom.se>, Juro Oravec <juraj.oravec.josefson@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/29/47/3cdd61d007e5f7a8947cee531675fb4a9bb2125d41dd047f9c08c70433ff/django_components-0.141.2.tar.gz",
"platform": null,
"description": "# <img src=\"https://raw.githubusercontent.com/django-components/django-components/master/logo/logo-black-on-white.svg\" alt=\"django-components\" style=\"max-width: 100%; background: white; color: black;\">\n\n[](https://pypi.org/project/django-components/) [](https://pypi.org/project/django-components/) [](https://github.com/django-components/django-components/blob/master/LICENSE/) [](https://pypistats.org/packages/django-components) [](https://github.com/django-components/django-components/actions/workflows/tests.yml) [](https://django-components.github.io/django-components/latest/benchmarks/)\n\n### <table><td>[Read the full documentation](https://django-components.github.io/django-components/latest/)</td></table>\n\n`django-components` is a modular and extensible UI framework for Django.\n\nIt combines Django's templating system with the modularity seen\nin modern frontend frameworks like Vue or React.\n\nWith `django-components` you can support Django projects small and large without leaving the Django ecosystem.\n\n## Quickstart\n\nA component in django-components can be as simple as a Django template and Python code to declare the component:\n\n```django\n{# components/calendar/calendar.html #}\n<div class=\"calendar\">\n Today's date is <span>{{ date }}</span>\n</div>\n```\n\n```py\n# components/calendar/calendar.py\nfrom django_components import Component, register\n\n@register(\"calendar\")\nclass Calendar(Component):\n template_file = \"calendar.html\"\n```\n\nOr a combination of Django template, Python, CSS, and Javascript:\n\n```django\n{# components/calendar/calendar.html #}\n<div class=\"calendar\">\n Today's date is <span>{{ date }}</span>\n</div>\n```\n\n```css\n/* components/calendar/calendar.css */\n.calendar {\n width: 200px;\n background: pink;\n}\n```\n\n```js\n/* components/calendar/calendar.js */\ndocument.querySelector(\".calendar\").onclick = () => {\n alert(\"Clicked calendar!\");\n};\n```\n\n```py\n# components/calendar/calendar.py\nfrom django_components import Component, register\n\n@register(\"calendar\")\nclass Calendar(Component):\n template_file = \"calendar.html\"\n js_file = \"calendar.js\"\n css_file = \"calendar.css\"\n\n def get_template_data(self, args, kwargs, slots, context):\n return {\"date\": kwargs[\"date\"]}\n```\n\nUse the component like this:\n\n```django\n{% component \"calendar\" date=\"2024-11-06\" %}{% endcomponent %}\n```\n\nAnd this is what gets rendered:\n\n```html\n<div class=\"calendar-component\">\n Today's date is <span>2024-11-06</span>\n</div>\n```\n\nRead on to learn about all the exciting details and configuration possibilities!\n\n(If you instead prefer to jump right into the code, [check out the example project](https://github.com/django-components/django-components/tree/master/sampleproject))\n\n## Features\n\n### Modern and modular UI\n\n- Create self-contained, reusable UI elements.\n- Each component can include its own HTML, CSS, and JS, or additional third-party JS and CSS.\n- HTML, CSS, and JS can be defined on the component class, or loaded from files.\n\n```python\nfrom django_components import Component\n\n@register(\"calendar\")\nclass Calendar(Component):\n template = \"\"\"\n <div class=\"calendar\">\n Today's date is\n <span>{{ date }}</span>\n </div>\n \"\"\"\n\n css = \"\"\"\n .calendar {\n width: 200px;\n background: pink;\n }\n \"\"\"\n\n js = \"\"\"\n document.querySelector(\".calendar\")\n .addEventListener(\"click\", () => {\n alert(\"Clicked calendar!\");\n });\n \"\"\"\n\n # Additional JS and CSS\n class Media:\n js = [\"https://cdn.jsdelivr.net/npm/htmx.org@2/dist/htmx.min.js\"]\n css = [\"bootstrap/dist/css/bootstrap.min.css\"]\n\n # Variables available in the template\n def get_template_data(self, args, kwargs, slots, context):\n return {\n \"date\": kwargs[\"date\"]\n }\n```\n\n### Composition with slots\n\n- Render components inside templates with\n [`{% component %}`](https://django-components.github.io/django-components/latest/reference/template_tags#component) tag.\n- Compose them with [`{% slot %}`](https://django-components.github.io/django-components/latest/reference/template_tags#slot)\n and [`{% fill %}`](https://django-components.github.io/django-components/latest/reference/template_tags#fill) tags.\n- Vue-like slot system, including [scoped slots](https://django-components.github.io/django-components/latest/concepts/fundamentals/slots/#slot-data).\n\n```django\n{% component \"Layout\"\n bookmarks=bookmarks\n breadcrumbs=breadcrumbs\n%}\n {% fill \"header\" %}\n <div class=\"flex justify-between gap-x-12\">\n <div class=\"prose\">\n <h3>{{ project.name }}</h3>\n </div>\n <div class=\"font-semibold text-gray-500\">\n {{ project.start_date }} - {{ project.end_date }}\n </div>\n </div>\n {% endfill %}\n\n {# Access data passed to `{% slot %}` with `data` #}\n {% fill \"tabs\" data=\"tabs_data\" %}\n {% component \"TabItem\" header=\"Project Info\" %}\n {% component \"ProjectInfo\"\n project=project\n project_tags=project_tags\n attrs:class=\"py-5\"\n attrs:width=tabs_data.width\n / %}\n {% endcomponent %}\n {% endfill %}\n{% endcomponent %}\n```\n\n### Extended template tags\n\n`django-components` is designed for flexibility, making working with templates a breeze.\n\nIt extends Django's template tags syntax with:\n\n<!-- TODO - Document literal lists and dictionaries -->\n- Literal lists and dictionaries in the template\n- [Self-closing tags](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#self-closing-tags) `{% mytag / %}`\n- [Multi-line template tags](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#multiline-tags)\n- [Spread operator](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#spread-operator) `...` to dynamically pass args or kwargs into the template tag\n- [Template tags inside literal strings](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#template-tags-inside-literal-strings) like `\"{{ first_name }} {{ last_name }}\"`\n- [Pass dictonaries by their key-value pairs](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#pass-dictonary-by-its-key-value-pairs) `attr:key=val`\n\n```django\n{% component \"table\"\n ...default_attrs\n title=\"Friend list for {{ user.name }}\"\n headers=[\"Name\", \"Age\", \"Email\"]\n data=[\n {\n \"name\": \"John\"|upper,\n \"age\": 30|add:1,\n \"email\": \"john@example.com\",\n \"hobbies\": [\"reading\"],\n },\n {\n \"name\": \"Jane\"|upper,\n \"age\": 25|add:1,\n \"email\": \"jane@example.com\",\n \"hobbies\": [\"reading\", \"coding\"],\n },\n ],\n attrs:class=\"py-4 ma-2 border-2 border-gray-300 rounded-md\"\n/ %}\n```\n\nYou too can define template tags with these features by using\n[`@template_tag()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.template_tag)\nor [`BaseNode`](https://django-components.github.io/django-components/latest/reference/api/#django_components.BaseNode).\n\nRead more on [Custom template tags](https://django-components.github.io/django-components/latest/concepts/advanced/template_tags/).\n\n### Full programmatic access\n\nWhen you render a component, you can access everything about the component:\n\n- Component input: [args, kwargs, slots and context](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#component-inputs)\n- Component's template, CSS and JS\n- Django's [context processors](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#request-and-context-processors)\n- Unique [render ID](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#component-id)\n\n```python\nclass Table(Component):\n js_file = \"table.js\"\n css_file = \"table.css\"\n\n template = \"\"\"\n <div class=\"table\">\n <span>{{ variable }}</span>\n </div>\n \"\"\"\n\n def get_template_data(self, args, kwargs, slots, context):\n # Access component's ID\n assert self.id == \"djc1A2b3c\"\n\n # Access component's inputs and slots\n assert self.args == [123, \"str\"]\n assert self.kwargs == {\"variable\": \"test\", \"another\": 1}\n footer_slot = self.slots[\"footer\"]\n some_var = self.context[\"some_var\"]\n\n # Access the request object and Django's context processors, if available\n assert self.request.GET == {\"query\": \"something\"}\n assert self.context_processors_data['user'].username == \"admin\"\n\n return {\n \"variable\": kwargs[\"variable\"],\n }\n\n# Access component's HTML / JS / CSS\nTable.template\nTable.js\nTable.css\n\n# Render the component\nrendered = Table.render(\n kwargs={\"variable\": \"test\", \"another\": 1},\n args=(123, \"str\"),\n slots={\"footer\": \"MY_FOOTER\"},\n)\n```\n\n### Granular HTML attributes\n\nUse the [`{% html_attrs %}`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/) template tag to render HTML attributes.\n\nIt supports:\n\n- Defining attributes as whole dictionaries or keyword arguments\n- Merging attributes from multiple sources\n- Boolean attributes\n- Appending attributes\n- Removing attributes\n- Defining default attributes\n\n```django\n<div\n {% html_attrs\n attrs\n defaults:class=\"default-class\"\n class=\"extra-class\"\n %}\n>\n```\n\n[`{% html_attrs %}`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/) offers a Vue-like granular control for\n[`class`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/#merging-class-attributes)\nand [`style`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/#merging-style-attributes)\nHTML attributes,\nwhere you can use a dictionary to manage each class name or style property separately.\n\n```django\n{% html_attrs\n class=\"foo bar\"\n class={\n \"baz\": True,\n \"foo\": False,\n }\n class=\"extra\"\n%}\n```\n\n```django\n{% html_attrs\n style=\"text-align: center; background-color: blue;\"\n style={\n \"background-color\": \"green\",\n \"color\": None,\n \"width\": False,\n }\n style=\"position: absolute; height: 12px;\"\n%}\n```\n\nRead more about [HTML attributes](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/).\n\n### HTML fragment support\n\n`django-components` makes integration with HTMX, AlpineJS or jQuery easy by allowing components to be rendered as [HTML fragments](https://django-components.github.io/django-components/latest/concepts/advanced/html_fragments/):\n\n- Components's JS and CSS files are loaded automatically when the fragment is inserted into the DOM.\n\n- Components can be [exposed as Django Views](https://django-components.github.io/django-components/latest/concepts/fundamentals/component_views_urls/) with `get()`, `post()`, `put()`, `patch()`, `delete()` methods\n\n- Automatically create an endpoint for a component with [`Component.View.public`](https://django-components.github.io/django-components/latest/concepts/fundamentals/component_views_urls/#register-urls-automatically)\n\n```py\n# components/calendar/calendar.py\n@register(\"calendar\")\nclass Calendar(Component):\n template_file = \"calendar.html\"\n\n class View:\n # Register Component with `urlpatterns`\n public = True\n\n # Define handlers\n def get(self, request, *args, **kwargs):\n page = request.GET.get(\"page\", 1)\n return self.component.render_to_response(\n request=request,\n kwargs={\n \"page\": page,\n },\n )\n\n def get_template_data(self, args, kwargs, slots, context):\n return {\n \"page\": kwargs[\"page\"],\n }\n\n# Get auto-generated URL for the component\nurl = get_component_url(Calendar)\n\n# Or define explicit URL in urls.py\npath(\"calendar/\", Calendar.as_view())\n```\n\n### Provide / Inject\n\n`django-components` supports the provide / inject pattern, similarly to React's [Context Providers](https://react.dev/learn/passing-data-deeply-with-context) or Vue's [provide / inject](https://vuejs.org/guide/components/provide-inject):\n\n- Use the [`{% provide %}`](https://django-components.github.io/django-components/latest/reference/template_tags/#provide) tag to provide data to the component tree\n- Use the [`Component.inject()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.Component.inject) method to inject data into the component\n\nRead more about [Provide / Inject](https://django-components.github.io/django-components/latest/concepts/advanced/provide_inject).\n\n```django\n<body>\n {% provide \"theme\" variant=\"light\" %}\n {% component \"header\" / %}\n {% endprovide %}\n</body>\n```\n\n```djc_py\n@register(\"header\")\nclass Header(Component):\n template = \"...\"\n\n def get_template_data(self, args, kwargs, slots, context):\n theme = self.inject(\"theme\").variant\n return {\n \"theme\": theme,\n }\n```\n\n### Input validation and static type hints\n\nAvoid needless errors with [type hints and runtime input validation](https://django-components.github.io/django-components/latest/concepts/fundamentals/typing_and_validation/).\n\nTo opt-in to input validation, define types for component's args, kwargs, slots, and more:\n\n```py\nfrom typing import NamedTuple, Optional\nfrom django.template import Context\nfrom django_components import Component, Slot, SlotInput\n\nclass Button(Component):\n class Args(NamedTuple):\n size: int\n text: str\n\n class Kwargs(NamedTuple):\n variable: str\n another: int\n maybe_var: Optional[int] = None # May be omitted\n\n class Slots(NamedTuple):\n my_slot: Optional[SlotInput] = None\n another_slot: SlotInput\n\n def get_template_data(self, args: Args, kwargs: Kwargs, slots: Slots, context: Context):\n args.size # int\n kwargs.variable # str\n slots.my_slot # Slot[MySlotData]\n```\n\nTo have type hints when calling\n[`Button.render()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.Component.render) or\n[`Button.render_to_response()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.Component.render_to_response),\nwrap the inputs in their respective `Args`, `Kwargs`, and `Slots` classes:\n\n```py\nButton.render(\n # Error: First arg must be `int`, got `float`\n args=Button.Args(\n size=1.25,\n text=\"abc\",\n ),\n # Error: Key \"another\" is missing\n kwargs=Button.Kwargs(\n variable=\"text\",\n ),\n)\n```\n\n### Extensions\n\nDjango-components functionality can be extended with [Extensions](https://django-components.github.io/django-components/latest/concepts/advanced/extensions/).\nExtensions allow for powerful customization and integrations. They can:\n\n- Tap into lifecycle events, such as when a component is created, deleted, or registered\n- Add new attributes and methods to the components\n- Add custom CLI commands\n- Add custom URLs\n\nSome of the extensions include:\n\n- [Component caching](https://github.com/django-components/django-components/blob/master/src/django_components/extensions/cache.py)\n- [Django View integration](https://github.com/django-components/django-components/blob/master/src/django_components/extensions/view.py)\n- [Component defaults](https://github.com/django-components/django-components/blob/master/src/django_components/extensions/defaults.py)\n- [Pydantic integration (input validation)](https://github.com/django-components/djc-ext-pydantic)\n\nSome of the planned extensions include:\n\n- AlpineJS integration\n- Storybook integration\n- Component-level benchmarking with asv\n\n### Caching\n\n- [Components can be cached](https://django-components.github.io/django-components/latest/concepts/advanced/component_caching/) using Django's cache framework.\n- Caching rules can be configured on a per-component basis.\n- Components are cached based on their input. Or you can write custom caching logic.\n\n```py\nfrom django_components import Component\n\nclass MyComponent(Component):\n class Cache:\n enabled = True\n ttl = 60 * 60 * 24 # 1 day\n\n def hash(self, *args, **kwargs):\n return hash(f\"{json.dumps(args)}:{json.dumps(kwargs)}\")\n```\n\n### Simple testing\n\n- Write tests for components with [`@djc_test`](https://django-components.github.io/django-components/latest/concepts/advanced/testing/) decorator.\n- The decorator manages global state, ensuring that tests don't leak.\n- If using `pytest`, the decorator allows you to parametrize Django or Components settings.\n- The decorator also serves as a stand-in for Django's [`@override_settings`](https://docs.djangoproject.com/en/5.2/topics/testing/tools/#django.test.override_settings).\n\n```python\nfrom django_components.testing import djc_test\n\nfrom components.my_table import MyTable\n\n@djc_test\ndef test_my_table():\n rendered = MyTable.render(\n kwargs={\n \"title\": \"My table\",\n },\n )\n assert rendered == \"<table>My table</table>\"\n```\n\n### Debugging features\n\n- **Visual component inspection**: Highlight components and slots directly in your browser.\n- **Detailed tracing logs to supply AI-agents with context**: The logs include component and slot names and IDs, and their position in the tree.\n\n<div style=\"text-align: center;\">\n<img src=\"https://github.com/django-components/django-components/blob/master/docs/images/debug-highlight-slots.png?raw=true\" alt=\"Component debugging visualization showing slot highlighting\" width=\"500\" style=\"margin: auto;\">\n</div>\n\n### Sharing components\n\n- Install and use third-party components from PyPI\n- Or publish your own \"component registry\"\n- Highly customizable - Choose how the components are called in the template (and more):\n\n ```django\n {% component \"calendar\" date=\"2024-11-06\" %}\n {% endcomponent %}\n\n {% calendar date=\"2024-11-06\" %}\n {% endcalendar %}\n ```\n\n## Documentation\n\n[Read the full documentation here](https://django-components.github.io/django-components/latest/).\n\n... or jump right into the code, [check out the example project](https://github.com/django-components/django-components/tree/master/sampleproject).\n\n## Performance\n\nOur aim is to be at least as fast as Django templates.\n\nAs of `0.130`, `django-components` is ~4x slower than Django templates.\n\n| | Render time|\n|----------|----------------------|\n| django | 68.9\u00b10.6ms |\n| django-components | 259\u00b14ms |\n\nSee the [full performance breakdown](https://django-components.github.io/django-components/latest/benchmarks/) for more information.\n\n## Release notes\n\nRead the [Release Notes](https://github.com/django-components/django-components/tree/master/CHANGELOG.md)\nto see the latest features and fixes.\n\n## Community examples\n\nOne of our goals with `django-components` is to make it easy to share components between projects. If you have a set of components that you think would be useful to others, please open a pull request to add them to the list below.\n\n- [django-htmx-components](https://github.com/iwanalabs/django-htmx-components): A set of components for use with [htmx](https://htmx.org/).\n\n- [djc-heroicons](https://pypi.org/project/djc-heroicons/): A component that renders icons from [Heroicons.com](https://heroicons.com/).\n\n## Contributing and development\n\nGet involved or sponsor this project - [See here](https://django-components.github.io/django-components/dev/overview/contributing/)\n\nRunning django-components locally for development - [See here](https://django-components.github.io/django-components/dev/overview/development/)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A way to create simple reusable template components in Django.",
"version": "0.141.2",
"project_urls": {
"Changelog": "https://django-components.github.io/django-components/latest/release_notes/",
"Documentation": "https://django-components.github.io/django-components/",
"Donate": "https://github.com/sponsors/EmilStenstrom",
"Homepage": "https://github.com/django-components/django-components/",
"Issues": "https://github.com/django-components/django-components/issues"
},
"split_keywords": [
"django",
" components",
" css",
" js",
" html"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "b0352dd26d400cba156e2ae23440daae5ac3db11e1fafd066321ea0592dbfbfb",
"md5": "44cd60757312a171a25fecb35a19c6f8",
"sha256": "90cf06b1b861c239702c4e7389f79f8181f47adccf19e66502bf5b3ac672eec3"
},
"downloads": -1,
"filename": "django_components-0.141.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "44cd60757312a171a25fecb35a19c6f8",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 220377,
"upload_time": "2025-07-20T22:13:22",
"upload_time_iso_8601": "2025-07-20T22:13:22.033781Z",
"url": "https://files.pythonhosted.org/packages/b0/35/2dd26d400cba156e2ae23440daae5ac3db11e1fafd066321ea0592dbfbfb/django_components-0.141.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "29473cdd61d007e5f7a8947cee531675fb4a9bb2125d41dd047f9c08c70433ff",
"md5": "cf94ec81474ed26e288a4a6280f5229f",
"sha256": "e36d584af71d6d7e38bd9a977c09197d181584d54fcd78f6db1a62286e030acf"
},
"downloads": -1,
"filename": "django_components-0.141.2.tar.gz",
"has_sig": false,
"md5_digest": "cf94ec81474ed26e288a4a6280f5229f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 199230,
"upload_time": "2025-07-20T22:13:23",
"upload_time_iso_8601": "2025-07-20T22:13:23.931045Z",
"url": "https://files.pythonhosted.org/packages/29/47/3cdd61d007e5f7a8947cee531675fb4a9bb2125d41dd047f9c08c70433ff/django_components-0.141.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-20 22:13:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "sponsors",
"github_project": "EmilStenstrom",
"github_not_found": true,
"lcname": "django-components"
}