contact messages: contact settings in /_api/settings, ?lang overrides
GET reports contact_enabled/label/email/subject; with a translation ?lang= it also reports the per-language label/subject overrides (*_tr). PUT accepts the contact fields; with a translation ?lang= only the label/subject apply, written as overrides into the chunk-keyed trans store (i18n.set_string_translation) — empty or the original's text drops the override.
This commit is contained in:
1 parent
f68071cb51
commit
f5fbe8ddc5
1 file changed
+63
-6
+63
-6
@@ -24,7 +24,7 @@ from html5tagger import E
|
||||
from pydantic import BaseModel
|
||||
|
||||
from pagerite import i18n, messages, views
|
||||
from pagerite.chunks import store_chunks
|
||||
from pagerite.chunks import chunk_key, store_chunks
|
||||
from pagerite.data import (
|
||||
Node,
|
||||
append_order,
|
||||
@@ -276,12 +276,18 @@ async def update_structure(op: StructureOp, request: Request) -> None:
|
||||
|
||||
|
||||
@router.get("/_api/settings")
|
||||
async def get_settings() -> dict:
|
||||
async def get_settings(lang: str | None = None) -> dict:
|
||||
"""Site-wide settings (brand, theme, custom CSS and favicon URL), plus
|
||||
the themes, banner designs and user fonts available on disk for the
|
||||
selectors, the translator service keys and the wanted translation
|
||||
languages (for the /_translate socket)."""
|
||||
return {
|
||||
languages (for the /_translate socket), and the contact-messaging
|
||||
configuration.
|
||||
|
||||
With a ``?lang=`` translation language the contact label/subject also
|
||||
come out as ``*_tr`` (their per-language override, "" = none — the
|
||||
site settings' messaging section edits those, falling back to the
|
||||
original it edits without the query)."""
|
||||
out = {
|
||||
"brand": data.brand,
|
||||
"brand_html": data.brand_html,
|
||||
"theme": data.theme,
|
||||
@@ -296,11 +302,23 @@ async def get_settings() -> dict:
|
||||
# Unanswered contact threads: the corner ✉️ icon's badge for
|
||||
# admins (this probe runs on every page load; no polling).
|
||||
"contact_unread": messages.unread_count(),
|
||||
"contact_enabled": data.contact_enabled,
|
||||
"contact_label": data.contact_label,
|
||||
"contact_email": data.contact_email,
|
||||
"contact_subject": data.contact_subject,
|
||||
# The site default primary language: the front page's resolved
|
||||
# setting (every page may override it, inherited down the tree).
|
||||
"primary_lang": i18n.primary_lang(data.menu, ""),
|
||||
"translate_langs": sorted(data.translate_langs),
|
||||
}
|
||||
tag = i18n.base_tag(lang or "")
|
||||
if tag and tag != out["primary_lang"]:
|
||||
for field in ("contact_label", "contact_subject"):
|
||||
original = getattr(data, field) or ("Contact us" if field == "contact_label" else "")
|
||||
out[f"{field}_tr"] = (
|
||||
data.trans.get(chunk_key(original), {}).get(tag, "") if original else ""
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
class SettingsIn(BaseModel):
|
||||
@@ -313,17 +331,56 @@ class SettingsIn(BaseModel):
|
||||
transition: str = "cube"
|
||||
translate_langs: list[str] | None = None # None keeps the current set
|
||||
translate_keys: dict[str, str] | None = None # None keeps the current keys
|
||||
contact_enabled: bool | None = None # None keeps the current setting
|
||||
contact_label: str | None = None
|
||||
contact_email: str | None = None
|
||||
contact_subject: str | None = None
|
||||
|
||||
|
||||
@router.put("/_api/settings", status_code=204)
|
||||
async def put_settings(settings: SettingsIn, request: Request) -> None:
|
||||
"""Update site-wide settings; invalidates cached pages and ETags."""
|
||||
async def put_settings(
|
||||
settings: SettingsIn, request: Request, lang: str | None = None
|
||||
) -> None:
|
||||
"""Update site-wide settings; invalidates cached pages and ETags.
|
||||
|
||||
With a ``?lang=`` translation language only the contact label/subject
|
||||
apply — as per-language overrides in the chunk-keyed trans store, the
|
||||
same storage machine translations use (i18n.set_string_translation);
|
||||
empty or the original's text drops the override."""
|
||||
tag = i18n.base_tag(lang or "")
|
||||
if tag and tag != i18n.primary_lang(data.menu, ""):
|
||||
with kanta.transaction(
|
||||
f"settings:{tag}", user=request.headers.get("remote-user")
|
||||
):
|
||||
changed = False
|
||||
for field in ("contact_label", "contact_subject"):
|
||||
value = getattr(settings, field)
|
||||
if value is None:
|
||||
continue
|
||||
original = getattr(data, field) or (
|
||||
"Contact us" if field == "contact_label" else ""
|
||||
)
|
||||
if original:
|
||||
changed |= i18n.set_string_translation(
|
||||
data, tag, original, value.strip()
|
||||
)
|
||||
if changed:
|
||||
_invalidate_pages()
|
||||
return
|
||||
with kanta.transaction("settings", user=request.headers.get("remote-user")):
|
||||
data.brand = settings.brand
|
||||
data.brand_html = settings.brand_html
|
||||
data.theme = settings.theme
|
||||
data.custom_css = settings.custom_css
|
||||
data.transition = settings.transition
|
||||
if settings.contact_enabled is not None:
|
||||
data.contact_enabled = settings.contact_enabled
|
||||
if settings.contact_label is not None:
|
||||
data.contact_label = settings.contact_label.strip()
|
||||
if settings.contact_email is not None:
|
||||
data.contact_email = settings.contact_email.strip()
|
||||
if settings.contact_subject is not None:
|
||||
data.contact_subject = settings.contact_subject.strip()
|
||||
if settings.translate_langs is not None:
|
||||
# Any language may be a target — including the site default
|
||||
# (an article in another language can be translated INTO it);
|
||||
|
||||
Reference in new issue
Block a user