2013-06-12 2 views
5

Я использую JMS\I18nRoutingBundle, Gedmo\Translatable и Gedmo\Sluggable. Маршруты со стандартными местоположениями также работают, но другие локали работают без перевода. Моя маршрутизация i18n имеют следующие параметры:Пользовательские i18n маршрутизации в Symfony

# Doctrine extensions 
stof_doctrine_extensions: 
    default_locale: %locale% 
    translation_fallback: true 
    orm: 
     default: 
      #… 
      sluggable:  true 
      translatable: true 
      loggable:  false 
      #… 

jms_i18n_routing: 
    default_locale: cs_CZ 
    locales: [cs_CZ, en_US] 
    strategy: custom 
    hosts: 
     cs_CZ: example.cz 
     en_US: example.com 
    redirect_to_host: true 

Когда я настраивал маршрут, как это:

hw_category: 
    pattern: /category/{slug} 
    defaults: { _controller: AcmeSiteBundle:Category:detail } 
/** 
* @Template 
*/ 
public function detailAction(Category $category) 
{} 

Эти маршруты работает
example.cz/category/slug-in-czech
example.com/category/slug-in-czech

Но я хочу, чтобы получить работа example.com/category/slug-in-english, которая выбрасывает исключение 404 object not found.

ответ

1

В контроллере, вы должны переопределить метод, используемый в хранилище объекта:

/** 
* @Template 
* @ParamConverter(
*  "category", 
*  class = "AcmeSiteBundle:Category", 
*  options = { 
*   "repository_method" = "findByTranslatedSlug" 
*  } 
* ) 
*/ 
public function detailAction(Category $category) 
{} 

 

namespace Acme\Bundle\SiteBundle\Entity; 

use Doctrine\ORM\EntityRepository; 

class CategoryRepository extends EntityRepository 
{ 
    public function findByTranslatedSlug($slug) 
    { 
     $qb = $this->createQueryBuilder('c') 
      ->where('c.slug = :slug') 
      ->setParameters($slug); 

     $query = $qb->getQuery(); 
     // set the translation query hint 
     $query->setHint(
      \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 
      'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker' 
     ); 

     return $query->getOneOrNullResult(); 
    } 
} 
1

Как я вижу, вы используете ParamConverter для автоматической загрузки вашей категории.

Если slug-in-english является существующим слизнем в вашей базе данных, но доктрина отказывается его извлекать.

У вас, вероятно, нет TranslitableListener, добавленный в ваш EntityManager в этот момент.

Пример:

$translatableListener = new \Gedmo\Translatable\TranslationListener(); 
$translatableListener->setTranslatableLocale('en_us'); 
$em->addEventSubscriber($translatableListener); 

Если вы используете StofDoctrineExtensionsBundle:

stof_doctrine_extensions: 
    default_locale: en_US 
    orm: 
     default: 
      # ... 
      translatable: true 
+0

Где я должен прикреплять 'TranslatableListener' - в каком файле? – kuboslav

+0

Вы используете StofDoctrineExtensionsBundle? – nifr

+0

обновил мой ответ :) – nifr

1

Я была такая же проблема и как это было предложено jkucharovic, вы можете использовать Doctrine ParamConverter для преобразования параметров запроса к объекту

Для извлечения объекта из базы данных, Учение конвертер использует метод find() по умолчанию. Но поскольку мы используем Translatable, поэтому несколько таблиц, для управления переводами недостаточно, поэтому нам нужно определить наши собственные. Здесь вы найдете findByTranslatedSlug.

/** 
* @Template 
* @ParamConverter(
*  "category", 
*  class = "AcmeSiteBundle:Category", 
*  options = { 
*   "id" = "slug", 
*   "repository_method" = "findByTranslatedSlug" 
*  } 
* ) 
*/ 
public function detailAction(Category $category) 
{} 

Некоторые подробности о параметрах ParamConverter:

  • Первый параметр "категория" относится к имени аргумента метода (здесь $ категории)
  • "идентификатор" вариант относится к заполнителю маршрута, который вы хотите передать (здесь {slug}) к настроенному методу репозитория (findByTranslatedSlug()). Не устанавливая этот параметр, он будет генерировать исключение PDO.

 

namespace Acme\Bundle\SiteBundle\Entity; 

use Doctrine\ORM\EntityRepository; 

class CategoryRepository extends EntityRepository 
{ 
    public function findByTranslatedSlug($slug) 
    { 
     $qb = $this->createQueryBuilder('c') 
      ->where('c.slug = :slug') 
      ->setParameter('slug',$slug); 

     $query = $qb->getQuery(); 
     // set the translation query hint 
     $query->setHint(
      \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 
      'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker' 
     ); 
     // If you need to set manually the locale to en_US, you can set this query hint 
     //$query->setHint(\Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE, 'en_US'); 

     return $query->getOneOrNullResult(); 
    } 
} 

Я надеюсь, что это может помочь

Docs:

Смежные вопросы