bummzack/translatable-dataobject

Silverstripe Translatable 扩展模块,用于 DataObjects

安装数: 6,935

依赖项: 1

建议者: 1

安全性: 0

星标: 18

关注者: 5

分支: 12

开放性问题: 7

类型:silverstripe-module

2.1 2019-03-09 15:27 UTC

This package is auto-updated.

Last update: 2024-09-10 04:40:26 UTC


README

为 SilverStripe 3.1 添加字段翻译的扩展模块。而不是为翻译创建新行,翻译作为列添加。这样,只有一个 DataObject 实例,它对所有本地化一致,但具有本地化字段。

此模块需要安装 translatable 模块。感谢 Uncle Cheese,他的 TranslatableDataObject 启发了我。

需求

安装

使用 composer

composer require bummzack/translatable-dataobject

或者将此仓库克隆/下载到 SilverStripe 安装文件夹中的一个文件夹中。

使用

定义内容区域

为模块定义区域的最理想/推荐方法是为 Translatable 模块设置允许的区域。这样,在整个 CMS 中可用的区域是一致的。示例

Translatable::set_allowed_locales(array('en_US', 'fr_FR', 'de_DE'));

如果您想手动/单独设置 translatable-dataobject 模块的区域,您可以通过 YAML 配置指定它们

# in your mysite/_config/config.yml

TranslatableDataObject:
  locales:
    - en_US
    - fr_FR

如果省略这两个调用,模块将使用以下方式从网站内容中获取区域

Translatable::get_existing_content_languages()

使用此设置要求您在向系统添加新的翻译语言时运行 dev/build

启用翻译

要使 DataObject 可翻译,通过 YAML 配置文件添加 TranslatableDataObject 扩展,如下所示

# in your mysite/_config/config.yml

MyDataObject:
  extensions:
    - TranslatableDataObject

之后运行 dev/build,以便创建额外的数据库字段。默认情况下,所有 VarcharTextHTMLText 字段都将被翻译,而所有其他字段保持不变。要更改这些默认字段,您可以按如下方式配置它们

# in your mysite/_config/config.yml

# Translate only 'Varchar' and 'HTMLText' fields per default
TranslatableDataObject:
  default_field_types:
    - Varchar
    - HTMLText

如果您想手动指定要本地化的字段,您可以通过 translatable_fields YAML 配置添加它们

# in your mysite/_config/config.yml
# Example with parameters

MyDataObject:
  extensions:
    - TranslatableDataObject
  translatable_fields:
    - Content
    - Title

或者,您还可以在 DataObject 的静态字段上设置要翻译的字段。因此,在您的 MyDataObject 类中,您可以添加以下内容

// create translatable fields for 'Title' and 'Content'
private static $translatable_fields = array(
    'Title', 'Content'
);

CMS 中的翻译

假设您有一个 TestimonialPage,它 has_many Testimonials,并且您在 GridField 中管理这些 Testimonials。

数据对象(Testimonial)

让我们从 Testimonial 数据对象开始

class Testimonial extends DataObject
{
    private static $db = array(
        'Title' => 'Varchar',
        'Content' => 'HTMLText'
    );

    private static $has_one = array(
        'TestimonialPage' => 'TestimonialPage'
    );

    private static $extensions = array(
        'TranslatableDataObject'
    );

    private static $translatable_fields = array(
        'Title',
        'Content'
    );
}

这部分应该看起来很熟悉。我们添加了 TranslatableDataObject 扩展,并声明了哪些字段应该被翻译,通过设置 translatable_fields。这也同样可以通过 YAML 配置完成(参见上面的配置示例)。

页面(TestimonialPage)

现在来谈谈 Testimonial 页面

class TestimonialPage extends Page
{
    private static $has_many = array(
        'Testimonials' => 'Testimonial'
    );

    public function getCMSFields()
    {
        $fields = parent::getCMSFields();

        // manage testimonials
        $gridConfig = GridFieldConfig_RelationEditor::create();
        $gridField = new GridField('Testimonials', 'Testimonials', $this->Master()->Testimonials(), $gridConfig);
        $gridField->setModelClass('Testimonial');
        $fields->addFieldsToTab('Root.Testimonials', $gridField);

        return $fields;
    }
}

class TestimonialPage_Controller extends Page_Controller
{

}

这看起来更像是一个常规页面,您可能想知道这里有什么特别之处。唯一改变的是,我们使用 $this->Master()->Testimonials() 而不是 $this->Testimonials() 作为 GridField 数据源。使用这种设置,您应该在 CMS 中能够切换到不同的语言并编辑当前语言的 Testimonials。试试看

表单和 ModelAdmin

TranslatableDataObject 扩展附带了一些辅助方法,这些方法可以使您更容易为 CMS 构建 可翻译表单。默认行为(如果您自己实现 getCMSFields,也称为脚手架)是您将只看到当前活动区域(如果您在 CMS 的 页面 部分工作,这很理想,因为您始终在一个语言树中工作)的表单字段。对于除默认区域以外的区域,您将看到原始内容作为每个表单字段的下面的只读字段(与可翻译模块为页面提供的功能相同)。

当然,您也可以自己实现 getCMSFields 方法。以下是一个示例

public function getCMSFields()
{
    $titleField = new TextField('Title');
    $contentField = new HtmlEditorField('Content');

    // transform the fields if we're not in the default locale
    if(Translatable::default_locale() != Translatable::get_current_locale()) {
        $transformation = new TranslatableFormFieldTransformation($this);
        $titleField = $transformation->transformFormField($titleField);
        $contentField = $transformation->transformFormField($contentField);
    }

    return new FieldList(
        $titleField,
        $contentField
    );
}

当我们在默认区域之外时,我们使用 TranslatableFormFieldTransformation 实例转换字段。这与您可能从可翻译模块中熟悉的 Translatable_Transformation 非常相似。这所做的是:它获取给定的表单字段,并用翻译内容替换其名称和内容。原始内容将作为 只读 在表单字段下方显示。

如果您希望获取当前区域的输入字段,有一个名为 getLocalizedFormField 的辅助方法。它将自动为给定的字段名称创建一个合适的输入字段。所以如果你的字段类型是 Varchar,你将得到一个 TextField 实例。一个 HTMLText 将返回一个 HtmlEditorField 实例等。

示例

public function getCMSFields()
{
    // get the current locale
    $locale = Translatable::get_current_locale();

    return new FieldList(
        $this->getLocalizedFormField('Title', $locale),
        $this->getLocalizedFormField('Content', $locale)
    );
}

使用 TranslatableFormFieldTransformation 类或 getLocalizedFormField 方法应该提供足够的工具来构建满足大多数需求的自定义后端表单。

还有一个特别有用的辅助方法,在 ModelAdmin 上下文中(因为与 页面 部分不同,在 ModelAdmin 中您不工作在一个区域)。该辅助方法称为 getTranslatableTabSet,并将为您提供每个语言的一个单独的 TabSet。以下是使用方法

public function getCMSFields(){
    $fields = new FieldList();
    $fields->add($this->getTranslatableTabSet());
    return $fields;
}

这样做将为每种语言提供一个选项卡,每个选项卡包含可翻译的表单字段。如果您有尚未翻译但仍然需要通过后端编辑的字段,请按照以下方式操作

public function getCMSFields(){
    $fields = new FieldList();
    $fields->add($this->getTranslatableTabSet());

    // add all "Global" fields to another tab
    $fields->addFieldsToTab('Root.Global', array(
        new TextField('NotTranslatedField'),
        new UploadField('MyImage')
        // etc...
    ));

    return $fields;
}

文件和图片

通常您还希望翻译文件类的某些字段。通过添加以下配置启用翻译很简单

# in your mysite/_config/config.yml

# Make 'Title' and 'Content' of Files translatable
File:
  extensions:
    - TranslatableDataObject
    - TranslatedFile
  translatable_fields:
    - Title
    - Content

TranslatedFile 扩展将在 CMS 的 文件 部分为每种语言生成一个选项卡。此外,它添加了一个辅助方法(getUploadEditorFields),当在区域上下文中时可以使用。您可以使用此方法为编辑 UploadField 中的文件提供翻译字段。以下是一个示例

$imageUpload = UploadField::create('Image');
$imageUpload->setFileEditFields('getUploadEditorFields');

用法和模板

每当您需要访问您的 DataObjects 时,请记住使用 $this->Master()->Relation() 而不是 $this->Relation()

Master()translatable-dataobject/code/extensions/TranslatableUtility.php 中的一个方便的方法。此扩展将自动在安装可翻译-dataobject 模块时添加到每个 SiteTree 对象。它是一个辅助方法,用于获取页面的主翻译,也可以在模板中非常有用。因此,如果您想在模板中输出所有推荐语,您将使用

    <h1>$Title</h1> <!-- Page Title -->
    <p>$Content</p> <!-- Page Content -->
    <% loop Master.Testimonials %>
        <h2>$T(Title)</h2> <!-- Localized Title -->
        $T(Content) <!-- Localized Content -->
    <hr/>
    <% end_loop %>

另一个在模板中使用的有用方法是 Languages。它将返回一个包含所有所需信息的 ArrayList,以构建语言导航。在模板中添加以下内容

    <ul class="langNav">
        <% loop Languages %>
        <li><a href="$Link" class="$LinkingMode" title="$Title.ATT">$Language</a></li>
        <% end_loop %>
    </ul>

或者,您可以包括预包装的模板

<% include TdLanguageSwitcher %>

这将创建一个所有可用内容语言的列表。链接将指向翻译页面,如果没有翻译,则指向该语言的首页。

待办事项

  • CMS UI 改进
  • 更好地与现有组件(如 GridField)集成
  • 更好地访问关系(例如,获取 has_one 关系时获取翻译页面)

限制

该模块当前仅支持翻译 DataObject 自身的 DB 字段。通过扩展添加的字段不可翻译。

由于此扩展向表中添加了更多字段,因此需要注意的是,本地化字段的数量和语言数量可能会对底层数据库造成问题。想象一下,一个具有10个可本地化字段的数据对象,以及一个将翻译成5种其他语言的网站。这将向表中添加50列。

根据MySQL文档,MySQL表列数的硬限制为4096,这对于大多数设置来说应该是足够的。但是,其他关系数据库管理系统可能具有不同的限制。