laravel 本地化 locale 語言包改造

laravel 的本地化 locale,用起來感覺很彆扭,不能像其他框架一樣,按照控制器等自動加載語言包。

結合文檔,並查看了源碼,簡單總結下 laravel 本地化的使用:
	1>支持引入 2 類文件:
		1.php 文件(php 文件 return 一個數組)
			不同語言包目錄下,根據用途,可創建多個 xx.php,例如:
			en
				messages.php
				other.php
			zh-cn
				messages.php
					<?php
						return [
							'name' => '姓名',
							'gender' => '性別',
						];
				other.php

			使用:
				__('message.name')

		2.json 文件(必須是json格式)
			不同語言包,只能是以 '不同語言' 命名的 json 文件	
				/path1/en.json
				/path1/zh-cn.json
					{
						'name': '姓名',
						'gender': '性別'
					}

			但是允許我們添加多個路徑
				/path2/en.json
				/path2/zh-cn.json

			使用:
				__('name')

			但多個路徑,對於我們項目組織語言包目錄結構,貌似沒啥用...

	2>一般使用 2 個函數:
		__('messages.name') 或 trans('messages.name'),__() 是 trans() 別名

		trans_choice('messages.minutes', 10) - 對於複數形式的處理

	3>關於 key 參數:
		當引入的 php 文件,必須使用 '文件名.鍵名',文檔中提到的 '使用短鍵'

		當引入的 json 文件,只使用 '鍵名',文檔中提到的 '使用翻譯字符串作爲鍵'

	4>重寫擴展包的語言文件
		laravel 的語言包,還支持使用 '命名空間',應該是 key 可以是 
			'namespace::message.name'

		部分擴展包可能會附帶自己的語言文件,我們可以在 resources/lang/vendor/{package}/{locale} 下放置語言包文件,來重寫

	5>總結,laravel 的語言包的 key,通過 '::' 和 '.' 進行解析,從而得到:
			namespace::group.item
		然後來進行字符串的替換

		裏面還有一些其他使用原則,例如:
			json 文件的引用,我們可以添加過個 json 路徑:
				use Lang;
				Lang::addJsonPath('path1');
				Lang::addJsonPath('path2');

			namespce 的引用,我們得先添加 namespace:
				use Lang;
				Lang::addNamespace('namespace1');
				Lang::addNamespace('namespace2');

好了,簡單的介紹到這,寫的有點亂,有些東西不好描述。最好是分析下源碼
接下來繼續我們的主題,我們想按照 '控制器' 自動加載語言包(或者可以說是,任意加載不同的語言包文件):
	
改造:
	vendor/laravel/framework/src/Illuminate/Translation/Translator.php

		文件末尾,添加 addCustomFile() 方法:
		    /**
		     * 添加自定義文件
		     */
		    public function addCustomFile($file)
		    {
		        $this->loader->addCustomFile($file);
		    }
	

	vendor/laravel/framework/src/Illuminate/Translation/FileLoader.php

		屬性末尾,添加 $customFiles 屬性
	    /**
	     * 所有的自定義文件
	     */
	    protected $customFiles = [];

		修改 load() 方法:
		    public function load($locale, $group, $namespace = null)
		    {
		        if ($group === '*' && $namespace === '*') {
		            // return $this->loadJsonPaths($locale);

		            /*
		                這裏我們進行重構,額外支持加載自定義的語言包路徑
		             */
		            $jsonFileMessages = $this->loadJsonPaths($locale);
		            $customFileMessages = $this->loadCustomFiles($locale);

		            return array_merge($jsonFileMessages, $customFileMessages);
		        }

		        if (is_null($namespace) || $namespace === '*') {
		            return $this->loadPath($this->path, $locale, $group);
		        }

		        return $this->loadNamespaced($locale, $group, $namespace);
		    }

		文件末尾,添加 loadCustomFiles(), addCustomFile() 方法:
		    /**
		     * 從給定的文件中加載語言包
		     */
		    protected function loadCustomFiles($locale)
		    {
		        return collect($this->customFiles)
		            ->reduce(function ($output, $file) use ($locale) {
		                if ($this->files->exists($file)) {
		                    $messages = $this->files->getRequire($file);
		                    $output = array_merge($output, $messages);
		                }

		                return $output;
		            }, []);
		    }

		    /**
		     * 添加自定義文件
		     */
		    public function addCustomFile($file)
		    {
		        $this->customFiles[] = $file;
		    }

使用:
	lang/zh-cn/admin/admin.php
		<?php
			return [
				'name' => '姓名',
				'avatar' => '頭像',
			];

	/*
		對於未改造前,我們想得到 name 的中文,laravel 其實是不支持的,laravel 默認只能是 zh-cn/ 的文件,不能再嵌套目錄。

		查看源碼,其實有種手法也可以實現,key 帶上文件目錄層級:
			__('admin/admin.name')	
	 */ 

	改造後:
		use Lang;
	    Lang::addCustomFile(resource_path('lang/zh-cn/admin/admin.php'));

	    __('name')

    注意:
    	可添加任意的絕對文件路徑,必須是 .php 文件,同時 return 一個數組


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章