Как работать с интернационализацией маршрутизации в Symfony 3 с помощью BeSimpleI18nRoutingBundle

В настоящее время многие компании нуждаются в поддержке клиентов со всего мира. К сожалению, не все говорят на одном языке, так что это небольшое ограничение, но не для рынка и не для разработчиков. Создание интернационализированных и локализованных приложений никогда не было легкой задачей, поэтому существует также множество инструментов, которые предоставляют вам простые способы добавления многоязычной поддержки для веб-сайтов и приложений. Но не многие предоставляют вам инструменты для интернационализации маршрутов ваших сайтов, поэтому они также получают выгоду от SEO. BeSimpleI18nRoutingBundle — это полезный инструмент, который поможет вам избежать копирования и вставки ваших маршрутов для разных языков. Кроме того, он позволяет транслировать данные параметры маршрутизации между языками в Router # match и UrlGenerator # генерировать, используя либо Symfony Translator, либо Doctrine DBAL (+ Cache) на основе бэкэнда.

Хотя объяснение этого подхода в этой статье может не соответствовать всем требованиям к очень сложному приложению (то, что делает пакет), оно довольно полезно для людей, которые используют Symfony только для создания веб-сайтов или приложений, для которых не требуются довольно сложные определения маршрутов. Однако не забывайте, что пакет поддерживает сложные шаблоны, например, с переводом слагов с использованием вашей собственной базы данных, поэтому обязательно читать документацию библиотеки.

1. Установите BeSimpleI18nRoutingBundle

Установите пакет с помощью composer, выполнив следующую команду:

composer require besimple/i18n-routing-bundle

После установки пакета вы сможете настроить маршруты. Для получения дополнительной информации об этом комплекте и документации, пожалуйста, посетите официальный репозиторий на Github здесь.

2. Настройте локали по умолчанию в вашем приложении

На втором этапе вам нужно определить, какие языки будут поддерживать маршрутизацию вашего приложения. Мы определим 2 параметра в config.yml файл вашего проекта с двумя именами, а именно, локаль (обычно локаль уже определена) и локали, в которых указывается, какие локали поддерживаются вашим приложением, поскольку вы явно не будете перенаправлять на страницу с русской локалью, если вы не поддерживаете этот язык. В этом примере мы обеспечим поддержку английского, французского, испанского и немецкого языков, поэтому определите параметры в своем config.yml:

parameters:
locale: en
locales: en|fr|es|de

Кроме того, вы должны быть уверены, что даете ответ на вопрос «Что делать, если локаль пользователя не была определена?» предоставив в качестве локали по умолчанию ту же опцию, что и для параметра локали (config.yml также):

framework:
# Set those properties with the locale parameter
translator: { fallbacks: ['%locale%'] }
default_locale: '%locale%'

При такой конфигурации наше приложение будет использовать в качестве локали по умолчанию английский язык всегда, если локаль пользователя не указана в URL. Наконец, вам нужно указать те же локали, но в формате массива в поддерживаемом свойстве be_simple_i18n_routing:

# app/config/config.yml
be_simple_i18n_routing:
locales:
supported: ['en', 'es', 'fr', 'de']
filter: true
strict: true

Этот пакет также работает в более старых версиях Symfony, поэтому, если вы столкнулись со следующим исключением после установки пакета или в какой-то момент после настройки:

[Symfony\Component\Config\Exception\FileLoaderLoadException]
Warning: trim() expects parameter 1 to be string, array given in /app/config/routing.yml (which is being imported from "/app/config/routing_dev.yml").           

Пожалуйста, измените ваш routing_dev.yml файл и добавьте параметр типа в _main имущество:

_main:
resource: routing.yml
type: be_simple_i18n

Это решит вашу проблему, и вы сможете продолжить настройку маршрутизации.

3. Настройте базовую маршрутизацию

Как и ожидалось, каждый URL будет иметь префикс локали, даже язык вашего приложения по умолчанию, например, английский. Однако, если вы пытаетесь получить доступ к своему приложению из основного домена, например, www.yourapp.com после настройки базовой маршрутизации вы увидите ошибку, которая говорит о том, что / Маршрут не определен. Это происходит потому, что на самом деле не любой маршрут будет использоваться для определения корневого адреса вашего домена, потому что мы будем использовать локаль в качестве префикса на каждом маршруте. Это будет означать проблему для пользователя, так как он или она должен будет написать URL с языком, например www.yourapp.com/en что, очевидно, раздражает, поэтому ожидаемое поведение пользователя перенаправляется на его домашнюю страницу с локалью по умолчанию. Вот почему вам нужно определить корневой параметр в вашем основном файле маршрутизации (app/config/routing.yml) который будет использовать действие urlRedirect пакета фреймворка перенаправить пользователя на указанный URL с использованием параметров локали. Затем создайте определитель маршрута, который в этом случае будет app_main, и определите там префиксы (следуя шаблону локали). Этот определитель будет предназначен для другого файла маршрутизации, который в этом примере находится внутри AppBundle/Resources/config/routing/routing.yml (вы можете изменить путь к файлу, если хотите), и мы создадим этот файл на следующем шаге:

# app/config/routing.yml
# Entry point of your application that redirects the user to the main routing
# using a locale, that means If the user goes to:
# www.yourapp.com
# Is redirected automatically to:
# www.yourapp.com/en/
root:
pattern: /
defaults:
_controller: FrameworkBundle:Redirect:urlRedirect
path: /%locale%/
permanent: true
requirements:
_locale: "%locales%"
# The main routing of your application whose content will be defined on
# the next step !
app_main:
resource: "@AppBundle/Resources/config/routing/routing.yml"
type: "be_simple_i18n"
# Add the locale prefix to every URL
# e.g Contact page English : /en/contact
#     Homepage French      : /fr/
#     Services page Spanish: /es/servicios
#     Contact page German  : /de/kontakt
prefix:
en: "/en"
fr: "/fr"
es: "/es"
de: "/de"

4. Создать основной маршрут

Как упоминалось в предыдущем шаге, определитель app_main нацелен на другой файл маршрутизации, который будет обрабатывать маршруты самого вашего приложения. Наше приложение будет иметь только 3 маршрута, а именно / (Домашняя страница), /services а также /contact, Все они будут естественно переведены на пользовательские языки, чтобы мы могли иметь удобную маршрутизацию. Содержание для создания 3-х маршрутов, чтобы они могли работать на 3-х разных языках:

# AppBundle/Resources/config/routing/routing.yml
main_homepage:
locales:
en: "/"
fr: "/"
es: "/"
de: "/"
defaults: { _controller: AppBundle:Default:homepage }
methods:  [GET]
requirements:
_locale: "%locales%"
main_services:
locales:
en: "/services"
fr: "/services"
es: "/servicios"
de: "/dienstleistungen"
defaults: { _controller: AppBundle:Default:contact }
methods:  [GET]
requirements:
_locale: "%locales%"
main_contact:
locales:
en: "/contact"
fr: "/contact"
es: "/contacto"
de: "/kontakt"
defaults: { _controller: AppBundle:Default:services }
methods:  [GET]
requirements:
_locale: "%locales%"

Как вы можете видеть, мы определяем различные шаблоны маршрутов для каждой локали, которые легко и удобно читать. Это очень хорошо даже для программиста, у которого не будет головной боли при чтении других файлов, чтобы увидеть слаг каждого маршрута и т. Д. Обратите внимание, что нам нужно установить _locale требование для каждого маршрута, так как это автоматически обновит пользовательский языковой стандарт в сеансе.

5. Создайте контроллер для маршрутов

Как вы видели на предыдущем шаге, мы используем один и тот же контроллер для каждого маршрута, даже с разными локалями. Вот почему этот пакет довольно замечательный, вам не нужно обязательно писать логику для каждого языка, так как вы можете спокойно работать с модулем переводчика или возвращать другое представление в контроллере в зависимости от локали. В этом случае наш контроллер довольно прост и возвращает представление, всего есть 3 действия (определенные в основном файле маршрутизации):

Заметка

Мы возвращаем то же представление, в котором мы хотим использовать модуль перевода для перевода вещей в представление, однако это не относится к этому руководству.

render("default/homepage.html.twig");
}
public function servicesAction(Request $request)
{
return $this->render("default/services.html.twig");
}
public function contactAction(Request $request)
{
return $this->render("default/contact.html.twig");
}
}

Как уже упоминалось, вы можете фильтровать в контроллере, используя локаль, чтобы вернуть другой файл, если вы хотите:

getLocale()){
case "es":
return $this->render("default/homepage_spanish.html.twig");
case "fr":
return $this->render("default/homepage_french.html.twig");
case "de":
return $this->render("default/homepage_german.html.twig");
case "en":
default:
return $this->render("default/homepage_english.html.twig");
}
}
}

Однако, по нашему мнению, реализация переводчика Symfony может быть чище и проще, чем поддержка нескольких файлов.

6. Создание перенаправленных ссылок на представления

До этого момента ваше приложение (если оно имеет упомянутый контроллер и маршруты) должно теперь иметь возможность отвечать на маршруты, такие как /en/homepage, /es/contacto, /de/dienstleistungen доступ к ним прямо в панели навигации браузера. Тем не менее, пользователь должен иметь возможность перемещаться по вашему веб-сайту, щелкая некоторые ссылки, поэтому обязательно создайте их в представлениях. Например, некоторые из наших маршрутов могут быть созданы с использованием языка пользователя по умолчанию:

{# /en/ #}
{{ path('main_homepage') }}
{# /en/services #}
{{ path('main_services') }}
{# /en/conctact #}
{{ path('main_contact') }}

Но если вы хотите перенаправить на какую-то специальную локаль, например. Посмотрите на это представление на другом языке, вы также можете форсировать локаль:

{#
Redirect to the homepage in english
/en/
#}
{{ path('main_homepage.en') }}
{{ path('main_homepage', { 'locale': 'en' }) }}
{#
Redirect to the homepage in french
/fr/
#}
{{ path('main_homepage.fr') }}
{{ path('main_homepage', { 'locale': 'fr' }) }}
{#
Redirect to the homepage in German
/de/
#}
{{ path('main_homepage.de') }}
{{ path('main_homepage', { 'locale': 'de' }) }}

7. Очистите кэш проекта с помощью команды cache: clear перед тестированием

Как последний шаг, супер важно очистить кеш вашего проекта с помощью командной строки. Повторюсь, очень и очень важно очистить кеш с помощью cache:clear командование Symfony, в противном случае, если вы удалите только папку кэша вручную, локаль не будет очищена, и вы можете расстроиться. Чтобы убедиться, что все работает по порядку, очистите кеш вашего проекта с помощью следующей команды:

Pro tip

Открытие окна «Инкогнито» в Google Chrome после очистки кэша вручную очень полезно для проведения теста, так как браузеры запускаются с нуля и ничего не сохраняется, поэтому, если есть проблема, это не в браузере, а в вашем коде.

php bin/console cache:clear

Помните также, что, как мы определили как требование к любому URL, специальный параметр _localeязыковой стандарт пользователя будет автоматически обновляться при каждом изменении языкового стандарта URL, например, с /en (английский) в /es (испанский), так что вы можете легко создать переключатель языка, который просто перенаправляет на main_homepage маршрут с нужной локалью, и все, пользователь будет перенаправлен на домашнюю страницу с языком, привязанным к локали. Для получения дополнительной информации об этом подходе, прочитайте больше о локаль и URL в документации Symfony.

Ссылка на основную публикацию
Adblock
detector