Mysql
 sql >> база данни >  >> RDS >> Mysql

Многоезичен уебсайт с най-добри практики

Предпоставка на темата

Има три различни аспекта в многоезичен сайт:

  • превод на интерфейс
  • съдържание
  • URL маршрутизиране

Въпреки че всички те са свързани помежду си по различни начини, от гледна точка на CMS те се управляват с помощта на различни елементи на потребителския интерфейс и се съхраняват по различен начин. Изглежда сте уверени в изпълнението и разбирането на първите две. Въпросът беше за последния аспект - „Превод на URL адрес? Трябва ли да направим това или не? и по какъв начин?“

От какво може да бъде направен URL адресът?

Много важно нещо е, не се захващайте с IDN . Вместо това предпочитайте транслитерация (също:транскрипция и романизация). Въпреки че на пръв поглед IDN изглежда жизнеспособна опция за международни URL адреси, тя всъщност не работи както се рекламира по две причини:

  • някои браузъри ще променят символите, различни от ASCII, като 'ч' или 'ž' в '%D1%87' и '%C5%BE'
  • ако потребителят има персонализирани теми, е много вероятно шрифтът на темата да няма символи за тези букви.

Всъщност се опитах да подходя към IDN преди няколко години в проект, базиран на Yii (ужасна рамка, IMHO). Срещнах и двата гореспоменати проблема, преди да изстържем това решение. Освен това подозирам, че може да е вектор на атака.

Налични опции ... както ги виждам.

По принцип имате два избора, които могат да се абстрахират като:

  • http://site.tld/[:query] :където [:query] определя избора както на език, така и на съдържание

  • http://site.tld/[:language]/[:query] :където [:language] част от URL дефинира избора на език и [:query] се използва само за идентифициране на съдържанието

Заявката е Α и Ω ..

Да приемем, че изберете http://site.tld/[:query] .

В този случай имате един основен източник на език:съдържанието на [:query] сегмент; и два допълнителни източника:

  • стойност $_COOKIE['lang'] за този конкретен браузър
  • списък с езици в заглавката на HTTP Accept-Language

Първо, трябва да съпоставите заявката с един от дефинираните модели за маршрутизиране (ако вашият избор е Laravel, тогава прочетете тук ). При успешно съвпадение на шаблона трябва да намерите езика.

Ще трябва да преминете през всички сегменти на шаблона. Намерете потенциалните преводи за всички тези сегменти и определете кой език е бил използван. Двата допълнителни източника (бисквитка и заглавка) ще бъдат използвани за разрешаване на конфликти при маршрутизиране, когато (а не „ако“) възникнат.

Вземете например:http://site.tld/blog/novinka .

Това е транслитерация на "блог, новинка" , което на английски означава приблизително "blog", "latest" .

Както вече можете да забележите, на руски "блог" ще се транслитерира като "блог". Което означава, че за първата част на [:query] вие (в най-добрия случай ) ще завърши с ['en', 'ru'] списък с възможни езици. След това взимате следващия сегмент - "новинка". Това може да има само един език в списъка с възможности:['ru'] .

Когато списъкът има един елемент, успешно сте намерили езика.

Но ако се окажете с 2 (пример:руски и украински) или повече възможности .. или 0 възможности, според случая. Ще трябва да използвате бисквитка и/или заглавка, за да намерите правилната опция.

И ако всичко друго не успее, вие избирате езика по подразбиране на сайта.

Език като параметър

Алтернативата е да използвате URL, който може да бъде дефиниран като http://site.tld/[:language]/[:query] . В този случай, когато превеждате заявка, не е необходимо да отгатвате езика, защото в този момент вече знаете кой да използвате.

Има и вторичен източник на език:стойността на бисквитката. Но тук няма смисъл да се забърквате със заглавката Accept-Language, защото не се занимавате с неизвестно количество възможни езици в случай на „студен старт“ (когато потребителят за първи път отвори сайта с персонализирана заявка).

Вместо това имате 3 прости, приоритетни опции:

  1. if [:language] сегментът е зададен, използвайте го
  2. if $_COOKIE['lang'] е зададен, използвайте го
  3. използвайте език по подразбиране

Когато имате езика, просто се опитвате да преведете заявката и ако преводът не успее, използвайте „стойността по подразбиране“ за този конкретен сегмент (въз основа на резултатите от маршрутизирането).

Тук ли не е трета опция?

Да, технически можете да комбинирате и двата подхода, но това би усложнило процеса и би настанило само хора, които искат ръчно да променят URL адреса на http://site.tld/en/news до http://site.tld/de/news и очаквайте страницата с новини да се промени на немски.

Но дори и този случай вероятно може да бъде смекчен с помощта на стойност на бисквитки (която ще съдържа информация за предишния избор на език), за да се приложи с по-малко магия и надежда.

Кой подход да използвате?

Както може би вече се досещате, бих препоръчал http://site.tld/[:language]/[:query] като по-разумния вариант.

Също така в ситуация с реална дума ще имате 3-та основна част в URL:"title". Както в името на продукта в онлайн магазина или заглавието на статия в новинарския сайт.

Пример:http://site.tld/en/news/article/121415/EU-as-global-reserve-currency

В този случай '/news/article/121415' ще бъде заявката, а 'EU-as-global-reserve-currency' е заглавие. Чисто за SEO цели.

Може ли да се направи в Laravel?

Донякъде, но не по подразбиране.

Не съм много запознат с него, но от това, което видях, Laravel използва прост механизъм за маршрутизиране, базиран на шаблони. За да внедрите многоезични URL адреси, вероятно ще трябва да разширите основни клас(ове) , тъй като многоезичното маршрутизиране се нуждае от достъп до различни форми на съхранение (база данни, кеш и/или конфигурационни файлове).

Препратен е. Какво сега?

В резултат на всичко ще получите две ценни части информация:текущ език и преведени сегменти от заявката. След това тези стойности могат да се използват за изпращане до класа(овете), които ще произведат резултата.

По принцип следният URL адрес:http://site.tld/ru/blog/novinka (или версията без '/ru' ) се превръща в нещо като

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

Което просто използвате за изпращане:

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

.. или някаква негова вариация, в зависимост от конкретната реализация.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как мога да намеря не-ASCII знаци в MySQL?

  2. Достъпът е отказан за потребител 'root'@'localhost' с PHPMyAdmin

  3. Светият граал на почистването на входа и изхода в php?

  4. Какво е обратното на GROUP_CONCAT в MySQL?

  5. 1114 (HY000):Масата е пълна