diff --git a/README.md b/README.md index 1a64e82..604c642 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,22 @@ default: autolink: false ``` +## Language / locale + +The editor UI language always follows the current Bolt **backend locale** — each +user sees the editor in the language they've selected for the Bolt admin, with no +configuration. The matching Article language file +(`assets/article/langs/.js`) is loaded automatically; English and Czech ship +with the extension, and locales without a translation file fall back to English. + +This is driven solely by the user's Bolt locale and is not overridable via +`editor.lang`. + +To add a language, copy `assets/article/langs/en.js` to `assets/article/langs/.js` +and translate the values (any key you leave out falls back to English). The file is +loaded before the plugin scripts, so each plugin's own English strings deep-merge on +top and remain available as fallbacks. + ## Adding custom plugins If you've written your own block or plugin for Article according to the diff --git a/assets/article/langs/cs.js b/assets/article/langs/cs.js new file mode 100644 index 0000000..638719c --- /dev/null +++ b/assets/article/langs/cs.js @@ -0,0 +1,175 @@ +/** + * Czech (cs) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in Czech. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['cs'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Textový editor' }, + editor: { title: 'Článek', multiple: 'Vícenásobné' }, + placeholders: { + figcaption: 'Zadejte popisek (nepovinné)', + text: 'Začněte psát...', + code: 'Upravte pro přidání kódu...', + layer: 'Stiskněte Enter pro přidání nového textu...' + }, + popup: { + link: 'Odkaz', add: 'Přidat', grid: 'Mřížka', back: 'Zpět', + image: 'Obrázek', snippets: 'Úryvky', 'add-image': 'Přidat obrázek' + }, + shortcuts: { + 'meta-a': 'Vybrat text v bloku', 'meta-shift-a': 'Vybrat všechny bloky', + 'meta-click': 'Vybrat více bloků', 'meta-z': 'Zpět', 'meta-shift-z': 'Znovu', + 'meta-shift-m': 'Odebrat vložené formátování', 'meta-b': 'Tučné', + 'meta-i': 'Kurzíva', 'meta-u': 'Podtržené', 'meta-h': 'Horní index', + 'meta-l': 'Dolní index', 'meta-k': 'Odkaz', 'meta-alt-0': 'Normální text', + 'meta-alt-1': 'Nadpis 1', 'meta-alt-2': 'Nadpis 2', 'meta-alt-3': 'Nadpis 3', + 'meta-alt-4': 'Nadpis 4', 'meta-alt-5': 'Nadpis 5', 'meta-alt-6': 'Nadpis 6', + 'meta-shift-7': 'Číslovaný seznam', 'meta-shift-8': 'Odrážkový seznam', + 'meta-indent': 'Odsadit', 'meta-outdent': 'Zrušit odsazení', + 'meta-shift-backspace': 'Smazat blok', 'meta-shift-d': 'Duplikovat blok', + 'meta-shift-up': 'Posunout řádek nahoru', 'meta-shift-down': 'Posunout řádek dolů' + }, + headings: { + h1: 'Nadpis 1', h2: 'Nadpis 2', h3: 'Nadpis 3', + h4: 'Nadpis 4', h5: 'Nadpis 5', h6: 'Nadpis 6' + }, + inline: { bold: 'Tučné', italic: 'Kurzíva', deleted: 'Přeškrtnuté' }, + list: { + 'unordered-list': 'Odrážkový seznam', 'ordered-list': 'Číslovaný seznam', + indent: 'Odsadit', outdent: 'Zrušit odsazení' + }, + link: { + link: 'Odkaz', 'edit-link': 'Upravit odkaz', unlink: 'Zrušit odkaz', + 'link-in-new-tab': 'Otevřít odkaz v nové kartě', save: 'Uložit', + insert: 'Vložit', cancel: 'Zrušit', text: 'Text', url: 'URL' + }, + table: { + width: 'Šířka', nowrap: 'Nezalamovat', save: 'Uložit', cancel: 'Zrušit', + 'table-cell': 'Buňka tabulky', 'add-head': 'Přidat záhlaví', + 'remove-head': 'Odebrat záhlaví', 'add-row-below': 'Přidat řádek pod', + 'add-row-above': 'Přidat řádek nad', 'remove-row': 'Odebrat řádek', + 'add-column-after': 'Přidat sloupec za', 'add-column-before': 'Přidat sloupec před', + 'remove-column': 'Odebrat sloupec' + }, + image: { + or: 'nebo', 'alt-text': 'Alternativní text', save: 'Uložit', link: 'Odkaz', + width: 'Šířka', delete: 'Smazat', cancel: 'Zrušit', insert: 'Vložit', + caption: 'Popisek', 'link-in-new-tab': 'Otevřít odkaz v nové kartě', + 'url-placeholder': 'Vložte URL obrázku...', + 'upload-new-placeholder': 'Přetáhněte pro nahrání nového obrázku
nebo klikněte pro výběr' + }, + code: { code: 'Kód', insert: 'Vložit', save: 'Uložit', cancel: 'Zrušit' }, + embed: { + embed: 'Vložený obsah', caption: 'Popisek', insert: 'Vložit', save: 'Uložit', + cancel: 'Zrušit', + description: 'Vložte libovolný embed/HTML kód nebo zadejte URL (pouze video Vimeo nebo YouTube)', + 'responsive-video': 'Responzivní video' + }, + upload: { placeholder: 'Přetáhněte pro nahrání
nebo klikněte pro výběr' }, + templates: { templates: 'Šablony' }, + snippets: { snippets: 'Úryvky' }, + form: { + link: 'Odkaz', url: 'URL', text: 'Text', name: 'Název', + 'alt-text': 'Alternativní text', image: 'Obrázek', upload: 'Nahrát', + alignment: 'Zarovnání', outset: 'Přesah', valign: 'Svislé zarovnání' + }, + buttons: { + 'mobile-view': 'Mobilní zobrazení', cancel: 'Zrušit', insert: 'Vložit', + unlink: 'Zrušit odkaz', save: 'Uložit', add: 'Přidat', + 'transform-to-text': 'Převést na text', align: 'Zarovnání', valign: 'Svislé zarovnání', + outset: 'Přesah', indent: 'Odsadit', outdent: 'Zrušit odsazení', head: 'Záhlaví', + row: 'Řádek', cell: 'Buňka', html: 'HTML', templates: 'Šablony', + shortcuts: 'Klávesové zkratky', format: 'Formát', bold: 'Tučné', italic: 'Kurzíva', + deleted: 'Přeškrtnuté', underline: 'Podtržené', table: 'Tabulka', link: 'Odkaz', + undo: 'Zpět', redo: 'Znovu', style: 'Styl', config: 'Konfigurace', + settings: 'Nastavení', text: 'Text', embed: 'Vložený obsah', grid: 'Mřížka', + image: 'Obrázek', list: 'Seznam', delete: 'Smazat', duplicate: 'Duplikovat', + sort: 'Seřadit', edit: 'Upravit', inline: 'Vložené' + }, + // Popisky bloků. Poslední dva přidávají pluginy `math` a `variable`; + // ostatní jsou základní typy bloků. + blocks: { + noneditable: 'Needitovatelné', paragraph: 'Odstavec', heading: 'Nadpis', + image: 'Obrázek', figcaption: 'Popisek obrázku', embed: 'Vložený obsah', + line: 'Čára', code: 'Kód', quote: 'Citace', quoteitem: 'Odstavec', + snippet: 'Úryvek', column: 'Sloupec', grid: 'Mřížka', list: 'Seznam', + table: 'Tabulka', layer: 'Vrstva', row: 'Řádek', text: 'Text', cell: 'Buňka', + dlist: 'Definiční seznam', address: 'Adresa', form: 'Formulář', card: 'Karta', + tags: 'Štítky', math: 'Matematický výraz', variable: 'Proměnná' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — jedna skupina na plugin (abecedně) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Uložit', cancel: 'Zrušit', 'edit-code': 'Upravit kód' }, + // buttonlink plugin + buttonlink: { button: 'Tlačítko' }, + // carousel plugin + carousel: { carousel: 'Karusel', save: 'Uložit', cancel: 'Zrušit', insert: 'Vložit' }, + // clips plugin + clips: { clips: 'Klipy' }, + // counter plugin + counter: { words: 'slov', chars: 'znaků' }, + // filelink plugin + filelink: { + file: 'Soubor', upload: 'Nahrát', title: 'Název', choose: 'Vybrat', + placeholder: 'Přetáhněte pro nahrání souboru
nebo klikněte pro výběr' + }, + // handle plugin + handle: { handle: 'Úchyt' }, + // icons plugin + icons: { icons: 'Ikony' }, + // imageposition plugin + imageposition: { 'image-position': 'Pozice obrázku' }, + // imageresize plugin + imageresize: { 'image-resize': 'Změna velikosti obrázku' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Vložené formátování', underline: 'Podtržené', + superscript: 'Horní index', subscript: 'Dolní index', mark: 'Zvýraznění', + code: 'Kód', shortcut: 'Zkratka', 'remove-format': 'Odebrat formátování' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Vytvořit tlačítko', 'remove-button': 'Odebrat tlačítko', + button: 'Tlačítko' + }, + // math plugin + math: { + math: 'Matematický výraz', label: 'Zadejte výraz', add: 'Přidat', + save: 'Uložit', cancel: 'Zrušit' + }, + // print plugin + print: { print: 'Tisk' }, + // removeformat plugin + removeformat: { removeformat: 'Odebrat formátování' }, + // selector plugin + selector: { selector: 'Výběr', save: 'Uložit', cancel: 'Zrušit' }, + // slideshow plugin + slideshow: { slideshow: 'Prezentace', save: 'Uložit', cancel: 'Zrušit', insert: 'Vložit' }, + // specialchars plugin + specialchars: { 'special-chars': 'Speciální znaky' }, + // style plugin + style: { style: 'Styl', 'remove-style': 'Odebrat styl' }, + // tags plugin + tags: { + tags: 'Štítky', add: 'Přidat', save: 'Uložit', cancel: 'Zrušit', + label: 'Přidejte štítky oddělené čárkou' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'Zleva doprava', rtl: 'Zprava doleva' }, + // variable plugin + variable: { variable: 'Proměnná' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/de.js b/assets/article/langs/de.js new file mode 100644 index 0000000..deb5e74 --- /dev/null +++ b/assets/article/langs/de.js @@ -0,0 +1,175 @@ +/** + * German (de) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in German. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['de'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Rich-Text-Editor' }, + editor: { title: 'Artikel', multiple: 'Mehrfach' }, + placeholders: { + figcaption: 'Beschriftung eingeben (optional)', + text: 'Etwas eingeben...', + code: 'Bearbeiten, um Code hinzuzufügen...', + layer: 'Enter drücken, um neuen Text hinzuzufügen...' + }, + popup: { + link: 'Link', add: 'Hinzufügen', grid: 'Raster', back: 'Zurück', + image: 'Bild', snippets: 'Snippets', 'add-image': 'Bild hinzufügen' + }, + shortcuts: { + 'meta-a': 'Text im Block auswählen', 'meta-shift-a': 'Alle Blöcke auswählen', + 'meta-click': 'Mehrere Blöcke auswählen', 'meta-z': 'Rückgängig', 'meta-shift-z': 'Wiederholen', + 'meta-shift-m': 'Inline-Formatierung entfernen', 'meta-b': 'Fett', + 'meta-i': 'Kursiv', 'meta-u': 'Unterstreichen', 'meta-h': 'Hochgestellt', + 'meta-l': 'Tiefgestellt', 'meta-k': 'Link', 'meta-alt-0': 'Normaler Text', + 'meta-alt-1': 'Überschrift 1', 'meta-alt-2': 'Überschrift 2', 'meta-alt-3': 'Überschrift 3', + 'meta-alt-4': 'Überschrift 4', 'meta-alt-5': 'Überschrift 5', 'meta-alt-6': 'Überschrift 6', + 'meta-shift-7': 'Nummerierte Liste', 'meta-shift-8': 'Aufzählungsliste', + 'meta-indent': 'Einrücken', 'meta-outdent': 'Ausrücken', + 'meta-shift-backspace': 'Block löschen', 'meta-shift-d': 'Block duplizieren', + 'meta-shift-up': 'Zeile nach oben verschieben', 'meta-shift-down': 'Zeile nach unten verschieben' + }, + headings: { + h1: 'Überschrift 1', h2: 'Überschrift 2', h3: 'Überschrift 3', + h4: 'Überschrift 4', h5: 'Überschrift 5', h6: 'Überschrift 6' + }, + inline: { bold: 'Fett', italic: 'Kursiv', deleted: 'Durchgestrichen' }, + list: { + 'unordered-list': 'Aufzählungsliste', 'ordered-list': 'Nummerierte Liste', + indent: 'Einrücken', outdent: 'Ausrücken' + }, + link: { + link: 'Link', 'edit-link': 'Link bearbeiten', unlink: 'Link entfernen', + 'link-in-new-tab': 'Link in neuem Tab öffnen', save: 'Speichern', + insert: 'Einfügen', cancel: 'Abbrechen', text: 'Text', url: 'URL' + }, + table: { + width: 'Breite', nowrap: 'Kein Zeilenumbruch', save: 'Speichern', cancel: 'Abbrechen', + 'table-cell': 'Tabellenzelle', 'add-head': 'Kopf hinzufügen', + 'remove-head': 'Kopf entfernen', 'add-row-below': 'Zeile darunter hinzufügen', + 'add-row-above': 'Zeile darüber hinzufügen', 'remove-row': 'Zeile entfernen', + 'add-column-after': 'Spalte danach hinzufügen', 'add-column-before': 'Spalte davor hinzufügen', + 'remove-column': 'Spalte entfernen' + }, + image: { + or: 'oder', 'alt-text': 'Alternativtext', save: 'Speichern', link: 'Link', + width: 'Breite', delete: 'Löschen', cancel: 'Abbrechen', insert: 'Einfügen', + caption: 'Beschriftung', 'link-in-new-tab': 'Link in neuem Tab öffnen', + 'url-placeholder': 'Bild-URL einfügen...', + 'upload-new-placeholder': 'Zum Hochladen eines neuen Bildes hierher ziehen
oder zum Auswählen klicken' + }, + code: { code: 'Code', insert: 'Einfügen', save: 'Speichern', cancel: 'Abbrechen' }, + embed: { + embed: 'Einbetten', caption: 'Beschriftung', insert: 'Einfügen', save: 'Speichern', + cancel: 'Abbrechen', + description: 'Beliebigen Embed-/HTML-Code einfügen oder URL eingeben (nur Vimeo- oder YouTube-Video)', + 'responsive-video': 'Responsives Video' + }, + upload: { placeholder: 'Zum Hochladen hierher ziehen
oder zum Auswählen klicken' }, + templates: { templates: 'Vorlagen' }, + snippets: { snippets: 'Snippets' }, + form: { + link: 'Link', url: 'URL', text: 'Text', name: 'Name', + 'alt-text': 'Alternativtext', image: 'Bild', upload: 'Hochladen', + alignment: 'Ausrichtung', outset: 'Überstand', valign: 'Vertikale Ausrichtung' + }, + buttons: { + 'mobile-view': 'Mobile Ansicht', cancel: 'Abbrechen', insert: 'Einfügen', + unlink: 'Link entfernen', save: 'Speichern', add: 'Hinzufügen', + 'transform-to-text': 'In Text umwandeln', align: 'Ausrichtung', valign: 'Vertikale Ausrichtung', + outset: 'Überstand', indent: 'Einrücken', outdent: 'Ausrücken', head: 'Kopf', + row: 'Zeile', cell: 'Zelle', html: 'HTML', templates: 'Vorlagen', + shortcuts: 'Tastenkürzel', format: 'Format', bold: 'Fett', italic: 'Kursiv', + deleted: 'Durchgestrichen', underline: 'Unterstreichen', table: 'Tabelle', link: 'Link', + undo: 'Rückgängig', redo: 'Wiederholen', style: 'Stil', config: 'Konfiguration', + settings: 'Einstellungen', text: 'Text', embed: 'Einbetten', grid: 'Raster', + image: 'Bild', list: 'Liste', delete: 'Löschen', duplicate: 'Duplizieren', + sort: 'Sortieren', edit: 'Bearbeiten', inline: 'Inline' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'Nicht bearbeitbar', paragraph: 'Absatz', heading: 'Überschrift', + image: 'Bild', figcaption: 'Bildbeschriftung', embed: 'Einbettung', + line: 'Linie', code: 'Code', quote: 'Zitat', quoteitem: 'Absatz', + snippet: 'Snippet', column: 'Spalte', grid: 'Raster', list: 'Liste', + table: 'Tabelle', layer: 'Ebene', row: 'Zeile', text: 'Text', cell: 'Zelle', + dlist: 'Definitionsliste', address: 'Adresse', form: 'Formular', card: 'Karte', + tags: 'Tags', math: 'Mathematik', variable: 'Variable' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Speichern', cancel: 'Abbrechen', 'edit-code': 'Code bearbeiten' }, + // buttonlink plugin + buttonlink: { button: 'Button' }, + // carousel plugin + carousel: { carousel: 'Karussell', save: 'Speichern', cancel: 'Abbrechen', insert: 'Einfügen' }, + // clips plugin + clips: { clips: 'Clips' }, + // counter plugin + counter: { words: 'Wörter', chars: 'Zeichen' }, + // filelink plugin + filelink: { + file: 'Datei', upload: 'Hochladen', title: 'Titel', choose: 'Auswählen', + placeholder: 'Datei zum Hochladen hierher ziehen
oder zum Auswählen klicken' + }, + // handle plugin + handle: { handle: 'Griff' }, + // icons plugin + icons: { icons: 'Symbole' }, + // imageposition plugin + imageposition: { 'image-position': 'Bildposition' }, + // imageresize plugin + imageresize: { 'image-resize': 'Bildgröße ändern' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Inline-Format', underline: 'Unterstreichen', + superscript: 'Hochgestellt', subscript: 'Tiefgestellt', mark: 'Markieren', + code: 'Code', shortcut: 'Tastenkürzel', 'remove-format': 'Formatierung entfernen' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Button erstellen', 'remove-button': 'Button entfernen', + button: 'Button' + }, + // math plugin + math: { + math: 'Mathematik', label: 'Ausdruck eingeben', add: 'Hinzufügen', + save: 'Speichern', cancel: 'Abbrechen' + }, + // print plugin + print: { print: 'Drucken' }, + // removeformat plugin + removeformat: { removeformat: 'Formatierung entfernen' }, + // selector plugin + selector: { selector: 'Selektor', save: 'Speichern', cancel: 'Abbrechen' }, + // slideshow plugin + slideshow: { slideshow: 'Diashow', save: 'Speichern', cancel: 'Abbrechen', insert: 'Einfügen' }, + // specialchars plugin + specialchars: { 'special-chars': 'Sonderzeichen' }, + // style plugin + style: { style: 'Stil', 'remove-style': 'Stil entfernen' }, + // tags plugin + tags: { + tags: 'Tags', add: 'Hinzufügen', save: 'Speichern', cancel: 'Abbrechen', + label: 'Kommagetrennte Tags hinzufügen' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'Von links nach rechts', rtl: 'Von rechts nach links' }, + // variable plugin + variable: { variable: 'Variable' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/en.js b/assets/article/langs/en.js new file mode 100644 index 0000000..8d308fe --- /dev/null +++ b/assets/article/langs/en.js @@ -0,0 +1,179 @@ +/** + * English UI language for the Bolt Article editor (Imperavi Article Editor). + * + * This is the canonical, editable English set. It is loaded (by + * Bolt\Article\TwigExtension::articleLangInclude) before the plugin scripts, so + * each plugin's own `translations.en` deep-merges on top of it. Copy this file to + * `.js` and translate the values to add a language; keys left out fall back + * to English automatically. + * + * The file is split into the core editor UI and, below it, one clearly labelled + * group per plugin so related strings stay together — mirror this grouping when + * translating so every plugin's UI is covered (plugin strings are NOT merged into + * non-English locales at runtime; each locale must carry them itself). + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['en'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Rich text editor' }, + editor: { title: 'Article', multiple: 'Multiple' }, + placeholders: { + figcaption: 'Type caption (optional)', + text: 'Type something...', + code: 'Edit to add code...', + layer: 'Press enter to add a new text...' + }, + popup: { + link: 'Link', add: 'Add', grid: 'Grid', back: 'Back', + image: 'Image', snippets: 'Snippets', 'add-image': 'Add Image' + }, + shortcuts: { + 'meta-a': 'Select text in the block', 'meta-shift-a': 'Select all blocks', + 'meta-click': 'Select multiple blocks', 'meta-z': 'Undo', 'meta-shift-z': 'Redo', + 'meta-shift-m': 'Remove inline format', 'meta-b': 'Bold', + 'meta-i': 'Italic', 'meta-u': 'Underline', 'meta-h': 'Superscript', + 'meta-l': 'Subscript', 'meta-k': 'Link', 'meta-alt-0': 'Normal text', + 'meta-alt-1': 'Heading 1', 'meta-alt-2': 'Heading 2', 'meta-alt-3': 'Heading 3', + 'meta-alt-4': 'Heading 4', 'meta-alt-5': 'Heading 5', 'meta-alt-6': 'Heading 6', + 'meta-shift-7': 'Ordered List', 'meta-shift-8': 'Unordered List', + 'meta-indent': 'Indent', 'meta-outdent': 'Outdent', + 'meta-shift-backspace': 'Delete block', 'meta-shift-d': 'Duplicate block', + 'meta-shift-up': 'Move line up', 'meta-shift-down': 'Move line down' + }, + headings: { + h1: 'Heading 1', h2: 'Heading 2', h3: 'Heading 3', + h4: 'Heading 4', h5: 'Heading 5', h6: 'Heading 6' + }, + inline: { bold: 'Bold', italic: 'Italic', deleted: 'Deleted' }, + list: { + 'unordered-list': 'Unordered List', 'ordered-list': 'Ordered List', + indent: 'Indent', outdent: 'Outdent' + }, + link: { + link: 'Link', 'edit-link': 'Edit link', unlink: 'Unlink', + 'link-in-new-tab': 'Open link in new tab', save: 'Save', + insert: 'Insert', cancel: 'Cancel', text: 'Text', url: 'URL' + }, + table: { + width: 'Width', nowrap: 'Nowrap', save: 'Save', cancel: 'Cancel', + 'table-cell': 'Table Cell', 'add-head': 'Add head', + 'remove-head': 'Remove head', 'add-row-below': 'Add row below', + 'add-row-above': 'Add row above', 'remove-row': 'Remove row', + 'add-column-after': 'Add column after', 'add-column-before': 'Add column before', + 'remove-column': 'Remove column' + }, + image: { + or: 'or', 'alt-text': 'Alt Text', save: 'Save', link: 'Link', + width: 'Width', delete: 'Delete', cancel: 'Cancel', insert: 'Insert', + caption: 'Caption', 'link-in-new-tab': 'Open link in new tab', + 'url-placeholder': 'Paste url of image...', + 'upload-new-placeholder': 'Drag to upload a new image
or click to select' + }, + code: { code: 'Code', insert: 'Insert', save: 'Save', cancel: 'Cancel' }, + embed: { + embed: 'Embed', caption: 'Caption', insert: 'Insert', save: 'Save', + cancel: 'Cancel', + description: 'Paste any embed/html code or enter the url (vimeo or youtube video only)', + 'responsive-video': 'Responsive video' + }, + upload: { placeholder: 'Drag to upload
or click to select' }, + templates: { templates: 'Templates' }, + snippets: { snippets: 'Snippets' }, + form: { + link: 'Link', url: 'Url', text: 'Text', name: 'Name', + 'alt-text': 'Alt Text', image: 'Image', upload: 'Upload', + alignment: 'Alignment', outset: 'Outset', valign: 'Valign' + }, + buttons: { + 'mobile-view': 'Mobile View', cancel: 'Cancel', insert: 'Insert', + unlink: 'Unlink', save: 'Save', add: 'Add', + 'transform-to-text': 'Transform to text', align: 'Alignment', valign: 'Valign', + outset: 'Outset', indent: 'Indent', outdent: 'Outdent', head: 'Head', + row: 'Row', cell: 'Cell', html: 'HTML', templates: 'Templates', + shortcuts: 'Keyboard Shortcuts', format: 'Format', bold: 'Bold', italic: 'Italic', + deleted: 'Deleted', underline: 'Underline', table: 'Table', link: 'Link', + undo: 'Undo', redo: 'Redo', style: 'Style', config: 'Config', + settings: 'Settings', text: 'Text', embed: 'Embed', grid: 'Grid', + image: 'Image', list: 'List', delete: 'Delete', duplicate: 'Duplicate', + sort: 'Sort', edit: 'Edit', inline: 'Inline' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'Noneditable', paragraph: 'Paragraph', heading: 'Heading', + image: 'Image', figcaption: 'Figcaption', embed: 'Embed', + line: 'Line', code: 'Code', quote: 'Quote', quoteitem: 'Paragraph', + snippet: 'Snippet', column: 'Column', grid: 'Grid', list: 'List', + table: 'Table', layer: 'Layer', row: 'Row', text: 'Text', cell: 'Cell', + dlist: 'Definition List', address: 'Address', form: 'Form', card: 'Card', + tags: 'Tags', math: 'Math', variable: 'Variable' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Save', cancel: 'Cancel', 'edit-code': 'Edit Code' }, + // buttonlink plugin + buttonlink: { button: 'Button' }, + // carousel plugin + carousel: { carousel: 'Carousel', save: 'Save', cancel: 'Cancel', insert: 'Insert' }, + // clips plugin + clips: { clips: 'Clips' }, + // counter plugin + counter: { words: 'words', chars: 'chars' }, + // filelink plugin + filelink: { + file: 'File', upload: 'Upload', title: 'Title', choose: 'Choose', + placeholder: 'Drag to upload a file
or click to select' + }, + // handle plugin + handle: { handle: 'Handle' }, + // icons plugin + icons: { icons: 'Icons' }, + // imageposition plugin + imageposition: { 'image-position': 'Image position' }, + // imageresize plugin + imageresize: { 'image-resize': 'Image resize' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Inline Format', underline: 'Underline', + superscript: 'Superscript', subscript: 'Subscript', mark: 'Mark', + code: 'Code', shortcut: 'Shortcut', 'remove-format': 'Remove Format' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Make a Button', 'remove-button': 'Remove button', + button: 'Button' + }, + // math plugin + math: { + math: 'Math', label: 'Type an expression', add: 'Add', + save: 'Save', cancel: 'Cancel' + }, + // print plugin + print: { print: 'Print' }, + // removeformat plugin + removeformat: { removeformat: 'Remove Format' }, + // selector plugin + selector: { selector: 'Selector', save: 'Save', cancel: 'Cancel' }, + // slideshow plugin + slideshow: { slideshow: 'Slideshow', save: 'Save', cancel: 'Cancel', insert: 'Insert' }, + // specialchars plugin + specialchars: { 'special-chars': 'Special Characters' }, + // style plugin + style: { style: 'Style', 'remove-style': 'Remove Style' }, + // tags plugin + tags: { + tags: 'Tags', add: 'Add', save: 'Save', cancel: 'Cancel', + label: 'Add comma-separated tags' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'Left to Right', rtl: 'Right to Left' }, + // variable plugin + variable: { variable: 'Variable' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/es.js b/assets/article/langs/es.js new file mode 100644 index 0000000..b3031e0 --- /dev/null +++ b/assets/article/langs/es.js @@ -0,0 +1,175 @@ +/** + * Spanish (es) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in Spanish. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['es'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Editor de texto enriquecido' }, + editor: { title: 'Artículo', multiple: 'Múltiple' }, + placeholders: { + figcaption: 'Escribe un pie de foto (opcional)', + text: 'Escribe algo...', + code: 'Edita para añadir código...', + layer: 'Pulsa Intro para añadir un nuevo texto...' + }, + popup: { + link: 'Enlace', add: 'Añadir', grid: 'Cuadrícula', back: 'Atrás', + image: 'Imagen', snippets: 'Fragmentos', 'add-image': 'Añadir imagen' + }, + shortcuts: { + 'meta-a': 'Seleccionar texto en el bloque', 'meta-shift-a': 'Seleccionar todos los bloques', + 'meta-click': 'Seleccionar varios bloques', 'meta-z': 'Deshacer', 'meta-shift-z': 'Rehacer', + 'meta-shift-m': 'Eliminar formato en línea', 'meta-b': 'Negrita', + 'meta-i': 'Cursiva', 'meta-u': 'Subrayado', 'meta-h': 'Superíndice', + 'meta-l': 'Subíndice', 'meta-k': 'Enlace', 'meta-alt-0': 'Texto normal', + 'meta-alt-1': 'Encabezado 1', 'meta-alt-2': 'Encabezado 2', 'meta-alt-3': 'Encabezado 3', + 'meta-alt-4': 'Encabezado 4', 'meta-alt-5': 'Encabezado 5', 'meta-alt-6': 'Encabezado 6', + 'meta-shift-7': 'Lista ordenada', 'meta-shift-8': 'Lista sin ordenar', + 'meta-indent': 'Aumentar sangría', 'meta-outdent': 'Reducir sangría', + 'meta-shift-backspace': 'Eliminar bloque', 'meta-shift-d': 'Duplicar bloque', + 'meta-shift-up': 'Mover línea arriba', 'meta-shift-down': 'Mover línea abajo' + }, + headings: { + h1: 'Encabezado 1', h2: 'Encabezado 2', h3: 'Encabezado 3', + h4: 'Encabezado 4', h5: 'Encabezado 5', h6: 'Encabezado 6' + }, + inline: { bold: 'Negrita', italic: 'Cursiva', deleted: 'Tachado' }, + list: { + 'unordered-list': 'Lista sin ordenar', 'ordered-list': 'Lista ordenada', + indent: 'Aumentar sangría', outdent: 'Reducir sangría' + }, + link: { + link: 'Enlace', 'edit-link': 'Editar enlace', unlink: 'Quitar enlace', + 'link-in-new-tab': 'Abrir enlace en una pestaña nueva', save: 'Guardar', + insert: 'Insertar', cancel: 'Cancelar', text: 'Texto', url: 'URL' + }, + table: { + width: 'Ancho', nowrap: 'Sin ajuste de línea', save: 'Guardar', cancel: 'Cancelar', + 'table-cell': 'Celda de tabla', 'add-head': 'Añadir encabezado', + 'remove-head': 'Quitar encabezado', 'add-row-below': 'Añadir fila debajo', + 'add-row-above': 'Añadir fila encima', 'remove-row': 'Eliminar fila', + 'add-column-after': 'Añadir columna después', 'add-column-before': 'Añadir columna antes', + 'remove-column': 'Eliminar columna' + }, + image: { + or: 'o', 'alt-text': 'Texto alternativo', save: 'Guardar', link: 'Enlace', + width: 'Ancho', delete: 'Eliminar', cancel: 'Cancelar', insert: 'Insertar', + caption: 'Pie de foto', 'link-in-new-tab': 'Abrir enlace en una pestaña nueva', + 'url-placeholder': 'Pega la URL de la imagen...', + 'upload-new-placeholder': 'Arrastra para subir una nueva imagen
o haz clic para seleccionar' + }, + code: { code: 'Código', insert: 'Insertar', save: 'Guardar', cancel: 'Cancelar' }, + embed: { + embed: 'Insertar contenido', caption: 'Pie de foto', insert: 'Insertar', save: 'Guardar', + cancel: 'Cancelar', + description: 'Pega cualquier código embebido/HTML o introduce la URL (solo video de Vimeo o YouTube)', + 'responsive-video': 'Video adaptable' + }, + upload: { placeholder: 'Arrastra para subir
o haz clic para seleccionar' }, + templates: { templates: 'Plantillas' }, + snippets: { snippets: 'Fragmentos' }, + form: { + link: 'Enlace', url: 'URL', text: 'Texto', name: 'Nombre', + 'alt-text': 'Texto alternativo', image: 'Imagen', upload: 'Subir', + alignment: 'Alineación', outset: 'Desplazamiento exterior', valign: 'Alineación vertical' + }, + buttons: { + 'mobile-view': 'Vista móvil', cancel: 'Cancelar', insert: 'Insertar', + unlink: 'Quitar enlace', save: 'Guardar', add: 'Añadir', + 'transform-to-text': 'Transformar en texto', align: 'Alineación', valign: 'Alineación vertical', + outset: 'Desplazamiento exterior', indent: 'Aumentar sangría', outdent: 'Reducir sangría', head: 'Encabezado', + row: 'Fila', cell: 'Celda', html: 'HTML', templates: 'Plantillas', + shortcuts: 'Atajos de teclado', format: 'Formato', bold: 'Negrita', italic: 'Cursiva', + deleted: 'Tachado', underline: 'Subrayado', table: 'Tabla', link: 'Enlace', + undo: 'Deshacer', redo: 'Rehacer', style: 'Estilo', config: 'Configuración', + settings: 'Ajustes', text: 'Texto', embed: 'Insertar contenido', grid: 'Cuadrícula', + image: 'Imagen', list: 'Lista', delete: 'Eliminar', duplicate: 'Duplicar', + sort: 'Ordenar', edit: 'Editar', inline: 'En línea' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'No editable', paragraph: 'Párrafo', heading: 'Encabezado', + image: 'Imagen', figcaption: 'Pie de imagen', embed: 'Contenido embebido', + line: 'Línea', code: 'Código', quote: 'Cita', quoteitem: 'Párrafo', + snippet: 'Fragmento', column: 'Columna', grid: 'Cuadrícula', list: 'Lista', + table: 'Tabla', layer: 'Capa', row: 'Fila', text: 'Texto', cell: 'Celda', + dlist: 'Lista de definiciones', address: 'Dirección', form: 'Formulario', card: 'Tarjeta', + tags: 'Etiquetas', math: 'Matemáticas', variable: 'Variable' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Guardar', cancel: 'Cancelar', 'edit-code': 'Editar código' }, + // buttonlink plugin + buttonlink: { button: 'Botón' }, + // carousel plugin + carousel: { carousel: 'Carrusel', save: 'Guardar', cancel: 'Cancelar', insert: 'Insertar' }, + // clips plugin + clips: { clips: 'Clips' }, + // counter plugin + counter: { words: 'palabras', chars: 'caracteres' }, + // filelink plugin + filelink: { + file: 'Archivo', upload: 'Subir', title: 'Título', choose: 'Elegir', + placeholder: 'Arrastra para subir un archivo
o haz clic para seleccionar' + }, + // handle plugin + handle: { handle: 'Asa' }, + // icons plugin + icons: { icons: 'Iconos' }, + // imageposition plugin + imageposition: { 'image-position': 'Posición de la imagen' }, + // imageresize plugin + imageresize: { 'image-resize': 'Cambiar tamaño de imagen' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Formato en línea', underline: 'Subrayado', + superscript: 'Superíndice', subscript: 'Subíndice', mark: 'Resaltado', + code: 'Código', shortcut: 'Atajo', 'remove-format': 'Eliminar formato' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Crear un botón', 'remove-button': 'Eliminar botón', + button: 'Botón' + }, + // math plugin + math: { + math: 'Matemáticas', label: 'Escribe una expresión', add: 'Añadir', + save: 'Guardar', cancel: 'Cancelar' + }, + // print plugin + print: { print: 'Imprimir' }, + // removeformat plugin + removeformat: { removeformat: 'Eliminar formato' }, + // selector plugin + selector: { selector: 'Selector', save: 'Guardar', cancel: 'Cancelar' }, + // slideshow plugin + slideshow: { slideshow: 'Presentación', save: 'Guardar', cancel: 'Cancelar', insert: 'Insertar' }, + // specialchars plugin + specialchars: { 'special-chars': 'Caracteres especiales' }, + // style plugin + style: { style: 'Estilo', 'remove-style': 'Eliminar estilo' }, + // tags plugin + tags: { + tags: 'Etiquetas', add: 'Añadir', save: 'Guardar', cancel: 'Cancelar', + label: 'Añade etiquetas separadas por comas' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'De izquierda a derecha', rtl: 'De derecha a izquierda' }, + // variable plugin + variable: { variable: 'Variable' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/fr.js b/assets/article/langs/fr.js new file mode 100644 index 0000000..e654ecc --- /dev/null +++ b/assets/article/langs/fr.js @@ -0,0 +1,175 @@ +/** + * French (fr) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in French. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['fr'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Éditeur de texte enrichi' }, + editor: { title: 'Article', multiple: 'Multiple' }, + placeholders: { + figcaption: 'Saisir une légende (facultatif)', + text: 'Saisissez quelque chose...', + code: 'Modifiez pour ajouter du code...', + layer: 'Appuyez sur Entrée pour ajouter un nouveau texte...' + }, + popup: { + link: 'Lien', add: 'Ajouter', grid: 'Grille', back: 'Retour', + image: 'Image', snippets: 'Extraits', 'add-image': 'Ajouter une image' + }, + shortcuts: { + 'meta-a': 'Sélectionner le texte dans le bloc', 'meta-shift-a': 'Sélectionner tous les blocs', + 'meta-click': 'Sélectionner plusieurs blocs', 'meta-z': 'Annuler', 'meta-shift-z': 'Rétablir', + 'meta-shift-m': 'Supprimer la mise en forme en ligne', 'meta-b': 'Gras', + 'meta-i': 'Italique', 'meta-u': 'Souligné', 'meta-h': 'Exposant', + 'meta-l': 'Indice', 'meta-k': 'Lien', 'meta-alt-0': 'Texte normal', + 'meta-alt-1': 'Titre 1', 'meta-alt-2': 'Titre 2', 'meta-alt-3': 'Titre 3', + 'meta-alt-4': 'Titre 4', 'meta-alt-5': 'Titre 5', 'meta-alt-6': 'Titre 6', + 'meta-shift-7': 'Liste ordonnée', 'meta-shift-8': 'Liste non ordonnée', + 'meta-indent': 'Augmenter le retrait', 'meta-outdent': 'Diminuer le retrait', + 'meta-shift-backspace': 'Supprimer le bloc', 'meta-shift-d': 'Dupliquer le bloc', + 'meta-shift-up': 'Déplacer la ligne vers le haut', 'meta-shift-down': 'Déplacer la ligne vers le bas' + }, + headings: { + h1: 'Titre 1', h2: 'Titre 2', h3: 'Titre 3', + h4: 'Titre 4', h5: 'Titre 5', h6: 'Titre 6' + }, + inline: { bold: 'Gras', italic: 'Italique', deleted: 'Barré' }, + list: { + 'unordered-list': 'Liste non ordonnée', 'ordered-list': 'Liste ordonnée', + indent: 'Augmenter le retrait', outdent: 'Diminuer le retrait' + }, + link: { + link: 'Lien', 'edit-link': 'Modifier le lien', unlink: 'Supprimer le lien', + 'link-in-new-tab': 'Ouvrir le lien dans un nouvel onglet', save: 'Enregistrer', + insert: 'Insérer', cancel: 'Annuler', text: 'Texte', url: 'URL' + }, + table: { + width: 'Largeur', nowrap: 'Sans retour à la ligne', save: 'Enregistrer', cancel: 'Annuler', + 'table-cell': 'Cellule de tableau', 'add-head': 'Ajouter un en-tête', + 'remove-head': 'Supprimer l’en-tête', 'add-row-below': 'Ajouter une ligne dessous', + 'add-row-above': 'Ajouter une ligne dessus', 'remove-row': 'Supprimer la ligne', + 'add-column-after': 'Ajouter une colonne après', 'add-column-before': 'Ajouter une colonne avant', + 'remove-column': 'Supprimer la colonne' + }, + image: { + or: 'ou', 'alt-text': 'Texte alternatif', save: 'Enregistrer', link: 'Lien', + width: 'Largeur', delete: 'Supprimer', cancel: 'Annuler', insert: 'Insérer', + caption: 'Légende', 'link-in-new-tab': 'Ouvrir le lien dans un nouvel onglet', + 'url-placeholder': 'Coller l’URL de l’image...', + 'upload-new-placeholder': 'Glissez pour téléverser une nouvelle image
ou cliquez pour sélectionner' + }, + code: { code: 'Code', insert: 'Insérer', save: 'Enregistrer', cancel: 'Annuler' }, + embed: { + embed: 'Intégration', caption: 'Légende', insert: 'Insérer', save: 'Enregistrer', + cancel: 'Annuler', + description: 'Collez un code d’intégration/HTML ou saisissez l’URL (vidéo Vimeo ou YouTube uniquement)', + 'responsive-video': 'Vidéo responsive' + }, + upload: { placeholder: 'Glissez pour téléverser
ou cliquez pour sélectionner' }, + templates: { templates: 'Modèles' }, + snippets: { snippets: 'Extraits' }, + form: { + link: 'Lien', url: 'URL', text: 'Texte', name: 'Nom', + 'alt-text': 'Texte alternatif', image: 'Image', upload: 'Téléverser', + alignment: 'Alignement', outset: 'Débord', valign: 'Alignement vertical' + }, + buttons: { + 'mobile-view': 'Vue mobile', cancel: 'Annuler', insert: 'Insérer', + unlink: 'Supprimer le lien', save: 'Enregistrer', add: 'Ajouter', + 'transform-to-text': 'Transformer en texte', align: 'Alignement', valign: 'Alignement vertical', + outset: 'Débord', indent: 'Augmenter le retrait', outdent: 'Diminuer le retrait', head: 'En-tête', + row: 'Ligne', cell: 'Cellule', html: 'HTML', templates: 'Modèles', + shortcuts: 'Raccourcis clavier', format: 'Format', bold: 'Gras', italic: 'Italique', + deleted: 'Barré', underline: 'Souligné', table: 'Tableau', link: 'Lien', + undo: 'Annuler', redo: 'Rétablir', style: 'Style', config: 'Configuration', + settings: 'Paramètres', text: 'Texte', embed: 'Intégration', grid: 'Grille', + image: 'Image', list: 'Liste', delete: 'Supprimer', duplicate: 'Dupliquer', + sort: 'Trier', edit: 'Modifier', inline: 'En ligne' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'Non modifiable', paragraph: 'Paragraphe', heading: 'Titre', + image: 'Image', figcaption: 'Légende d’image', embed: 'Intégration', + line: 'Ligne', code: 'Code', quote: 'Citation', quoteitem: 'Paragraphe', + snippet: 'Extrait', column: 'Colonne', grid: 'Grille', list: 'Liste', + table: 'Tableau', layer: 'Calque', row: 'Ligne', text: 'Texte', cell: 'Cellule', + dlist: 'Liste de définitions', address: 'Adresse', form: 'Formulaire', card: 'Carte', + tags: 'Étiquettes', math: 'Mathématiques', variable: 'Variable' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Enregistrer', cancel: 'Annuler', 'edit-code': 'Modifier le code' }, + // buttonlink plugin + buttonlink: { button: 'Bouton' }, + // carousel plugin + carousel: { carousel: 'Carrousel', save: 'Enregistrer', cancel: 'Annuler', insert: 'Insérer' }, + // clips plugin + clips: { clips: 'Clips' }, + // counter plugin + counter: { words: 'mots', chars: 'caractères' }, + // filelink plugin + filelink: { + file: 'Fichier', upload: 'Téléverser', title: 'Titre', choose: 'Choisir', + placeholder: 'Glissez pour téléverser un fichier
ou cliquez pour sélectionner' + }, + // handle plugin + handle: { handle: 'Poignée' }, + // icons plugin + icons: { icons: 'Icônes' }, + // imageposition plugin + imageposition: { 'image-position': 'Position de l’image' }, + // imageresize plugin + imageresize: { 'image-resize': 'Redimensionnement de l’image' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Format en ligne', underline: 'Souligné', + superscript: 'Exposant', subscript: 'Indice', mark: 'Surlignage', + code: 'Code', shortcut: 'Raccourci', 'remove-format': 'Supprimer la mise en forme' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Créer un bouton', 'remove-button': 'Supprimer le bouton', + button: 'Bouton' + }, + // math plugin + math: { + math: 'Mathématiques', label: 'Saisir une expression', add: 'Ajouter', + save: 'Enregistrer', cancel: 'Annuler' + }, + // print plugin + print: { print: 'Imprimer' }, + // removeformat plugin + removeformat: { removeformat: 'Supprimer la mise en forme' }, + // selector plugin + selector: { selector: 'Sélecteur', save: 'Enregistrer', cancel: 'Annuler' }, + // slideshow plugin + slideshow: { slideshow: 'Diaporama', save: 'Enregistrer', cancel: 'Annuler', insert: 'Insérer' }, + // specialchars plugin + specialchars: { 'special-chars': 'Caractères spéciaux' }, + // style plugin + style: { style: 'Style', 'remove-style': 'Supprimer le style' }, + // tags plugin + tags: { + tags: 'Étiquettes', add: 'Ajouter', save: 'Enregistrer', cancel: 'Annuler', + label: 'Ajouter des étiquettes séparées par des virgules' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'De gauche à droite', rtl: 'De droite à gauche' }, + // variable plugin + variable: { variable: 'Variable' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/hr.js b/assets/article/langs/hr.js new file mode 100644 index 0000000..bc2250e --- /dev/null +++ b/assets/article/langs/hr.js @@ -0,0 +1,175 @@ +/** + * Croatian (hr) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in Croatian. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['hr'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Uređivač obogaćenog teksta' }, + editor: { title: 'Članak', multiple: 'Višestruko' }, + placeholders: { + figcaption: 'Unesite opis (neobavezno)', + text: 'Upišite nešto...', + code: 'Uredite za dodavanje koda...', + layer: 'Pritisnite Enter za dodavanje novog teksta...' + }, + popup: { + link: 'Poveznica', add: 'Dodaj', grid: 'Mreža', back: 'Natrag', + image: 'Slika', snippets: 'Isječci', 'add-image': 'Dodaj sliku' + }, + shortcuts: { + 'meta-a': 'Odaberi tekst u bloku', 'meta-shift-a': 'Odaberi sve blokove', + 'meta-click': 'Odaberi više blokova', 'meta-z': 'Poništi', 'meta-shift-z': 'Ponovi', + 'meta-shift-m': 'Ukloni umetnuto oblikovanje', 'meta-b': 'Podebljano', + 'meta-i': 'Kurziv', 'meta-u': 'Podcrtano', 'meta-h': 'Eksponent', + 'meta-l': 'Indeks', 'meta-k': 'Poveznica', 'meta-alt-0': 'Normalan tekst', + 'meta-alt-1': 'Naslov 1', 'meta-alt-2': 'Naslov 2', 'meta-alt-3': 'Naslov 3', + 'meta-alt-4': 'Naslov 4', 'meta-alt-5': 'Naslov 5', 'meta-alt-6': 'Naslov 6', + 'meta-shift-7': 'Numerirani popis', 'meta-shift-8': 'Popis s oznakama', + 'meta-indent': 'Uvuci', 'meta-outdent': 'Smanji uvlačenje', + 'meta-shift-backspace': 'Izbriši blok', 'meta-shift-d': 'Dupliciraj blok', + 'meta-shift-up': 'Pomakni redak gore', 'meta-shift-down': 'Pomakni redak dolje' + }, + headings: { + h1: 'Naslov 1', h2: 'Naslov 2', h3: 'Naslov 3', + h4: 'Naslov 4', h5: 'Naslov 5', h6: 'Naslov 6' + }, + inline: { bold: 'Podebljano', italic: 'Kurziv', deleted: 'Precrtano' }, + list: { + 'unordered-list': 'Popis s oznakama', 'ordered-list': 'Numerirani popis', + indent: 'Uvuci', outdent: 'Smanji uvlačenje' + }, + link: { + link: 'Poveznica', 'edit-link': 'Uredi poveznicu', unlink: 'Ukloni poveznicu', + 'link-in-new-tab': 'Otvori poveznicu u novoj kartici', save: 'Spremi', + insert: 'Umetni', cancel: 'Odustani', text: 'Tekst', url: 'URL' + }, + table: { + width: 'Širina', nowrap: 'Bez prijeloma', save: 'Spremi', cancel: 'Odustani', + 'table-cell': 'Ćelija tablice', 'add-head': 'Dodaj zaglavlje', + 'remove-head': 'Ukloni zaglavlje', 'add-row-below': 'Dodaj redak ispod', + 'add-row-above': 'Dodaj redak iznad', 'remove-row': 'Ukloni redak', + 'add-column-after': 'Dodaj stupac poslije', 'add-column-before': 'Dodaj stupac prije', + 'remove-column': 'Ukloni stupac' + }, + image: { + or: 'ili', 'alt-text': 'Alternativni tekst', save: 'Spremi', link: 'Poveznica', + width: 'Širina', delete: 'Izbriši', cancel: 'Odustani', insert: 'Umetni', + caption: 'Opis', 'link-in-new-tab': 'Otvori poveznicu u novoj kartici', + 'url-placeholder': 'Zalijepite URL slike...', + 'upload-new-placeholder': 'Povucite za prijenos nove slike
ili kliknite za odabir' + }, + code: { code: 'Kod', insert: 'Umetni', save: 'Spremi', cancel: 'Odustani' }, + embed: { + embed: 'Ugradi', caption: 'Opis', insert: 'Umetni', save: 'Spremi', + cancel: 'Odustani', + description: 'Zalijepite bilo koji embed/HTML kod ili unesite URL (samo Vimeo ili YouTube video)', + 'responsive-video': 'Responzivni video' + }, + upload: { placeholder: 'Povucite za prijenos
ili kliknite za odabir' }, + templates: { templates: 'Predlošci' }, + snippets: { snippets: 'Isječci' }, + form: { + link: 'Poveznica', url: 'URL', text: 'Tekst', name: 'Naziv', + 'alt-text': 'Alternativni tekst', image: 'Slika', upload: 'Prenesi', + alignment: 'Poravnanje', outset: 'Izmak', valign: 'Okomito poravnanje' + }, + buttons: { + 'mobile-view': 'Mobilni prikaz', cancel: 'Odustani', insert: 'Umetni', + unlink: 'Ukloni poveznicu', save: 'Spremi', add: 'Dodaj', + 'transform-to-text': 'Pretvori u tekst', align: 'Poravnanje', valign: 'Okomito poravnanje', + outset: 'Izmak', indent: 'Uvuci', outdent: 'Smanji uvlačenje', head: 'Zaglavlje', + row: 'Redak', cell: 'Ćelija', html: 'HTML', templates: 'Predlošci', + shortcuts: 'Tipkovnički prečaci', format: 'Format', bold: 'Podebljano', italic: 'Kurziv', + deleted: 'Precrtano', underline: 'Podcrtano', table: 'Tablica', link: 'Poveznica', + undo: 'Poništi', redo: 'Ponovi', style: 'Stil', config: 'Konfiguracija', + settings: 'Postavke', text: 'Tekst', embed: 'Ugradi', grid: 'Mreža', + image: 'Slika', list: 'Popis', delete: 'Izbriši', duplicate: 'Dupliciraj', + sort: 'Sortiraj', edit: 'Uredi', inline: 'Umetnuto' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'Neuredivo', paragraph: 'Odlomak', heading: 'Naslov', + image: 'Slika', figcaption: 'Opis slike', embed: 'Ugrađeni sadržaj', + line: 'Linija', code: 'Kod', quote: 'Citat', quoteitem: 'Odlomak', + snippet: 'Isječak', column: 'Stupac', grid: 'Mreža', list: 'Popis', + table: 'Tablica', layer: 'Sloj', row: 'Redak', text: 'Tekst', cell: 'Ćelija', + dlist: 'Definicijski popis', address: 'Adresa', form: 'Obrazac', card: 'Kartica', + tags: 'Oznake', math: 'Matematika', variable: 'Varijabla' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Spremi', cancel: 'Odustani', 'edit-code': 'Uredi kod' }, + // buttonlink plugin + buttonlink: { button: 'Gumb' }, + // carousel plugin + carousel: { carousel: 'Karusel', save: 'Spremi', cancel: 'Odustani', insert: 'Umetni' }, + // clips plugin + clips: { clips: 'Isječci' }, + // counter plugin + counter: { words: 'riječi', chars: 'znakova' }, + // filelink plugin + filelink: { + file: 'Datoteka', upload: 'Prenesi', title: 'Naslov', choose: 'Odaberi', + placeholder: 'Povucite za prijenos datoteke
ili kliknite za odabir' + }, + // handle plugin + handle: { handle: 'Ručka' }, + // icons plugin + icons: { icons: 'Ikone' }, + // imageposition plugin + imageposition: { 'image-position': 'Položaj slike' }, + // imageresize plugin + imageresize: { 'image-resize': 'Promjena veličine slike' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Umetnuto oblikovanje', underline: 'Podcrtano', + superscript: 'Eksponent', subscript: 'Indeks', mark: 'Istaknuto', + code: 'Kod', shortcut: 'Prečac', 'remove-format': 'Ukloni oblikovanje' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Stvori gumb', 'remove-button': 'Ukloni gumb', + button: 'Gumb' + }, + // math plugin + math: { + math: 'Matematika', label: 'Unesite izraz', add: 'Dodaj', + save: 'Spremi', cancel: 'Odustani' + }, + // print plugin + print: { print: 'Ispis' }, + // removeformat plugin + removeformat: { removeformat: 'Ukloni oblikovanje' }, + // selector plugin + selector: { selector: 'Selektor', save: 'Spremi', cancel: 'Odustani' }, + // slideshow plugin + slideshow: { slideshow: 'Dijaprojekcija', save: 'Spremi', cancel: 'Odustani', insert: 'Umetni' }, + // specialchars plugin + specialchars: { 'special-chars': 'Posebni znakovi' }, + // style plugin + style: { style: 'Stil', 'remove-style': 'Ukloni stil' }, + // tags plugin + tags: { + tags: 'Oznake', add: 'Dodaj', save: 'Spremi', cancel: 'Odustani', + label: 'Dodajte oznake odvojene zarezima' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'Slijeva nadesno', rtl: 'Zdesna nalijevo' }, + // variable plugin + variable: { variable: 'Varijabla' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/it.js b/assets/article/langs/it.js new file mode 100644 index 0000000..9da3eb0 --- /dev/null +++ b/assets/article/langs/it.js @@ -0,0 +1,175 @@ +/** + * Italian (it) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in Italian. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['it'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Editor di testo avanzato' }, + editor: { title: 'Articolo', multiple: 'Multiplo' }, + placeholders: { + figcaption: 'Inserisci didascalia (opzionale)', + text: 'Scrivi qualcosa...', + code: 'Modifica per aggiungere codice...', + layer: 'Premi Invio per aggiungere un nuovo testo...' + }, + popup: { + link: 'Link', add: 'Aggiungi', grid: 'Griglia', back: 'Indietro', + image: 'Immagine', snippets: 'Frammenti', 'add-image': 'Aggiungi immagine' + }, + shortcuts: { + 'meta-a': 'Seleziona il testo nel blocco', 'meta-shift-a': 'Seleziona tutti i blocchi', + 'meta-click': 'Seleziona più blocchi', 'meta-z': 'Annulla', 'meta-shift-z': 'Ripeti', + 'meta-shift-m': 'Rimuovi formato in linea', 'meta-b': 'Grassetto', + 'meta-i': 'Corsivo', 'meta-u': 'Sottolineato', 'meta-h': 'Apice', + 'meta-l': 'Pedice', 'meta-k': 'Link', 'meta-alt-0': 'Testo normale', + 'meta-alt-1': 'Titolo 1', 'meta-alt-2': 'Titolo 2', 'meta-alt-3': 'Titolo 3', + 'meta-alt-4': 'Titolo 4', 'meta-alt-5': 'Titolo 5', 'meta-alt-6': 'Titolo 6', + 'meta-shift-7': 'Elenco ordinato', 'meta-shift-8': 'Elenco non ordinato', + 'meta-indent': 'Aumenta rientro', 'meta-outdent': 'Riduci rientro', + 'meta-shift-backspace': 'Elimina blocco', 'meta-shift-d': 'Duplica blocco', + 'meta-shift-up': 'Sposta riga in alto', 'meta-shift-down': 'Sposta riga in basso' + }, + headings: { + h1: 'Titolo 1', h2: 'Titolo 2', h3: 'Titolo 3', + h4: 'Titolo 4', h5: 'Titolo 5', h6: 'Titolo 6' + }, + inline: { bold: 'Grassetto', italic: 'Corsivo', deleted: 'Barrato' }, + list: { + 'unordered-list': 'Elenco non ordinato', 'ordered-list': 'Elenco ordinato', + indent: 'Aumenta rientro', outdent: 'Riduci rientro' + }, + link: { + link: 'Link', 'edit-link': 'Modifica link', unlink: 'Rimuovi link', + 'link-in-new-tab': 'Apri link in una nuova scheda', save: 'Salva', + insert: 'Inserisci', cancel: 'Annulla', text: 'Testo', url: 'URL' + }, + table: { + width: 'Larghezza', nowrap: 'Non andare a capo', save: 'Salva', cancel: 'Annulla', + 'table-cell': 'Cella tabella', 'add-head': 'Aggiungi intestazione', + 'remove-head': 'Rimuovi intestazione', 'add-row-below': 'Aggiungi riga sotto', + 'add-row-above': 'Aggiungi riga sopra', 'remove-row': 'Rimuovi riga', + 'add-column-after': 'Aggiungi colonna dopo', 'add-column-before': 'Aggiungi colonna prima', + 'remove-column': 'Rimuovi colonna' + }, + image: { + or: 'o', 'alt-text': 'Testo alternativo', save: 'Salva', link: 'Link', + width: 'Larghezza', delete: 'Elimina', cancel: 'Annulla', insert: 'Inserisci', + caption: 'Didascalia', 'link-in-new-tab': 'Apri link in una nuova scheda', + 'url-placeholder': 'Incolla URL dell’immagine...', + 'upload-new-placeholder': 'Trascina per caricare una nuova immagine
o fai clic per selezionare' + }, + code: { code: 'Codice', insert: 'Inserisci', save: 'Salva', cancel: 'Annulla' }, + embed: { + embed: 'Incorpora', caption: 'Didascalia', insert: 'Inserisci', save: 'Salva', + cancel: 'Annulla', + description: 'Incolla qualsiasi codice embed/HTML o inserisci l’URL (solo video Vimeo o YouTube)', + 'responsive-video': 'Video responsive' + }, + upload: { placeholder: 'Trascina per caricare
o fai clic per selezionare' }, + templates: { templates: 'Template' }, + snippets: { snippets: 'Frammenti' }, + form: { + link: 'Link', url: 'URL', text: 'Testo', name: 'Nome', + 'alt-text': 'Testo alternativo', image: 'Immagine', upload: 'Carica', + alignment: 'Allineamento', outset: 'Sporgenza', valign: 'Allineamento verticale' + }, + buttons: { + 'mobile-view': 'Vista mobile', cancel: 'Annulla', insert: 'Inserisci', + unlink: 'Rimuovi link', save: 'Salva', add: 'Aggiungi', + 'transform-to-text': 'Trasforma in testo', align: 'Allineamento', valign: 'Allineamento verticale', + outset: 'Sporgenza', indent: 'Aumenta rientro', outdent: 'Riduci rientro', head: 'Intestazione', + row: 'Riga', cell: 'Cella', html: 'HTML', templates: 'Template', + shortcuts: 'Scorciatoie da tastiera', format: 'Formato', bold: 'Grassetto', italic: 'Corsivo', + deleted: 'Barrato', underline: 'Sottolineato', table: 'Tabella', link: 'Link', + undo: 'Annulla', redo: 'Ripeti', style: 'Stile', config: 'Configurazione', + settings: 'Impostazioni', text: 'Testo', embed: 'Incorpora', grid: 'Griglia', + image: 'Immagine', list: 'Elenco', delete: 'Elimina', duplicate: 'Duplica', + sort: 'Ordina', edit: 'Modifica', inline: 'In linea' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'Non modificabile', paragraph: 'Paragrafo', heading: 'Titolo', + image: 'Immagine', figcaption: 'Didascalia immagine', embed: 'Incorporamento', + line: 'Linea', code: 'Codice', quote: 'Citazione', quoteitem: 'Paragrafo', + snippet: 'Frammento', column: 'Colonna', grid: 'Griglia', list: 'Elenco', + table: 'Tabella', layer: 'Livello', row: 'Riga', text: 'Testo', cell: 'Cella', + dlist: 'Elenco di definizioni', address: 'Indirizzo', form: 'Modulo', card: 'Scheda', + tags: 'Tag', math: 'Matematica', variable: 'Variabile' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Salva', cancel: 'Annulla', 'edit-code': 'Modifica codice' }, + // buttonlink plugin + buttonlink: { button: 'Pulsante' }, + // carousel plugin + carousel: { carousel: 'Carosello', save: 'Salva', cancel: 'Annulla', insert: 'Inserisci' }, + // clips plugin + clips: { clips: 'Clip' }, + // counter plugin + counter: { words: 'parole', chars: 'caratteri' }, + // filelink plugin + filelink: { + file: 'File', upload: 'Carica', title: 'Titolo', choose: 'Scegli', + placeholder: 'Trascina per caricare un file
o fai clic per selezionare' + }, + // handle plugin + handle: { handle: 'Maniglia' }, + // icons plugin + icons: { icons: 'Icone' }, + // imageposition plugin + imageposition: { 'image-position': 'Posizione immagine' }, + // imageresize plugin + imageresize: { 'image-resize': 'Ridimensiona immagine' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Formato in linea', underline: 'Sottolineato', + superscript: 'Apice', subscript: 'Pedice', mark: 'Evidenziato', + code: 'Codice', shortcut: 'Scorciatoia', 'remove-format': 'Rimuovi formato' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Crea un pulsante', 'remove-button': 'Rimuovi pulsante', + button: 'Pulsante' + }, + // math plugin + math: { + math: 'Matematica', label: 'Digita un’espressione', add: 'Aggiungi', + save: 'Salva', cancel: 'Annulla' + }, + // print plugin + print: { print: 'Stampa' }, + // removeformat plugin + removeformat: { removeformat: 'Rimuovi formato' }, + // selector plugin + selector: { selector: 'Selettore', save: 'Salva', cancel: 'Annulla' }, + // slideshow plugin + slideshow: { slideshow: 'Presentazione', save: 'Salva', cancel: 'Annulla', insert: 'Inserisci' }, + // specialchars plugin + specialchars: { 'special-chars': 'Caratteri speciali' }, + // style plugin + style: { style: 'Stile', 'remove-style': 'Rimuovi stile' }, + // tags plugin + tags: { + tags: 'Tag', add: 'Aggiungi', save: 'Salva', cancel: 'Annulla', + label: 'Aggiungi tag separati da virgole' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'Da sinistra a destra', rtl: 'Da destra a sinistra' }, + // variable plugin + variable: { variable: 'Variabile' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/nl.js b/assets/article/langs/nl.js new file mode 100644 index 0000000..49df2d3 --- /dev/null +++ b/assets/article/langs/nl.js @@ -0,0 +1,175 @@ +/** + * Dutch (nl) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in Dutch. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['nl'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Rich text-editor' }, + editor: { title: 'Artikel', multiple: 'Meerdere' }, + placeholders: { + figcaption: 'Voer bijschrift in (optioneel)', + text: 'Typ iets...', + code: 'Bewerk om code toe te voegen...', + layer: 'Druk op Enter om nieuwe tekst toe te voegen...' + }, + popup: { + link: 'Link', add: 'Toevoegen', grid: 'Raster', back: 'Terug', + image: 'Afbeelding', snippets: 'Fragmenten', 'add-image': 'Afbeelding toevoegen' + }, + shortcuts: { + 'meta-a': 'Tekst in het blok selecteren', 'meta-shift-a': 'Alle blokken selecteren', + 'meta-click': 'Meerdere blokken selecteren', 'meta-z': 'Ongedaan maken', 'meta-shift-z': 'Opnieuw', + 'meta-shift-m': 'Inline-opmaak verwijderen', 'meta-b': 'Vet', + 'meta-i': 'Cursief', 'meta-u': 'Onderstrepen', 'meta-h': 'Bovenindex', + 'meta-l': 'Onderindex', 'meta-k': 'Link', 'meta-alt-0': 'Normale tekst', + 'meta-alt-1': 'Kop 1', 'meta-alt-2': 'Kop 2', 'meta-alt-3': 'Kop 3', + 'meta-alt-4': 'Kop 4', 'meta-alt-5': 'Kop 5', 'meta-alt-6': 'Kop 6', + 'meta-shift-7': 'Genummerde lijst', 'meta-shift-8': 'Ongenummerde lijst', + 'meta-indent': 'Inspringen', 'meta-outdent': 'Inspringing verkleinen', + 'meta-shift-backspace': 'Blok verwijderen', 'meta-shift-d': 'Blok dupliceren', + 'meta-shift-up': 'Regel omhoog verplaatsen', 'meta-shift-down': 'Regel omlaag verplaatsen' + }, + headings: { + h1: 'Kop 1', h2: 'Kop 2', h3: 'Kop 3', + h4: 'Kop 4', h5: 'Kop 5', h6: 'Kop 6' + }, + inline: { bold: 'Vet', italic: 'Cursief', deleted: 'Doorgehaald' }, + list: { + 'unordered-list': 'Ongenummerde lijst', 'ordered-list': 'Genummerde lijst', + indent: 'Inspringen', outdent: 'Inspringing verkleinen' + }, + link: { + link: 'Link', 'edit-link': 'Link bewerken', unlink: 'Link verwijderen', + 'link-in-new-tab': 'Link openen in nieuw tabblad', save: 'Opslaan', + insert: 'Invoegen', cancel: 'Annuleren', text: 'Tekst', url: 'URL' + }, + table: { + width: 'Breedte', nowrap: 'Niet afbreken', save: 'Opslaan', cancel: 'Annuleren', + 'table-cell': 'Tabelcel', 'add-head': 'Kop toevoegen', + 'remove-head': 'Kop verwijderen', 'add-row-below': 'Rij onder toevoegen', + 'add-row-above': 'Rij boven toevoegen', 'remove-row': 'Rij verwijderen', + 'add-column-after': 'Kolom rechts toevoegen', 'add-column-before': 'Kolom links toevoegen', + 'remove-column': 'Kolom verwijderen' + }, + image: { + or: 'of', 'alt-text': 'Alternatieve tekst', save: 'Opslaan', link: 'Link', + width: 'Breedte', delete: 'Verwijderen', cancel: 'Annuleren', insert: 'Invoegen', + caption: 'Bijschrift', 'link-in-new-tab': 'Link openen in nieuw tabblad', + 'url-placeholder': 'Plak URL van afbeelding...', + 'upload-new-placeholder': 'Sleep om een nieuwe afbeelding te uploaden
of klik om te selecteren' + }, + code: { code: 'Code', insert: 'Invoegen', save: 'Opslaan', cancel: 'Annuleren' }, + embed: { + embed: 'Insluiten', caption: 'Bijschrift', insert: 'Invoegen', save: 'Opslaan', + cancel: 'Annuleren', + description: 'Plak embed-/HTML-code of voer de URL in (alleen Vimeo- of YouTube-video)', + 'responsive-video': 'Responsieve video' + }, + upload: { placeholder: 'Sleep om te uploaden
of klik om te selecteren' }, + templates: { templates: 'Sjablonen' }, + snippets: { snippets: 'Fragmenten' }, + form: { + link: 'Link', url: 'URL', text: 'Tekst', name: 'Naam', + 'alt-text': 'Alternatieve tekst', image: 'Afbeelding', upload: 'Uploaden', + alignment: 'Uitlijning', outset: 'Uitstekend', valign: 'Verticale uitlijning' + }, + buttons: { + 'mobile-view': 'Mobiele weergave', cancel: 'Annuleren', insert: 'Invoegen', + unlink: 'Link verwijderen', save: 'Opslaan', add: 'Toevoegen', + 'transform-to-text': 'Omzetten naar tekst', align: 'Uitlijning', valign: 'Verticale uitlijning', + outset: 'Uitstekend', indent: 'Inspringen', outdent: 'Inspringing verkleinen', head: 'Kop', + row: 'Rij', cell: 'Cel', html: 'HTML', templates: 'Sjablonen', + shortcuts: 'Sneltoetsen', format: 'Opmaak', bold: 'Vet', italic: 'Cursief', + deleted: 'Doorgehaald', underline: 'Onderstrepen', table: 'Tabel', link: 'Link', + undo: 'Ongedaan maken', redo: 'Opnieuw', style: 'Stijl', config: 'Configuratie', + settings: 'Instellingen', text: 'Tekst', embed: 'Insluiten', grid: 'Raster', + image: 'Afbeelding', list: 'Lijst', delete: 'Verwijderen', duplicate: 'Dupliceren', + sort: 'Sorteren', edit: 'Bewerken', inline: 'Inline' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'Niet bewerkbaar', paragraph: 'Alinea', heading: 'Kop', + image: 'Afbeelding', figcaption: 'Afbeeldingsbijschrift', embed: 'Insluiting', + line: 'Lijn', code: 'Code', quote: 'Citaat', quoteitem: 'Alinea', + snippet: 'Fragment', column: 'Kolom', grid: 'Raster', list: 'Lijst', + table: 'Tabel', layer: 'Laag', row: 'Rij', text: 'Tekst', cell: 'Cel', + dlist: 'Definitielijst', address: 'Adres', form: 'Formulier', card: 'Kaart', + tags: 'Tags', math: 'Wiskunde', variable: 'Variabele' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Opslaan', cancel: 'Annuleren', 'edit-code': 'Code bewerken' }, + // buttonlink plugin + buttonlink: { button: 'Knop' }, + // carousel plugin + carousel: { carousel: 'Carrousel', save: 'Opslaan', cancel: 'Annuleren', insert: 'Invoegen' }, + // clips plugin + clips: { clips: 'Clips' }, + // counter plugin + counter: { words: 'woorden', chars: 'tekens' }, + // filelink plugin + filelink: { + file: 'Bestand', upload: 'Uploaden', title: 'Titel', choose: 'Kiezen', + placeholder: 'Sleep om een bestand te uploaden
of klik om te selecteren' + }, + // handle plugin + handle: { handle: 'Handgreep' }, + // icons plugin + icons: { icons: 'Pictogrammen' }, + // imageposition plugin + imageposition: { 'image-position': 'Afbeeldingspositie' }, + // imageresize plugin + imageresize: { 'image-resize': 'Afbeelding schalen' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Inline-opmaak', underline: 'Onderstrepen', + superscript: 'Bovenindex', subscript: 'Onderindex', mark: 'Markeren', + code: 'Code', shortcut: 'Sneltoets', 'remove-format': 'Opmaak verwijderen' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Knop maken', 'remove-button': 'Knop verwijderen', + button: 'Knop' + }, + // math plugin + math: { + math: 'Wiskunde', label: 'Typ een expressie', add: 'Toevoegen', + save: 'Opslaan', cancel: 'Annuleren' + }, + // print plugin + print: { print: 'Afdrukken' }, + // removeformat plugin + removeformat: { removeformat: 'Opmaak verwijderen' }, + // selector plugin + selector: { selector: 'Selector', save: 'Opslaan', cancel: 'Annuleren' }, + // slideshow plugin + slideshow: { slideshow: 'Diavoorstelling', save: 'Opslaan', cancel: 'Annuleren', insert: 'Invoegen' }, + // specialchars plugin + specialchars: { 'special-chars': 'Speciale tekens' }, + // style plugin + style: { style: 'Stijl', 'remove-style': 'Stijl verwijderen' }, + // tags plugin + tags: { + tags: 'Tags', add: 'Toevoegen', save: 'Opslaan', cancel: 'Annuleren', + label: 'Voeg door komma’s gescheiden tags toe' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'Van links naar rechts', rtl: 'Van rechts naar links' }, + // variable plugin + variable: { variable: 'Variabele' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/pl.js b/assets/article/langs/pl.js new file mode 100644 index 0000000..d4dfe33 --- /dev/null +++ b/assets/article/langs/pl.js @@ -0,0 +1,175 @@ +/** + * Polish (pl) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in Polish. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['pl'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Edytor tekstu sformatowanego' }, + editor: { title: 'Artykuł', multiple: 'Wielokrotne' }, + placeholders: { + figcaption: 'Wpisz podpis (opcjonalnie)', + text: 'Wpisz coś...', + code: 'Edytuj, aby dodać kod...', + layer: 'Naciśnij Enter, aby dodać nowy tekst...' + }, + popup: { + link: 'Link', add: 'Dodaj', grid: 'Siatka', back: 'Wstecz', + image: 'Obraz', snippets: 'Fragmenty', 'add-image': 'Dodaj obraz' + }, + shortcuts: { + 'meta-a': 'Zaznacz tekst w bloku', 'meta-shift-a': 'Zaznacz wszystkie bloki', + 'meta-click': 'Zaznacz wiele bloków', 'meta-z': 'Cofnij', 'meta-shift-z': 'Ponów', + 'meta-shift-m': 'Usuń formatowanie w tekście', 'meta-b': 'Pogrubienie', + 'meta-i': 'Kursywa', 'meta-u': 'Podkreślenie', 'meta-h': 'Indeks górny', + 'meta-l': 'Indeks dolny', 'meta-k': 'Link', 'meta-alt-0': 'Zwykły tekst', + 'meta-alt-1': 'Nagłówek 1', 'meta-alt-2': 'Nagłówek 2', 'meta-alt-3': 'Nagłówek 3', + 'meta-alt-4': 'Nagłówek 4', 'meta-alt-5': 'Nagłówek 5', 'meta-alt-6': 'Nagłówek 6', + 'meta-shift-7': 'Lista numerowana', 'meta-shift-8': 'Lista punktowana', + 'meta-indent': 'Zwiększ wcięcie', 'meta-outdent': 'Zmniejsz wcięcie', + 'meta-shift-backspace': 'Usuń blok', 'meta-shift-d': 'Duplikuj blok', + 'meta-shift-up': 'Przenieś wiersz w górę', 'meta-shift-down': 'Przenieś wiersz w dół' + }, + headings: { + h1: 'Nagłówek 1', h2: 'Nagłówek 2', h3: 'Nagłówek 3', + h4: 'Nagłówek 4', h5: 'Nagłówek 5', h6: 'Nagłówek 6' + }, + inline: { bold: 'Pogrubienie', italic: 'Kursywa', deleted: 'Przekreślenie' }, + list: { + 'unordered-list': 'Lista punktowana', 'ordered-list': 'Lista numerowana', + indent: 'Zwiększ wcięcie', outdent: 'Zmniejsz wcięcie' + }, + link: { + link: 'Link', 'edit-link': 'Edytuj link', unlink: 'Usuń link', + 'link-in-new-tab': 'Otwórz link w nowej karcie', save: 'Zapisz', + insert: 'Wstaw', cancel: 'Anuluj', text: 'Tekst', url: 'URL' + }, + table: { + width: 'Szerokość', nowrap: 'Bez zawijania', save: 'Zapisz', cancel: 'Anuluj', + 'table-cell': 'Komórka tabeli', 'add-head': 'Dodaj nagłówek', + 'remove-head': 'Usuń nagłówek', 'add-row-below': 'Dodaj wiersz poniżej', + 'add-row-above': 'Dodaj wiersz powyżej', 'remove-row': 'Usuń wiersz', + 'add-column-after': 'Dodaj kolumnę po', 'add-column-before': 'Dodaj kolumnę przed', + 'remove-column': 'Usuń kolumnę' + }, + image: { + or: 'lub', 'alt-text': 'Tekst alternatywny', save: 'Zapisz', link: 'Link', + width: 'Szerokość', delete: 'Usuń', cancel: 'Anuluj', insert: 'Wstaw', + caption: 'Podpis', 'link-in-new-tab': 'Otwórz link w nowej karcie', + 'url-placeholder': 'Wklej URL obrazu...', + 'upload-new-placeholder': 'Przeciągnij, aby przesłać nowy obraz
lub kliknij, aby wybrać' + }, + code: { code: 'Kod', insert: 'Wstaw', save: 'Zapisz', cancel: 'Anuluj' }, + embed: { + embed: 'Osadź', caption: 'Podpis', insert: 'Wstaw', save: 'Zapisz', + cancel: 'Anuluj', + description: 'Wklej dowolny kod osadzania/HTML lub wpisz URL (tylko film Vimeo lub YouTube)', + 'responsive-video': 'Responsywne wideo' + }, + upload: { placeholder: 'Przeciągnij, aby przesłać
lub kliknij, aby wybrać' }, + templates: { templates: 'Szablony' }, + snippets: { snippets: 'Fragmenty' }, + form: { + link: 'Link', url: 'URL', text: 'Tekst', name: 'Nazwa', + 'alt-text': 'Tekst alternatywny', image: 'Obraz', upload: 'Prześlij', + alignment: 'Wyrównanie', outset: 'Wysunięcie', valign: 'Wyrównanie pionowe' + }, + buttons: { + 'mobile-view': 'Widok mobilny', cancel: 'Anuluj', insert: 'Wstaw', + unlink: 'Usuń link', save: 'Zapisz', add: 'Dodaj', + 'transform-to-text': 'Przekształć na tekst', align: 'Wyrównanie', valign: 'Wyrównanie pionowe', + outset: 'Wysunięcie', indent: 'Zwiększ wcięcie', outdent: 'Zmniejsz wcięcie', head: 'Nagłówek', + row: 'Wiersz', cell: 'Komórka', html: 'HTML', templates: 'Szablony', + shortcuts: 'Skróty klawiaturowe', format: 'Format', bold: 'Pogrubienie', italic: 'Kursywa', + deleted: 'Przekreślenie', underline: 'Podkreślenie', table: 'Tabela', link: 'Link', + undo: 'Cofnij', redo: 'Ponów', style: 'Styl', config: 'Konfiguracja', + settings: 'Ustawienia', text: 'Tekst', embed: 'Osadź', grid: 'Siatka', + image: 'Obraz', list: 'Lista', delete: 'Usuń', duplicate: 'Duplikuj', + sort: 'Sortuj', edit: 'Edytuj', inline: 'W tekście' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'Nieedytowalne', paragraph: 'Akapit', heading: 'Nagłówek', + image: 'Obraz', figcaption: 'Podpis obrazu', embed: 'Osadzenie', + line: 'Linia', code: 'Kod', quote: 'Cytat', quoteitem: 'Akapit', + snippet: 'Fragment', column: 'Kolumna', grid: 'Siatka', list: 'Lista', + table: 'Tabela', layer: 'Warstwa', row: 'Wiersz', text: 'Tekst', cell: 'Komórka', + dlist: 'Lista definicji', address: 'Adres', form: 'Formularz', card: 'Karta', + tags: 'Tagi', math: 'Matematyka', variable: 'Zmienna' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Zapisz', cancel: 'Anuluj', 'edit-code': 'Edytuj kod' }, + // buttonlink plugin + buttonlink: { button: 'Przycisk' }, + // carousel plugin + carousel: { carousel: 'Karuzela', save: 'Zapisz', cancel: 'Anuluj', insert: 'Wstaw' }, + // clips plugin + clips: { clips: 'Klipy' }, + // counter plugin + counter: { words: 'słów', chars: 'znaków' }, + // filelink plugin + filelink: { + file: 'Plik', upload: 'Prześlij', title: 'Tytuł', choose: 'Wybierz', + placeholder: 'Przeciągnij, aby przesłać plik
lub kliknij, aby wybrać' + }, + // handle plugin + handle: { handle: 'Uchwyt' }, + // icons plugin + icons: { icons: 'Ikony' }, + // imageposition plugin + imageposition: { 'image-position': 'Pozycja obrazu' }, + // imageresize plugin + imageresize: { 'image-resize': 'Zmiana rozmiaru obrazu' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Formatowanie w tekście', underline: 'Podkreślenie', + superscript: 'Indeks górny', subscript: 'Indeks dolny', mark: 'Wyróżnienie', + code: 'Kod', shortcut: 'Skrót', 'remove-format': 'Usuń formatowanie' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Utwórz przycisk', 'remove-button': 'Usuń przycisk', + button: 'Przycisk' + }, + // math plugin + math: { + math: 'Matematyka', label: 'Wpisz wyrażenie', add: 'Dodaj', + save: 'Zapisz', cancel: 'Anuluj' + }, + // print plugin + print: { print: 'Drukuj' }, + // removeformat plugin + removeformat: { removeformat: 'Usuń formatowanie' }, + // selector plugin + selector: { selector: 'Selektor', save: 'Zapisz', cancel: 'Anuluj' }, + // slideshow plugin + slideshow: { slideshow: 'Pokaz slajdów', save: 'Zapisz', cancel: 'Anuluj', insert: 'Wstaw' }, + // specialchars plugin + specialchars: { 'special-chars': 'Znaki specjalne' }, + // style plugin + style: { style: 'Styl', 'remove-style': 'Usuń styl' }, + // tags plugin + tags: { + tags: 'Tagi', add: 'Dodaj', save: 'Zapisz', cancel: 'Anuluj', + label: 'Dodaj tagi oddzielone przecinkami' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'Od lewej do prawej', rtl: 'Od prawej do lewej' }, + // variable plugin + variable: { variable: 'Zmienna' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/ru.js b/assets/article/langs/ru.js new file mode 100644 index 0000000..34ca1e3 --- /dev/null +++ b/assets/article/langs/ru.js @@ -0,0 +1,175 @@ +/** + * Russian (ru) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in Russian. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['ru'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Редактор форматированного текста' }, + editor: { title: 'Статья', multiple: 'Несколько' }, + placeholders: { + figcaption: 'Введите подпись (необязательно)', + text: 'Введите текст...', + code: 'Отредактируйте, чтобы добавить код...', + layer: 'Нажмите Enter, чтобы добавить новый текст...' + }, + popup: { + link: 'Ссылка', add: 'Добавить', grid: 'Сетка', back: 'Назад', + image: 'Изображение', snippets: 'Фрагменты', 'add-image': 'Добавить изображение' + }, + shortcuts: { + 'meta-a': 'Выбрать текст в блоке', 'meta-shift-a': 'Выбрать все блоки', + 'meta-click': 'Выбрать несколько блоков', 'meta-z': 'Отменить', 'meta-shift-z': 'Повторить', + 'meta-shift-m': 'Удалить встроенное форматирование', 'meta-b': 'Жирный', + 'meta-i': 'Курсив', 'meta-u': 'Подчеркнутый', 'meta-h': 'Надстрочный', + 'meta-l': 'Подстрочный', 'meta-k': 'Ссылка', 'meta-alt-0': 'Обычный текст', + 'meta-alt-1': 'Заголовок 1', 'meta-alt-2': 'Заголовок 2', 'meta-alt-3': 'Заголовок 3', + 'meta-alt-4': 'Заголовок 4', 'meta-alt-5': 'Заголовок 5', 'meta-alt-6': 'Заголовок 6', + 'meta-shift-7': 'Нумерованный список', 'meta-shift-8': 'Маркированный список', + 'meta-indent': 'Увеличить отступ', 'meta-outdent': 'Уменьшить отступ', + 'meta-shift-backspace': 'Удалить блок', 'meta-shift-d': 'Дублировать блок', + 'meta-shift-up': 'Переместить строку вверх', 'meta-shift-down': 'Переместить строку вниз' + }, + headings: { + h1: 'Заголовок 1', h2: 'Заголовок 2', h3: 'Заголовок 3', + h4: 'Заголовок 4', h5: 'Заголовок 5', h6: 'Заголовок 6' + }, + inline: { bold: 'Жирный', italic: 'Курсив', deleted: 'Зачеркнутый' }, + list: { + 'unordered-list': 'Маркированный список', 'ordered-list': 'Нумерованный список', + indent: 'Увеличить отступ', outdent: 'Уменьшить отступ' + }, + link: { + link: 'Ссылка', 'edit-link': 'Редактировать ссылку', unlink: 'Удалить ссылку', + 'link-in-new-tab': 'Открыть ссылку в новой вкладке', save: 'Сохранить', + insert: 'Вставить', cancel: 'Отмена', text: 'Текст', url: 'URL' + }, + table: { + width: 'Ширина', nowrap: 'Без переноса', save: 'Сохранить', cancel: 'Отмена', + 'table-cell': 'Ячейка таблицы', 'add-head': 'Добавить заголовок', + 'remove-head': 'Удалить заголовок', 'add-row-below': 'Добавить строку ниже', + 'add-row-above': 'Добавить строку выше', 'remove-row': 'Удалить строку', + 'add-column-after': 'Добавить столбец после', 'add-column-before': 'Добавить столбец перед', + 'remove-column': 'Удалить столбец' + }, + image: { + or: 'или', 'alt-text': 'Альтернативный текст', save: 'Сохранить', link: 'Ссылка', + width: 'Ширина', delete: 'Удалить', cancel: 'Отмена', insert: 'Вставить', + caption: 'Подпись', 'link-in-new-tab': 'Открыть ссылку в новой вкладке', + 'url-placeholder': 'Вставьте URL изображения...', + 'upload-new-placeholder': 'Перетащите, чтобы загрузить новое изображение
или нажмите, чтобы выбрать' + }, + code: { code: 'Код', insert: 'Вставить', save: 'Сохранить', cancel: 'Отмена' }, + embed: { + embed: 'Встраивание', caption: 'Подпись', insert: 'Вставить', save: 'Сохранить', + cancel: 'Отмена', + description: 'Вставьте любой embed/HTML-код или введите URL (только видео Vimeo или YouTube)', + 'responsive-video': 'Адаптивное видео' + }, + upload: { placeholder: 'Перетащите для загрузки
или нажмите, чтобы выбрать' }, + templates: { templates: 'Шаблоны' }, + snippets: { snippets: 'Фрагменты' }, + form: { + link: 'Ссылка', url: 'URL', text: 'Текст', name: 'Название', + 'alt-text': 'Альтернативный текст', image: 'Изображение', upload: 'Загрузить', + alignment: 'Выравнивание', outset: 'Вынос', valign: 'Вертикальное выравнивание' + }, + buttons: { + 'mobile-view': 'Мобильный вид', cancel: 'Отмена', insert: 'Вставить', + unlink: 'Удалить ссылку', save: 'Сохранить', add: 'Добавить', + 'transform-to-text': 'Преобразовать в текст', align: 'Выравнивание', valign: 'Вертикальное выравнивание', + outset: 'Вынос', indent: 'Увеличить отступ', outdent: 'Уменьшить отступ', head: 'Заголовок', + row: 'Строка', cell: 'Ячейка', html: 'HTML', templates: 'Шаблоны', + shortcuts: 'Сочетания клавиш', format: 'Формат', bold: 'Жирный', italic: 'Курсив', + deleted: 'Зачеркнутый', underline: 'Подчеркнутый', table: 'Таблица', link: 'Ссылка', + undo: 'Отменить', redo: 'Повторить', style: 'Стиль', config: 'Конфигурация', + settings: 'Настройки', text: 'Текст', embed: 'Встраивание', grid: 'Сетка', + image: 'Изображение', list: 'Список', delete: 'Удалить', duplicate: 'Дублировать', + sort: 'Сортировать', edit: 'Редактировать', inline: 'Встроенный' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'Нередактируемый', paragraph: 'Абзац', heading: 'Заголовок', + image: 'Изображение', figcaption: 'Подпись к изображению', embed: 'Встраивание', + line: 'Линия', code: 'Код', quote: 'Цитата', quoteitem: 'Абзац', + snippet: 'Фрагмент', column: 'Столбец', grid: 'Сетка', list: 'Список', + table: 'Таблица', layer: 'Слой', row: 'Строка', text: 'Текст', cell: 'Ячейка', + dlist: 'Список определений', address: 'Адрес', form: 'Форма', card: 'Карточка', + tags: 'Теги', math: 'Математика', variable: 'Переменная' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Сохранить', cancel: 'Отмена', 'edit-code': 'Редактировать код' }, + // buttonlink plugin + buttonlink: { button: 'Кнопка' }, + // carousel plugin + carousel: { carousel: 'Карусель', save: 'Сохранить', cancel: 'Отмена', insert: 'Вставить' }, + // clips plugin + clips: { clips: 'Клипы' }, + // counter plugin + counter: { words: 'слов', chars: 'символов' }, + // filelink plugin + filelink: { + file: 'Файл', upload: 'Загрузить', title: 'Заголовок', choose: 'Выбрать', + placeholder: 'Перетащите файл для загрузки
или нажмите, чтобы выбрать' + }, + // handle plugin + handle: { handle: 'Ручка' }, + // icons plugin + icons: { icons: 'Иконки' }, + // imageposition plugin + imageposition: { 'image-position': 'Позиция изображения' }, + // imageresize plugin + imageresize: { 'image-resize': 'Изменение размера изображения' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Встроенное форматирование', underline: 'Подчеркнутый', + superscript: 'Надстрочный', subscript: 'Подстрочный', mark: 'Выделение', + code: 'Код', shortcut: 'Сочетание клавиш', 'remove-format': 'Удалить форматирование' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Создать кнопку', 'remove-button': 'Удалить кнопку', + button: 'Кнопка' + }, + // math plugin + math: { + math: 'Математика', label: 'Введите выражение', add: 'Добавить', + save: 'Сохранить', cancel: 'Отмена' + }, + // print plugin + print: { print: 'Печать' }, + // removeformat plugin + removeformat: { removeformat: 'Удалить форматирование' }, + // selector plugin + selector: { selector: 'Селектор', save: 'Сохранить', cancel: 'Отмена' }, + // slideshow plugin + slideshow: { slideshow: 'Слайд-шоу', save: 'Сохранить', cancel: 'Отмена', insert: 'Вставить' }, + // specialchars plugin + specialchars: { 'special-chars': 'Специальные символы' }, + // style plugin + style: { style: 'Стиль', 'remove-style': 'Удалить стиль' }, + // tags plugin + tags: { + tags: 'Теги', add: 'Добавить', save: 'Сохранить', cancel: 'Отмена', + label: 'Добавьте теги, разделенные запятыми' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'Слева направо', rtl: 'Справа налево' }, + // variable plugin + variable: { variable: 'Переменная' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/sk.js b/assets/article/langs/sk.js new file mode 100644 index 0000000..396825e --- /dev/null +++ b/assets/article/langs/sk.js @@ -0,0 +1,175 @@ +/** + * Slovak (sk) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in Slovak. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['sk'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Textový editor' }, + editor: { title: 'Článok', multiple: 'Viacnásobné' }, + placeholders: { + figcaption: 'Zadajte popis (voliteľné)', + text: 'Začnite písať...', + code: 'Upravte na pridanie kódu...', + layer: 'Stlačte Enter na pridanie nového textu...' + }, + popup: { + link: 'Odkaz', add: 'Pridať', grid: 'Mriežka', back: 'Späť', + image: 'Obrázok', snippets: 'Úryvky', 'add-image': 'Pridať obrázok' + }, + shortcuts: { + 'meta-a': 'Vybrať text v bloku', 'meta-shift-a': 'Vybrať všetky bloky', + 'meta-click': 'Vybrať viac blokov', 'meta-z': 'Späť', 'meta-shift-z': 'Znova', + 'meta-shift-m': 'Odstrániť vložené formátovanie', 'meta-b': 'Tučné', + 'meta-i': 'Kurzíva', 'meta-u': 'Podčiarknuté', 'meta-h': 'Horný index', + 'meta-l': 'Dolný index', 'meta-k': 'Odkaz', 'meta-alt-0': 'Normálny text', + 'meta-alt-1': 'Nadpis 1', 'meta-alt-2': 'Nadpis 2', 'meta-alt-3': 'Nadpis 3', + 'meta-alt-4': 'Nadpis 4', 'meta-alt-5': 'Nadpis 5', 'meta-alt-6': 'Nadpis 6', + 'meta-shift-7': 'Číslovaný zoznam', 'meta-shift-8': 'Odrážkový zoznam', + 'meta-indent': 'Odsadiť', 'meta-outdent': 'Zrušiť odsadenie', + 'meta-shift-backspace': 'Odstrániť blok', 'meta-shift-d': 'Duplikovať blok', + 'meta-shift-up': 'Presunúť riadok nahor', 'meta-shift-down': 'Presunúť riadok nadol' + }, + headings: { + h1: 'Nadpis 1', h2: 'Nadpis 2', h3: 'Nadpis 3', + h4: 'Nadpis 4', h5: 'Nadpis 5', h6: 'Nadpis 6' + }, + inline: { bold: 'Tučné', italic: 'Kurzíva', deleted: 'Prečiarknuté' }, + list: { + 'unordered-list': 'Odrážkový zoznam', 'ordered-list': 'Číslovaný zoznam', + indent: 'Odsadiť', outdent: 'Zrušiť odsadenie' + }, + link: { + link: 'Odkaz', 'edit-link': 'Upraviť odkaz', unlink: 'Zrušiť odkaz', + 'link-in-new-tab': 'Otvoriť odkaz na novej karte', save: 'Uložiť', + insert: 'Vložiť', cancel: 'Zrušiť', text: 'Text', url: 'URL' + }, + table: { + width: 'Šírka', nowrap: 'Nezalamovať', save: 'Uložiť', cancel: 'Zrušiť', + 'table-cell': 'Bunka tabuľky', 'add-head': 'Pridať hlavičku', + 'remove-head': 'Odstrániť hlavičku', 'add-row-below': 'Pridať riadok pod', + 'add-row-above': 'Pridať riadok nad', 'remove-row': 'Odstrániť riadok', + 'add-column-after': 'Pridať stĺpec za', 'add-column-before': 'Pridať stĺpec pred', + 'remove-column': 'Odstrániť stĺpec' + }, + image: { + or: 'alebo', 'alt-text': 'Alternatívny text', save: 'Uložiť', link: 'Odkaz', + width: 'Šírka', delete: 'Odstrániť', cancel: 'Zrušiť', insert: 'Vložiť', + caption: 'Popis', 'link-in-new-tab': 'Otvoriť odkaz na novej karte', + 'url-placeholder': 'Vložte URL obrázka...', + 'upload-new-placeholder': 'Presuňte sem nový obrázok na nahratie
alebo kliknite na výber' + }, + code: { code: 'Kód', insert: 'Vložiť', save: 'Uložiť', cancel: 'Zrušiť' }, + embed: { + embed: 'Vložený obsah', caption: 'Popis', insert: 'Vložiť', save: 'Uložiť', + cancel: 'Zrušiť', + description: 'Vložte ľubovoľný embed/HTML kód alebo zadajte URL (iba video Vimeo alebo YouTube)', + 'responsive-video': 'Responzívne video' + }, + upload: { placeholder: 'Presuňte sem na nahratie
alebo kliknite na výber' }, + templates: { templates: 'Šablóny' }, + snippets: { snippets: 'Úryvky' }, + form: { + link: 'Odkaz', url: 'URL', text: 'Text', name: 'Názov', + 'alt-text': 'Alternatívny text', image: 'Obrázok', upload: 'Nahrať', + alignment: 'Zarovnanie', outset: 'Presah', valign: 'Zvislé zarovnanie' + }, + buttons: { + 'mobile-view': 'Mobilné zobrazenie', cancel: 'Zrušiť', insert: 'Vložiť', + unlink: 'Zrušiť odkaz', save: 'Uložiť', add: 'Pridať', + 'transform-to-text': 'Previesť na text', align: 'Zarovnanie', valign: 'Zvislé zarovnanie', + outset: 'Presah', indent: 'Odsadiť', outdent: 'Zrušiť odsadenie', head: 'Hlavička', + row: 'Riadok', cell: 'Bunka', html: 'HTML', templates: 'Šablóny', + shortcuts: 'Klávesové skratky', format: 'Formát', bold: 'Tučné', italic: 'Kurzíva', + deleted: 'Prečiarknuté', underline: 'Podčiarknuté', table: 'Tabuľka', link: 'Odkaz', + undo: 'Späť', redo: 'Znova', style: 'Štýl', config: 'Konfigurácia', + settings: 'Nastavenia', text: 'Text', embed: 'Vložený obsah', grid: 'Mriežka', + image: 'Obrázok', list: 'Zoznam', delete: 'Odstrániť', duplicate: 'Duplikovať', + sort: 'Zoradiť', edit: 'Upraviť', inline: 'Vložené' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'Neupraviteľné', paragraph: 'Odsek', heading: 'Nadpis', + image: 'Obrázok', figcaption: 'Popis obrázka', embed: 'Vložený obsah', + line: 'Čiara', code: 'Kód', quote: 'Citát', quoteitem: 'Odsek', + snippet: 'Úryvok', column: 'Stĺpec', grid: 'Mriežka', list: 'Zoznam', + table: 'Tabuľka', layer: 'Vrstva', row: 'Riadok', text: 'Text', cell: 'Bunka', + dlist: 'Definičný zoznam', address: 'Adresa', form: 'Formulár', card: 'Karta', + tags: 'Štítky', math: 'Matematika', variable: 'Premenná' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Uložiť', cancel: 'Zrušiť', 'edit-code': 'Upraviť kód' }, + // buttonlink plugin + buttonlink: { button: 'Tlačidlo' }, + // carousel plugin + carousel: { carousel: 'Karusel', save: 'Uložiť', cancel: 'Zrušiť', insert: 'Vložiť' }, + // clips plugin + clips: { clips: 'Klipy' }, + // counter plugin + counter: { words: 'slov', chars: 'znakov' }, + // filelink plugin + filelink: { + file: 'Súbor', upload: 'Nahrať', title: 'Názov', choose: 'Vybrať', + placeholder: 'Presuňte súbor na nahratie
alebo kliknite na výber' + }, + // handle plugin + handle: { handle: 'Úchyt' }, + // icons plugin + icons: { icons: 'Ikony' }, + // imageposition plugin + imageposition: { 'image-position': 'Pozícia obrázka' }, + // imageresize plugin + imageresize: { 'image-resize': 'Zmena veľkosti obrázka' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Vložené formátovanie', underline: 'Podčiarknuté', + superscript: 'Horný index', subscript: 'Dolný index', mark: 'Zvýraznenie', + code: 'Kód', shortcut: 'Skratka', 'remove-format': 'Odstrániť formátovanie' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Vytvoriť tlačidlo', 'remove-button': 'Odstrániť tlačidlo', + button: 'Tlačidlo' + }, + // math plugin + math: { + math: 'Matematika', label: 'Zadajte výraz', add: 'Pridať', + save: 'Uložiť', cancel: 'Zrušiť' + }, + // print plugin + print: { print: 'Tlač' }, + // removeformat plugin + removeformat: { removeformat: 'Odstrániť formátovanie' }, + // selector plugin + selector: { selector: 'Výber', save: 'Uložiť', cancel: 'Zrušiť' }, + // slideshow plugin + slideshow: { slideshow: 'Prezentácia', save: 'Uložiť', cancel: 'Zrušiť', insert: 'Vložiť' }, + // specialchars plugin + specialchars: { 'special-chars': 'Špeciálne znaky' }, + // style plugin + style: { style: 'Štýl', 'remove-style': 'Odstrániť štýl' }, + // tags plugin + tags: { + tags: 'Štítky', add: 'Pridať', save: 'Uložiť', cancel: 'Zrušiť', + label: 'Pridajte štítky oddelené čiarkou' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'Zľava doprava', rtl: 'Sprava doľava' }, + // variable plugin + variable: { variable: 'Premenná' } + }; +})(ArticleEditor); diff --git a/assets/article/langs/sl.js b/assets/article/langs/sl.js new file mode 100644 index 0000000..833d5a8 --- /dev/null +++ b/assets/article/langs/sl.js @@ -0,0 +1,175 @@ +/** + * Slovenian (sl) UI language for the Bolt Article editor. + * + * Loaded by Bolt\Article\TwigExtension::articleLangInclude before the plugin + * scripts. Keys left out fall back to English (see en.js) automatically. + * + * Structure mirrors en.js: the core editor UI first, then one clearly labelled + * group per plugin. Plugin strings are NOT merged into non-English locales at + * runtime, so every plugin group must be carried here to be shown in Slovenian. + */ +(function (AE) { + AE.lang = AE.lang || {}; + AE.lang['sl'] = { + // ───────────────────────────────────────────────────────────── + // Core editor UI + // ───────────────────────────────────────────────────────────── + accessibility: { 'help-label': 'Urejevalnik obogatenega besedila' }, + editor: { title: 'Članek', multiple: 'Večkratno' }, + placeholders: { + figcaption: 'Vnesite napis (neobvezno)', + text: 'Vnesite besedilo...', + code: 'Uredite za dodajanje kode...', + layer: 'Pritisnite Enter za dodajanje novega besedila...' + }, + popup: { + link: 'Povezava', add: 'Dodaj', grid: 'Mreža', back: 'Nazaj', + image: 'Slika', snippets: 'Izrezki', 'add-image': 'Dodaj sliko' + }, + shortcuts: { + 'meta-a': 'Izberi besedilo v bloku', 'meta-shift-a': 'Izberi vse bloke', + 'meta-click': 'Izberi več blokov', 'meta-z': 'Razveljavi', 'meta-shift-z': 'Uveljavi', + 'meta-shift-m': 'Odstrani oblikovanje v vrstici', 'meta-b': 'Krepko', + 'meta-i': 'Ležeče', 'meta-u': 'Podčrtano', 'meta-h': 'Nadpisano', + 'meta-l': 'Podpisano', 'meta-k': 'Povezava', 'meta-alt-0': 'Običajno besedilo', + 'meta-alt-1': 'Naslov 1', 'meta-alt-2': 'Naslov 2', 'meta-alt-3': 'Naslov 3', + 'meta-alt-4': 'Naslov 4', 'meta-alt-5': 'Naslov 5', 'meta-alt-6': 'Naslov 6', + 'meta-shift-7': 'Oštevilčen seznam', 'meta-shift-8': 'Neoštevilčen seznam', + 'meta-indent': 'Povečaj zamik', 'meta-outdent': 'Zmanjšaj zamik', + 'meta-shift-backspace': 'Izbriši blok', 'meta-shift-d': 'Podvoji blok', + 'meta-shift-up': 'Premakni vrstico navzgor', 'meta-shift-down': 'Premakni vrstico navzdol' + }, + headings: { + h1: 'Naslov 1', h2: 'Naslov 2', h3: 'Naslov 3', + h4: 'Naslov 4', h5: 'Naslov 5', h6: 'Naslov 6' + }, + inline: { bold: 'Krepko', italic: 'Ležeče', deleted: 'Prečrtano' }, + list: { + 'unordered-list': 'Neoštevilčen seznam', 'ordered-list': 'Oštevilčen seznam', + indent: 'Povečaj zamik', outdent: 'Zmanjšaj zamik' + }, + link: { + link: 'Povezava', 'edit-link': 'Uredi povezavo', unlink: 'Odstrani povezavo', + 'link-in-new-tab': 'Odpri povezavo v novem zavihku', save: 'Shrani', + insert: 'Vstavi', cancel: 'Prekliči', text: 'Besedilo', url: 'URL' + }, + table: { + width: 'Širina', nowrap: 'Brez preloma', save: 'Shrani', cancel: 'Prekliči', + 'table-cell': 'Celica tabele', 'add-head': 'Dodaj glavo', + 'remove-head': 'Odstrani glavo', 'add-row-below': 'Dodaj vrstico spodaj', + 'add-row-above': 'Dodaj vrstico zgoraj', 'remove-row': 'Odstrani vrstico', + 'add-column-after': 'Dodaj stolpec za', 'add-column-before': 'Dodaj stolpec pred', + 'remove-column': 'Odstrani stolpec' + }, + image: { + or: 'ali', 'alt-text': 'Nadomestno besedilo', save: 'Shrani', link: 'Povezava', + width: 'Širina', delete: 'Izbriši', cancel: 'Prekliči', insert: 'Vstavi', + caption: 'Napis', 'link-in-new-tab': 'Odpri povezavo v novem zavihku', + 'url-placeholder': 'Prilepite URL slike...', + 'upload-new-placeholder': 'Povlecite za nalaganje nove slike
ali kliknite za izbiro' + }, + code: { code: 'Koda', insert: 'Vstavi', save: 'Shrani', cancel: 'Prekliči' }, + embed: { + embed: 'Vdelava', caption: 'Napis', insert: 'Vstavi', save: 'Shrani', + cancel: 'Prekliči', + description: 'Prilepite poljubno vdelano/HTML kodo ali vnesite URL (samo video Vimeo ali YouTube)', + 'responsive-video': 'Odziven video' + }, + upload: { placeholder: 'Povlecite za nalaganje
ali kliknite za izbiro' }, + templates: { templates: 'Predloge' }, + snippets: { snippets: 'Izrezki' }, + form: { + link: 'Povezava', url: 'URL', text: 'Besedilo', name: 'Ime', + 'alt-text': 'Nadomestno besedilo', image: 'Slika', upload: 'Naloži', + alignment: 'Poravnava', outset: 'Odmik navzven', valign: 'Navpična poravnava' + }, + buttons: { + 'mobile-view': 'Mobilni pogled', cancel: 'Prekliči', insert: 'Vstavi', + unlink: 'Odstrani povezavo', save: 'Shrani', add: 'Dodaj', + 'transform-to-text': 'Pretvori v besedilo', align: 'Poravnava', valign: 'Navpična poravnava', + outset: 'Odmik navzven', indent: 'Povečaj zamik', outdent: 'Zmanjšaj zamik', head: 'Glava', + row: 'Vrstica', cell: 'Celica', html: 'HTML', templates: 'Predloge', + shortcuts: 'Bližnjice na tipkovnici', format: 'Oblika', bold: 'Krepko', italic: 'Ležeče', + deleted: 'Prečrtano', underline: 'Podčrtano', table: 'Tabela', link: 'Povezava', + undo: 'Razveljavi', redo: 'Uveljavi', style: 'Slog', config: 'Konfiguracija', + settings: 'Nastavitve', text: 'Besedilo', embed: 'Vdelava', grid: 'Mreža', + image: 'Slika', list: 'Seznam', delete: 'Izbriši', duplicate: 'Podvoji', + sort: 'Razvrsti', edit: 'Uredi', inline: 'V vrstici' + }, + // Block labels. The last two are contributed by the `math` and `variable` + // plugins; the rest are core block types. + blocks: { + noneditable: 'Neuredivo', paragraph: 'Odstavek', heading: 'Naslov', + image: 'Slika', figcaption: 'Napis slike', embed: 'Vdelava', + line: 'Črta', code: 'Koda', quote: 'Citat', quoteitem: 'Odstavek', + snippet: 'Izrezek', column: 'Stolpec', grid: 'Mreža', list: 'Seznam', + table: 'Tabela', layer: 'Plast', row: 'Vrstica', text: 'Besedilo', cell: 'Celica', + dlist: 'Seznam definicij', address: 'Naslov', form: 'Obrazec', card: 'Kartica', + tags: 'Oznake', math: 'Matematika', variable: 'Spremenljivka' + }, + + // ───────────────────────────────────────────────────────────── + // Plugin UI — one group per plugin (alphabetical) + // ───────────────────────────────────────────────────────────── + // blockcode plugin + blockcode: { save: 'Shrani', cancel: 'Prekliči', 'edit-code': 'Uredi kodo' }, + // buttonlink plugin + buttonlink: { button: 'Gumb' }, + // carousel plugin + carousel: { carousel: 'Vrtiljak', save: 'Shrani', cancel: 'Prekliči', insert: 'Vstavi' }, + // clips plugin + clips: { clips: 'Izrezki' }, + // counter plugin + counter: { words: 'besed', chars: 'znakov' }, + // filelink plugin + filelink: { + file: 'Datoteka', upload: 'Naloži', title: 'Naslov', choose: 'Izberi', + placeholder: 'Povlecite za nalaganje datoteke
ali kliknite za izbiro' + }, + // handle plugin + handle: { handle: 'Ročaj' }, + // icons plugin + icons: { icons: 'Ikone' }, + // imageposition plugin + imageposition: { 'image-position': 'Položaj slike' }, + // imageresize plugin + imageresize: { 'image-resize': 'Spreminjanje velikosti slike' }, + // inlineformat plugin + inlineformat: { + 'inline-format': 'Oblikovanje v vrstici', underline: 'Podčrtano', + superscript: 'Nadpisano', subscript: 'Podpisano', mark: 'Označeno', + code: 'Koda', shortcut: 'Bližnjica', 'remove-format': 'Odstrani oblikovanje' + }, + // makebutton plugin + makebutton: { + 'make-a-button': 'Ustvari gumb', 'remove-button': 'Odstrani gumb', + button: 'Gumb' + }, + // math plugin + math: { + math: 'Matematika', label: 'Vnesite izraz', add: 'Dodaj', + save: 'Shrani', cancel: 'Prekliči' + }, + // print plugin + print: { print: 'Natisni' }, + // removeformat plugin + removeformat: { removeformat: 'Odstrani oblikovanje' }, + // selector plugin + selector: { selector: 'Izbirnik', save: 'Shrani', cancel: 'Prekliči' }, + // slideshow plugin + slideshow: { slideshow: 'Diaprojekcija', save: 'Shrani', cancel: 'Prekliči', insert: 'Vstavi' }, + // specialchars plugin + specialchars: { 'special-chars': 'Posebni znaki' }, + // style plugin + style: { style: 'Slog', 'remove-style': 'Odstrani slog' }, + // tags plugin + tags: { + tags: 'Oznake', add: 'Dodaj', save: 'Shrani', cancel: 'Prekliči', + label: 'Dodajte oznake, ločene z vejicami' + }, + // textdirection plugin + textdirection: { title: 'RTL-LTR', ltr: 'Od leve proti desni', rtl: 'Od desne proti levi' }, + // variable plugin + variable: { variable: 'Spremenljivka' } + }; +})(ArticleEditor); diff --git a/config/config.yaml b/config/config.yaml index a3a290a..6a1f8d5 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -1,9 +1,9 @@ # Settings for Bolt Article -# All options: blockcode, buttonlink, carousel, counter, definedlinks, filelink, -# handle, icons, imageposition, inlineformat, makebutton, print, reorder, -# selector, specialchars, style, tags, textdirection, underline, variable, -# removeformat, imageresize +# All options: blockcode, buttonlink, carousel, clips, counter, definedlinks, +# filelink, handle, icons, imageposition, imageresize, inlineformat, makebutton, +# math, print, removeformat, reorder, selector, slideshow, specialchars, style, +# tags, textdirection, underline, variable default: plugins: [ blockcode, buttonlink, definedlinks, inlineformat, reorder, tags, underline, imageposition, filelink, removeformat, imageresize ] source: true diff --git a/config/services.yaml b/config/services.yaml index db030e9..16ecca4 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -10,6 +10,16 @@ services: Bolt\Article\Controller\Images: tags: [ 'controller.service_arguments' ] + Bolt\Article\TwigExtension: + arguments: + $projectDir: '%kernel.project_dir%' + $publicFolder: '%bolt.public_folder%' + + Bolt\Article\ArticleConfig: + arguments: + $projectDir: '%kernel.project_dir%' + $publicFolder: '%bolt.public_folder%' + ### Map entities doctrine: orm: diff --git a/src/ArticleConfig.php b/src/ArticleConfig.php index 40788ec..c1f20ba 100644 --- a/src/ArticleConfig.php +++ b/src/ArticleConfig.php @@ -11,6 +11,7 @@ use Pagerfanta\PagerfantaInterface; use RuntimeException; use Symfony\Bundle\SecurityBundle\Security; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; use Symfony\Contracts\Cache\CacheInterface; @@ -33,7 +34,10 @@ public function __construct( private readonly Config $boltConfig, private readonly Query $query, private readonly CacheInterface $cache, - private readonly Security $security + private readonly Security $security, + private readonly RequestStack $requestStack, + private readonly string $projectDir, + private readonly string $publicFolder ) { } @@ -50,6 +54,15 @@ public function getConfig(): array $this->config = array_replace_recursive($this->getDefaults(), $extension->getConfig()['default'], $this->getLinks()); + // The editor UI language always follows the current Bolt backend locale + // (resolved per user by Bolt's LocaleSubscriber). It is intentionally not + // configurable — set last so any stray `editor.lang` in config can't freeze + // it. The matching langs/.js is auto-loaded by article_includes(). + if (! isset($this->config['editor']) || ! is_array($this->config['editor'])) { + $this->config['editor'] = []; + } + $this->config['editor']['lang'] = $this->resolveLocale(); + return $this->config; } @@ -215,6 +228,37 @@ private function getLinksHelper(): array ]; } + /** + * The locale to use for the editor UI. Uses the current request locale, which + * Bolt resolves per user in the backend (LocaleSubscriber sets it from the + * user's `_backend_locale`). + * + * Falls back to English when there is no request (e.g. CLI / cache warmup) or + * when we ship no matching langs/.js. The fallback is essential: the + * editor does NOT fall back on its own — set `editor.lang` to a locale whose + * language table was never loaded and every toolbar label resolves to + * `undefined`, rendering an empty editor UI. Keeping this in sync with the file + * that article_includes() actually loads guarantees the two never disagree. + */ + private function resolveLocale(): string + { + $request = $this->requestStack->getCurrentRequest(); + $locale = $request?->getLocale() ?: 'en'; + + return $this->hasLangFile($locale) ? $locale : 'en'; + } + + private function hasLangFile(string $locale): bool + { + if ($locale === '') { + return false; + } + + $path = sprintf('%s/%s/assets/article/langs/%s.js', $this->projectDir, $this->publicFolder, $locale); + + return is_file($path); + } + private function getExtension(): Extension { /** @var Extension|null $extension */ diff --git a/src/TwigExtension.php b/src/TwigExtension.php index 67dc7c3..f053e0a 100644 --- a/src/TwigExtension.php +++ b/src/TwigExtension.php @@ -12,7 +12,9 @@ class TwigExtension extends AbstractExtension { public function __construct( - private readonly ArticleConfig $articleConfig + private readonly ArticleConfig $articleConfig, + private readonly string $projectDir, + private readonly string $publicFolder, ) { } @@ -40,7 +42,14 @@ public function articleIncludes(): string $used = $this->articleConfig->getConfig()['plugins']; $plugins = collect($this->articleConfig->getPlugins()); - $output = ''; + // The UI language file matching the resolved locale (see + // ArticleConfig::resolveLocale) is emitted FIRST, before the plugin + // scripts below. Each plugin registers its own `translations.en`, which + // deep-merges onto `ArticleEditor.lang.`; loading the base language + // first lets those merge in so the English fallback stays complete for + // every enabled plugin. English is included on purpose (langs/en.js is the + // canonical, editable English set). Unsupported locales are skipped. + $output = $this->articleLangInclude(); foreach ($used as $item) { if (! is_string($item) || ! $plugins->get($item)) { @@ -60,4 +69,28 @@ public function articleIncludes(): string return $output; } + + /** + * A `', $relative) . "\n"; + } }