From 00f431c50e1f02314c2e15c72728ee2bb70487eb Mon Sep 17 00:00:00 2001 From: Joscha <34318751+josxha@users.noreply.github.com> Date: Tue, 3 Sep 2024 07:24:26 +0200 Subject: [PATCH] add german translation, update docs (#931) - add german translation (following the changes in https://github.com/maplibre/maputnik/pull/929) - using an alphabecial order for the languages - update the documentation with a step-by-step guide - add myself as a helping person for german - move the helping-users list to the implementation of new features - update CHANGELOG.md - add a link to the l18n README in the root README ![image](https://github.com/user-attachments/assets/2834f2c5-2cb7-4848-a6bf-24149be979ae) --- .gitignore | 1 + CHANGELOG.md | 1 + README.md | 1 - i18next-parser.config.ts | 2 +- src/i18n.ts | 5 +- src/locales/README.md | 51 +++++++-- src/locales/de/translation.json | 185 ++++++++++++++++++++++++++++++++ 7 files changed, 234 insertions(+), 12 deletions(-) create mode 100644 src/locales/de/translation.json diff --git a/.gitignore b/.gitignore index d9cb3aaf..a512bea7 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ public # IDE .vscode/ +.idea/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b7d5338..cd77a6d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## main ### ✨ Features and improvements +- Add german translation - _...Add new stuff here..._ ### 🐞 Bug fixes diff --git a/README.md b/README.md index 99ea2e2b..10f9ce88 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,6 @@ npm run lint-css npm run sort-styles ``` - ## Tests For E2E testing we use [Cypress](https://www.cypress.io/) diff --git a/i18next-parser.config.ts b/i18next-parser.config.ts index 9503e147..7701b911 100644 --- a/i18next-parser.config.ts +++ b/i18next-parser.config.ts @@ -1,6 +1,6 @@ export default { output: 'src/locales/$LOCALE/$NAMESPACE.json', - locales: [ 'fr', 'ja', 'he','zh' ], + locales: [ 'de', 'fr', 'he', 'ja', 'zh' ], // Because some keys are dynamically generated, i18next-parser can't detect them. // We add these keys manually, so we don't want to remove them. diff --git a/src/i18n.ts b/src/i18n.ts index cfd530d5..cbee43f4 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -4,10 +4,11 @@ import resourcesToBackend from "i18next-resources-to-backend"; import { initReactI18next } from "react-i18next"; export const supportedLanguages = { - "fr": "Français", + "de": "Deutsch", "en": "English", - "ja": "日本語", + "fr": "Français", "he": "עברית", + "ja": "日本語", "zh": "简体中文" } as const; diff --git a/src/locales/README.md b/src/locales/README.md index 5535f79b..6e456701 100644 --- a/src/locales/README.md +++ b/src/locales/README.md @@ -2,22 +2,57 @@ The process of internationlization is pretty straight forward for Maputnik. -In order to add a new translation you'll need to create a new folder and a json file with the relevant language code and make sure all the keys are translated. -The following users can help you with the relevant languages: +## Add a new language + +#### 1. Edit configuration + +In order to add a new translation you'll need to add it to the configuration files. Please put it in alphabetical order. + +- Open [/i18next-parser.config.ts](/i18next-parser.config.ts) and add the ISO Code of your language to the `locales` array. +- Now, open [/src/i18n.ts](/src/i18n.ts) and add the ISO Code and localized name to the supported languages. + +#### 2. Add the localized strings + +Refresh the localization to generate a new directory under `/src/locales/` for your new language. + +```bash +npm install +npm run i18n:refresh +``` + +Replace every `__STRING_NOT_TRANSLATED__` value in the newly generated `translation.json` file with the according translation. +Make sure all the keys are translated. -- English - @HarelM -- Japanese - @keichan34 -- Simplified Chinese - @jieme -- Hebrew - @HarelM -- French - @lhapaipai +#### 3. Test your new locale + +Finally, test your language locally by starting a local instance of Maputnik. + +```bash +npm run start +``` + +Consider adding your name as a helping person for the translation of new features. + +## Add localization for a new feature If you happen to add a feature which needs some text to be translated, update the translation files. After running, check your working copy for files and add/correct as needed. -``` +```bash npm run i18n:refresh ``` +The following users can help you with the relevant languages: + +| ISO Code | Language | User | +|----------|--------------------|--------------------------------------------| +| de | German | [@josxha](https://github.com/josxha) | +| en | English | [@HarelM](https://github.com/HarelM) | +| fr | French | [@lhapaipai](https://github.com/lhapaipai) | +| hr | Hebrew | [@HarelM](https://github.com/HarelM) | +| ja | Japanese | [@keichan34](https://github.com/keichan34) | +| zh | Simplified Chinese | [@jieme](https://github.com/jieme) | + You can test the UI in different languages using the dropdown in the top menu Note that Maputnik automatically localize based on browser language settings and stores this language in local storage. You can use incognito mode to check a first time usage. diff --git a/src/locales/de/translation.json b/src/locales/de/translation.json new file mode 100644 index 00000000..f7f88f22 --- /dev/null +++ b/src/locales/de/translation.json @@ -0,0 +1,185 @@ +{ + "Input value": "Eingabewert", + "Data value": "Datenwert", + "Output value": "Ausgabewert", + "Function": "Funktion", + "Select a type of data scale (default is 'categorical').": "Wähle eine Art Datenskala (Standard ist 'kategorisch').", + "Base": "Basis", + "Input a data property to base styles off of.": "Gib eine Dateneigenschaft ein, um Stile darauf zu basieren.", + "Default": "Standard", + "Stops": "Stopps", + "Zoom": "Zoom", + "Add stop": "Stopp hinzufügen", + "Convert to expression": "In Ausdruck umwandeln", + "Remove zoom level from stop": "Zoom-Stufe vom Stopp entfernen", + "Revert from expression": "Vom Ausdruck zurücksetzen", + "Delete expression": "Ausdruck löschen", + "Convert property into a zoom function": "Eigenschaft in eine Zoom-Funktion umwandeln", + "Convert property to data function": "Eigenschaft in eine Datenfunktion umwandeln", + "Layer <1>{formatLayerId(layerId)}: {parsed.data.message}": "Ebene <1>{formatLayerId(layerId)}: {parsed.data.message}", + "switch to layer": "zur Ebene wechseln", + "Map": "Karte", + "Inspect": "Untersuchen", + "Deuteranopia filter": "Deuteranopie-Filter", + "Protanopia filter": "Protanopie-Filter", + "Tritanopia filter": "Tritanopie-Filter", + "Achromatopsia filter": "Achromatopsie-Filter", + "Layers list": "Ebenenliste", + "Layer editor": "Ebenen-Editor", + "Map view": "Kartenansicht", + "Maputnik on GitHub": "Maputnik auf GitHub", + "Open": "Öffnen", + "Export": "Exportieren", + "Data Sources": "Datenquellen", + "Style Settings": "Stileinstellungen", + "View": "Ansicht", + "Color accessibility": "Farbzugänglichkeit", + "Help": "Hilfe", + "Comments for the current layer. This is non-standard and not in the spec.": "Kommentare zur aktuellen Ebene. Das ist nicht standardmäßig und nicht in der Spezifikation.", + "Comments": "Kommentare", + "Comment...": "Dein Kommentar...", + "Max Zoom": "Max-Zoom", + "Min Zoom": "Min-Zoom", + "Source": "Quelle", + "Source Layer": "Quellenebene", + "Type": "Typ", + "Nested filters are not supported.": "Verschachtelte Filter werden nicht unterstützt.", + "Upgrade to expression": "Aufrüsten zu Ausdruck", + "Filter": "Filter", + "every filter matches": "alle Filter passen", + "no filter matches": "kein Filter passt", + "any filter matches": "irgendein Filter passt", + "Add filter": "Filter hinzufügen", + "You've entered an old style filter.": "Du hast einen alten Filter-Stil eingegeben.", + "Switch to filter editor.": "Zum Filter-Editor wechseln.", + "Delete filter block": "Filterblock löschen", + "Add value": "Wert hinzufügen", + "Remove array item": "Element aus Array entfernen", + "Press <1>ESC to lose focus": "Drück <1>ESC, um den Fokus zu verlieren", + "Must provide protocol: <1>https://": "Protokoll erforderlich: <1>https://", + "Must provide protocol: <1>http:// or <3>https://": "Protokoll erforderlich: <1>http:// oder <3>https://", + "CORS policy won't allow fetching resources served over http from https, use a <1>https:// domain": "Die CORS-Politik erlaubt es nicht, Ressourcen über http von https zu laden, benutze eine <1>https://-Domain", + "Layer": "Ebene", + "JSON Editor": "JSON-Editor", + "Delete": "Löschen", + "Duplicate": "Duplizieren", + "Show": "Anzeigen", + "Hide": "Verstecken", + "Move layer up": "Ebene nach oben verschieben", + "Move layer down": "Ebene nach unten verschieben", + "Layer: {{layerId}}": "Ebene: {{layerId}}", + "Layers": "Ebenen", + "Collapse": "Einklappen", + "Expand": "Ausklappen", + "Add Layer": "Ebene hinzufügen", + "Search": "Suche", + "Zoom:": "Zoom:", + "Close popup": "Popup schließen", + "cursor:": "Mauszeiger:", + "center:": "Zentrum:", + "rotation:": "Rotation:", + "Close modal": "Modale Fenster schließen", + "Debug": "Debug", + "Options": "Optionen", + "<0>Open in OSM — Opens the current view on openstreetmap.org": "<0>In OSM öffnen — Öffnet die aktuelle Ansicht auf openstreetmap.org", + "Export Style": "Stil exportieren", + "Download Style": "Stil herunterladen", + "Download a JSON style to your computer.": "Lade einen JSON-Stil auf deinen Computer herunter.", + "Download HTML": "HTML herunterladen", + "Cancel": "Abbrechen", + "Open Style": "Stil öffnen", + "Upload Style": "Stil hochladen", + "Upload a JSON style from your computer.": "Lade einen JSON-Stil von deinem Computer hoch.", + "Style file": "Stildatei", + "Upload": "Hochladen", + "Load from URL": "Von URL laden", + "Load from a URL. Note that the URL must have <1>CORS enabled.": "Von einer URL laden. Beachte, dass die URL <1>CORS aktiviert haben muss.", + "Style URL": "Stil-URL", + "Enter URL...": "URL eingeben...", + "Gallery Styles": "Galerie-Stile", + "Open one of the publicly available styles to start from.": "Öffne einen der öffentlich verfügbaren Stile, um zu starten.", + "Loading style": "Stil wird geladen", + "Loading: {{requestUrl}}": "Lädt: {{requestUrl}}", + "Name": "Name", + "Owner": "Besitzer", + "Owner ID of the style. Used by Mapbox or future style APIs.": "Besitzer-ID des Stils. Wird von Mapbox oder zukünftigen Style-APIs verwendet.", + "Sprite URL": "Sprite-URL", + "Glyphs URL": "Glyphen-URL", + "Center": "Mittelpunkt", + "Bearing": "Ausrichtung", + "Pitch": "Neigung", + "Light anchor": "Lichtanker", + "Light color": "Lichtfarbe", + "Light intensity": "Lichtintensität", + "Light position": "Lichtposition", + "Terrain source": "Geländequelle", + "Terrain exaggeration": "Gelände-Übertreibung", + "Transition delay": "Übergangsverzögerung", + "Transition duration": "Übergangsdauer", + "Open Layers (experimental)": "Ebenen öffnen (experimentell)", + "Shortcuts menu": "Shortcuts-Menü", + "Open modal": "Modale Fenster öffnen", + "Export modal": "Modale Fenster exportieren", + "Data Sources modal": "Modale Datenquellen", + "Style Settings modal": "Modale Stileinstellungen", + "Toggle inspect": "Inspektion umschalten", + "Focus map": "Karte fokussieren", + "Debug modal": "Debug (modale Fenster)", + "Increase the zoom level by 1.": "Zoom-Stufe um 1 erhöhen.", + "Increase the zoom level by 2.": "Zoom-Stufe um 2 erhöhen.", + "Decrease the zoom level by 1.": "Zoom-Stufe um 1 verringern.", + "Decrease the zoom level by 2.": "Zoom-Stufe um 2 verringern.", + "Pan up by 100 pixels.": "Um 100 Pixel nach oben schwenken.", + "Pan down by 100 pixels.": "Um 100 Pixel nach unten schwenken.", + "Pan left by 100 pixels.": "Um 100 Pixel nach links schwenken.", + "Pan right by 100 pixels.": "Um 100 Pixel nach rechts schwenken.", + "Increase the rotation by 15 degrees.": "Rotation um 15 Grad erhöhen.", + "Decrease the rotation by 15 degrees.": "Rotation um 15 Grad verringern.", + "Increase the pitch by 10 degrees.": "Neigung um 10 Grad erhöhen.", + "Decrease the pitch by 10 degrees.": "Neigung um 10 Grad verringern.", + "Shortcuts": "Shortcuts", + "Press <1>ESC to lose focus of any active elements, then press one of:": "Drück <1>ESC, um den Fokus von aktiven Elementen zu verlieren, und dann drück eine der folgenden Tasten:", + "If the Map is in focused you can use the following shortcuts": "Wenn die Karte fokussiert ist, kannst du die folgenden Shortcuts benutzen", + "Remove '{{sourceId}}' source": "Quelle '{{sourceId}}' entfernen", + "Source ID": "Quellen-ID", + "Unique ID that identifies the source and is used in the layer to reference the source.": "Eindeutige ID, die die Quelle identifiziert und in der Ebene verwendet wird, um auf die Quelle zu verweisen.", + "Source Type": "Quellentyp", + "GeoJSON (JSON)": "GeoJSON (JSON)", + "GeoJSON (URL)": "GeoJSON (URL)", + "Vector (TileJSON URL)": "Vektor (TileJSON URL)", + "Vector (XYZ URLs)": "Vektor (XYZ URLs)", + "Raster (TileJSON URL)": "Raster (TileJSON URL)", + "Raster (XYZ URL)": "Raster (XYZ URL)", + "Raster DEM (TileJSON URL)": "Raster DEM (TileJSON URL)", + "Raster DEM (XYZ URLs)": "Raster DEM (XYZ URLs)", + "Image": "Bild", + "Video": "Video", + "Add Source": "Quelle hinzufügen", + "Sources": "Quellen", + "Active Sources": "Aktive Quellen", + "Choose Public Source": "Öffentliche Quelle auswählen", + "Add one of the publicly available sources to your style.": "Füge eine der öffentlich verfügbaren Quellen zu deinem Stil hinzu.", + "Add New Source": "Neue Quelle hinzufügen", + "Add a new source to your style. You can only choose the source type and id at creation time!": "Füge eine neue Quelle zu deinem Stil hinzu. Du kannst den Quellentyp und die ID nur bei der Erstellung auswählen!", + "TileJSON URL": "TileJSON URL", + "Tile URL": "Kachel-URL", + "Coord top left": "Koordinate oben links", + "Coord top right": "Koordinate oben rechts", + "Coord bottom right": "Koordinate unten rechts", + "Coord bottom left": "Koordinate unten links", + "Image URL": "Bild-URL", + "Video URL": "Video-URL", + "GeoJSON URL": "GeoJSON URL", + "GeoJSON": "GeoJSON", + "Cluster": "Cluster", + "Encoding": "Kodierung", + "Error:": "Fehler:", + "MapTiler Access Token": "MapTiler Zugriffstoken", + "Public access token for MapTiler Cloud.": "Öffentlicher Zugriffstoken für MapTiler Cloud.", + "Thunderforest Access Token": "Thunderforest Zugriffstoken", + "Public access token for Thunderforest services.": "Öffentlicher Zugriffstoken für Thunderforest-Dienste.", + "Style Renderer": "Stil-Renderer", + "Choose the default Maputnik renderer for this style.": "Wähle den Standard-Renderer für diesen Stil aus.", + "Language": "Sprache", + "Press <1>ESC to lose focus of any input box": "Drück <1>ESC, um den Fokus von jedem Eingabefeld zu verlieren" +}