Metadata-Version: 2.5
Name: dialecto-django
Version: 0.1.0
Summary: Dialecto for Django: the usage scan CLI, call-site renames and in-context editing.
License-Expression: MIT
License-File: LICENSE
Keywords: dialecto,django,gettext,i18n,localization
Classifier: Framework :: Django
Classifier: Framework :: Django :: 5.2
Classifier: Framework :: Django :: 6.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# dialecto-django

Dialecto's client for Django projects. It has no runtime dependencies and the scan never imports your project.

```sh
DIALECTO_SCAN_TOKEN=dlk_… DIALECTO_PROJECT=12 dialecto-django scan --usages
```

| Command | Does |
| --- | --- |
| `scan` | Sends the committed `.po` files, and with `--usages` every place the code and templates read a msgid, to Dialecto. |
| `usages` | Prints what the usage scan found, in the view Dialecto gets (`--summary`, `--out FILE`). Sends nothing. |
| `check` | Re-scans and fails when code reads a msgid that no catalog holds. Sends nothing. |
| `doctor` | Checks Python, git, the catalogs, the token and the server. |

## Edit text in place (development only)

Add the middleware under `if DEBUG:`, run `runserver`, and open your own pages in Dialecto's editor.

```python
# settings.py
if DEBUG:
    MIDDLEWARE.insert(0, "dialecto_django.middleware.InContextMiddleware")  # first, or just inside GZipMiddleware
```

Install it as a development dependency (`pip install dialecto-django` in your dev requirements only). With
`DEBUG = False`, or `DIALECTO_IN_CONTEXT=off` (an environment variable or a Django setting), Django drops the middleware
at load: nothing is patched, no `/__dialecto` route answers and no marker reaches a page.

- Pages are marked only while Dialecto's editor is open (it heartbeats every 30 s; the flag lapses after 90 s), for a
  top-level `GET` of a page on a loopback address. POSTs, JSON, XHR and
  frames are never marked, and a marked request that returns something other than HTML has the markers stripped.
- Only strings from `.po` files inside your repository are marked (`LOCALE_PATHS` and your apps' `locale/` folders).
  Django's and packages' strings, `djangojs`, and a missing `pgettext` translation are not.
- Drafts preview in place for plain strings, `%(name)s` strings (`%%` is a literal `%`) and `ngettext` plurals in any locale; the
  overlay reads the values off the page and the plural form from the marker. Brace (`{name}`) and positional (`%s`) strings, and
  a page value it cannot read back unambiguously, show "Reload to preview" instead, which renders the draft on the server.
- `INSTALLED_APPS += ["dialecto_django"]` is optional; it starts the same add-on in `AppConfig.ready()`.
- Settings: `DIALECTO_URL`, `DIALECTO_PROJECT`, `DIALECTO_PATHS` (URL prefixes the add-on is limited to) and
  `DIALECTO_ROOT` (the repository folder; default the git top level). A `DIALECTO = {...}` dict in settings sets the same
  options by lower-case name.
- With django-csp the add-on adds the Dialecto origin to `CONTENT_SECURITY_POLICY` directives when it starts. State
  (drafts, the marking flag) is per process: run one worker. Avoid `{% cache %}` and `cache_page` while editing; use
  `DummyCache`.
- `dialecto-django doctor` with `DJANGO_SETTINGS_MODULE` set checks the middleware position, django-csp, `i18n_patterns`,
  the cache backend, `--forwarded-allow-ips='*'` and worker count.

## Settings

Option over environment over default.

| Variable | Default |
| --- | --- |
| `DIALECTO_URL` | `https://app.dialecto.eu` |
| `DIALECTO_PROJECT` | none (the project's number) |
| `DIALECTO_SCAN_TOKEN` | none (environment only) |
| `DIALECTO_CATALOG_PATHS` | `locale/**/*.po,*/locale/**/*.po` |
| `DIALECTO_USAGES=on` | off |
| `DIALECTO_REQUIRE_USAGES` | off |
| `DIALECTO_USAGES_EXCLUDE` | none |
| `DIALECTO_I18N_FUNCTIONS` | none (your wrappers that take a msgid first) |
| `DIALECTO_TEMPLATE_EXTENSIONS` | none (added to `.html`, `.txt`, `.xml`) |
| `DIALECTO_DEFAULT_BRANCH` | the remote's `origin/HEAD` |

## CI

```yaml
- uses: actions/setup-python@v5
  with: { python-version: "3.12" }
- run: pip install dialecto-django
- run: dialecto-django scan --usages
  env:
    DIALECTO_SCAN_TOKEN: ${{ secrets.DIALECTO_SCAN_TOKEN }}
    DIALECTO_PROJECT: "12"
```

Dialecto reads committed `.po` files only. `.mo` files are build output: they are never read, sent or written, so run
`compilemessages` in your own build after a merged Dialecto pull request.

## Exit codes

| Exit | When |
| --- | --- |
| 0 | Sent, already scanned, or the branch isn't scanned |
| 1 | `check` found problems |
| 2 | The command can't start: missing token or project, bad URL, not a git repository, a limit |
| 3 | Dialecto refused and a retry can't help (401, 403, 413, 422) |
| 4 | Still failing after three tries (429, 5xx, timeout, connection refused) |
