sql >> Database >  >> RDS >> Mysql

Best practice meertalige website

Het uitgangspunt van het onderwerp

Er zijn drie verschillende aspecten in een meertalige site:

  • interface vertaling
  • inhoud
  • url-routering

Hoewel ze allemaal op verschillende manieren met elkaar verbonden zijn, worden ze vanuit CMS-oogpunt beheerd met verschillende UI-elementen en anders opgeslagen. U lijkt vertrouwen te hebben in uw implementatie en begrip van de eerste twee. De vraag ging over het laatste aspect - "URL-vertaling? Moeten we dit doen of niet? en op welke manier?"

Waar kan de URL van gemaakt zijn?

Een heel belangrijk ding is dat je geen zin hebt in IDN . Geef in plaats daarvan de voorkeur aan transliteratie (ook:transcriptie en romanisering). Hoewel IDN op het eerste gezicht een haalbare optie lijkt voor internationale URL's, werkt het om twee redenen niet zoals geadverteerd:

  • sommige browsers zetten de niet-ASCII-tekens om, zoals 'ч' of 'ž' in '%D1%87' en '%C5%BE'
  • als de gebruiker aangepaste thema's heeft, bevat het lettertype van het thema hoogstwaarschijnlijk geen symbolen voor die letters

Ik heb een paar jaar geleden geprobeerd IDN te benaderen in een op Yii gebaseerd project (horrible framework, IMHO). Ik kwam beide bovengenoemde problemen tegen voordat ik die oplossing schrapte. Ik vermoed ook dat het een aanvalsvector zou kunnen zijn.

Beschikbare opties ... zoals ik ze zie.

In principe heb je twee keuzes, die kunnen worden geabstraheerd als:

  • http://site.tld/[:query] :waar [:query] bepaalt zowel de taal- als de inhoudskeuze

  • http://site.tld/[:language]/[:query] :waar [:language] een deel van de URL definieert de taalkeuze en [:query] wordt alleen gebruikt om de inhoud te identificeren

Query is Α en Ω ..

Stel dat u http://site.tld/[:query] . kiest .

In dat geval heb je één primaire taalbron:de inhoud van [:query] segment; en twee extra bronnen:

  • waarde $_COOKIE['lang'] voor die specifieke browser
  • lijst met talen in HTTP Accept-Language header

Eerst moet u de zoekopdracht afstemmen op een van de gedefinieerde routeringspatronen (als uw keuze Laravel is, lees hier ). Als het patroon met succes overeenkomt, moet u de taal vinden.

Je zou door alle segmenten van het patroon moeten gaan. Vind de mogelijke vertalingen voor al die segmenten en bepaal welke taal is gebruikt. De twee extra bronnen (cookie en header) zouden worden gebruikt om routeringsconflicten op te lossen, wanneer (niet "als") ze zich voordoen.

Neem bijvoorbeeld:http://site.tld/blog/novinka .

Dat is de transliteratie van "блог, новинка" , dat in het Engels ongeveer "blog", "latest" . betekent .

Zoals je al kunt zien, wordt "блог" in het Russisch getranscribeerd als "blog". Wat betekent dat voor het eerste deel van [:query] jij (in het beste scenario ) zal eindigen met ['en', 'ru'] lijst met mogelijke talen. Dan neem je het volgende segment - "novinka". Dat heeft misschien maar één taal op de lijst met mogelijkheden:['ru'] .

Als de lijst één item bevat, heb je de taal gevonden.

Maar als je 2 (voorbeeld:Russisch en Oekraïens) of meer mogelijkheden krijgt.. of 0 mogelijkheden, evt. U moet een cookie en/of header gebruiken om de juiste optie te vinden.

En als al het andere faalt, kies je de standaardtaal van de site.

Taal als parameter

Het alternatief is om een ​​URL te gebruiken, die kan worden gedefinieerd als http://site.tld/[:language]/[:query] . In dit geval hoeft u bij het vertalen van de zoekopdracht de taal niet te raden, omdat u op dat moment al weet welke u moet gebruiken.

Er is ook een secundaire taalbron:de cookiewaarde. Maar hier heeft het geen zin om te knoeien met de Accept-Language-header, omdat je niet te maken hebt met een onbekend aantal mogelijke talen in het geval van een "koude start" (wanneer de gebruiker de site voor het eerst opent met een aangepaste query).

In plaats daarvan heb je 3 eenvoudige, geprioriteerde opties:

  1. if [:language] segment is ingesteld, gebruik het
  2. if $_COOKIE['lang'] is ingesteld, gebruik het
  3. gebruik standaardtaal

Als je de taal hebt, probeer je gewoon de zoekopdracht te vertalen, en als de vertaling mislukt, gebruik je de "standaardwaarde" voor dat specifieke segment (gebaseerd op routeringsresultaten).

Is hier geen derde optie?

Ja, technisch gezien kun je beide benaderingen combineren, maar dat zou het proces bemoeilijken en alleen geschikt zijn voor mensen die de URL van http://site.tld/en/news handmatig willen wijzigen. naar http://site.tld/de/news en verwacht dat de nieuwspagina in het Duits verandert.

Maar zelfs dit geval kan waarschijnlijk worden verzacht door de cookiewaarde (die informatie zou bevatten over eerdere taalkeuze) te gebruiken om met minder magie en hoop te implementeren.

Welke aanpak te gebruiken?

Zoals je misschien al geraden had, raad ik http://site.tld/[:language]/[:query] aan als de meest verstandige optie.

Ook in de echte woordsituatie zou je het 3e hoofddeel in de URL hebben:"titel". Zoals in de naam van het product in de online winkel of de kop van het artikel op de nieuwssite.

Voorbeeld:http://site.tld/en/news/article/121415/EU-as-global-reserve-currency

In dit geval '/news/article/121415' zou de query zijn, en de 'EU-as-global-reserve-currency' titel is. Puur voor SEO-doeleinden.

Kan het in Laravel?

Een beetje, maar niet standaard.

Ik ben er niet zo bekend mee, maar van wat ik heb gezien, gebruikt Laravel een eenvoudig op patronen gebaseerd routeringsmechanisme. Om meertalige URL's te implementeren, moet u waarschijnlijk kernklasse(n) uitbreiden , omdat meertalige routering toegang nodig heeft tot verschillende vormen van opslag (database, cache en/of configuratiebestanden).

Het is gerouteerd. Wat nu?

Als resultaat van dit alles zou je eindigen met twee waardevolle stukjes informatie:de huidige taal en vertaalde segmenten van de zoekopdracht. Deze waarden kunnen vervolgens worden gebruikt om naar de klasse(n) te verzenden die het resultaat zullen produceren.

Kortom, de volgende URL:http://site.tld/ru/blog/novinka (of de versie zonder '/ru' ) verandert in iets als

$parameters = [
   'language' => 'ru',
   'classname' => 'blog',
   'method' => 'latest',
];

Die je alleen gebruikt voor verzending:

$instance = new {$parameter['classname']};
$instance->{'get'.$parameters['method']}( $parameters );

.. of een variatie ervan, afhankelijk van de specifieke implementatie.



  1. GROUP BY in de clausule UPDATE FROM

  2. datagrip Kan geen wijzigingen toepassen Deze tabel is alleen-lezen. Wijzigingen in de celeditor kunnen niet worden toegepast

  3. SQL Server 2016:Queryresultaten opslaan in een CSV-bestand

  4. Bereken het tijdsverschil tussen twee rijen