leanadmin/gloss

为 Laravel 提供卓越的本地化支持

资助包维护!
stancl

v0.1.11 2023-02-16 10:38 UTC

This package is auto-updated.

Last update: 2024-09-16 13:58:29 UTC


README

Gloss 是一个 Laravel 包,用于高级本地化。

Laravel 的本地化系统对许多语言来说都很完美,但当您需要更多控制时,它就会失效。

例如,一些语言中的单词会根据它们所在的环境而改变。单词可能会被前缀或后缀,甚至完全改变。

除了支持复杂语言外,Gloss 还提供了一些生活质量的改进,例如可以向翻译字符串添加格式。

安装

需要 Laravel 6 或 8,需要 PHP 7.4。

composer require leanadmin/gloss

配置

默认情况下,Gloss 附带 gloss() 辅助函数和 ___() 辅助函数。

如果您愿意,您可以通过设置禁用 ___() 辅助函数

use Gloss;

Gloss::$underscoreHelper = false;

如果您希望使所有现有的 __() 调用都了解 Gloss

use Gloss;

Gloss::$shouldReplaceTranslator = true;

这些调用的好地方是您的 LeanServiceProviderAppServiceProviderboot() 方法。

用法

Gloss 可以像标准的 Laravel 本地化辅助函数一样使用

___('Create :Resource', ['resource' => 'product']);

// 'resources.edit' => 'Show :Resource :title'
gloss('resources.create', ['resource' => 'product', 'title' => 'MacBook Pro 2019']); // Show Product MacBook Pro 2019

// 'notifications.updated' => ':Resource :title has been updated!'
Gloss::get('resources.edit', ['resource' => 'product', 'title' => 'iPhone 12']); // Product iPhone 12 has been updated!

// 'foo.apple' => 'There is one apple|There are many apples'
Gloss::choice('foo.apple', ['count' => 2]); // There are many apples

但是,与标准的本地化不同,它允许您在运行时更改这些字符串

值覆盖

想象一下,您正在编辑管理面板中的 Order 资源。您的资源单数标签是 Objednávka,这是捷克语中的 Order

创建按钮的语言字符串是

// Original in English: 'create' => 'Create :Resource',
'create' => 'Vytvořit :Resource',

如果我们用资源名称填充值,我们得到 Vytvořit Objednávka。不幸的是,这不仅是错误的,而且是两次错误。

首先,它应该是 Objednávku,因为后缀会根据上下文而变化。其次,在这里首字母大写是不合语法的。

- Vytvořit Objednávka
+ Vytvořit objednávku

因此,我们希望在 Order 资源上下文中指定该语言字符串的完整覆盖。

为此,只需调用

Gloss::value('resource.create', 'Vytvořit objednávku');

(从适当的位置,应用程序正在处理 Order 资源。)

如果您使用 Lean,这将为您处理。您只需在资源的 $lang 属性中定义整个语言字符串,它们将在使用资源的所有模板中使用。

请注意,上面的例子中提到了资源,但这只是 Lean 的实现方式。Gloss 适用于任何设置。

您还可以在单个调用中设置多个值覆盖

Gloss::values([
    'resource.create' => 'Vytvořit objednávku',
    'resource.edit' => 'Upravit objednávku',
]);

您也可以使用 gloss() 辅助函数来做到这一点。只需将数组作为第一个参数传递。

作用域覆盖

有时您可能想要限定您的覆盖范围。例如,您可能只想在 resource 参数是 order 时覆盖所有 resource.create

为此,传递第三个参数

Gloss::value('resource.create', 'Vytvořit objednávku', ['resource' => 'order');

条件也可以传递给 values()

Gloss::values([
    'resource.create' => 'Vytvořit objednávku',
    'resource.edit' => 'Upravit objednávku',
], ['resource' => 'order']);

或者当设置覆盖时,传递给 gloss() 辅助函数

gloss([
    'resource.create' => 'Vytvořit objednávku',
    'resource.edit' => 'Upravit objednávku',
], ['resource' => 'order']);

键覆盖

基于上面的例子,假设我们的管理面板使用多种语言。因此,用代码中的翻译替换语言字符串是不可行的。

因此,Gloss 还允许您将键别名到其他键

// 'orders.create' => 'Vytvořit objednávku',
// 'resources.create' => 'Vytvořit :resource',

Gloss::key('resource.create', 'orders.create');

这相当于使用翻译辅助函数获取值。

Gloss::value('resource.create', gloss('orders.create'));
Gloss::key('resource.create', 'orders.create');

value() 一样,您可以通过传递条件

Gloss::key('resource.create', 'orders.create', ['resource' => 'order');

扩展值

您还可以基于完全解析的语言字符串构建。

例如,考虑以下示例

Showing <strong>10</strong> to <strong>20</strong> of <strong>50</strong> results.

为了本地化,我们可能需要单独本地化每个单词(这是Laravel的做法,效果类似于“订单”这个词的例子),或者将标记添加到翻译字符串中(这对安全性、翻译员的生活质量都不好),或者完全放弃格式化。

这些都是不必要的权衡。

Gloss允许在字符串完全构建后添加格式

// 'pagination' => 'Showing :start to :end of :total results',

Gloss::extend('foo.pagination', fn ($value, $replace) => $replace($value, [
    ':start' => '<span class="font-medium">:start</span>',
    ':end' => '<span class="font-medium">:end</span>',
    ':total' => '<span class="font-medium">:total</span>',
]));

Gloss::get('foo.pagination', ['start' => 10, 'end' => 20, 'total' => 50])
// Showing <span class="font-medium">10</span> to <span class="font-medium">20</span> of <span class="font-medium">50</span> results

当然,extend()与本地化字符串完美配合

// 'pagination' => 'Zobrazeno :start až :end z :total výsledků',

// Zobrazeno <span class="font-medium">10</span> až <span class="font-medium">20</span> z <span class="font-medium">50</span> výsledků

它甚至适用于复数/基于选择的字符串

// 'apples' => '{0} There are no apples|[1,*]There are :count apples'

Gloss::extend('foo.apples', fn ($apples, $replace) => $replace($apples, [
    ':count' => '<span class="font-medium">:count</span>',
]));

gloss()->choice('foo.apples', 0); // There are no apples
gloss()->choice('foo.apples', 5); // There are <span class="font-medium">5</span> apples

第二个参数是一个可调用的函数,它可以返回任何字符串,但在大多数情况下,这仅仅是将一些片段替换后的解析字符串。

因此,Gloss自动将$replace传递给可调用的函数,这让你可以使用美观的、箭头函数兼容的语法替换字符串的部分。

// So elegant!

fn ($string, $replace) => $replace($string, [
   'elegant' => 'eloquent',
]);

// So eloquent!

可调用的翻译字符串

Gloss还添加了对可调用翻译字符串的支持。

当您有一些处理诸如屈折(名词的屈折变位)之类的代码时,这很有用。

例如,考虑这三个语言字符串

'index' => ':resources',
'create' => 'Create :resource',
'edit' => 'Edit :resource :title',
'delete' => 'Delete :resource :title',

在许多有屈折的语言中(如名词的屈折变位,更多关于本地化复杂性的信息请参阅我们的文档),:Resource的形式对于创建编辑删除都是相同的。

没有必要手动翻译每个字符串,这会很痛苦。更好的解决方案是使用智能屈折逻辑作为默认设置,同时仍保留在需要时手动更改特定字符串的选项。

'index' => fn ($resource) => nominative($resource, 'plural'),
'create' => fn ($resource) => 'Vytvořit ' . oblique($resource, 'singular'),
'edit' => fn ($resource, $title) => 'Upravit ' . oblique($resource, 'singular') . $title,
'delete' => fn ($resource, $title) => 'Smazat ' . oblique($resource, 'singular') . $title,

您可以为默认值使用这样的逻辑(配合您自己的辅助函数),只在某些单词有非标准的语法规则并需要自定义值时使用覆盖。