Metadata-Version: 2.4
Name: conjunto
Version: 0.9.1
Summary: Django application framework/helpers using HTMX, tabler.io, tables2, crispy-forms & more.
Author-email: Christian González <christian.gonzalez@nerdocs.at>
License-Expression: MIT
Project-URL: Homepage, https://github.com/nerdocs/conjunto
Project-URL: Repository, https://github.com/nerdocs/conjunto
Keywords: python,django,framework,i18n
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Programming Language :: Python
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: django>=6.0.3
Requires-Dist: django-countries
Requires-Dist: django-phonenumber-field[phonenumberslite]
Requires-Dist: django-crispy-forms
Requires-Dist: crispy-bootstrap5
Requires-Dist: django-htmx
Requires-Dist: django-tables2
Requires-Dist: django-versionfield
Requires-Dist: markdown>=3.5
Requires-Dist: django-web-components
Requires-Dist: django-statici18n
Requires-Dist: gdaps>=0.18.0
Requires-Dist: django-extensions>=3.2
Requires-Dist: Pillow
Requires-Dist: channels
Requires-Dist: channels-redis
Requires-Dist: django-tomselect>=2026.5.6
Requires-Dist: bleach>=6.0
Requires-Dist: requests>=2.31
Provides-Extra: crypto
Requires-Dist: cryptography>=48; extra == "crypto"
Provides-Extra: cms
Requires-Dist: django-polymorphic>=3.1; extra == "cms"
Dynamic: license-file

# Conjunto

**A Django framework for component-based, plugin-extendable web applications.**

Conjunto bundles a curated, opinionated stack so you can build modern, interactive Django apps without wiring the same
plumbing together every time:

- **[GDAPS](https://gdaps.readthedocs.io)** — plugin architecture: drop-in apps extend the host through typed interfaces,
  auto-discovered at startup.
- **[Tabler.io](https://tabler.io)** (Bootstrap 5) — a complete, themeable admin/app UI kit (light & dark).
- **[HTMX](https://htmx.org)** — server-rendered interactivity without a SPA build step.
- **[django-tables2](https://django-tables2.readthedocs.io)** + **[crispy-forms](https://github.com/django-crispy-forms/django-crispy-forms)**
  — declarative tables, filters and forms.

The result is a batteries-included foundation for multi-tenant, permission-aware line-of-business applications.

## What's in the box

| Area | What you get |
|------|--------------|
| **Plugins (GDAPS)** | Extend menus, settings, tables, login and more via `I…` interfaces — no host code changes. |
| **Layout** | `app_base.html` (topbar, collapsible sidebar, statusbar, offcanvas) and a chrome-less `base.html`. Server-side theming avoids the dark-mode flash. |
| **Menus** | `IMenuItem` registry for topbar, sidebar (2 levels), user dropdown and footer — permission- and visibility-aware. |
| **Scoped settings** | Layered settings resolution **USER > DEVICE > GROUP > TENANT > VENDOR** with lockable floors; typed registry, DB-backed, request-cached. |
| **Settings UI** | Plugin-extendable settings page (`ISettingsGroup` / `ISettingsSection` / `ISettingsForm`) with HTMX save-in-place. |
| **Tenants** | Multi-tenancy: `AbstractTenant`, membership & runtime-editable roles, tenant-scoped model managers, and a tenant picker. |
| **Tables & lists** | `TableListView` with search, filters, row/header actions and HTMX modals — pluggable via `IRowAction` / `IHeaderAction`. |
| **Forms** | Smart `TimeField`/`TimePickerInput`, `DatePickerInput`, dependent-fields HTMX wiring, persistent file fields, safe-HTML fields. |
| **Toasts & messages** | Django messages surfaced as Tabler toasts on both full loads and HTMX swaps. |
| **Audit log** | `log_action()` + a pluggable action registry. |
| **Dashboard widgets** | Lazy-loading, reorderable (Gridstack) HTMX widgets with per-user layout. |
| **Auth** | Plugin-extendable login (`ILoginMethod`, `ILoginViewExtension`, `IPostLoginAction`), remember-me, two-step tenant pick. |
| **Archive** | Soft-delete + versioning + retention (no `django-safedelete` needed). |
| **Wizard** | Multi-step form wizard with session drafts. |
| **Sortable lists** | Fully HTMX-declarative drag-and-drop ordering for FK-linked models. |
| **Profiles & avatars** | Optional `UserProfile` with avatar, plus an always-available `{% avatar %}` tag. |
| **Optional extras** | Block CMS (`conjunto[cms]`) and at-rest encryption (`conjunto[crypto]`). |

## Requirements

- Python **≥ 3.12**
- Django **≥ 6.0**

## Installation

```bash
pip install conjunto            # or: uv add conjunto
```

Optional subsystems:

```bash
pip install "conjunto[cms]"     # block CMS (pulls in django-polymorphic)
pip install "conjunto[crypto]"  # at-rest field/file encryption (pulls in cryptography)
```

## Quick setup

**1. Register the app.** Add `conjunto` **before** `django_extensions` (it overrides the `update_permissions` command),
and add `gdaps` for plugin discovery:

```python
INSTALLED_APPS = [
    # ...
    "conjunto",
    "django_extensions",
    "gdaps",
    # optional: "conjunto.profiles", "conjunto.cms", ...
]
```

**2. Add the middleware** (order matters — `TimezoneMiddleware` after `ConjuntoMiddleware`; `ConjuntoMessagesMiddleware`
after Django's `MessageMiddleware` and after `django_htmx`'s `HtmxMiddleware`):

```python
MIDDLEWARE = [
    # ...
    "django.contrib.messages.middleware.MessageMiddleware",
    "django_htmx.middleware.HtmxMiddleware",
    "conjunto.middleware.ConjuntoMiddleware",
    "conjunto.middleware.ConjuntoMessagesMiddleware",
    "conjunto.middleware.TimezoneMiddleware",
]
```

**3. Fetch the front-end libraries.** Third-party JS/CSS (Tabler, HTMX, Alpine, TinyMCE, …) are **not** bundled in the
wheel — download them into your project's static tree once:

```bash
python manage.py update_libraries --suggest   # prints a CONJUNTO_LIBRARIES = [...] block
# paste it into settings.py, then:
python manage.py update_libraries             # download the files
python manage.py update_libraries --check     # CI guard (no network)
```

This keeps the wheel small (~1 MB instead of ~16 MB) and puts library versions under your control. See
[`docs/usage/static_libraries.md`](docs/usage/static_libraries.md) for `CONJUNTO_VENDOR_DIR`, `STATICFILES_DIRS` and CI
integration.

The [installation guide](docs/usage/installation.md) covers the remaining settings (context processors, `.env`, layout).

## Usage

Full documentation lives under [`docs/`](docs/) — start with the [layout](docs/usage/layout.md),
[menus](docs/usage/menus.md), [scoped settings](docs/usage/settings.md) and [tenants](docs/usage/tenants.md) guides.

## Development

```bash
uv sync                          # install deps (dev group included)
uv run pytest                    # run the test suite
uv run pytest tests/test_x.py    # run a single test module
uv run black .                   # format
uv build                         # build the wheel
```

Formatting is enforced with **Black ≥ 25.12.0**. Tests run against a bundled test app in `tests/`.

## Contributing

Pull requests and ideas are welcome. For major changes, please open an issue first to discuss the direction.

## License

Conjunto is open source under the **MIT License**. Note that it integrates many third-party libraries, which carry their
own (possibly different) licenses — see [`THIRD_PARTY_LICENSES.md`](THIRD_PARTY_LICENSES.md).
