Prémisse du sujet
Il y a trois aspects distincts dans un site multilingue :
- traduction de l'interface
- contenu
- routage d'URL
Bien qu'ils soient tous interconnectés de différentes manières, du point de vue du CMS, ils sont gérés à l'aide d'éléments d'interface utilisateur différents et stockés différemment. Vous semblez confiant dans votre mise en œuvre et votre compréhension des deux premiers. La question portait sur ce dernier aspect - "Traduction d'URL ? Devrions-nous le faire ou non ? et de quelle manière ?"
De quoi peut être composée l'URL ?
Une chose très importante est de ne pas être fantaisiste avec IDN . Privilégiez plutôt la la translittération (aussi :transcription et romanisation). Bien qu'à première vue, l'IDN semble une option viable pour les URL internationales, il ne fonctionne pas comme annoncé pour deux raisons :
- certains navigateurs transformeront les caractères non-ASCII comme
'ч'
ou'ž'
en'%D1%87'
et'%C5%BE'
- si l'utilisateur a des thèmes personnalisés, la police du thème est très susceptible de ne pas avoir de symboles pour ces lettres
J'ai en fait essayé l'approche IDN il y a quelques années dans un projet basé sur Yii (horrible framework, IMHO). J'ai rencontré les deux problèmes mentionnés ci-dessus avant de gratter cette solution. De plus, je soupçonne qu'il pourrait s'agir d'un vecteur d'attaque.
Options disponibles... telles que je les vois.
Fondamentalement, vous avez deux choix, qui pourraient être résumés comme :
-
http://site.tld/[:query]
:où[:query]
détermine à la fois la langue et le choix du contenu -
http://site.tld/[:language]/[:query]
:où[:language]
une partie de l'URL définit le choix de la langue et[:query]
sert uniquement à identifier le contenu
La requête est Α et Ω ..
Disons que vous choisissez http://site.tld/[:query]
.
Dans ce cas, vous disposez d'une source principale de langage :le contenu de [:query]
segment; et deux sources supplémentaires :
- valeur
$_COOKIE['lang']
pour ce navigateur particulier - liste des langues dans l'en-tête HTTP Accept-Language
Tout d'abord, vous devez faire correspondre la requête à l'un des modèles de routage définis (si votre choix est Laravel, alors lire ici ). En cas de correspondance réussie du modèle, vous devez ensuite trouver la langue.
Vous auriez à parcourir tous les segments du motif. Trouvez les traductions potentielles pour tous ces segments et déterminez la langue utilisée. Les deux sources supplémentaires (cookie et en-tête) seraient utilisées pour résoudre les conflits de routage, lorsqu'ils surviennent (et non "si").
Prenons par exemple :http://site.tld/blog/novinka
.
C'est la translittération de "блог, новинка"
, qui signifie en anglais approximativement "blog", "latest"
.
Comme vous pouvez déjà le remarquer, en russe "блог" sera translittéré en "blog". Ce qui signifie que pour la première partie de [:query]
vous (dans le meilleur scénario ) finira par ['en', 'ru']
liste des langues possibles. Ensuite, vous prenez le segment suivant - "novinka". Cela pourrait n'avoir qu'une seule langue sur la liste des possibilités :['ru']
.
Lorsque la liste contient un élément, vous avez réussi à trouver la langue.
Mais si vous vous retrouvez avec 2 (exemple :Russe et Ukrainien) ou plus de possibilités .. ou 0 possibilités, selon le cas. Vous devrez utiliser un cookie et/ou un en-tête pour trouver la bonne option.
Et si tout le reste échoue, vous choisissez la langue par défaut du site.
Langue comme paramètre
L'alternative est d'utiliser l'URL, qui peut être définie comme http://site.tld/[:language]/[:query]
. Dans ce cas, lors de la traduction de la requête, vous n'avez pas besoin de deviner la langue, car à ce stade, vous savez déjà laquelle utiliser.
Il existe également une source secondaire de langage :la valeur du cookie. Mais ici, il est inutile de jouer avec l'en-tête Accept-Language, car vous n'avez pas affaire à un nombre inconnu de langues possibles en cas de "démarrage à froid" (lorsque l'utilisateur ouvre le site pour la première fois avec une requête personnalisée).
À la place, vous disposez de 3 options simples et hiérarchisées :
- si
[:language]
segment est défini, utilisez-le - si
$_COOKIE['lang']
est défini, utilisez-le - utiliser la langue par défaut
Lorsque vous avez la langue, vous essayez simplement de traduire la requête, et si la traduction échoue, utilisez la "valeur par défaut" pour ce segment particulier (en fonction des résultats de routage).
N'y a-t-il pas ici une troisième option ?
Oui, techniquement, vous pouvez combiner les deux approches, mais cela compliquerait le processus et n'accueillerait que les personnes qui souhaitent modifier manuellement l'URL de http://site.tld/en/news
à http://site.tld/de/news
et attendez-vous à ce que la page d'actualités passe en allemand.
Mais même ce cas pourrait probablement être atténué en utilisant la valeur du cookie (qui contiendrait des informations sur le choix de langue précédent), à mettre en œuvre avec moins de magie et d'espoir.
Quelle approche utiliser ?
Comme vous l'avez peut-être déjà deviné, je recommanderais http://site.tld/[:language]/[:query]
comme l'option la plus sensée.
De plus, dans une situation de mot réel, vous auriez la 3e partie majeure de l'URL :"titre". Comme dans le nom du produit dans la boutique en ligne ou le titre de l'article dans le site d'actualités.
Exemple :http://site.tld/en/news/article/121415/EU-as-global-reserve-currency
Dans ce cas '/news/article/121415'
serait la requête, et le 'EU-as-global-reserve-currency'
est le titre. Uniquement à des fins de référencement.
Cela peut-il être fait dans Laravel ?
Un peu, mais pas par défaut.
Je ne le connais pas trop, mais d'après ce que j'ai vu, Laravel utilise un mécanisme de routage simple basé sur des modèles. Pour implémenter des URL multilingues, vous devrez probablement étendre la ou les classes principales , car le routage multilingue nécessite l'accès à différentes formes de stockage (base de données, cache et/ou fichiers de configuration).
Il est acheminé. Et maintenant ?
À la suite de tout cela, vous vous retrouveriez avec deux informations précieuses :la langue actuelle et les segments de requête traduits. Ces valeurs peuvent ensuite être utilisées pour envoyer à la ou aux classes qui produiront le résultat.
En gros, l'URL suivante :http://site.tld/ru/blog/novinka
(ou la version sans '/ru'
) se transforme en quelque chose comme
$parameters = [
'language' => 'ru',
'classname' => 'blog',
'method' => 'latest',
];
Que vous utilisez juste pour l'expédition :
$instance = new {$parameter['classname']};
$instance->{'get'.$parameters['method']}( $parameters );
.. ou une variante de celui-ci, selon l'implémentation particulière.