【问题标题】:Symfony2+Doctrine2: How to properly localize records?Symfony2+Doctrine2:如何正确本地化记录?
【发布时间】:2014-01-11 21:38:00
【问题描述】:

我希望在 Symfony2 框架上使用 Doctrine 管理记录本地化。

要求是

  • 翻译记录的能力
  • 只能在一种语言环境中添加记录
  • 任何类型的开发人员友好的可重用模式来完成此任务

到目前为止,我已经实现了 DoctrineExtensions 库来使用 Translatable 扩展。在我阅读的任何地方,它都被认为是处理翻译的首选方式。我意识到这与本地化不同,但似乎这是我最接近的。

假设我有一个包含可翻译产品的产品表。我的默认语言是英语。在默认的英语语言环境中插入产品后,我可以稍后添加翻译,比如说意大利语。 我无法使用 Translatable 扩展程序做的是仅在意大利语区域设置中添加产品。如果我这样做,可翻译扩展程序还会以默认语言(英语)添加产品,但内容为意大利语。然后它继续添加意大利语翻译。

我的产品实体如下所示; (简体)

<?php
namespace Acme\DemoBundle\Entity;

use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="acmedemobundle_product")
 */
class Product
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column()
     * @Gedmo\Translatable
     */
    protected $name;
    ...
}

有没有办法以非默认语言添加记录?还是我找错地方了?

-

在使用 Symfony&Doctrine 之前,我习惯于管理两个表中的本地化数据,然后使用请求的语言环境将它们连接在一起。

例如,products 表包含所有与语言环境无关的数据,例如

  • 身份证
  • category_id

products_i18n 表包含所有本地化数据,例如

  • product_id
  • 语言环境
  • 姓名
  • 说明
  • 蛞蝓

这样,只有一个主记录可用于关系,以及一个或多个本地化扩展。没有本地化扩展的记录将被视为不存在。

也许有办法代替它?

-

说实话,到目前为止,我还没有找到关于这个特定主题的太多有用信息。我无法想象我是第一个遇到这个问题的人。

非常感谢您对此事的任何帮助!

=============== 更新

我决定采用自定义解决方案,将两个表联系在一起,就像我在上面的示例中说明的那样。这样做的主要原因(除了我需要该功能)是Translatable 将所有翻译的数据保存在一个表中。从性能和危机情景的角度来看,这并不正确。更有条理,将每个表的本地化数据放在自己的表中,而不是汇总。

目前,我接受了彼得的回答,因为它是最有帮助的。如果有更好的答案,我会考虑换。干杯!

【问题讨论】:

    标签: php mysql symfony doctrine-orm internationalization


    【解决方案1】:

    【讨论】:

    • 如我的问题所述; Translatable 对我不起作用。除非你认为我使用不正确,但请详细说明你认为我应该做的不同。
    【解决方案2】:

    这个问题似乎有点引起误解。当您想让产品仅在某些地区(基于语言环境)可用时,您并不是在询问翻译是否仅基于语言环境可用。
    原则扩展坚持为您的产品提供默认翻译是非常完美的,否则您的应用程序将无法正确处理请求。
    毕竟该产品在所有地区或区域区域都可用,那么如何提供翻译内容的信息,例如名称?
    如果翻译后的名称没有默认设置,这意味着默认区域内显示的产品无法解析其名称。该实体不完整,因为名称将为空。
    要将产品仅添加到某个区域设置区域,您必须向您的产品添加一个属性,如

    /**
     * @ORM\Column(type="string")
     */
    private $localeZone;
    

    然后为您提供过滤实体的可能性。 您还可以将您的实体产品设置为 MappedEntity 并为本地实体使用多个 Subs,这将使您更改在 ItalianProducts 中存储意大利产品,例如虽然我个人不喜欢这个想法,因为它是基于其中属性的值来区分对象,而不是行为或数据结构的差异。

    【讨论】:

    • 感谢您的回复。我的重点是使记录在所有语言环境中都可用。只要 Doctrine 不介意,我的应用程序就不用担心处理它。但我并没有设定一个特定的解决方案,只要有可能让它发挥作用。从长远来看,我认为您的想法不会奏效,每当添加语言环境时,我都必须添加大量实体。
    • 第一种方法是基于现有实体中的附加属性。过滤可以很容易地基于存储库实现作为实现方法,如“findAllProductsByLocale()”来完成。该属性不必在表单中公开,而是可以由处理表单的控制器插入。由于 Symfony 2 支持基于语言环境的 url,因此语言环境 - 字符串是框架容易检索的参数。所以这种方法很简单。
    • 另一种方法是加入 Doctrine Extension 以更改它的默认行为,即双倍插入到默认和指定的语言环境中,这将使扩展不再可更新。这就像破解 Symonfy - Core。
    • 如果您查看github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/…,您会发现翻译是通过 MappedSuperClass 处理的。翻译存储在幕后,您的实体被包装到 github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/… 中。因此,虽然有一些方法可以提供自己的 github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/… 实现
    • 不修改扩展本身就无法指定:只有特定语言环境的实体应该可用。你必须在应用层实现它。
    猜你喜欢
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多