История коммитов

.
feat(consent): allow HTML in the title and consents without a text page
The title is shown next to the checkbox and may now carry inline HTML with links, so it is sanitized on output with an inline-only allowlist and shown as plain text in page titles, breadcrumbs and admin tables. The text field became optional: a consent without text has no page of its own (/consent/{id} returns 404) and the form renders the title with its own links instead of linking to the text.

Forms now get FormConsentDTO from ConsentService and render the shared system::app/consent-checkbox partial. The consents.title column is widened to TEXT; existing installations are updated with install/update_consent_title.php.
.
fix(collections): escape ckeditor attributes in the admin item form
Item text is stored raw and was printed unescaped into the value attribute of the CKEditor Vue component, so quotes inside the HTML (links, images, figures) closed the attribute early and mangled the editor content on load and on re-save. Escape all attributes in the partial itself, which is the output boundary and is only used inside this module.
.
fix(contacts): make the admin link in the notification email a real button
.
simba77
docs(changelog): note the contacts module
.
docs(changelog): note the contacts module
.
simba77
feat(contacts): add contacts module with feedback form
- public /contacts page with contact info (email, phone, address, working hours, socials) and Schema.org markup
- feedback form with captcha for guests, honeypot, CSRF/flood/ban checks and consent checkboxes
- contact_messages table, admin list with status filter, message view, mark as processed and delete
- admin settings stored in the johncms config: multilingual texts with current language / site default / english fallback
- admin notification via the EmailMessage queue with a new mail template
- install/install_contacts.php for existing sites
.
feat(contacts): add contacts module with feedback form
- public /contacts page with contact info (email, phone, address, working hours, socials) and Schema.org markup
- feedback form with captcha for guests, honeypot, CSRF/flood/ban checks and consent checkboxes
- contact_messages table, admin list with status filter, message view, mark as processed and delete
- admin settings stored in the johncms config: multilingual texts with current language / site default / english fallback
- admin notification via the EmailMessage queue with a new mail template
- install/install_contacts.php for existing sites
.
docs(changelog): note language name normalization
.
i18n: normalize language names in locale ini files
Use native endonyms in short form consistently:
- ar: Arabic -> العربية
- az: Azərbaycan dili -> Azərbaycanca
- id: Indonesia (country) -> Bahasa Indonesia
- kk: Қазақ тілі -> Қазақша
- ky: Кыргыз тили -> Кыргызча
- lt: Lietuvos (country, genitive) -> Lietuvių
- ro: Romana -> Română (restore diacritics)
- uz: O'zbek tili -> Oʻzbekcha
- vi: Việt Nam (country) -> Tiếng Việt
.
i18n(ky): add draft Kyrgyz translations for untranslated strings
Fill all 351 untranslated Kyrgyz strings across 14 locale files.

- 279 machine-drafted strings are marked fuzzy: gettext keeps them out of the runtime and Crowdin receives them as unconfirmed suggestions, so a native speaker reviews them before they go live.
- 72 strings reuse existing human translations of the same msgid from other locale files, so they are added as confirmed.
- Terminology follows the existing translations (Өчүрүү, Оңдоо, Бөлүк, Колдонуучу, Китепкана).
- Also fixes broken placeholders in ky: %value% in the flood validator message, and spaced % s / % d specifiers.
- Adds the locale files for the collections and consent modules; the non-Kyrgyz ones are empty templates for Crowdin.