terminal42 / dc_multilingual
一个多语言DC驱动,用于Contao开源CMS,将翻译存储在同一张表中
Requires
- php: ^8.1
- contao/core-bundle: ^5.1
Requires (Dev)
- contao/manager-plugin: ^2.0
- terminal42/contao-build-tools: dev-main
Conflicts
- contao/manager-plugin: <2.0 || >=3.0
- dev-main
- 4.5.4
- 4.5.3
- 4.5.2
- 4.5.1
- 4.5.0
- 4.4.1
- 4.4.0
- 4.3.1
- 4.3.0
- 4.2.3
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.4
- 4.1.3
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 3.0.8
- 3.0.7
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.1
- 2.0.0
- dev-bugfix/model-id
- dev-hotfix/3.0.9
- dev-support/3.0
- dev-support/2.1
This package is auto-updated.
Last update: 2024-09-08 09:37:21 UTC
README
这是一个独立的DC驱动,用于Contao开源CMS,允许您轻松地使数据可翻译。
DCA配置
// Set the driver $GLOBALS['TL_DCA']['table']['config']['dataContainer'] = \Terminal42\DcMultilingualBundle\Driver::class; // Languages you want to provide for translation (default: Languages of all root pages) $GLOBALS['TL_DCA']['table']['config']['languages'] = ['en', 'de', 'pl']; // Database column that contains the language keys (default: "language") $GLOBALS['TL_DCA']['table']['config']['langColumnName'] = 'language'; // Database column that contains the reference id (default: "langPid") $GLOBALS['TL_DCA']['table']['config']['langPid'] = 'langPid'; // Fallback language - if none is given then there will be another language "fallback" selectable from the dropdown $GLOBALS['TL_DCA']['table']['config']['fallbackLang'] = 'en'; // Use '*' to make a field translatable for all languages $GLOBALS['TL_DCA']['table']['fields']['username']['eval']['translatableFor'] = '*'; // Use an array of language keys to specify for which languages the field is translatable $GLOBALS['TL_DCA']['table']['fields']['name']['eval']['translatableFor'] = ['de']; // Note: // If you don't use ['eval']['translatableFor'] and the user is not editing the fallback language, then the field will be hidden for all the languages
示例用法
// Update tl_news configuration $GLOBALS['TL_DCA']['tl_news']['config']['dataContainer'] = \Terminal42\DcMultilingualBundle\Driver::class; $GLOBALS['TL_DCA']['tl_news']['config']['languages'] = ['en', 'de', 'pl']; $GLOBALS['TL_DCA']['tl_news']['config']['langPid'] = 'langPid'; $GLOBALS['TL_DCA']['tl_news']['config']['langColumnName'] = 'language'; $GLOBALS['TL_DCA']['tl_news']['config']['fallbackLang'] = 'en'; // Add the language fields $GLOBALS['TL_DCA']['tl_news']['config']['sql']['keys']['langPid'] = 'index'; $GLOBALS['TL_DCA']['tl_news']['config']['sql']['keys']['language'] = 'index'; $GLOBALS['TL_DCA']['tl_news']['fields']['langPid']['sql'] = "int(10) unsigned NOT NULL default '0'"; $GLOBALS['TL_DCA']['tl_news']['fields']['language']['sql'] = "varchar(2) NOT NULL default ''"; // Make some fields translatable $GLOBALS['TL_DCA']['tl_news']['fields']['headline']['eval']['translatableFor'] = '*'; $GLOBALS['TL_DCA']['tl_news']['fields']['subheadline']['eval']['translatableFor'] = ['de'];
使用模型进行查询
class NewsModel extends Terminal42\DcMultilingualBundle\Model\Multilingual { protected static $strTable = 'tl_news'; public static function findPublished() { return static::findBy(['t1.published=?'], [1]); } }
内部工作原理
基本上,驱动器只将翻译存储到同一张表中,使用“langPid”列(或您配置的任何列)建立与其父条目的关系。在后台列表和树视图中,它确保翻译被过滤,以便您只能在那里看到后备语言。当使用Multilingual
模型或使用MultilingualQueryBuilder
进行查询时,简单地将相同的表连接起来,这样我们就有后备语言别名为t1
和目标语言(您明确指定的或使用当前页面的语言)别名为translation
。现在,使用MySQL的IFNULL()
函数,它会检查是否存在翻译值,如果没有,则自动回退到后备语言。这允许您仅翻译字段的一部分。
别名处理
您可以将所有翻译的别名共享,因此您会得到类似这样的结果
* EN: domain.com/my-post/my-beautiful-alias.html
* DE: domain.de/mein-artikel/my-beautiful-alias.html
* FR: domain.fr/mon-post/my-beautiful-alias.html
这可以通过使用您可能从其他模块(如新闻等)在后台了解的常规别名处理来实现。对于前端,您只需使用Multilingual
模型提供的findByAlias()
方法即可
MyModel::findByAlias($alias);
然而,有许多情况下,您可能希望将别名翻译成这样
* EN: domain.com/my-post/my-beautiful-alias.html
* DE: domain.de/mein-artikel/mein-wunderschoenes-alias.html
* FR: domain.fr/mon-post/mon-alias-magnifique.html
在后台,这稍微困难一些,因为现在没有检查整个表中是否有重复别名的意义,但只有在相同语言的全表中才有意义。为了尽可能方便您,只需在您的alias
字段上使用以下eval
定义即可
'eval' => [ 'maxlength' => 255, 'rgxp' => 'alias', 'translatableFor' => '*', 'isMultilingualAlias' => true, 'generateAliasFromField' => 'title' // optional ("title" is default) ],
它将自动生成别名(如果尚未存在),并在相同语言内检查重复项。
然后您可以在前端通过多语言别名进行搜索
MyModel::findByMultilingualAlias($alias);
与Doctrine实体一起使用
由于驱动器只从后台将数据写入数据库,因此它与前端使用Doctrine实体完全兼容。目前,您必须自己处理翻译。以下是一个实体的示例
#[Entity()] #[Table('tl_my_entity')] class MyEntity { #[Id] #[GeneratedValue('IDENTITY')] #[Column(options: ['unsigned' => true])] private int $id; #[Column(options: ['unsigned' => true, 'default' => 0])] private int $tstamp; #[OneToMany('parent', self::class)] protected $translations; #[ManyToOne(self::class, inversedBy: 'translations')] #[JoinColumn('langPid')] protected $parent; #[Column(length: 5, options: ['default' => ''])] protected string $language; // ... any other properties of your entity }
有用的注意事项
- 有时,您想要使其多语言化的表已经包含
language
字段(例如tl_user
),这可能会导致意外结果。在这种情况下,您必须确保数据容器的属性$GLOBALS['TL_DCA']['tl_table']['config']['langColumnName']
设置为不是language
的任何内容。有关更多详细信息,请参阅#53。