在写我个人网站时,我是想通过接口返回分页数据,没成想,我是用的 Laravel 10 给我返回的居然是一个英文。我的本意是返回中文的。
我再看看 API,确实:
- {
- url: null,
- label: "« Previous",
- active: false
},
好吧,我有必要在 Laravel 上,写一个“本地化”了,默认返回中文。
但是要做这件事情,我们就需要来看看 Laravel 是怎么实现这个【本地化】功能的,返回英文内容的。
且看源代码截图:
我先看看在 Translation\lang\en\pagination.php
里,是不是真有分页的内容:
<?php
return [
'previous' => '« Previous',
'next' => 'Next »',
];
果不其然,既然已经找到了。那我们开始研究【Translation】源代码之旅吧。
源代码
加上上文的截图和 Contracts\Translation
中的三个文件:
整个 Translation 组件一共不超过12个核心功能文件。
阅读源代码,那肯定还是从 ServiceProvider 开始,看 TranslationServiceProvider:
<?php
namespace Illuminate\Translation;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
class TranslationServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerLoader();
$this->app->singleton('translator', function ($app) {
$loader = $app['translation.loader'];
// When registering the translator component, we'll need to set the default
// locale as well as the fallback locale. So, we'll grab the application // configuration so we can easily get both of these values from there. $locale = $app->getLocale();
$trans = new Translator($loader, $locale);
$trans->setFallback($app->getFallbackLocale());
return $trans;
});
}
/**
* Register the translation line loader.
*
* @return void
*/
protected function registerLoader()
{
$this->app->singleton('translation.loader', function ($app) {
return new FileLoader($app['files'], [__DIR__.'/lang', $app['path.lang']]);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['translator', 'translation.loader'];
}
}
注册两个 Provides:translator
和 translation.loader
。先注册 translation.loader
$this->app->singleton('translation.loader', function ($app) {
return new FileLoader($app['files'], [__DIR__.'/lang', $app['path.lang']]);
});
先不看 FileLoader
类,字面上理解就是先载入 lang
文件夹里的内容,即我们自定义的【本地化】语音文件,从 en
的案例可以看出每一个文件都是一个数组 php
文件内容,至于有没有其他格式的,我们后面再看。
测试使用
那我们就按他说的,先创建 lang
目录用于存放翻译内容。我们可通过 lang:publish
Artisan 命令构建 lang
目录。
php artisan lang:publish
直接把组件的 en
目录内容 copy 过来,那我们依葫芦画瓢,也创建一个中文【zh_CN】目录,只有pagination.php
测试使用。
<?php
return [
'previous' => '« 最先',
'next' => '最后 »',
];
接着看下一个 Provide:
$this->app->singleton('translator', function ($app) {
$loader = $app['translation.loader'];
$locale = $app->getLocale();
$trans = new Translator($loader, $locale);
$trans->setFallback($app->getFallbackLocale());
return $trans;
});
这里有几个参数,需要我们关注:getLocale()
,getFallbackLocale()
,字面上的意思是获取设置的本地化 locale
和 fallbacklocale
值。我们看看这两个值在哪设置的。放出 PHPStorm
大招搜一搜,在 welcome.blade.php
上有用到,直接追溯到 Foundation
:
/**
* Get the current application locale. * * @return string
*/
public function getLocale()
{
return $this['config']->get('app.locale');
}
得,按常理,我们也能猜到这种配置基本都在config
配置好,其中 fallbacklocale
表示备选 locale
。直接看配置内容:
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'zh_CN',
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
'fallback_locale' => 'en',
最简单的配置和翻译文件都有了,直接运行,看看是不是显示成中文的了:
完美
注
很多人都在讨论是 zh-CN
还是zh_CN
?直接看类 MessageSelector
代码,借鉴它的写法:
到目前为止,基本把使用说了,下一步继续走读源代码。