# laces

> Django components that know how to render themselves.

- **URL**: https://www.freshcrate.ai/projects/laces
- **Author**: pypi
- **Category**: Frameworks
- **Latest version**: `0.1.2` (2026-04-21)
- **License**: Unknown
- **Source**: https://github.com/tbrlpld/laces/blob/main/CHANGELOG.md
- **Homepage**: https://pypi.org/project/laces/
- **Language**: Python
- **GitHub**: 28 stars
- **Registry**: pypi (`laces`)
- **Tags**: `components`, `django`, `pypi`, `render`, `templates`

## Description

# Laces 👟

[![License: BSD-3-Clause](https://img.shields.io/github/license/tbrlpld/laces)](https://github.com/tbrlpld/laces/blob/main/LICENSE)
[![PyPI version](https://img.shields.io/pypi/v/laces)](https://pypi.org/project/laces/)
[![laces CI](https://github.com/tbrlpld/laces/actions/workflows/test.yml/badge.svg)](https://github.com/tbrlpld/laces/actions/workflows/test.yml)
[![codecov](https://codecov.io/gh/tbrlpld/laces/graph/badge.svg?token=FMHEHNVPSX)](https://codecov.io/gh/tbrlpld/laces)

---

Django components that know how to render themselves.

Laces components provide a simple way to combine data (in the form of Python objects) with the Django templates that are meant to render that data.
The components can then be simply rendered in any other template using the `{% component %}` template tag.
That parent template does not need to know anything about the component's template or data.
No need to receive, filter, restructure or pass any data to the component's template.
Just let the component render itself.

Template and data are tied together (sorry, not sorry 😅) in the component, and they can be passed around together.
This becomes especially useful when components are nested — it allows us to avoid building the same nested structure twice (once in the data and again in the templates).

Working with objects that know how to render themselves as HTML elements is a common pattern found in complex Django applications, such as the [Wagtail](https://github.com/wagtail/wagtail) admin interface.
The Wagtail admin is also where the APIs provided in this package have previously been discovered, developed and solidified.
The purpose of this package is to make these tools available to other Django projects outside the Wagtail ecosystem.

## Links

- [Getting started](#getting-started)
    - [Installation](#installation)
    - [Creating components](#creating-components)
    - [Passing context to the component template](#passing-context-to-the-component-template)
    - [Using components in other templates](#using-components-in-other-templates)
    - [Adding JavaScript and CSS assets to a component](#adding-javascript-and-css-assets-to-a-component)
- [Patterns for using components](#patterns-for-using-components)
  - [Nesting components](#nesting-components)
  - [Nested groups of components](#nested-groups-of-components)
  - [Container components](#container-components)
  - [Using dataclasses](#using-dataclasses)
- [About Laces](#about-laces)
- [Contributing](#contributing)
- [Changelog](https://github.com/tbrlpld/laces/blob/main/CHANGELOG.md)
- [Discussions](https://github.com/tbrlpld/laces/discussions)
- [Security](https://github.com/tbrlpld/laces/security)

## Getting started

### Installation

First, install with pip:
```sh
$ python -m pip install laces
```

Then, add to your installed apps:

```python
# settings.py

INSTALLED_APPS = ["laces", ...]
```

That's it.

### Creating components

The simplest way to create a component is to define a subclass of `laces.components.Component` and specify a `template_name` attribute on it.

```python
# my_app/components.py

from laces.components import Component


class WelcomePanel(Component):
    template_name = "my_app/components/welcome.html"
```

```html+django
{# my_app/templates/my_app/components/welcome.html #}

<h1>Hello World!</h1>
```

With the above in place, you then instantiate the component (e.g., in a view) and pass it to another template for rendering.

```python
# my_app/views.py

from django.shortcuts import render

from my_app.components import WelcomePanel


def home(request):
    welcome = WelcomePanel()  # <-- Instantiates the component
    return render(
        request,
        "my_app/home.html",
        {"welcome": welcome},  # <-- Passes the component to the view template
    )
```

In the view template, we `load` the `laces` tag library and use the `{% component %}` tag to render the component.

```html+django
{# my_app/templates/my_app/home.html #}

{% load laces %}
{% component welcome %}  {# <-- Renders the component #}
```

That's it!
The component's template will be rendered right there in the view template.

Of course, this is a very simple example and not much more useful than using a simple `include`.
We will go into some more useful use cases below.

### Without a template

Before we dig deeper into the component use cases, just a quick note that components don't have to have a template.
For simple cases that don't require a template, the `render_html` method can be overridden instead.
If the return value contains HTML, it should be marked as safe using `django.utils.html.format_html` or `django.utils.safestring.mark_safe`.

```python
# my_app/components.py

from django.utils.html import format_html
from laces.components import Component


class WelcomePanel(Component):
    def render_html(self, parent_context=None):
        return format_html("<h1>Hello World!</h1>")
```

### Passing context to the component template

Now back to

## Recent releases

| Version | Date | Urgency | Changes |
| --- | --- | --- | --- |
| `0.1.2` | 2026-04-21 | Low | Imported from PyPI (0.1.2) |
| `v0.1.2` | 2025-01-14 | Low | ## What's Changed  * Add "Laces and Wagtail" section to README by @tbrlpld in https://github.com/tbrlpld/laces/pull/26 * Add some more package metadata by @tbrlpld in https://github.com/tbrlpld/laces/pull/32 * Parent context refactor by @tbrlpld in https://github.com/tbrlpld/laces/pull/24 * Remove context `None` guard exception by @tbrlpld in https://github.com/tbrlpld/laces/pull/30  **Full Changelog**: https://github.com/tbrlpld/laces/compare/v0.1.1...v0.1.2 |
| `v0.1.2` | 2025-01-14 | Low | ## What's Changed  * Add "Laces and Wagtail" section to README by @tbrlpld in https://github.com/tbrlpld/laces/pull/26 * Add some more package metadata by @tbrlpld in https://github.com/tbrlpld/laces/pull/32 * Parent context refactor by @tbrlpld in https://github.com/tbrlpld/laces/pull/24 * Remove context `None` guard exception by @tbrlpld in https://github.com/tbrlpld/laces/pull/30  **Full Changelog**: https://github.com/tbrlpld/laces/compare/v0.1.1...v0.1.2 |
| `v0.1.2` | 2025-01-14 | Low | ## What's Changed  * Add "Laces and Wagtail" section to README by @tbrlpld in https://github.com/tbrlpld/laces/pull/26 * Add some more package metadata by @tbrlpld in https://github.com/tbrlpld/laces/pull/32 * Parent context refactor by @tbrlpld in https://github.com/tbrlpld/laces/pull/24 * Remove context `None` guard exception by @tbrlpld in https://github.com/tbrlpld/laces/pull/30  **Full Changelog**: https://github.com/tbrlpld/laces/compare/v0.1.1...v0.1.2 |
| `v0.1.2` | 2025-01-14 | Low | ## What's Changed  * Add "Laces and Wagtail" section to README by @tbrlpld in https://github.com/tbrlpld/laces/pull/26 * Add some more package metadata by @tbrlpld in https://github.com/tbrlpld/laces/pull/32 * Parent context refactor by @tbrlpld in https://github.com/tbrlpld/laces/pull/24 * Remove context `None` guard exception by @tbrlpld in https://github.com/tbrlpld/laces/pull/30  **Full Changelog**: https://github.com/tbrlpld/laces/compare/v0.1.1...v0.1.2 |
| `v0.1.2` | 2025-01-14 | Low | ## What's Changed  * Add "Laces and Wagtail" section to README by @tbrlpld in https://github.com/tbrlpld/laces/pull/26 * Add some more package metadata by @tbrlpld in https://github.com/tbrlpld/laces/pull/32 * Parent context refactor by @tbrlpld in https://github.com/tbrlpld/laces/pull/24 * Remove context `None` guard exception by @tbrlpld in https://github.com/tbrlpld/laces/pull/30  **Full Changelog**: https://github.com/tbrlpld/laces/compare/v0.1.1...v0.1.2 |
| `v0.1.2` | 2025-01-14 | Low | ## What's Changed  * Add "Laces and Wagtail" section to README by @tbrlpld in https://github.com/tbrlpld/laces/pull/26 * Add some more package metadata by @tbrlpld in https://github.com/tbrlpld/laces/pull/32 * Parent context refactor by @tbrlpld in https://github.com/tbrlpld/laces/pull/24 * Remove context `None` guard exception by @tbrlpld in https://github.com/tbrlpld/laces/pull/30  **Full Changelog**: https://github.com/tbrlpld/laces/compare/v0.1.1...v0.1.2 |
| `v0.1.2` | 2025-01-14 | Low | ## What's Changed  * Add "Laces and Wagtail" section to README by @tbrlpld in https://github.com/tbrlpld/laces/pull/26 * Add some more package metadata by @tbrlpld in https://github.com/tbrlpld/laces/pull/32 * Parent context refactor by @tbrlpld in https://github.com/tbrlpld/laces/pull/24 * Remove context `None` guard exception by @tbrlpld in https://github.com/tbrlpld/laces/pull/30  **Full Changelog**: https://github.com/tbrlpld/laces/compare/v0.1.1...v0.1.2 |
| `v0.1.2` | 2025-01-14 | Low | ## What's Changed  * Add "Laces and Wagtail" section to README by @tbrlpld in https://github.com/tbrlpld/laces/pull/26 * Add some more package metadata by @tbrlpld in https://github.com/tbrlpld/laces/pull/32 * Parent context refactor by @tbrlpld in https://github.com/tbrlpld/laces/pull/24 * Remove context `None` guard exception by @tbrlpld in https://github.com/tbrlpld/laces/pull/30  **Full Changelog**: https://github.com/tbrlpld/laces/compare/v0.1.1...v0.1.2 |
| `v0.1.2` | 2025-01-14 | Low | ## What's Changed  * Add "Laces and Wagtail" section to README by @tbrlpld in https://github.com/tbrlpld/laces/pull/26 * Add some more package metadata by @tbrlpld in https://github.com/tbrlpld/laces/pull/32 * Parent context refactor by @tbrlpld in https://github.com/tbrlpld/laces/pull/24 * Remove context `None` guard exception by @tbrlpld in https://github.com/tbrlpld/laces/pull/30  **Full Changelog**: https://github.com/tbrlpld/laces/compare/v0.1.1...v0.1.2 |

## Citation

- HTML: https://www.freshcrate.ai/projects/laces
- Markdown: https://www.freshcrate.ai/projects/laces.md
- Dependencies JSON: https://www.freshcrate.ai/api/projects/laces/deps

_Generated by freshcrate.ai. Indexes pypi releases for AI-agent ecosystem packages._
