Initial commit
Test / test (push) Successful in 7m5s
Release / gates (push) Successful in 7m28s
Release / build (amd64, freebsd) (push) Successful in 2m52s
Release / build (amd64, linux) (push) Successful in 2m46s
Release / build (arm64, freebsd) (push) Successful in 2m22s
Release / build (arm64, linux) (push) Successful in 2m38s
Release / build (loong64, linux) (push) Successful in 2m7s
Release / build (riscv64, linux) (push) Successful in 2m17s
Release / release (push) Successful in 1m0s
Test / test (push) Successful in 7m5s
Release / gates (push) Successful in 7m28s
Release / build (amd64, freebsd) (push) Successful in 2m52s
Release / build (amd64, linux) (push) Successful in 2m46s
Release / build (arm64, freebsd) (push) Successful in 2m22s
Release / build (arm64, linux) (push) Successful in 2m38s
Release / build (loong64, linux) (push) Successful in 2m7s
Release / build (riscv64, linux) (push) Successful in 2m17s
Release / release (push) Successful in 1m0s
Assisted-by: GLM 5.3
This commit is contained in:
@@ -0,0 +1,831 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
|
||||
// Package i18n holds the admin interface strings in every language the
|
||||
// UI ships. Simple messages are keyed by their English text, so the
|
||||
// template keeps its meaning and an untranslated key falls back to
|
||||
// English rather than an identifier. Messages with a numeral use an
|
||||
// explicit id and per-language plural forms, because Czech declines
|
||||
// the counted noun where English does not.
|
||||
//
|
||||
// The catalogue never stores markup: sentences with <code>, <strong> and
|
||||
// friends stay in the template, split into fragments, so every string
|
||||
// the funcs return can take the template engine's escaping. The one
|
||||
// exception is trh, for static sentences that only make sense whole.
|
||||
//
|
||||
// Some keys never appear literally outside this file: the editor
|
||||
// matches payloads validation errors against the catalogue at runtime
|
||||
// ("Slug is required." and friends), and the page scripts read their
|
||||
// strings from the JSON dump, so a key being absent from the templates
|
||||
// does not mean it is dead.
|
||||
package i18n
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Languages the admin interface ships, in the order the settings
|
||||
// switch lists them.
|
||||
var Languages = []string{"en", "cs"}
|
||||
|
||||
// Cookie carries the interface language across the login screen, where
|
||||
// no account is known yet.
|
||||
const Cookie = "volumen_admin_lang"
|
||||
|
||||
// Valid reports whether the value is a shipped language.
|
||||
func Valid(lang string) bool {
|
||||
return slices.Contains(Languages, lang)
|
||||
}
|
||||
|
||||
// Normalize maps a language tag, which may carry a region ("cs-CZ"),
|
||||
// onto a shipped language, or "" when nothing matches.
|
||||
func Normalize(tag string) string {
|
||||
tag = strings.ToLower(strings.TrimSpace(tag))
|
||||
for _, l := range Languages {
|
||||
if tag == l || strings.HasPrefix(tag, l+"-") {
|
||||
return l
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// pluralSet holds the counted forms of one message: one for exactly
|
||||
// one, few for the Czech "2 to 4" class (22 to 24 included), other for
|
||||
// the rest. English never uses few.
|
||||
type pluralSet struct {
|
||||
one, few, other string
|
||||
}
|
||||
|
||||
// pluralForms are the messages that carry a numeral. Every language
|
||||
// defines one and other; few exists for Czech alone.
|
||||
var pluralForms = map[string]map[string]pluralSet{
|
||||
"posts.total": {
|
||||
"en": {one: "%d post in total", other: "%d posts in total"},
|
||||
"cs": {one: "Celkem %d publikace", few: "Celkem %d publikace", other: "Celkem %d publikací"},
|
||||
},
|
||||
"media.count": {
|
||||
"en": {one: "%d file uploaded", other: "%d files uploaded"},
|
||||
"cs": {one: "Nahraný %d soubor", few: "Nahrané %d soubory", other: "Nahraných %d souborů"},
|
||||
},
|
||||
"revisions.count": {
|
||||
"en": {one: "%d archived version", other: "%d archived versions"},
|
||||
"cs": {one: "Archivovaná %d verze", few: "Archivované %d verze", other: "Archivovaných %d verzí"},
|
||||
},
|
||||
"posts.published": {
|
||||
"en": {one: "%d post published.", other: "%d posts published."},
|
||||
"cs": {one: "Zveřejněna %d publikace.", few: "Zveřejněny %d publikace.", other: "Zveřejněno %d publikací."},
|
||||
},
|
||||
"posts.drafted": {
|
||||
"en": {one: "%d post moved to draft.", other: "%d posts moved to draft."},
|
||||
"cs": {one: "Přesunuta %d publikace do konceptu.", few: "Přesunuty %d publikace do konceptu.", other: "Přesunuto %d publikací do konceptu."},
|
||||
},
|
||||
"posts.deleted": {
|
||||
"en": {one: "%d post deleted.", other: "%d posts deleted."},
|
||||
"cs": {one: "Smazána %d publikace.", few: "Smazány %d publikace.", other: "Smazáno %d publikací."},
|
||||
},
|
||||
"diff.unchanged": {
|
||||
"en": {one: "%d unchanged line", other: "%d unchanged lines"},
|
||||
"cs": {one: "%d nezměněný řádek", few: "%d nezměněné řádky", other: "%d nezměněných řádků"},
|
||||
},
|
||||
"password.min": {
|
||||
"en": {one: "Password must be at least %d character long.", other: "Password must be at least %d characters long."},
|
||||
"cs": {one: "Heslo musí mít nejméně %d znak.", few: "Heslo musí mít nejméně %d znaky.", other: "Heslo musí mít nejméně %d znaků."},
|
||||
},
|
||||
"password.max": {
|
||||
"en": {one: "Password must be at most %d character long.", other: "Password must be at most %d characters long."},
|
||||
"cs": {one: "Heslo musí mít nejvýše %d znak.", few: "Heslo musí mít nejvýše %d znaky.", other: "Heslo musí mít nejvýše %d znaků."},
|
||||
},
|
||||
"editor.words": {
|
||||
"en": {one: "%d word", other: "%d words"},
|
||||
"cs": {one: "%d slovo", few: "%d slova", other: "%d slov"},
|
||||
},
|
||||
"refs.count": {
|
||||
"en": {one: "%d reference", other: "%d references"},
|
||||
"cs": {one: "%d reference", few: "%d reference", other: "%d referencí"},
|
||||
},
|
||||
"editor.chars": {
|
||||
"en": {one: "%d char", other: "%d chars"},
|
||||
"cs": {one: "%d znak", few: "%d znaky", other: "%d znaků"},
|
||||
},
|
||||
"editor.reading": {
|
||||
"en": {one: "%d min read", other: "%d min read"},
|
||||
"cs": {one: "%d min čtení", few: "%d min čtení", other: "%d min čtení"},
|
||||
},
|
||||
"bulk.selected": {
|
||||
"en": {one: "%d selected", other: "%d selected"},
|
||||
"cs": {one: "Vybráno %d", few: "Vybráno %d", other: "Vybráno %d"},
|
||||
},
|
||||
"login.seconds": {
|
||||
"en": {one: "Too many login attempts. Try again in %d second.", other: "Too many login attempts. Try again in %d seconds."},
|
||||
"cs": {one: "Příliš mnoho pokusů o přihlášení. Zkuste to znovu za %d s.", few: "Příliš mnoho pokusů o přihlášení. Zkuste to znovu za %d s.", other: "Příliš mnoho pokusů o přihlášení. Zkuste to znovu za %d s."},
|
||||
},
|
||||
"deliveries.attempts": {
|
||||
"en": {one: "failed (%d attempt)", other: "failed (%d attempts)"},
|
||||
"cs": {one: "selhalo (%d pokus)", few: "selhalo (%d pokusy)", other: "selhalo (%d pokusů)"},
|
||||
},
|
||||
"posts.count": {
|
||||
"en": {one: "%d post", other: "%d posts"},
|
||||
"cs": {one: "%d publikace", few: "%d publikace", other: "%d publikací"},
|
||||
},
|
||||
"backup.files": {
|
||||
"en": {one: "Backup restored (%d file).", other: "Backup restored (%d files)."},
|
||||
"cs": {one: "Záloha obnovena (%d soubor).", few: "Záloha obnovena (%d soubory).", other: "Záloha obnovena (%d souborů)."},
|
||||
},
|
||||
}
|
||||
|
||||
// cs translates the simple messages, keyed by the English text the
|
||||
// templates and handlers use. Markup stays out: where the template
|
||||
// carries <code> or <strong>, the sentence is split into fragments.
|
||||
var cs = map[string]string{
|
||||
// Layout: sidebar, topbar, mobile sheet, shared dialogs.
|
||||
"Content": "Obsah",
|
||||
"Configure": "Nastavení",
|
||||
"Posts": "Publikace",
|
||||
"New post": "Nová publikace",
|
||||
"Import": "Import",
|
||||
"Media": "Média",
|
||||
"Settings": "Nastavení",
|
||||
"Log out": "Odhlásit se",
|
||||
"Menu": "Nabídka",
|
||||
"Main menu": "Hlavní nabídka",
|
||||
"Collapse sidebar": "Sbalit postranní panel",
|
||||
"Expand sidebar": "Rozbalit postranní panel",
|
||||
"administration": "administrace",
|
||||
"Skip to content": "Přejít na obsah",
|
||||
"Breadcrumb": "Navigace",
|
||||
"Colour mode": "Režim barev",
|
||||
"Follow system": "Podle systému",
|
||||
"Light": "Světlý",
|
||||
"Dark": "Tmavý",
|
||||
"Update now": "Aktualizovat",
|
||||
"Details": "Podrobnosti",
|
||||
"is available; you are running": "je k dispozici; provozujete",
|
||||
"Update to %s now?": "Aktualizovat na %s hned?",
|
||||
"The server will restart.": "Server se restartuje.",
|
||||
"Are you sure?": "Opravdu?",
|
||||
"Continue": "Pokračovat",
|
||||
"URL": "URL",
|
||||
"OK": "Budiž",
|
||||
|
||||
// The admin 404 page.
|
||||
"Page not found": "Stránka nenalezena",
|
||||
"The address does not exist; it may have been moved or deleted.": "Tato adresa neexistuje; možná byla přesunuta nebo zrušena.",
|
||||
"Back to dashboard": "Zpět na přehled",
|
||||
|
||||
// Login page.
|
||||
"Volumen · administration": "Volumen · administrace",
|
||||
"Sign in": "Přihlásit se",
|
||||
"Welcome back. Sign in to manage your posts.": "Vítejte zpět. Přihlaste se ke správě publikací.",
|
||||
"Username": "Uživatel",
|
||||
"Password": "Heslo",
|
||||
"Show password": "Zobrazit heslo",
|
||||
"Hide password": "Skrýt heslo",
|
||||
"Invalid username or password.": "Neplatné uživatelské jméno nebo heslo.",
|
||||
"Auto-unlock in {} s.": "Odemčení za {} s.",
|
||||
" You can try again now.": " Můžete to zkusit znovu.",
|
||||
|
||||
// First-run wizard.
|
||||
"Welcome to Volumen": "Vítejte ve Volumenu",
|
||||
"Set up Volumen": "Nastavení Volumenu",
|
||||
"Set up the administrator account to open this installation.": "Nastavte účet správce, tím se instalace otevře.",
|
||||
"The page takes the colours as you choose.": "Stránka mění barvy podle vaší volby.",
|
||||
"Create account": "Vytvořit účet",
|
||||
"The users file cannot be read; repair it before setting up.": "Soubor uživatelů nelze přečíst; před nastavením ho opravte.",
|
||||
"The account could not be created: %s": "Účet se nepodařilo vytvořit: %s",
|
||||
"Weak": "Slabé",
|
||||
"Fair": "Dostatečné",
|
||||
"Good": "Dobré",
|
||||
"Strong": "Silné",
|
||||
|
||||
// Posts list.
|
||||
"Published": "Publikované",
|
||||
"Drafts": "Koncepty",
|
||||
"Scheduled": "Naplánované",
|
||||
"Total": "Celkem",
|
||||
"Recent published": "Nedávno publikované",
|
||||
"Search title, slug, tag...": "Hledat v titulku, slagu, značce…",
|
||||
"Select all posts": "Vybrat všechny publikace",
|
||||
"All": "Vše",
|
||||
"Filter by status": "Filtrovat podle stavu",
|
||||
"Filter by tag": "Filtrovat podle značky",
|
||||
"Publish": "Publikovat",
|
||||
"Move to draft": "Přesunout do konceptu",
|
||||
"Delete": "Smazat",
|
||||
"Cancel": "Zrušit",
|
||||
"Two-factor authentication": "Dvoufázové přihlášení",
|
||||
"Two-factor code": "Kód dvoufázového přihlášení",
|
||||
"The password is accepted; answer the second question.": "Heslo přijato; odpovězte na druhou otázku.",
|
||||
"Verification code": "Ověřovací kód",
|
||||
"six digits, or a recovery code": "šest číslic, nebo záložní kód",
|
||||
"Six digits from your application, or one of your recovery codes.": "Šest číslic z vaší aplikace, nebo jeden ze záložních kódů.",
|
||||
"Back to sign in": "Zpět na přihlášení",
|
||||
"Your sign-in asks for a code from your application after the password.": "Po přihlášení heslem se žádá ještě kód z vaší aplikace.",
|
||||
"Current code": "Současný kód",
|
||||
"Regenerate recovery codes": "Vygenerovat záložní kódy znovu",
|
||||
"Turn two-factor off? Your application will no longer be asked.": "Vypnout dvoufázové přihlášení? Vaše aplikace se už nebude dotazovat.",
|
||||
"Turn off": "Vypnout",
|
||||
"Scan the code with your authenticator application, or enter the secret by hand, then confirm with the code it shows.": "Naskenujte kód svou aplikací pro ověřování, nebo zadejte tajný klíč ručně, a potvrďte kódem, který ukáže.",
|
||||
"Secret": "Tajný klíč",
|
||||
"Verify and enable": "Ověřit a zapnout",
|
||||
"Ask for a code from your authenticator application after the password. Voluntary: nothing changes until you finish the setup.": "Po hesle se bude žádat o kód z vaší ověřovací aplikace. Dobrovolné: nic se nezmění, dokud nastavení nedokončíte.",
|
||||
"Set up two-factor": "Nastavit dvoufázové přihlášení",
|
||||
"Wrong or expired code.": "Nesprávný nebo propadlý kód.",
|
||||
"That code did not match; start again.": "Kód nesouhlasil; začněte znovu.",
|
||||
"Two-factor is already on.": "Dvoufázové přihlášení už je zapnuté.",
|
||||
"Two-factor could not be enabled: %s": "Dvoufázové přihlášení nešlo zapnout: %s",
|
||||
"Two-factor could not be disabled: %s": "Dvoufázové přihlášení nešlo vypnout: %s",
|
||||
"The codes could not be replaced: %s": "Záložní kódy nešlo vyměnit: %s",
|
||||
"Two-factor is off.": "Dvoufázové přihlášení je vypnuté.",
|
||||
"Two-factor is on. Store these recovery codes now; they will not be shown again.": "Dvoufázové přihlášení je zapnuté. Uschovejte si tyto záložní kódy; znovu se neukážou.",
|
||||
"New recovery codes. Store them now; they will not be shown again.": "Nové záložní kódy. Uschovejte si je; znovu se neukážou.",
|
||||
"No posts yet": "Zatím žádné publikace",
|
||||
"Create your first post to get started.": "Začněte vytvořením první publikace.",
|
||||
"Create post": "Vytvořit publikaci",
|
||||
"No posts match your search": "Žádná publikace neodpovídá hledání",
|
||||
"Try a different search term or status filter.": "Zkuste jiné hledané slovo nebo jiný filtr stavu.",
|
||||
"Clear filters": "Vymazat filtry",
|
||||
"Draft": "Koncept",
|
||||
"Edit": "Upravit",
|
||||
"Delete post": "Smazat publikaci",
|
||||
"Delete %s?": "Smazat %s?",
|
||||
"Post created.": "Publikace vytvořena.",
|
||||
"Post saved.": "Publikace uložena.",
|
||||
"Post deleted.": "Publikace smazána.",
|
||||
"Post duplicated.": "Publikace zkopírována.",
|
||||
"Post restored.": "Publikace obnovena.",
|
||||
"Could not restore the post; it may already be back.": "Publikaci se nepodařilo obnovit; možná už je zpět.",
|
||||
"The post could not be duplicated.": "Publikaci se nepodařilo zdvojit.",
|
||||
"Undo": "Zpět",
|
||||
"Undo failed.": "Obnovení se nezdařilo.",
|
||||
"Delete the selected posts?": "Smazat vybrané publikace?",
|
||||
"Delete this post?": "Smazat tuto publikaci?",
|
||||
|
||||
// Editor.
|
||||
"Draft a new article in Markdown.": "Napište nový článek v Markdownu.",
|
||||
"Edit post": "Úprava publikace",
|
||||
"Update and publish this post.": "Upravte a zveřejněte tuto publikaci.",
|
||||
"Draft, not visible to the public": "Koncept, veřejnosti nezobrazovaný",
|
||||
"Scheduled for %s": "Naplánováno na %s",
|
||||
"Scheduled for later": "Naplánováno na později",
|
||||
"Preview": "Náhled",
|
||||
"Download": "Stáhnout",
|
||||
"History": "Historie",
|
||||
"Duplicate": "Zkopírovat",
|
||||
"Duplicate as draft": "Zkopírovat jako koncept",
|
||||
"Duplicate this post as a draft?": "Zkopírovat tuto publikaci jako koncept?",
|
||||
"Save": "Uložit",
|
||||
"Save (Ctrl+S)": "Uložit (Ctrl+S)",
|
||||
"Revision restored. The previous content was archived; see": "Verze obnovena. Předchozí obsah byl archivován; viz",
|
||||
"Duplicated as draft. The new slug is": "Zkopírováno jako koncept. Nový slug je",
|
||||
", adjust the title and body, then publish.": ", upravte titulek a obsah a publikujte.",
|
||||
"Template": "Šablona",
|
||||
"Blank": "Prázdná",
|
||||
"Restore": "Obnovit",
|
||||
"Discard": "Zahodit",
|
||||
"Title, slug, and publishing options": "Titulek, slug a volby publikování",
|
||||
"Title": "Titulek",
|
||||
"A clear, descriptive title": "Výstižný, popisný titulek",
|
||||
"Slug": "Slug",
|
||||
"my-post-slug": "moje-publikace",
|
||||
"Language": "Jazyk",
|
||||
"Author": "Autor",
|
||||
"Author name": "Jméno autora",
|
||||
"Fediverse creator": "Autor na fediverse",
|
||||
"@user@instance.tld": "@uzivatel@instance.tld",
|
||||
"DOI": "DOI",
|
||||
"Author ORCID": "ORCID autora",
|
||||
"10.5281/zenodo.1234567": "10.5281/zenodo.1234567",
|
||||
"0000-0002-1825-0097": "0000-0002-1825-0097",
|
||||
"Digital Object Identifier; a doi.org URL is stored as the bare 10.… form.": "Digital Object Identifier; URL na doi.org se uloží jako holý tvar 10.…",
|
||||
"The author's Open Researcher and Contributor ID, checked against its own digit.": "Open Researcher and Contributor ID autora, kontroluje se i kontrolní číslice.",
|
||||
"DOI must look like 10.xxxx/suffix.": "DOI musí mít tvar 10.xxxx/sufix.",
|
||||
"Bibliography": "Bibliografie",
|
||||
"The numbered reference list; cite entries as [n] in the body": "Číslovaný seznam literatury; v textu citujte jako [n]",
|
||||
"No references yet.": "Zatím žádné reference.",
|
||||
"Add reference": "Přidat referenci",
|
||||
"Insert [[refs]] marker into the body": "Vložit do textu značku [[refs]]",
|
||||
"Fill the verbatim citation line, or the structured fields; the marker places the list in the body and without it the list is appended.": "Vyplňte doslovný citovaný řádek nebo strukturovaná pole; značka umístí seznam do textu a bez něj se seznam připojí na konec.",
|
||||
"Move up": "Posunout výš",
|
||||
"Move down": "Posunout níž",
|
||||
"Remove reference": "Odebrat referenci",
|
||||
"Verbatim citation": "Doslovná citace",
|
||||
"Structured fields": "Strukturovaná pole",
|
||||
"One author per line, optionally with [orcid:0000-0002-1825-0097]": "Každý autor na vlastním řádku, volitelně s [orcid:0000-0002-1825-0097]",
|
||||
"Authors": "Autoři",
|
||||
"Journal or proceedings": "Časopis nebo sborník",
|
||||
"Venue": "Místo publikace",
|
||||
"Year": "Rok",
|
||||
"Volume": "Ročník",
|
||||
"Pages": "Strany",
|
||||
"arXiv": "arXiv",
|
||||
"Author, title, venue, year": "Autor, titul, kde vyšlo, rok",
|
||||
"Publish date": "Datum publikace",
|
||||
"Schedule for": "Naplánovat na",
|
||||
"Pick a date": "Vyberte datum",
|
||||
"Leave empty to publish immediately. Date is interpreted as your local timezone.": "Necháte-li prázdné, publikuje se hned. Datum se interpretuje v místním časovém pásmu.",
|
||||
"Markdown": "Markdown",
|
||||
"Visual": "Vizuální",
|
||||
"Tags": "Značky",
|
||||
"comma, separated": "čárkami, oddělené",
|
||||
"Series": "Série",
|
||||
"e.g. rust-tutorial": "např. rust-tutorial",
|
||||
"Group multi-part posts; leave empty for standalone posts": "Sdružuje díly publikací; pro samostatné nechte prázdné",
|
||||
"Part number": "Číslo dílu",
|
||||
"Order within the series": "Pořadí v sérii",
|
||||
"Excerpt": "Perex",
|
||||
"Auto-generated from the first paragraph if left empty": "Nevyplněno: vygeneruje se z prvního odstavce",
|
||||
"Available in all languages": "Dostupné ve všech jazycích",
|
||||
"Cover image": "Úvodní obrázek",
|
||||
"Header image shown on the article page": "Obrázek v záhlaví stránky článku",
|
||||
"/media/… or https://…": "/media/… nebo https://…",
|
||||
"Upload": "Nahrát",
|
||||
"Clear": "Vymazat",
|
||||
"Today": "Dnes",
|
||||
"ALT text (for accessibility)": "ALT text (pro přístupnost)",
|
||||
"Caption (e.g. 'Generated by AI')": "Popisek (např. „Vygenerováno AI“)",
|
||||
"Write your post in Markdown…": "Pište publikaci v Markdownu…",
|
||||
"Drop image to upload": "Pusťte obrázek a nahrajte",
|
||||
"Bold (Ctrl+B)": "Tučně (Ctrl+B)",
|
||||
"Italic (Ctrl+I)": "Kurzíva (Ctrl+I)",
|
||||
"Heading 2": "Nadpis 2",
|
||||
"Heading 3": "Nadpis 3",
|
||||
"Link (Ctrl+K)": "Odkaz (Ctrl+K)",
|
||||
"Bullet list": "Odrážky",
|
||||
"Numbered list": "Číslovaný seznam",
|
||||
"Quote": "Citace",
|
||||
"Code": "Kód",
|
||||
"Image": "Obrázek",
|
||||
"Toggle preview": "Přepnout náhled",
|
||||
"✓ saved": "✓ uloženo",
|
||||
"Keyboard shortcuts": "Klávesové zkratky",
|
||||
"Bold": "Tučně",
|
||||
"Italic": "Kurzíva",
|
||||
"Link": "Odkaz",
|
||||
"Save post": "Uložit publikaci",
|
||||
"Show this help": "Zobrazit tuto nápovědu",
|
||||
"Close modal": "Zavřít okno",
|
||||
"Editor": "Editor",
|
||||
"Unsaved changes from %s are available.": "K dispozici jsou neuložené změny z %s.",
|
||||
"Slug is available.": "Slug je volný.",
|
||||
"Already used by “%s”.": "Už ho používá „%s“.",
|
||||
"Will be published immediately (date is today or earlier).": "Publikuje se okamžitě (datum je dnešní nebo dřívější).",
|
||||
"Link URL": "Adresa odkazu",
|
||||
"Only WebP, AVIF and SVG images are accepted (got “%s”).": "Přijímají se jen obrázky WebP, AVIF a SVG (obdrženo „%s“).",
|
||||
"Upload failed:\n\n%s": "Nahrání selhalo:\n\n%s",
|
||||
|
||||
// History.
|
||||
"Back to editor": "Zpět do editoru",
|
||||
"No revisions yet": "Zatím žádné verze",
|
||||
"Every time this post is saved, the previous version is archived here.": "Při každém uložení publikace se předchozí verze archivuje tady.",
|
||||
"Saved": "Uloženo",
|
||||
"Size": "Velikost",
|
||||
"Actions": "Akce",
|
||||
"Restore this revision? The current content will be archived first.": "Obnovit tuto verzi? Současný obsah se nejdřív archivuje.",
|
||||
"Compare": "Porovnat",
|
||||
"Back to history": "Zpět do historie",
|
||||
"Changes": "Změny",
|
||||
"Archived version": "Archivovaná verze",
|
||||
"compared with the current content.": "srovnáno se současným obsahem.",
|
||||
"No differences from the current content.": "Žádné rozdíly oproti současnému obsahu.",
|
||||
"removed": "odebráno",
|
||||
"added": "přidáno",
|
||||
"Upcoming": "Nadcházející",
|
||||
|
||||
// Import.
|
||||
"Import post": "Import publikace",
|
||||
"frontmatter": "hlavička",
|
||||
"Bring a post written anywhere: a Markdown file with optional TOML frontmatter.": "Přineste publikaci psanou kdekoliv: soubor Markdown s volitelnou TOML hlavičkou.",
|
||||
"Drop your post here": "Pusťte sem svou publikaci",
|
||||
"or click to browse": "nebo klikněte a vyberte",
|
||||
"Remove": "Odebrat",
|
||||
"No frontmatter found; the slug will be derived from the file name.": "Hlavička nenalezena; slug se odvodí z názvu souboru.",
|
||||
"Only .md files are accepted, got “%s”": "Přijímají se jen soubory .md, obdrženo „%s“",
|
||||
|
||||
// Media.
|
||||
"No media yet": "Zatím žádná média",
|
||||
"Upload an image to use as a cover or inline content. WebP, AVIF and SVG are supported.": "Nahrajte obrázek jako úvodní nebo do obsahu. Podporovány jsou WebP, AVIF a SVG.",
|
||||
"You can also paste or drop an image directly into the editor body.": "Obrázek můžete také vložit nebo přetáhnout přímo do těla editoru.",
|
||||
"Upload images": "Nahrát obrázky",
|
||||
"Drop images here, or click to browse": "Pusťte sem obrázky, nebo klikněte a vyberte",
|
||||
"WebP, AVIF or SVG, up to 10 MB each.": "WebP, AVIF nebo SVG, každý nejvýše 10 MB.",
|
||||
"Search files...": "Hledat soubory…",
|
||||
"No files match your search.": "Žádný soubor neodpovídá hledání.",
|
||||
"Copy link": "Kopírovat odkaz",
|
||||
"Open in new tab": "Otevřít v nové kartě",
|
||||
"Link copied.": "Odkaz zkopírován.",
|
||||
"Copy the link:": "Zkopírujte odkaz:",
|
||||
"Upload failed: %s": "Nahrání selhalo: %s",
|
||||
"Upload complete.": "Nahrání dokončeno.",
|
||||
"Uploading %s…": "Nahrávám %s…",
|
||||
|
||||
// Settings, shared.
|
||||
"Manage your account and users": "Spravujte svůj účet a uživatele",
|
||||
"Account": "Účet",
|
||||
"Users": "Uživatelé",
|
||||
"Templates": "Šablony",
|
||||
"Backup": "Záloha",
|
||||
"Version": "Verze",
|
||||
"Webhooks": "Webhooky",
|
||||
"API tokens": "API tokeny",
|
||||
"Signed in as": "Přihlášen jako",
|
||||
|
||||
// Account section.
|
||||
"Profile photo": "Profilová fotka",
|
||||
"WebP, AVIF or SVG, max 10 MB. Shown in the sidebar.": "WebP, AVIF nebo SVG, nejvýše 10 MB. Zobrazuje se v postranní liště.",
|
||||
"Identity": "Identita",
|
||||
"Display name": "Zobrazované jméno",
|
||||
"Your real name": "Vaše skutečné jméno",
|
||||
"Save name": "Uložit jméno",
|
||||
"Fediverse handle": "Fediverse účet",
|
||||
"Save handle": "Uložit účet",
|
||||
"Security": "Zabezpečení",
|
||||
"Change your password and username. You can also lock yourself out.": "Změňte heslo i uživatelské jméno. Můžete si i sami zablokovat přístup.",
|
||||
"Current password": "Současné heslo",
|
||||
"New password": "Nové heslo",
|
||||
"Update password": "Změnit heslo",
|
||||
"Update username": "Změnit uživatele",
|
||||
"Language version": "Jazyková verze",
|
||||
"The interface language of your account. The login screen follows your last choice.": "Jazyk rozhraní vašeho účtu. Přihlašovací stránka se řídí poslední volbou.",
|
||||
"Unsupported language.": "Nepodporovaný jazyk.",
|
||||
"The language could not be saved: %s": "Jazyk nešlo uložit: %s",
|
||||
"Colour scheme": "Barevné schéma",
|
||||
"The colour scheme of your account. The login screen follows your last choice.": "Barevné schéma vašeho účtu. Přihlašovací stránka se řídí poslední volbou.",
|
||||
"Unsupported colour scheme.": "Nepodporované barevné schéma.",
|
||||
"The colour scheme could not be saved: %s": "Barevné schéma nešlo uložit: %s",
|
||||
"The colour scheme is set.": "Barevné schéma je nastaveno.",
|
||||
|
||||
// Users section.
|
||||
"Add or remove admin and editor accounts": "Přidávejte a odstraňujte účty správců a autorů",
|
||||
"you": "vy",
|
||||
"Remove this user?": "Odebrat tohoto uživatele?",
|
||||
"Add user": "Přidat uživatele",
|
||||
"Role": "Role",
|
||||
"jane-doe": "jana-novakova",
|
||||
|
||||
// Templates section.
|
||||
"Post templates": "Šablony publikací",
|
||||
"Pre-fill new posts with a reusable structure": "Předvyplňují nové publikace opakovaně použitelnou strukturou",
|
||||
"No templates yet. Templates pre-fill the new-post form so you can keep your favourite structure on hand.": "Zatím žádné šablony. Předvyplňují formulář nové publikace, abyste měli svou oblíbenou strukturu po ruce.",
|
||||
"Name": "Název",
|
||||
"Fields to pre-fill": "Předvyplněná pole",
|
||||
"Extra editor inputs as TOML key = value lines, one per line, strings quoted: author, lang, doi, orcid, series, series_order, cover, excerpt.": "Doplňující hodnoty editoru jako řádky TOML key = value, jeden na řádek, řetězce v uvozovkách: author, lang, doi, orcid, series, series_order, cover, excerpt.",
|
||||
"Template fields must be key = value TOML lines.": "Pole šablony musí být řádky TOML key = value.",
|
||||
"Unknown template field %s.": "Neznámé pole šablony %s.",
|
||||
"Default title": "Výchozí titulek",
|
||||
"Optional": "Volitelné",
|
||||
"Default slug": "Výchozí slug",
|
||||
"Tags (comma-separated)": "Značky (oddělené čárkou)",
|
||||
"Body template (Markdown)": "Šablona obsahu (Markdown)",
|
||||
"e.g. Review": "např. Recenze",
|
||||
"Add template": "Přidat šablonu",
|
||||
|
||||
// Backup section.
|
||||
"Backup & restore": "Záloha a obnova",
|
||||
"Export or import all posts, media, users, and templates": "Exportujte nebo importujte všechny publikace, média, uživatele i šablony",
|
||||
"Export": "Export",
|
||||
"Download backup": "Stáhnout zálohu",
|
||||
"Restore from a previously exported archive. Overwrites existing data.": "Obnova z dříve exportovaného archivu. Přepíše existující data.",
|
||||
"This will overwrite existing posts and users. Continue?": "Tím se přepíšou existující publikace i uživatelé. Pokračovat?",
|
||||
"Restore backup": "Obnovit ze zálohy",
|
||||
|
||||
// Version section.
|
||||
"Keep Volumen up to date": "Udržujte Volumen aktuální",
|
||||
"Installed version": "Nainstalovaná verze",
|
||||
"Running": "Provozuji",
|
||||
"latest": "nejnovější",
|
||||
"Update to %s": "Aktualizovat na %s",
|
||||
"Check for updates": "Zkontrolovat aktualizace",
|
||||
|
||||
// Webhooks section.
|
||||
"Notify external services when posts change": "Upozorněte externí služby na změny publikací",
|
||||
"Endpoints": "Koncové body",
|
||||
"Signed JSON payloads are POSTed on post changes. Changes apply without a restart.": "Podepsané zprávy JSON se posílají při změnách publikací. Změny se projeví bez restartu.",
|
||||
"Events": "Události",
|
||||
"Send test": "Poslat test",
|
||||
"disabled": "vypnuto",
|
||||
"signed": "podepsáno",
|
||||
"from config": "z konfigurace",
|
||||
"Add webhook": "Přidat webhook",
|
||||
"Endpoint URL": "URL koncového bodu",
|
||||
"Signing secret (optional)": "Podpisový tajný klíč (nepovinný)",
|
||||
"Events (comma-separated, empty for all)": "Události (oddělené čárkou, prázdné znamená všechny)",
|
||||
"Enabled": "Zapnuto",
|
||||
"Add": "Přidat",
|
||||
"Enable": "Zapnout",
|
||||
"Disable": "Vypnout",
|
||||
"Remove this webhook?": "Odebrat tento webhook?",
|
||||
"Webhook added.": "Webhook přidán.",
|
||||
"Webhook updated.": "Webhook uložen.",
|
||||
"Webhook removed.": "Webhook odebrán.",
|
||||
"That URL is not a valid http(s) endpoint.": "Tato URL není platný koncový bod http(s).",
|
||||
"That URL is already configured.": "Tato URL už je nastavená.",
|
||||
"The webhook store could not be read: %s": "Soubor webhooků se nepodařilo přečíst: %s",
|
||||
"The webhook could not be saved: %s": "Webhook se nepodařilo uložit: %s",
|
||||
"Recent deliveries": "Nedávná doručení",
|
||||
"Kept in memory; cleared on restart.": "Uchovaná v paměti; po restartu smazána.",
|
||||
"When": "Kdy",
|
||||
"Event": "Událost",
|
||||
"Endpoint": "Kam",
|
||||
"Result": "Výsledek",
|
||||
|
||||
// Tokens section.
|
||||
"Programmatic write access to the public API": "Programový zápis do veřejného API",
|
||||
"Access tokens": "Přístupové tokeny",
|
||||
"Copy this token now; it will never be shown again.": "Token si zkopírujte hned; znovu se nezobrazí.",
|
||||
"No tokens yet. Create one to publish posts from scripts or CI.": "Zatím žádné tokeny. Vytvořte si jeden pro publikování ze skriptů nebo CI.",
|
||||
"Created": "Vytvořeno",
|
||||
"Last used": "Naposledy",
|
||||
"Revoke token “%s”? Scripts using it will stop working.": "Odvolat token „%s“? Skripty, které ho používají, přestanou fungovat.",
|
||||
"Revoke": "Odvolat",
|
||||
"Token name": "Název tokenu",
|
||||
"e.g. deploy-script": "např. deploy-script",
|
||||
"Scopes": "Oprávnění",
|
||||
"Write": "Zápis",
|
||||
"Write creates and edits posts; delete removes them. Read endpoints are public, so no scope is needed for them. Selecting neither grants full access.": "Zápis vytváří a upravuje publikace; mazání je odstraňuje. Čtení je veřejné, oprávnění nepotřebuje. Bez výběru platí plný přístup.",
|
||||
"Create token": "Vytvořit token",
|
||||
|
||||
// Update page.
|
||||
"The server is restarting. This page will reload automatically.": "Server se restartuje. Tato stránka se obnoví sama.",
|
||||
"Server is back; reloading.": "Server je zpět; obnovuji.",
|
||||
"The server did not come back within 3 minutes. Check the service manually.": "Server se do 3 minut nevrátil. Zkontrolujte službu ručně.",
|
||||
|
||||
// Date picker.
|
||||
"Previous month": "Předchozí měsíc",
|
||||
"Next month": "Další měsíc",
|
||||
|
||||
// Editor page actions and crumbs.
|
||||
"Select %s": "Vybrat: %s",
|
||||
"Updated to": "Aktualizováno na",
|
||||
"Short summary for listings and previews": "Krátké shrnutí pro výčty a náhledy",
|
||||
"Volumen admin": "Volumen administrace",
|
||||
|
||||
// Editor crumbs and roles.
|
||||
"Untitled": "Bez názvu",
|
||||
"%d of %d": "%d z %d",
|
||||
"admin": "administrátor",
|
||||
"author": "autor",
|
||||
"date must be an ISO 8601 date.": "Datum musí být ve tvaru ISO 8601 (RRRR-MM-DD).",
|
||||
"publish_at must be an ISO 8601 date.": "Datum publikace musí být ve tvaru ISO 8601 (RRRR-MM-DD).",
|
||||
|
||||
// Go handler messages: posts.
|
||||
"No file selected.": "Nevybrán žádný soubor.",
|
||||
"No file was uploaded.": "Nevybrán žádný soubor.",
|
||||
"The upload could not be stored.": "Nahraný soubor nešlo uložit.",
|
||||
"Only .md files are accepted.": "Přijímají se jen soubory .md.",
|
||||
"File is too large.": "Soubor je příliš velký.",
|
||||
"The file could not be read as a post: %s": "Soubor nešlo přečíst jako publikaci: %s",
|
||||
"Import failed.": "Import selhal.",
|
||||
"The file could not be read (limit %s bytes).": "Soubor nešlo přečíst (limit %s bajtů).",
|
||||
"Only WebP, AVIF and SVG images are supported.": "Podporovány jsou jen obrázky WebP, AVIF a SVG.",
|
||||
"The post could not be saved: %s": "Publikaci nešlo uložit: %s",
|
||||
"The post could not be deleted: %s": "Publikaci nešlo smazat: %s",
|
||||
"Slug is required.": "Slug je povinný.",
|
||||
"Invalid slug.": "Neplatný slug.",
|
||||
"Invalid language.": "Neplatný jazyk.",
|
||||
"A post with that slug already exists.": "Publikace s tímto slugem už existuje.",
|
||||
"Fediverse creator must look like @user@host.": "Autor fediverse musí mít tvar @uzivatel@hostitel.",
|
||||
|
||||
// Go handler messages: login and security.
|
||||
"Invalid CSRF token": "Neplatný CSRF token",
|
||||
// Go handler messages: settings, account.
|
||||
"Current password is incorrect.": "Současné heslo není správné.",
|
||||
"New password cannot be empty.": "Nové heslo nesmí být prázdné.",
|
||||
"The new password could not be saved: %s": "Nové heslo nešlo uložit: %s",
|
||||
"Password updated.": "Heslo změněno.",
|
||||
"Username cannot be empty.": "Uživatelské jméno nesmí být prázdné.",
|
||||
"Username may use letters, numbers, dot, dash, underscore.": "Uživatelské jméno smí používat písmena, čísla, tečku, pomlčku a podtržítko.",
|
||||
"Username unchanged.": "Uživatelské jméno nezměněno.",
|
||||
"The username could not be changed: %s": "Uživatelské jméno nešlo změnit: %s",
|
||||
"Username updated.": "Uživatelské jméno změněno.",
|
||||
"The display name could not be saved: %s": "Zobrazované jméno nešlo uložit: %s",
|
||||
"Display name cleared.": "Zobrazované jméno vymazáno.",
|
||||
"Display name updated.": "Zobrazované jméno uloženo.",
|
||||
"The handle could not be saved: %s": "Fediverse účet nešlo uložit: %s",
|
||||
"Fediverse handle cleared.": "Fediverse účet vymazán.",
|
||||
"Fediverse handle must look like @user@host.": "Fediverse účet musí mít tvar @uzivatel@hostitel.",
|
||||
"Fediverse handle updated.": "Fediverse účet uložen.",
|
||||
"ORCID iD": "ORCID iD",
|
||||
"Save ORCID": "Uložit ORCID",
|
||||
"ORCID updated.": "ORCID uložen.",
|
||||
"ORCID cleared.": "ORCID vymazán.",
|
||||
"The ORCID could not be saved: %s": "ORCID nešlo uložit: %s",
|
||||
"ORCID must look like 0000-0002-1825-0097.": "ORCID musí mít tvar 0000-0002-1825-0097.",
|
||||
"Your Open Researcher and Contributor ID; it pre-fills the author field of new publications.": "Váš Open Researcher and Contributor ID; předvyplňuje pole autora nových publikací.",
|
||||
"Display name pre-fills the author field. Fediverse handle pre-fills the creator, and the ORCID pre-fills the author identifier of new publications.": "Zobrazované jméno předvyplňuje pole autora, fediverse účet tvůrce a ORCID identifikátor autora nových publikací.",
|
||||
"The photo could not be stored.": "Fotku nešlo uložit.",
|
||||
"The profile photo could not be saved: %s": "Profilovou fotku nešlo uložit: %s",
|
||||
"Profile photo updated.": "Profilová fotka uložena.",
|
||||
"The profile photo could not be removed: %s": "Profilovou fotku nešlo odstranit: %s",
|
||||
"Profile photo removed.": "Profilová fotka odstraněna.",
|
||||
"The interface language is set.": "Jazyk rozhraní je nastaven.",
|
||||
|
||||
// Go handler messages: settings, users.
|
||||
"Username and password are required.": "Uživatelské jméno a heslo jsou povinné.",
|
||||
"That user could not be added: %s": "Uživatele nešlo přidat: %s",
|
||||
"User added.": "Uživatel přidán.",
|
||||
"You cannot change your own role.": "Vlastní roli nelze změnit.",
|
||||
"The role could not be changed: %s": "Roli nešlo změnit: %s",
|
||||
"Role updated.": "Role uložena.",
|
||||
"You cannot delete your own account.": "Vlastní účet nelze smazat.",
|
||||
"The user could not be removed: %s": "Uživatele nešlo odebrat: %s",
|
||||
"User removed.": "Uživatel odebrán.",
|
||||
"Reset password": "Resetovat heslo",
|
||||
"You cannot reset your own password here.": "Vlastní heslo tady resetovat nemůžete.",
|
||||
"That user was not found.": "Takový uživatel nebyl nalezen.",
|
||||
"Password reset; that user's sessions were signed out.": "Heslo resetováno; relace toho uživatele byly odhlášeny.",
|
||||
"Reset this user's password? Their sessions will be signed out.": "Resetovat heslo tohoto uživatele? Jeho relace budou odhlášeny.",
|
||||
|
||||
// Go handler messages: settings, templates and tokens.
|
||||
"Template name is required.": "Název šablony je povinný.",
|
||||
"That template could not be added: %s": "Šablonu nešlo přidat: %s",
|
||||
"Template added.": "Šablona přidána.",
|
||||
"The template could not be deleted: %s": "Šablonu nešlo smazat: %s",
|
||||
"Template deleted.": "Šablona smazána.",
|
||||
"The token could not be created: %s": "Token nešlo vytvořit: %s",
|
||||
"Token revoked.": "Token odvolán.",
|
||||
"That token was not found.": "Token nenalezen.",
|
||||
|
||||
// Go handler messages: settings, webhooks, backup and version.
|
||||
"No webhooks configured.": "Žádné webhooky nenastaveny.",
|
||||
"Webhook not found.": "Webhook nenalezen.",
|
||||
"Test delivery sent.": "Testovací doručení odesláno.",
|
||||
"Test delivery failed.": "Testovací doručení selhalo.",
|
||||
"No backup file selected.": "Nevybrán žádný soubor zálohy.",
|
||||
"Could not restore backup: %s": "Zálohu nešlo obnovit: %s",
|
||||
"The archive holds no files this deployment recognises.": "Archiv neobsahuje žádné soubory, které by tahle instalace poznala.",
|
||||
"Update checks are not available in this build.": "Kontrola aktualizací není v tomto buildu dostupná.",
|
||||
"Update check failed: %s": "Kontrola aktualizací selhala: %s",
|
||||
"volumen %s is already the latest release.": "Volumen %s je už nejnovější vydání.",
|
||||
"volumen %s is available.": "Volumen %s je k dispozici.",
|
||||
"Self-update is not available in this build.": "Automatická aktualizace není v tomto buildu dostupná.",
|
||||
"The upgrade failed: %s": "Aktualizace selhala: %s",
|
||||
"Upgrade to %s failed: %s": "Aktualizace na %s selhala: %s",
|
||||
}
|
||||
|
||||
// csHTML translates the static sentences that only make sense with
|
||||
// their markup whole. They never carry an interpolated value, so
|
||||
// returning them unescaped is safe.
|
||||
var csHTML = map[string]string{
|
||||
"On macOS use <kbd>Cmd</kbd> instead of <kbd>Ctrl</kbd>.": "Na macOS použijte <kbd>Cmd</kbd> místo <kbd>Ctrl</kbd>.",
|
||||
"Download a <code>.tar.gz</code> archive of your entire site.": "Stáhněte <code>.tar.gz</code> archiv celého webu.",
|
||||
"No webhooks yet. Add an endpoint below, or declare <code>[[webhooks]]</code> blocks in <code>config.toml</code> (those are read-only here):": "Žádné webhooky. Přidejte koncový bod níže, nebo deklarujte bloky <code>[[webhooks]]</code> v <code>config.toml</code> (ty tady jsou jen ke čtení):",
|
||||
"Send a token as <code>Authorization: Bearer <token></code> on <code>POST/PUT/DELETE /api/volumen/posts</code>.": "Token posílejte jako <code>Authorization: Bearer <token></code> na <code>POST/PUT/DELETE /api/volumen/posts</code>.",
|
||||
}
|
||||
|
||||
// Catalog translates the admin interface.
|
||||
type Catalog struct{}
|
||||
|
||||
// Admin is the catalogue the binary ships.
|
||||
var Admin = Catalog{}
|
||||
|
||||
// T translates a simple message. The key is the English text; an
|
||||
// unknown key or the "en" language returns the key itself, so English
|
||||
// needs no table and a missing translation degrades to English rather
|
||||
// than to an identifier.
|
||||
func (Catalog) T(lang, s string) string {
|
||||
if lang != "cs" {
|
||||
return s
|
||||
}
|
||||
if out, ok := cs[s]; ok && out != "" {
|
||||
return out
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// TH translates a static sentence that carries its own markup. The
|
||||
// sentences are authored here, never interpolated, so returning them
|
||||
// unescaped cannot smuggle request data into the page.
|
||||
func (Catalog) TH(lang, s string) string {
|
||||
if lang != "cs" {
|
||||
return s
|
||||
}
|
||||
if out, ok := csHTML[s]; ok {
|
||||
return out
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Tf translates a simple message with one %s value. The result stays a
|
||||
// plain string, so the template engine escapes the interpolated value.
|
||||
func (c Catalog) Tf(lang, s, arg string) string {
|
||||
t := c.T(lang, s)
|
||||
if before, after, ok := strings.Cut(t, "%s"); ok {
|
||||
return before + arg + after
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// Tf2 translates a simple message with two %s values.
|
||||
func (c Catalog) Tf2(lang, s, first, second string) string {
|
||||
t := c.T(lang, s)
|
||||
for _, arg := range []string{first, second} {
|
||||
if i := strings.Index(t, "%s"); i >= 0 {
|
||||
t = t[:i] + arg + t[i+2:]
|
||||
}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// N translates a numbered message, picking the form the language's
|
||||
// cardinal rule asks for. Czech follows CLDR: one for 1, few for the
|
||||
// 2 to 4 class except 12 to 14, other otherwise.
|
||||
func (c Catalog) N(lang, id string, n int) string {
|
||||
forms, ok := pluralForms[id]
|
||||
if !ok {
|
||||
return id
|
||||
}
|
||||
set := forms["en"]
|
||||
if lang != "en" {
|
||||
if l := forms[lang]; l.one != "" || l.other != "" {
|
||||
set = l
|
||||
}
|
||||
}
|
||||
var form string
|
||||
switch {
|
||||
case n == 1:
|
||||
form = set.one
|
||||
case lang == "cs" && n%10 >= 2 && n%10 <= 4 && (n%100 < 12 || n%100 > 14):
|
||||
form = set.few
|
||||
default:
|
||||
form = set.other
|
||||
}
|
||||
// A plural set without a few form (an id added with English forms
|
||||
// only) would otherwise render an empty string for the 2 to 4 class.
|
||||
if form == "" {
|
||||
form = set.other
|
||||
}
|
||||
num := strconv.Itoa(n)
|
||||
if i := strings.Index(form, "%d"); i >= 0 {
|
||||
return form[:i] + num + form[i+2:]
|
||||
}
|
||||
return form
|
||||
}
|
||||
|
||||
// JS returns the strings the page scripts need, as a map ready for
|
||||
// JSON encoding into the page. Plural messages carry their three
|
||||
// forms; the client picks one with the same cardinal rule as N.
|
||||
func (c Catalog) JS(lang string) map[string]any {
|
||||
if lang == "" {
|
||||
lang = "en"
|
||||
}
|
||||
out := map[string]any{}
|
||||
for _, id := range []string{
|
||||
"editor.words", "editor.chars", "editor.reading",
|
||||
"bulk.selected", "posts.count", "refs.count",
|
||||
} {
|
||||
set := pluralForms[id]["en"]
|
||||
if lang != "en" {
|
||||
if l := pluralForms[id][lang]; l.one != "" || l.other != "" {
|
||||
set = l
|
||||
}
|
||||
}
|
||||
out[id] = []string{set.one, set.few, set.other}
|
||||
}
|
||||
plain := map[string]string{
|
||||
"post.created": c.T(lang, "Post created."),
|
||||
"post.updated": c.T(lang, "Post saved."),
|
||||
"post.deleted": c.T(lang, "Post deleted."),
|
||||
"post.duplicated": c.T(lang, "Post duplicated."),
|
||||
"post.undone": c.T(lang, "Post restored."),
|
||||
"post.undelete_failed": c.T(lang, "Could not restore the post; it may already be back."),
|
||||
"post.duplicate_failed": c.T(lang, "The post could not be duplicated."),
|
||||
"undo": c.T(lang, "Undo"),
|
||||
"undo.failed": c.T(lang, "Undo failed."),
|
||||
"autosave.available": c.T(lang, "Unsaved changes from %s are available."),
|
||||
"slug.ok": c.T(lang, "Slug is available."),
|
||||
"slug.taken": c.T(lang, "Already used by “%s”."),
|
||||
"upload.prefix": c.T(lang, "Upload failed:\n\n%s"),
|
||||
"upload.rejected": c.T(lang, "Only WebP, AVIF and SVG images are accepted (got “%s”)."),
|
||||
"link.prompt": c.T(lang, "Link URL"),
|
||||
"Show password": c.T(lang, "Show password"),
|
||||
"Hide password": c.T(lang, "Hide password"),
|
||||
"Collapse sidebar": c.T(lang, "Collapse sidebar"),
|
||||
"Expand sidebar": c.T(lang, "Expand sidebar"),
|
||||
"login.unlock": c.T(lang, "Auto-unlock in {} s."),
|
||||
"login.retry": c.T(lang, " You can try again now."),
|
||||
"update.reload": c.T(lang, "Server is back; reloading."),
|
||||
"update.gaveup": c.T(lang, "The server did not come back within 3 minutes. Check the service manually."),
|
||||
"datepicker.prev": c.T(lang, "Previous month"),
|
||||
"datepicker.next": c.T(lang, "Next month"),
|
||||
"Pick a date": c.T(lang, "Pick a date"),
|
||||
"Clear": c.T(lang, "Clear"),
|
||||
"Today": c.T(lang, "Today"),
|
||||
"filter.of": c.T(lang, "%d of %d"),
|
||||
"import.rejected": c.T(lang, "Only .md files are accepted, got “%s”"),
|
||||
"media.uploading": c.T(lang, "Uploading %s…"),
|
||||
"media.upload_failed": c.T(lang, "Upload failed: %s"),
|
||||
"media.copied": c.T(lang, "Link copied."),
|
||||
"media.copy_prompt": c.T(lang, "Copy the link:"),
|
||||
"upload.complete": c.T(lang, "Upload complete."),
|
||||
"pw.weak": c.T(lang, "Weak"),
|
||||
"pw.fair": c.T(lang, "Fair"),
|
||||
"pw.good": c.T(lang, "Good"),
|
||||
"pw.strong": c.T(lang, "Strong"),
|
||||
}
|
||||
for id, v := range plain {
|
||||
out[id] = v
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user