5

我正在使用JMS\I18nRoutingBundle,Gedmo\TranslatableGedmo\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

4

4 回答 4

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 参数的一些细节:

  • 第一个参数“类别”是指方法参数的名称(这里是$category
  • “id”选项是指您要传递的路由占位符(此处为{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();
    }
}

我希望这可以帮助

文件:

于 2014-09-30T16:04:27.597 回答
1

如我所见,您正在使用 ParamConverter 自动获取您的类别。

Ifslug-in-english是您数据库中现有的 slug,但教义拒绝获取它。

那时您可能没有将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
于 2013-06-12T10:39:34.987 回答
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();
    }
}
于 2014-02-14T08:04:52.500 回答
0

对于 Symfony > 4,解决方法是

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;

     * @Route("/{slug}", name="your_route_name"))
     * @Entity("your_entity_name", expr="repository.findByTranslatedSlug(slug)")

并使用接受的答案中的 repo 方法;)

一整天都在寻找这个,我很高兴找到你的帖子!

于 2022-01-14T22:49:37.800 回答