Metadata-Version: 2.5
Name: djhtmx
Version: 1.4.0
Summary: Interactive UI Components for Django using HTMX
Project-URL: Homepage, https://github.com/edelvalle/djhtmx
Project-URL: Documentation, https://github.com/edelvalle/djhtmx#readme
Project-URL: Repository, https://github.com/edelvalle/djhtmx.git
Project-URL: Issues, https://github.com/edelvalle/djhtmx/issues
Project-URL: Changelog, https://github.com/edelvalle/djhtmx/blob/master/CHANGELOG.md
Author-email: Eddy Ernesto del Valle Pino <eddy@edelvalle.me>
License-Expression: MIT
License-File: LICENSE
Keywords: django,htmx,liveview,reactive,real-time,spa,websockets
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 5.2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.13
Requires-Dist: channels>=4.1.0
Requires-Dist: django>=5.2
Requires-Dist: immutables~=0.21; python_version < '3.15'
Requires-Dist: mmh3>=5.1.0
Requires-Dist: orjson>=3.10.7; python_version < '3.14'
Requires-Dist: orjson>=3.11.0; python_version >= '3.14'
Requires-Dist: pydantic<3,>=2.10; python_version < '3.14'
Requires-Dist: pydantic<3,>=2.13; python_version >= '3.14'
Requires-Dist: redis[hiredis]>=7.4.0
Requires-Dist: uuid6>=2024.7.10
Requires-Dist: xotl-tools>=3.1.1
Provides-Extra: logfire
Requires-Dist: logfire[django]>=3.8.0; extra == 'logfire'
Provides-Extra: sentry
Requires-Dist: sentry-sdk<2.63,>=2.62.0; extra == 'sentry'
Description-Content-Type: text/markdown

# djhtmx

[![CI](https://github.com/edelvalle/djhtmx/actions/workflows/ci.yml/badge.svg)](https://github.com/edelvalle/djhtmx/actions/workflows/ci.yml)

Interactive UI Components for Django using [htmx](https://htmx.org)

## Agent Skills

This repository is the home of three skills for coding agents: `djhtmx-setup` for wiring djhtmx into a project and its settings, `djhtmx-components` for writing components, and `djhtmx-testing` for testing them.  Install them in your project with [dotagents](https://github.com/getsentry/dotagents), so the guidance travels with the library instead of drifting in each consumer:

```toml
[[skills]]
name = "djhtmx-setup"
source = "edelvalle/djhtmx"

[[skills]]
name = "djhtmx-components"
source = "edelvalle/djhtmx"

[[skills]]
name = "djhtmx-testing"
source = "edelvalle/djhtmx"
```

They describe djhtmx alone; the conventions of your own project belong in a skill of your own that points at these.

## Install

```bash
uv add djhtmx
```

or

```bash
pip install djhtmx
```

# Configuration

djhtmx needs **Redis** running for component state, and five things wired:

```python
INSTALLED_APPS = [
    ...,
    "djhtmx",
]

# Last, so its exception hook runs first.
MIDDLEWARE = [
    ...,
    "djhtmx.middleware",
]

TEMPLATES = [{
    ...,
    "OPTIONS": {"context_processors": [
        ...,
        "django.template.context_processors.request",
        "djhtmx.context.component_repo",
    ]},
}]
```

```python
# urls.py -- the prefix is yours
urlpatterns = [
    ...,
    path("_htmx/", include("djhtmx.urls")),
]
```

```html
{# the base template #}
{% load htmx %}
<!doctype html>
<html>
  <head>
    {% htmx-headers %}
  </head>
</html>
```

`DJHTMX_REDIS_URL` defaults to `redis://localhost/0`.  Every setting, what running server-sent events asks of the deployment, and what to look at when a component renders but does not respond are in the `djhtmx-setup` skill.

## Getting started

djhtmx is a framework for building components, not a component library: it ships no components, templates or styles, and is unopinionated about all three.

Components are discovered in the `htmx` module -- or the `htmx` package -- of each installed app.

```python
from djhtmx.component import HtmxComponent


class Counter(HtmxComponent):
    _template_name = "Counter.html"
    counter: int = 0

    def inc(self, amount: int = 1):
        self.counter += amount
```

The `inc` event handler is ready to be called from the front-end to respond to an event.

The `counter.html` would be:

```html
{% load htmx %}
<div {% hx-tag %}>
  {{ counter }}
  <button {% on "inc" %}>+</button>
  <button {% on "inc" amount=2 %}>+2</button>
</div>
```

When the event is dispatched to the back-end the component state is reconstructed, the event handler called and then the full component is rendered back to the front-end.

Now use the component in any of your html templates, by passing attributes that are part of the component state:

```html
{% load htmx %}

Counters: <br />
{% htmx "Counter" %} Counter with init value 3:<br />
{% htmx "Counter" counter=3 %}
```

The `djhtmx-components` skill covers the rest -- state and model fields, handlers, events, model subscriptions, query-string state, rendering, SSE -- and `djhtmx-testing` covers testing components with `djhtmx.testing.Htmx`.
