tutorial instalar español symfony

instalar - Symfony2 configuración regional predeterminada en el enrutamiento



symfony español (11)

Tengo un problema con el enrutamiento y la internacionalización de mi sitio creado con Symfony2.
Si defino rutas en el archivo routing.yml, así:

example: pattern: /{_locale}/example defaults: { _controller: ExampleBundle:Example:index, _locale: fr }

Funciona bien con URL como:

mysite.com/en/example mysite.com/fr/example

Pero no funciona con

mysite.com/example

¿Podría ser que los marcadores de posición opcionales están permitidos solo al final de una URL?
En caso afirmativo, ¿cuál podría ser una posible solución para mostrar una url como:

mysite.com/example

en un idioma predeterminado o redirigir al usuario a:

mysite.com/defaultlanguage/example

cuando visita:

mysite.com/example. ?

Estoy tratando de resolverlo pero sin éxito hasta ahora.

Gracias.


¡Hay mi Solución, hace que este proceso sea más rápido!

Controlador:

/** * @Route("/change/locale/{current}/{locale}/", name="locale_change") */ public function setLocaleAction($current, $locale) { $this->get(''request'')->setLocale($locale); $referer = str_replace($current,$locale,$this->getRequest()->headers->get(''referer'')); return $this->redirect($referer); }

Ramita:

<li {% if app.request.locale == language.locale %} class="selected" {% endif %}> <a href="{{ path(''locale_change'', { ''current'' : app.request.locale, ''locale'' : language.locale } ) }}"> {{ language.locale }}</a> </li>


Creo que simplemente podría agregar una ruta como esta:

example: pattern: /example defaults: { _controller: ExampleBundle:Example:index }

De esta manera, la configuración regional sería la última configuración regional seleccionada por el usuario, o la configuración regional predeterminada si la configuración regional del usuario no se ha establecido. También puede agregar el parámetro "_locale" a los "valores predeterminados" en su configuración de enrutamiento si desea establecer una configuración regional específica para / ejemplo:

example: pattern: /example defaults: { _controller: ExampleBundle:Example:index, _locale: fr }

No sé si hay una mejor manera de hacer esto.


Esto es lo que uso para la detección y redirección automática de la configuración regional, funciona bien y no requiere largas anotaciones de ruta:

routing.yml

La ruta de locale maneja la raíz del sitio web y luego todas las demás acciones del controlador se anexan a la configuración regional.

locale: path: / defaults: { _controller: AppCoreBundle:Core:locale } main: resource: "@AppCoreBundle/Controller" prefix: /{_locale} type: annotation requirements: _locale: en|fr

CoreController.php

Esto detecta el idioma del usuario y redirige a la ruta que elijas. Uso el hogar como predeterminado, ya que es el caso más común.

public function localeAction($route = ''home'', $parameters = array()) { $this->getRequest()->setLocale($this->getRequest()->getPreferredLanguage(array(''en'', ''fr''))); return $this->redirect($this->generateUrl($route, $parameters)); }

Entonces, las anotaciones de ruta pueden ser simplemente:

/** * @Route("/", name="home") */ public function indexAction(Request $request) { // Do stuff }

Ramita

La opción localeAction se puede usar para permitir al usuario cambiar la configuración regional sin navegar desde la página actual:

<a href="{{ path(app.request.get(''_route''), app.request.get(''_route_params'')|merge({''_locale'': targetLocale })) }}">{{ targetLanguage }}</a>

Limpio y simple!


La solución de Joseph Astrahan de LocalRewriteListener funciona a excepción de la ruta con params debido a $routePath == "/{_locale}".$path)

Ej: $routePath = "/{_locale}/my/route/{foo}" es diferente de $path = "/{_locale}/my/route/bar"

Tuve que usar UrlMatcher (enlace a Symfony 2.7 api doc) para hacer coincidir la ruta real con la url.

Cambio isLocaleSupported para usar el código local del navegador (por ejemplo, fr -> fr_FR). Uso la configuración regional del navegador como clave y la configuración regional de la ruta como valor. Tengo una matriz como esta array([''fr_FR''] => [''fr''], [''en_GB''] => ''en''...) (ver el archivo de parámetros a continuación para más información)

Los cambios :

  • Verifique si el local dado en la solicitud es compatible. Si no, usa la configuración regional predeterminada.
  • Intenta hacer coincidir la ruta con la colección de ruta de la aplicación. Si no, no hagas nada (la aplicación arroja un 404 si la ruta no existe). En caso afirmativo, redirija con la configuración regional correcta en parámetro de ruta.

Aquí está mi código. Funciona para cualquier ruta con o sin param. Esto agrega la configuración regional solo cuando se configura {_local} en la ruta.

Archivo de enrutamiento (en mi caso, el de la aplicación / config)

app: resource: "@AppBundle/Resources/config/routing.yml" prefix: /{_locale}/ requirements: _locale: ''%app.locales%'' defaults: { _locale: %locale%}

El parámetro en el archivo app / config / parameters.yml

locale: fr app.locales: fr|gb|it|es locale_supported: fr_FR: fr en_GB: gb it_IT: it es_ES: es

services.yml

app.eventListeners.localeRewriteListener: class: AppBundle/EventListener/LocaleRewriteListener arguments: ["@router", "%kernel.default_locale%", "%locale_supported%"] tags: - { name: kernel.event_subscriber }

LocaleRewriteListener.php

<?php namespace AppBundle/EventListener; use Symfony/Component/HttpFoundation/RedirectResponse; use Symfony/Component/Routing/RouterInterface; use Symfony/Component/HttpKernel/Event/GetResponseEvent; use Symfony/Component/HttpKernel/KernelEvents; use Symfony/Component/EventDispatcher/EventSubscriberInterface; use Symfony/Component/HttpFoundation/Session/Session; use Symfony/Component/Routing/RouteCollection; use Symfony/Component/Routing/Matcher/UrlMatcher; use Symfony/Component/Routing/RequestContext; class LocaleRewriteListener implements EventSubscriberInterface { /** * @var Symfony/Component/Routing/RouterInterface */ private $router; /** * @var routeCollection /Symfony/Component/Routing/RouteCollection */ private $routeCollection; /** * @var urlMatcher /Symfony/Component/Routing/Matcher/UrlMatcher; */ private $urlMatcher; /** * @var string */ private $defaultLocale; /** * @var array */ private $supportedLocales; /** * @var string */ private $localeRouteParam; public function __construct(RouterInterface $router, $defaultLocale = ''fr'', array $supportedLocales, $localeRouteParam = ''_locale'') { $this->router = $router; $this->routeCollection = $router->getRouteCollection(); $this->defaultLocale = $defaultLocale; $this->supportedLocales = $supportedLocales; $this->localeRouteParam = $localeRouteParam; $context = new RequestContext("/"); $this->matcher = new UrlMatcher($this->routeCollection, $context); } public function isLocaleSupported($locale) { return array_key_exists($locale, $this->supportedLocales); } public function onKernelRequest(GetResponseEvent $event) { //GOAL: // Redirect all incoming requests to their /locale/route equivalent when exists. // Do nothing if it already has /locale/ in the route to prevent redirect loops // Do nothing if the route requested has no locale param $request = $event->getRequest(); $baseUrl = $request->getBaseUrl(); $path = $request->getPathInfo(); //Get the locale from the users browser. $locale = $request->getPreferredLanguage(); if ($this->isLocaleSupported($locale)) { $locale = $this->supportedLocales[$locale]; } else if ($locale == ""){ $locale = $request->getDefaultLocale(); } $pathLocale = "/".$locale.$path; //We have to catch the ResourceNotFoundException try { //Try to match the path with the local prefix $this->matcher->match($pathLocale); $event->setResponse(new RedirectResponse($baseUrl.$pathLocale)); } catch (/Symfony/Component/Routing/Exception/ResourceNotFoundException $e) { } catch (/Symfony/Component/Routing/Exception/MethodNotAllowedException $e) { } } public static function getSubscribedEvents() { return array( // must be registered before the default Locale listener KernelEvents::REQUEST => array(array(''onKernelRequest'', 17)), ); } }


Puede definir varios patrones como este:

example_default: pattern: /example defaults: { _controller: ExampleBundle:Example:index, _locale: fr } example: pattern: /{_locale}/example defaults: { _controller: ExampleBundle:Example:index} requirements: _locale: fr|en

Debería poder lograr el mismo tipo de cosas con las anotaciones:

/** * @Route("/example", defaults={"_locale"="fr"}) * @Route("/{_locale}/example", requirements={"_locale" = "fr|en"}) */

¡Espero que ayude!


Quizás resolví esto de una manera bastante simple:

example: path: ''/{_locale}{_S}example'' defaults: { _controller: ''AppBundle:Example:index'' , _locale="de" , _S: "/" } requirements: _S: "/?" _locale: ''|de|en|fr''

Curioso sobre el juicio de los críticos ... Mis mejores deseos, Greg


Si alguien está interesado, logré poner un prefijo en mi routing.yml sin usar otros paquetes.

Entonces, esas URL funcionan:

www.example.com/ www.example.com//home/ www.example.com/fr/home/ www.example.com/en/home/

Edite su app/config/routing.yml :

ex_example: resource: "@ExExampleBundle/Resources/config/routing.yml" prefix: /{_locale} requirements: _locale: |fr|en # put a pipe "|" first

Luego, en tu app/config/parameters.yml , debes configurar una configuración regional

parameters: locale: en

Con esto, las personas pueden acceder a su sitio web sin ingresar a un lugar específico.


Symfony3

app: resource: "@AppBundle/Controller/" type: annotation prefix: /{_locale} requirements: _locale: en|bg| # put a pipe "|" last


Tengo una solución completa a esto que descubrí después de algunas investigaciones. Mi solución asume que quieres que cada ruta tenga una configuración regional delante, incluso iniciar sesión. Esto se modifica para admitir Symfony 3, pero creo que todavía funcionará en 2.

Esta versión también asume que desea utilizar la configuración regional de los navegadores como configuración regional predeterminada si van a una ruta como / admin, pero si van a / en / admin sabrán usar en locale. Este es el caso, por ejemplo, el n. ° 2 a continuación.

Así por ejemplo:

1. User Navigates To -> "/" -> (redirects) -> "/en/" 2. User Navigates To -> "/admin" -> (redirects) -> "/en/admin" 3. User Navigates To -> "/en/admin" -> (no redirects) -> "/en/admin"

En todos los escenarios, la configuración regional se configurará correctamente de la forma que desee para su uso en todo el programa.

Puede ver la solución completa a continuación, que incluye cómo hacer que funcione con el inicio de sesión y la seguridad, de lo contrario, la versión corta probablemente funcione para usted:

Versión completa

Symfony 3 redirige todas las rutas a la versión de configuración regional actual

Version corta

Para que sea posible que el caso n. ° 2 en mis ejemplos sea necesario, debe hacerlo usando un listador httpKernal

LocaleRewriteListener.php

<?php //src/AppBundle/EventListener/LocaleRewriteListener.php namespace AppBundle/EventListener; use Symfony/Component/HttpFoundation/RedirectResponse; use Symfony/Component/Routing/RouterInterface; use Symfony/Component/HttpKernel/Event/GetResponseEvent; use Symfony/Component/HttpKernel/KernelEvents; use Symfony/Component/EventDispatcher/EventSubscriberInterface; use Symfony/Component/HttpFoundation/Session/Session; use Symfony/Component/Routing/RouteCollection; class LocaleRewriteListener implements EventSubscriberInterface { /** * @var Symfony/Component/Routing/RouterInterface */ private $router; /** * @var routeCollection /Symfony/Component/Routing/RouteCollection */ private $routeCollection; /** * @var string */ private $defaultLocale; /** * @var array */ private $supportedLocales; /** * @var string */ private $localeRouteParam; public function __construct(RouterInterface $router, $defaultLocale = ''en'', array $supportedLocales = array(''en''), $localeRouteParam = ''_locale'') { $this->router = $router; $this->routeCollection = $router->getRouteCollection(); $this->defaultLocale = $defaultLocale; $this->supportedLocales = $supportedLocales; $this->localeRouteParam = $localeRouteParam; } public function isLocaleSupported($locale) { return in_array($locale, $this->supportedLocales); } public function onKernelRequest(GetResponseEvent $event) { //GOAL: // Redirect all incoming requests to their /locale/route equivlent as long as the route will exists when we do so. // Do nothing if it already has /locale/ in the route to prevent redirect loops $request = $event->getRequest(); $path = $request->getPathInfo(); $route_exists = false; //by default assume route does not exist. foreach($this->routeCollection as $routeObject){ $routePath = $routeObject->getPath(); if($routePath == "/{_locale}".$path){ $route_exists = true; break; } } //If the route does indeed exist then lets redirect there. if($route_exists == true){ //Get the locale from the users browser. $locale = $request->getPreferredLanguage(); //If no locale from browser or locale not in list of known locales supported then set to defaultLocale set in config.yml if($locale=="" || $this->isLocaleSupported($locale)==false){ $locale = $request->getDefaultLocale(); } $event->setResponse(new RedirectResponse("/".$locale.$path)); } //Otherwise do nothing and continue on~ } public static function getSubscribedEvents() { return array( // must be registered before the default Locale listener KernelEvents::REQUEST => array(array(''onKernelRequest'', 17)), ); } }

Para entender cómo funciona, busque la interfaz del suscriptor del evento en la documentación de Symfony.

Para activar el listner debes configurarlo en tus servicios.yml

services.yml

# Learn more about services, parameters and containers at # http://symfony.com/doc/current/book/service_container.html parameters: # parameter_name: value services: # service_name: # class: AppBundle/Directory/ClassName # arguments: ["@another_service_name", "plain_value", "%parameter_name%"] appBundle.eventListeners.localeRewriteListener: class: AppBundle/EventListener/LocaleRewriteListener arguments: ["@router", "%kernel.default_locale%", "%locale_supported%"] tags: - { name: kernel.event_subscriber }

Finalmente, esto se refiere a las variables que deben definirse en su config.yml

config.yml

# Put parameters here that don''t need to change on each machine where the app is deployed # http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration parameters: locale: en app.locales: en|es|zh locale_supported: [''en'',''es'',''zh'']

Finalmente, debe asegurarse de que todas sus rutas comiencen con / {locale} por el momento. Una muestra de esto está debajo en mi controller.php predeterminado

<?php namespace AppBundle/Controller; use Sensio/Bundle/FrameworkExtraBundle/Configuration/Route; use Symfony/Bundle/FrameworkBundle/Controller/Controller; use Symfony/Component/HttpFoundation/Request; /** * @Route("/{_locale}", requirements={"_locale" = "%app.locales%"}) */ class DefaultController extends Controller { /** * @Route("/", name="home") */ public function indexAction(Request $request) { $translated = $this->get(''translator'')->trans(''Symfony is great''); // replace this example code with whatever you need return $this->render(''default/index.html.twig'', [ ''base_dir'' => realpath($this->container->getParameter(''kernel.root_dir'').''/..''), ''translated'' => $translated ]); } /** * @Route("/admin", name="admin") */ public function adminAction(Request $request) { $translated = $this->get(''translator'')->trans(''Symfony is great''); // replace this example code with whatever you need return $this->render(''default/index.html.twig'', [ ''base_dir'' => realpath($this->container->getParameter(''kernel.root_dir'').''/..''), ''translated'' => $translated ]); } } ?>

Tenga en cuenta los requisitos de requirements={"_locale" = "%app.locales%"} , esto hace referencia al archivo config.yml por lo que solo debe definir esos requisitos en un solo lugar para todas las rutas.

Espero que esto ayude a alguien :)


Yo uso anotaciones, y lo haré

/** * @Route("/{_locale}/example", defaults={"_locale"=""}) * @Route("/example", defaults={"_locale"="en"}, , requirements = {"_locale" = "fr|en|uk"}) */

Pero para la forma yml, pruebe algunos equivalentes ...