bummzack / translatable-dataobject
Silverstripe Translatable 扩展模块,用于 DataObjects
Requires
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
,以便创建额外的数据库字段。默认情况下,所有 Varchar
、Text
和 HTMLText
字段都将被翻译,而所有其他字段保持不变。要更改这些默认字段,您可以按如下方式配置它们
# 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
,这对于大多数设置来说应该是足够的。但是,其他关系数据库管理系统可能具有不同的限制。