2016-03-15 2 views
1

Я работаю над проектом веб-приложения с использованием Symfony 2. Страница будет доступна на трех разных языках. Дополнительные языки будут добавлены позже.Symfony Локализация: перенаправление/xyz to/en/xyz

So somepage будет доступен под номером /en/somepage, /fr/somepage и так далее.

Я решил это в два этапа:

  1. Посетительница домашней страницы / автоматически перенаправлены на главную страницу локализованной /en, /fr и т.д. в соответствии с заголовком языка HTTP
  2. Все маршруты импортируются с prefix="/{_locale}"

Это код, я использую:

app/config/config.xml

... 
parameters: 
    app.default_locale: en 
    app.locales: en|fr|es 

src/AppBundle/Resources/config/routing.xml

<?xml version="1.0" encoding="UTF-8" ?> 
<routes xmlns="http://symfony.com/schema/routing" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> 

    <!-- Home route to redirect to the right route --> 
    <route id="home_redirect" path="" methods="GET"> 
     <default key="_controller">AppBundle:Public:home</default> 
    </route> 

    <!-- Routes for the localized public pages --> 
    <import 
     resource="@AppBundle/Resources/config/public_routes.xml" prefix="/{_locale}" > 

     <requirement key="_locale">%app.locales%</requirement> 
     <default key="_locale">%app.default_locale%</default>   
    </import> 

    <!-- Routes that should not be extended by any locale --> 
    <import resource="@AppBundle/Resources/config/unlocalized_routes.xml" /> 
</routes> 

src/AppBundle/Resources/config/public_routes.xml

... 

<route id="home" path="" methods="GET"> 
    <default key="_controller">AppBundle:Public:home</default> 
</route> 

<route id="public_register" path="/somepage" methods="GET"> 
    <default key="_controller">AppBundle:Public:register</default> 
</route> 

... 

src/AppBundle/Controller/PublicController.php

class PublicController extends Controller { 

    public function homeAction(Request $request) { 
     // Check if the locale is set in the url 
     $locale = $request->attributes->get('_locale'); 

     if (!$locale) { 
      // Try to get the preferred language from the request header 
      $locale = AppSettings::getLanguage($request); 

      return $this->redirectToRoute('home', array('_locale' => $locale)); 
     } 
     elseif (!AppSettings::checkLanguage($locale)) { 
      // Language in URL is not supported --> Page not found 
      throw $this->createNotFoundException(); 
     } 

     return $this->render('AppBundle:Default:homepage.html.twig'); 
    } 

} 

Так посещение example.com не проблема. Это будет перенаправлено на example.com/xx, где xx - это локаль. Кроме того, все маршруты, импортированные из public_routes.xml, автоматически начинаются с языкового стандарта. С другой стороны, маршруты, импортированные из unlocalized_routes.xml, все еще доступны напрямую/без локали.

Однако посещение example.com/somepage (определено в public_routes.xml) напрямую невозможно. Нужно использовать поддерживаемый язык, такой как example.com/en/somepage

Я хотел был бы сделать так, чтобы позвонить по всем маршрутам из public_routes.xml напрямую (без языкового стандарта) и позволить Symfony перенаправить на локализованную страницу/маршрут. Также как на домашней странице / прямо сейчас.

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

Любая идея, как это можно решить?

ответ

2

У вас есть несколько вариантов здесь:

  • создать действие для обработки перенаправлять и создать catch-all маршрут для него, и поместить его в app/config/routing.yml как самый последний маршрут. Вы можете проверить заказ командой router:debug (или debug:router). Действие будет выполнено, если никакой другой маршрут не будет соответствовать.

  • вы можете создать прослушиватель события для kernel.exception события и установить ответ перенаправлять там

  • использовать существующий пакет JMSI18nRoutingBundle или BeSimpleI18nRoutingBundle

Я бы с пачкой.

+0

Благодарим вас за ответ. Теперь я использую решение 'catch-all'. –