Round out referee amounts/colors, and add bilingual (nl/en) news content
Referee display: drop the redundant "External" pill from the PDF form, round the event/dashboard "due" summary to 2 decimals (a fine-grained km rate like 0.083 was pushing the raw total to 3+ decimals), and theme the PDF's accent colors off the club's own primary/secondary colors instead of a hardcoded default. News: title/body stay the club's own-language (Dutch) text; new optional title_en/body_en carry a translation, with News.effective_title_en/ effective_body_en resolving the fallback to the original on read rather than copying it in at save time -- so editing the Dutch text later never leaves a stale English copy behind, and existing rows get correct fallback behaviour with no backfill. The news form lays both languages out side by side; the detail page only shows an English section when one was actually added. The public API returns both languages in one call (title_nl/body_nl/excerpt_nl alongside title_en/body_en/excerpt_en, the latter never blank) -- a breaking rename of the previously-unprefixed title/body/excerpt fields. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -622,6 +622,8 @@ team-tagged instead of categorised, with a two-step release flow rather than a b
|
||||
```
|
||||
news.News(ClubScopedModel) # -> carries `club`
|
||||
title, slug (SlugField, auto from title), body (TextField)
|
||||
title_en CharField (blank) -- optional English translation of `title`
|
||||
body_en TextField (blank) -- optional English translation of `body`
|
||||
teams M2M teams.Team (blank -- empty means club-wide)
|
||||
visibility CharField (TextChoices: internal | external | both)
|
||||
status CharField (TextChoices: draft | published)
|
||||
@@ -665,9 +667,23 @@ home.HomeConfig(ClubScopedModel) # one row PER CLUB: featured articles/teams,
|
||||
club person, not a raw login; `SET_NULL` so deleting a member doesn't erase their posts.
|
||||
- `slug`s back clean public URLs and feed `search`; they are **unique per club** (§2.4), so
|
||||
two clubs can both have `/news/season-kickoff`. Resolve within the request's club.
|
||||
- `visibility` (internal/external/both) is stored and enforced nowhere yet — no
|
||||
member-facing reading page or public API exists. Both are later work; the field is
|
||||
there so they don't need a backfill when they land.
|
||||
- `visibility` (internal/external/both) is enforced by the public read-only API
|
||||
(`news/api.py`, mounted under `api/`) — only `external`/`both` items, published and
|
||||
past their release date, are ever returned. No member-facing internal reading page
|
||||
exists yet; that's later work.
|
||||
- **`title`/`body` are Dutch (the club's own language, and the only one required);
|
||||
`title_en`/`body_en` are an optional English translation**, both left blank by
|
||||
default. Nothing computes or stores a fallback — `News.effective_title_en` /
|
||||
`effective_body_en` resolve it on read (`title_en or title`), so translating a Dutch
|
||||
edit later never leaves a stale English copy behind, and every existing row gets
|
||||
correct fallback behaviour with no backfill. The public API always returns both
|
||||
languages in one call (`title_nl`/`body_nl`/`excerpt_nl` alongside
|
||||
`title_en`/`body_en`/`excerpt_en`, the latter three via the `effective_*` properties
|
||||
so they're never blank) — no `?lang=` param, the consumer picks what it needs. The
|
||||
control panel's news form lays the two languages out in side-by-side columns
|
||||
(`management/templates/management/news_form.html`); the detail page only shows an
|
||||
"English" section when a translation was actually added, not the fallback-filled
|
||||
text under a second heading.
|
||||
- `NewsPhoto.image` / hero images use `ImageField` → **media storage must be configured**
|
||||
(§8). If page/news trees grow, consider a tree library later — start flat.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user