我正在使用JMS\I18nRoutingBundle
,Gedmo\Translatable
和Gedmo\Sluggable
。具有默认位置的路由也可以工作,但其他语言环境无需翻译slug。我的i18n路由具有以下设置:
# 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
。
答案 0 :(得分:1)
正如我所知,您正在使用ParamConverter自动获取您的类别。
如果slug-in-english
是数据库中的现有slug,但是doctrine拒绝获取它。
此时您可能没有将 TranslatableListener 添加到您的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
答案 1 :(得分: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();
}
}
答案 2 :(得分:1)
我有同样的问题,并且按照jkucharovic的建议,您可以使用 Doctrine ParamConverter 将您的请求参数转换为对象
要从数据库中获取对象,Doctrine转换器默认使用find()方法。但由于我们使用Translatable,因此使用多个表,仅仅管理翻译是不够的,这就是我们需要定义自己的翻译的原因。这是findByTranslatedSlug。
/**
* @Template
* @ParamConverter(
* "category",
* class = "AcmeSiteBundle:Category",
* options = {
* "id" = "slug",
* "repository_method" = "findByTranslatedSlug"
* }
* )
*/
public function detailAction(Category $category)
{}
有关ParamConverter参数的一些细节:
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();
}
}
我希望这可以提供帮助
文档: