Metadata-Version: 2.4
Name: django-admin-wiki
Version: 0.1.0
Summary: Collaborative staff wiki for Django Admin — edit in the browser, search with Postgres.
Project-URL: Homepage, https://github.com/csurbier/the-django-admin-wiki
Project-URL: Documentation, https://github.com/csurbier/the-django-admin-wiki#readme
Project-URL: Issues, https://github.com/csurbier/the-django-admin-wiki/issues
Author: Christophe Surbier
License-Expression: BSD-3-Clause
License-File: LICENSE
Keywords: admin,django,fts,mkdocs,staff,wiki
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 5.1
Classifier: Framework :: Django :: 5.2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: bleach>=6.0
Requires-Dist: django-summernote>=0.8.20
Requires-Dist: django<6,>=4.2
Requires-Dist: markdown>=3.5
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: pytest-django>=4.8; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: markdown-extras
Requires-Dist: pymdown-extensions>=10.0; extra == 'markdown-extras'
Provides-Extra: s3
Requires-Dist: boto3>=1.34; extra == 's3'
Requires-Dist: django-storages[s3]>=1.14; extra == 's3'
Description-Content-Type: text/markdown

# django-admin-wiki

**Collaborative staff wiki for Django Admin — edit in the browser, search with Postgres.**

A reusable Django app for internal / back-office documentation next to `django.contrib.admin`.
Not a public MediaWiki clone.

## Features

- In-browser **WYSIWYG editing** (Summernote by default; switchable to textarea or a custom widget)
- Up to **three-level** navigation tree
- Full-text search (PostgreSQL FTS) with SQLite/MySQL substring fallback
- Revision history on every staff save
- Import from Markdown / MkDocs (`import_mkdocs`)
- Visible link from Django admin (Wiki pages changelist)
- **Premium cloud mode**:  Hosted on our servers via API (no local wiki tables)

## Requirements

- Python ≥ 3.10
- Django ≥ 4.2, &lt; 6
- PostgreSQL recommended for production search (`django.contrib.postgres`) when `STORAGE="local"`

## Install (5 minutes) — self-hosted (OSS)

```bash
pip install django-admin-wiki
```

```python
# settings.py
INSTALLED_APPS = [
    ...,
    "django.contrib.postgres",  # if using Postgres FTS
    "django_summernote",        # required for default WYSIWYG editor
    "django_admin_wiki",
]

MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"

DJANGO_ADMIN_WIKI = {
    "STORAGE": "local",
    "SEARCH_BACKEND": "postgres",  # or "fallback"
    "SEARCH_CONFIG": "french",
    "EDITOR": "summernote",
    "ALLOW_MARKDOWN_READ": True,
    "DOCS_DIR": BASE_DIR / "wiki_docs",
    "MKDOCS_YML": BASE_DIR / "wiki_docs" / "mkdocs.yml",
    "URL_PREFIX": "wiki/",
    # Media: default local FS under DOCS_DIR/uploads via POST /wiki/media/upload/
    # "MEDIA_BACKEND": "django",  # use Django STORAGES (S3) instead
    # "MEDIA_MAX_UPLOAD_BYTES": 5 * 1024 * 1024,
}
```

Images in the editor are uploaded as files (no base64 in the database). Optional S3 for self-hosted:

```bash
pip install "django-admin-wiki[s3]"
```

```python
# settings — host-owned bucket
INSTALLED_APPS += ["storages"]
STORAGES = {
    "default": {
        "BACKEND": "storages.backends.s3.S3Storage",
        "OPTIONS": { ... },
    },
    "staticfiles": {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"},
}
DJANGO_ADMIN_WIKI = {..., "MEDIA_BACKEND": "django"}
```

```python
# urls.py
path("summernote/", include("django_summernote.urls")),
path("wiki/", include("django_admin_wiki.urls")),
```

```bash
python manage.py migrate
python manage.py setup_wiki_groups   # creates "Wiki readers" + "Wiki editors"
python manage.py runserver
```

Then assign users to a group in Django Admin → Users (or Groups). `is_staff` alone does **not** grant wiki access.

## Premium — cloud storage (no local wiki tables)

Subscribe at [django-admin-wiki.enprod.fr](https://django-admin-wiki.enprod.fr). You receive write and read-only API keys from the account dashboard.

```python
INSTALLED_APPS = [..., "django_summernote", "django_admin_wiki"]

# Prevent host migrate from creating wiki tables:
MIGRATION_MODULES = {"django_admin_wiki": None}

DJANGO_ADMIN_WIKI = {
    "STORAGE": "cloud",
    "CLOUD_API_URL": "https://django-admin-wiki.enprod.fr",
    "CLOUD_API_KEY": "daw_live_...",        # write key (editors)
    "CLOUD_API_KEY_READ": "daw_live_...",   # read-only key (readers)
    "EDITOR": "summernote",
}
```

```python
path("summernote/", include("django_summernote.urls")),
path("wiki/", include("django_admin_wiki.urls")),
# Do NOT run migrations for django_admin_wiki
```

Isolation: every API request is scoped by the tenant bound to your API key. Tenant A cannot read Tenant B data.

### Read vs write (client Django users)

| URL | Who can enter |
|-----|----------------|
| `/admin/` | Django Admin → needs `is_staff` (always) |
| `/wiki/` | membership in **Wiki readers** or **Wiki editors** (not `is_staff`) |

Rights follow the **logged-in user of your Django project** (session cookie). Cloud SaaS accounts (email/password on the Premium site) only manage billing / API keys.

After `migrate` (or `python manage.py setup_wiki_groups`), two groups exist:

| Group | Can |
|-------|-----|
| **Wiki readers** | open `/wiki/`, search, view pages |
| **Wiki editors** | readers + create / edit / upload media |

Assign users in Django Admin → Users. Superusers always have full wiki access.

**Premium cloud mode — dual API keys**

The host app holds two keys; the package picks one from `request.user`:

| User group | Key used |
|------------|----------|
| Wiki editors (`wiki_can_write`) | `CLOUD_API_KEY` |
| Wiki readers | `CLOUD_API_KEY_READ` |

Create both keys from the account dashboard. The cloud API rejects writes on a read-only key.

See [docs/PREMIUM.md](docs/PREMIUM.md).

### Change the editor

```python
DJANGO_ADMIN_WIKI = {"EDITOR": "textarea"}  # or "custom" + EDITOR_WIDGET
```

### Import existing MkDocs docs (local mode)

```bash
python manage.py import_mkdocs
python manage.py refresh_wiki_search_vectors  # Postgres
```

## Settings reference

| Key | Default | Description |
|-----|---------|-------------|
| `STORAGE` | `"local"` | `"local"` (host DB) or `"cloud"` (Premium API) |
| `CLOUD_API_URL` | `""` | Base URL of the cloud API |
| `CLOUD_API_KEY` | `""` | Bearer write key `daw_live_…` |
| `CLOUD_API_KEY_READ` | `""` | Bearer read-only key (readers in cloud mode) |
| `SEARCH_BACKEND` | `"postgres"` | local mode only |
| `SEARCH_CONFIG` | `"french"` | local Postgres FTS config |
| `EDITOR` | `"summernote"` | `summernote`, `textarea`, or `custom` |
| `EDITOR_WIDGET` | `None` | Dotted path when `EDITOR="custom"` |
| `ALLOW_MARKDOWN_READ` | `True` | Convert legacy Markdown on read |
| `DOCS_DIR` / `MKDOCS_YML` | `wiki_docs` | MkDocs import (local) |
| `HOME_SLUG` | `"index"` | Home page slug |
| `URL_PREFIX` | `"wiki/"` | Link rewrite prefix for import |
| `MAX_NAV_DEPTH` | `3` | Max menu depth (root → …) |

## Breaking choices (v1)

- Postgres recommended for local FTS; SQLite uses fallback search
- Summernote is the default editor
- Navigation is up to **three levels** (root → section → page)
- Cloud mode uses shared DB with `tenant_id` isolation (not DB-per-customer)

## Example project

From the repository root:

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cd example_project
python manage.py migrate
python manage.py setup_wiki_groups
python manage.py import_mkdocs
python manage.py createsuperuser
python manage.py runserver
```

See [example_project/README.md](example_project/README.md).

## License

BSD-3-Clause (OSS / local mode). Premium cloud hosting is a commercial subscription.
