背景
laravel 的本地化功能提供了一种方便的方法来检索各种语言的字符串,从而可以轻松的在应用内支持多种语言,我们一般将语言文件存放在 lang
目录下,随后使用 __
辅助函数从语言文件检索翻译字符串。同样,laravel-admin 也使用这种方式来实现本地化,但这个目录是公共翻译路径,如果同一个键在不同控制器翻译的结果不一致情况,将翻译内容直接放置在 lang
就会造成一定的歧义
为了解决此问题,本文介绍根据控制器来区分不同的翻译文件
代码部分
SwitchLanguage.php
新建 app\Admin\Middleware\SwitchLanguage.php
文件
<?php
namespace App\Admin\Middleware;
use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Cookie; use Illuminate\Support\Facades\App; use Illuminate\Support\Str;
class SwitchLanguage {
public function handle(Request $request, Closure $next) { $multi_language = config('admin.multi_language'); $languages = $multi_language['languages']; $current = $multi_language['default']; $cookie_name = $multi_language['cookie_name']; $cookie_language = Cookie::get($cookie_name); if (!$cookie_language || !array_key_exists($cookie_language, $languages)) { $cookie_language = $current; } App::setLocale($cookie_language);
$controller = $request->route()->controller; if (!$controller) { return $next($request); }
if (strtolower(substr($controller_name, -10)) === 'controller' and Str::startsWith($controller_name, 'App\\Admin\\Controllers\\')) { $controller_name = str_replace('App\\Admin\\Controllers\\', '', $controller_name); $controller_name = substr($controller_name, 0, strlen($controller_name) - 10); $translator_path = config('admin.multi_language.lang_directory') . str_replace('\\', DIRECTORY_SEPARATOR, $controller_name . DIRECTORY_SEPARATOR); app('translator')->addJsonPath($translator_path); } return $next($request); } }
|
新建 app/Admin/Widgets/LanguageMenu.php
文件
<?php
namespace App\Admin\Widgets;
use Illuminate\Contracts\Support\Renderable; use Illuminate\Support\Facades\Cookie;
class LanguageMenu implements Renderable {
public function render() { $multi_language = config('admin.multi_language'); $languages = $multi_language['languages']; $current = $multi_language['default']; $cookie_name = $multi_language['cookie_name']; if(Cookie::has($cookie_name)) { $cookie_current = Cookie::get($cookie_name); if (array_key_exists($cookie_current, $languages)) { $current = $cookie_current; } } return view('admin.widgets.lang_menu', compact('languages', 'current', 'cookie_name'))->render(); } }
|
新建 resources/views/admin/widgets/lang_menu.blade.php
文件
<li class="dropdown messages-menu"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <i class="fa fa-language"></i> </a> <ul class="dropdown-menu" style="height: 83px;"> <li> <ul class="menu">
@foreach($languages as $key => $language) <li> <a class="language" href="#" data-id="{{$key}}"> {{$language}} @if($key == $current) <i class="fa fa-check pull-right"></i> @endif </a> </li> @endforeach </ul> </li> </ul> </li> <script> $(function () { $(".language").click(function () { let id = $(this).data('id'); $.ajax({ url: '{{ route('admin.setLocation') }}', type: 'POST', data: { _token: LA.token, location: id }, success: function (data) { location.reload(); } }); }); }); </script>
|
bootstrap.php
在 app/Admin/bootstrap.php
新增如下代码:
Admin::navbar(function (\Encore\Admin\Widgets\Navbar $navbar) { $navbar->right(new \App\Admin\Widgets\LanguageMenu()); });
|
routes.php
在 app/Admin/routes.php
中新增路由:
$router->post('setLocation', function () { $cookie_name = config('admin.multi_language.cookie_name');
$location = request()->input('location'); $cookie = cookie($cookie_name, $location, 60 * 24 * 365); return response()->json(['status' => true,])->withCookie($cookie); })->name('setLocation');
|
admin.php
在 config/admin.php
新增如下配置:
'multi_language' => [ 'lang_directory' => resource_path('lang_admin') . DIRECTORY_SEPARATOR, 'languages' => [ 'en' => 'English', 'zh-CN' => '简体中文', ], 'default' => 'zh-CN', 'cookie_name' => 'backend_locale', ],
|
最后在 config/admin.php
中添加该中间件:
'route' => [
'prefix' => env('ADMIN_ROUTE_PREFIX', 'admin'),
'namespace' => 'App\\Admin\\Controllers',
- 'middleware' => ['web', 'admin'], + 'middleware' => ['web', 'admin', \App\Admin\Middleware\SwitchLanguage::class], ],
|
后续操作
随后在 resources/lang_admin/控制器名/区域名.json
中新增翻译内容即可,例如给 ProductsController
创建单独翻译文件,则翻译文件路径为 resources/lang_admin/Products/zh-CN.json
注意:如果翻译键值与公共翻译处冲突,则以单独的翻译文件为准。
效果