Einführung
Im Rahmen meines Projekts stand ich vor der Aufgabe, die aktuelle Website des Unternehmens mehrsprachig zu gestalten. Genauer gesagt: um die Möglichkeit zu schaffen, die Website schnell und einfach ins Englische, Polnische, Italienische usw. zu übersetzen.
Eine Suche im Internet ergab, dass die vorhandenen Optionen zum Erstellen einer mehrsprachigen Website äußerst umfangreich und ineffizient sind. Das Verbinden von Bibliotheken von Drittanbietern ist häufig problematisch, und Tipps zum Schreiben Ihrer Lösung sind mit einem großen Arbeitsaufwand des gleichen Typs verbunden.
Das Schreiben einer alternativen Methode zum Ändern des Gebietsschemas dauerte nur wenige Stunden, und die Beibehaltung der semantischen Einheit minimiert die Änderungen beim Hinzufügen neuer Seiten vollständig.
Die Quelldateien für die Beispielseite mit automatischer Übersetzung können
auf github heruntergeladen
werdenBestehende Alternativen
Als die Aufgabe gerade in der Entwicklung auftauchte, bestand der erste Schritt natürlich darin, vorgefertigte Lösungen und Tipps in den Foren zu studieren, wie die Möglichkeit einer Änderung des Gebietsschemas am einfachsten und korrektesten implementiert werden kann. Die beliebtesten Internetquellen zum Erstellen mehrsprachiger Websites bieten die folgenden Lösungen:
- Erstellen doppelter HTML-Blöcke mit Text in verschiedenen Sprachen, von denen nur einer für den Benutzer aktiv bleibt und der Rest ausgeblendet ist (Anzeige: keine).
Der offensichtliche Nachteil dieser Methode ist die unglaublich schnelle Zunahme des Codes und ein sofortiger Verlust der Lesbarkeit und Wartbarkeit des Codes. Darüber hinaus ist diese Lösung anfällig für Textfehler und Skalierbarkeit in Bezug auf die Erhöhung der Anzahl der Sprachen (im Folgenden als Gebietsschemas bezeichnet).
- Verbinden eines maschinellen Übersetzungsdienstes eines Drittanbieters (z. B. Google Übersetzer) mit vielen integrierten Sprachen und minimalen Änderungen am Quellcode der Seite.
Als die Aufgabe zum ersten Mal in der Aufgabenliste angezeigt wurde, haben wir diese Methode als die offensichtlichste und bequemste verwendet. Die Erfahrung mit Muttersprachlern aus den USA und Israel hat jedoch gezeigt, dass die maschinelle Übersetzung beim Ändern des Gebietsschemas häufig Fehler macht und die Benutzer der Website sehr scharf darauf reagieren Übersetzungsfehler. Am Ende rieten die strategischen Partner nachdrücklich, die Methode zum Ändern des Gebietsschemas zu ändern, und diese Methode musste aufgegeben werden.
- Ändern der Sprache mithilfe der Funktionen von js oder Bibliotheken / Frameworks von Drittanbietern wie jQuery basierend auf der Suche und direkten Änderung von DOM-Elementen.
Ein Merkmal dieses Ansatzes ist die Suche nach einer großen Anzahl von js-Selektoren, deren Text ersetzt werden muss. Dieser Ansatz mag für kleine Projekte gut funktionieren, aber mit zunehmender Anzahl von Seiten nimmt die Anzahl von Textersetzungsfunktionen proportional zu, was bei großen Projekten zu einem Effizienzverlust führt.
Alternative Lösung
Die Grundlage des von mir vorgeschlagenen Ansatzes als Alternative zu bestehenden Methoden ist seltsamerweise nicht die von mir geschriebene Basis, die im Allgemeinen trivial ist, und das Design von Selektoren, deren Unterstützung es Ihnen ermöglicht, die Übersetzung einer beliebigen Anzahl von Seiten in eine beliebige Sprache ohne diese flexibel und einfach zu konfigurieren Änderungen der Codebasis und übermäßige Duplizierung von Daten.
Bei der Änderung des Gebietsschemas mit einem alternativen Ansatz werden drei Hauptakteure unterschieden:
- HTML-Seite mit der festgelegten Regel für Blockselektoren mit Text
- Allgemeiner js-Dienst, dessen Hauptaufgabe darin besteht, textContet-DOM-Elemente gemäß der Selektorentwurfsregel zu ersetzen
- JSON-Datei für das Gebietsschema, die eine Struktur enthält, die HTML-Blöcke in allen Sprachen enthält, die beim Ändern des Gebietsschemas verwendet werden
Durch die Einhaltung der Entwurfsregeln für Selektoren veränderlicher Elemente muss der js-Code des Gebietsschema-Änderungsdienstes nicht mehr geändert werden. Dies ist ein großes Plus in Bezug auf die Skalierbarkeit des Projekts.
Die Regel zum Erstellen von Selektoren
Die meisten Methoden zum Ändern des Seitengebietsschemas (unter den Alternativen 1.3 und teilweise 2) schlagen vor, dass Sie den zu ändernden HTML-Block auf irgendeine Weise „markieren“ müssen, da dies durch Ändern des Klassenfelds korrekt ist. Der gleiche Mechanismus verwendet eine alternative Option.
Der erste Schritt beim Entwerfen von Selektoren besteht darin, die Quellseite in Funktionsblöcke der obersten Ebene aufzuteilen. Auf der Seite unseres Unternehmens befinden sich Blöcke:
Wir geben jedem Block einen bedingten Namen, zum Beispiel
Menü
Visitenkarte (zu Hause)
Beispiel für einen Servicebetrieb (Beispiel)
Partner (Kunden)
Servicebereich (userfulBlock)
Beispiele für den Service (Beispiele)
Kontakte und Feedback (Kontakte)
Danach teilen wir jeden Block weiter in kleinere Funktionsblöcke auf, wie dies bei der React-Bibliothek der Fall ist.
Wir weisen den ausgewählten Bereichen unsere Namen zu und erhalten eine Struktur des Formulars:
Menü
Hauptleitung, Beschreibung, Tasten
Beispielstatistik , Überschrift, Beschreibung, Schaltflächen
Client- Schaltflächen
userfulBlock- Überschrift, userfulCards, elseBlock
Beispiele Überschrift, Karten
Kontakte Überschrift, Beschreibung, Kontakte, Formular
Wir setzen diesen Vorgang fort, bis wir die Blöcke erreichen, die den Quelltext enthalten.
Als Ergebnis erhalten wir eine vorgefertigte JSON-Dateistruktur für das Gebietsschema, die alle erforderlichen Texte zum Ändern der Sprache enthält. Basierend auf diesem Algorithmus wird auch die Regel zum Erstellen von Selektoren bestimmt:
Jeder Selektor beginnt mit dem Schlüsselwort locale, und dann werden gemäß dem Strich-Groß- / Kleinschreibung-Stil die Namen aller übergeordneten Blöcke hinzugefügt, einschließlich des Blocks, der den Quelltext enthält. Beispielsweise enthält die Beispielbeschreibung auf der ersten Karte den Selektor für das Gebietsschema-Beispielkartenbeschreibung
Ein Beispiel für die resultierende Gebietsschema-JSON-Datei ist
auf Github zu sehen
Gebietsschema-Änderungsdienst
Der Gebietsschemaänderungsdienst ist ein Modul, das die Funktion zum Laden einer Gebietsschemadatei enthält
loadLocale(defLang)
mit dem optionalen Parameter defLang - die nach dem Laden des Gebietsschemas festgelegte Sprache (Standardsprache) sowie die Hauptfunktion zum Ändern des aktuellen Gebietsschemas
changeLocale(lang)
Angabe der gewünschten Sprache.
Gebietsschema-Download-Funktion
Die Funktion zum Laden des Gebietsschemas verwendet die Standardanforderung XMLHttpRequest für Daten. Die Verwendung dieses Standards beruht auf dem Wunsch, die Anzahl der Abhängigkeiten und die Benutzerfreundlichkeit der Anforderung zu minimieren. Nach dem Empfang der Gebietsschemadatei wird in der Konsole eine Benachrichtigung über den Empfang von Daten angezeigt, und die Funktion zum Ändern des Gebietsschemas in die Standardsprache wird aufgerufen, wenn diese Sprache als optionaler Parameter an die Funktion übergeben wurde. Hier können Sie sich mit dem Funktionscode vertraut machen:
function loadLocale(defLang) { var xhr = new XMLHttpRequest(); xhr.open("GET", 'http://localhost:3000/locale.json', true); xhr.onreadystatechange = saveLocale.bind(this); xhr.onerror = function () { console.log("no found page"); }; xhr.send(); function saveLocale() { if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) { locale = JSON.parse(xhr.responseText); console.log("locale loaded"); if(defLang) changeLocale(defLang); } } }
Gebietsschemaänderungsfunktion
Datentypen
Es ist eine rekursive Funktion, deren Hauptaufgabe darin besteht, das Objekt mit dem Seitengebietsschema zu durchlaufen (unter Verwendung des DFS-Algorithmus). Durch die Verwendung der Rekursion beim Erstellen einer Funktion können Sie den Algorithmus so einfach und präzise wie möglich codieren. Eine zu große Rekursionstiefe kann jedoch zu einem Stapelüberlauf führen. Funktionen zur Umgehung dieses Problems finden Sie im gleichnamigen Forum oder in den entsprechenden Artikeln auf habr.com.
Die rekursive Funktion basiert auf der Verarbeitung von 4 Datentypen:
- Feld mit einer Quelltextzeichenfolge, die zum Hinzufügen zur Seite verwendet wird.
Zum Beispiel:
"main": " "
- Feld mit einem Array von Quelltextzeilen, die zum Hinzufügen verwendet werden
Seite. Dieses Feld ist erforderlich, um Listen zu erstellen, deren Elemente geändert werden können.
bestellen. Zum Beispiel:
"menu":["Home","Example","Clients","Info","Contacts"]
- Verschachtelte Datenstruktur mit eigenen Feldern, die zum Erstellen benötigt werden
Seitenarchitektur. Zum Beispiel:
"home": { "main": "selling quest from your video", "description": "for social networks & sites", "buttons": ["try","order"] }
- Ein Array verschachtelter Datenstrukturen mit denselben verwendeten Feldern. So.
Arrays werden verwendet, wenn Listen identischer Codeblöcke angezeigt werden, z.
Karten von Teammitgliedern oder Portfolio oder Tarife für erbrachte Dienstleistungen.
Zum Beispiel:
"usefulCards": [ { "headline": "Marketers and agencies", "statistics": ["convers 26%", "retent 25%"], "button": "ORDER" }, { "headline": "Production studios and TV platforms", "statistics": ["convers 24%", "retent 33%"], "button": "ORDER" }, { "headline": "Conference creators", "statistics": ["convers 65%", "retent 15%"], "button": "ORDER" }, { "headline": "Bloggers and streamers", "statistics": ["convers 24%", "retent 33%"], "button": "ORDER" } ],
Auf einer Site könnte es so aussehen:
Verarbeitungsfunktionen
Die Verarbeitung des Quelldatentyps wird von einer separaten Funktion ausgeführt
function getText(key, object, name,startIndex)
Der Eingabefeldname des Strukturfelds mit dem Quelltext, das aktuelle Gebietsschemaobjekt, das den hinzuzufügenden Text enthält, und der aktuelle Auswahlname, der für die Suche nach dem DOM-Element erforderlich ist.
function getText(key, object, name, startIndex) { var elementKey=0; if(startIndex) elementKey = startIndex; for ( ; elementKey < document.getElementsByClassName(name + "-" + key).length; elementKey++) if (!isNaN(elementKey)) document.getElementsByClassName(name + "-" + key)[elementKey].textContent = object[key]; }
Die Verarbeitung eines Arrays von Strings mit Quelltext erfolgt ebenfalls über eine separate Funktion
function getArrayText(key, object, name,startIndex)
Die Signatur und der Hauptteil dieser Funktion unterscheiden sich nicht von der Vergangenheit, außer dass die Elemente aus dem Array den DOM-Elementen zugewiesen sind.
function getArrayText(key, object, name, startIndex) { var elementKey=0; if(startIndex) elementKey = startIndex; for ( ; elementKey < document.getElementsByClassName(name + "-" + key).length; elementKey++) if (!isNaN(elementKey)) document.getElementsByClassName(name + "-" + key)[elementKey].textContent = object[key][elementKey % object[key].length]; }
Die rekursive Hauptfunktion zum Ersetzen von Text befasst sich mit der Klassifizierung des aktuellen Gebietsschemafelds in einen der vier oben genannten Typen und der entsprechenden Reaktion auf den resultierenden Typ:
function changeText(name, object, startIndex) { for (key in object) if (Array.isArray(object[key]) && typeof object[key] != 'string' && typeof object[key][0] == 'string') getArrayText(key, object, name); else if (typeof object[key] == "object" ){ if(isNaN(key)) changeText(name + "-" + key, object[key]); else changeText(name, object[key],key); } else getText(key, object, name, startIndex); }
Diese Funktion akzeptiert das aktuelle Sprachgebietsschema und den Stammselektor (in diesem Fall „Gebietsschema“). Ferner ruft sich die Funktion beim Erkennen einer verschachtelten Struktur oder eines Arrays von Strukturen rekursiv auf und ändert die Eingabeparameter entsprechend.
Der Hauptvorteil des alternativen Ansatzes besteht darin, dass der oben beschriebene Dienst keine funktionalen Änderungen erfordert und unter Verwendung der von Ihnen erstellten Gebietsschemadatei als js-Datei hinzugefügt wird.
Fazit
Das Wesentliche des oben beschriebenen Ansatzes ist eine feste Regel zum Beschreiben von Selektoren und zum Erstellen einer Gebietsschemadatei. Dank dessen gibt es eine einzigartige Möglichkeit, alle Seiten sofort zu übersetzen und bereits übersetztes Material wiederzuverwenden.
Der oben beschriebene Algorithmus zum Aufbau der Selektoren ist nicht obligatorisch und für den Dienst kritisch. Der Dienst ist flexibel zum Erweitern und Hinzufügen neuer Methoden und Algorithmen sowie zum Erstellen von Selektornamen und JSON-Gebietsschemastrukturen. Ein mögliches Plus wäre, das Gebietsschema im Browser-Cookie zu speichern und das Gebietsschema abhängig vom Standort des Benutzers des Dienstes zu ändern.
Die Quelldateien für die Beispielseite mit automatischer Übersetzung können
auf github heruntergeladen
werden .