Skip to main content

[CoronaSDK] 多國語系支援



CoronaSDK 中取得 Android 與 iOS 語系方法並不相同,繁體與簡體取得名稱也不一樣,為了簡化兩系統的繁體與簡體語系支持,所以特別打包了一支函式來控制多國語設定,之前一直忘了分享出來也剛好很久沒更新 Blog 了...=D

使用方法很簡單:
將語系字串放在 locale/ 並以 strings.i18n(預設)與 strings_[ISO_639-1].i18n
繁體共用命名:zh_hant
簡體共用命名:zh_hans

語系字串資料採用 JSON 格式:
locale/strings.i18n
{
"hello" : "Hello",
"welcome" : "Welcome"
}


locale/strings_zh_hant.i18n
{
"welcome" : "歡迎"
}


執行:Global function
L( str: String ) -> String
Usage:

local i18n = require( "i18n" )
-- set device language -> locale/strings_[device setting].i18n
i18n.setLocale()
-- 假使目前語系為 i18n.language = "zh_hant"
print( L("hello"), L("welcome"), L("no data"))
-- Hello 歡迎 no data

-- 動態更改支援語系到預設值
i18n.setLocale("")
print( L("hello"), L("welcome"), L("no data"))
-- Hello Welcome no data


備註:僅測試於 Android 與 iOS 系統,如其他裝置需要做修正的話,請自行 DIY。

-------------------------------------
-- i18n
-- Copyright (c) 2015 Erin Lin
-- erinylin.com
-- Licensed under the MIT license.
-------------------------------------
--[[
All strings files are under a folder names "locale"
Internationalization string file format:
Default
locale/strings.i18n
{
"hello" : "Hello",
"welcome" : "Welcome"
}
Traditional Chinese : zh_hant
locale/strings_zh_hant.i18n
{
"hello" : "哈囉",
"welcome" : "歡迎"
}
Simplified Chinese : zh_hans
locale/strings_zh_hans.i18n
{
"hello" : "哈啰",
"welcome" : "欢迎"
}
-------------------------------------
Usage:
-------------------------------------
local i18n = require( "i18n" )
-- set device language -> locale/strings_[device setting].i18n
i18n.setLocale()
-- set default language, -> locale/strings.i18n
i18n.setLocale("")
-- set specific language
i18n.setLocale("zh_hant") -> locale/strings_zh_hant.i18n
-- golbal localization string function L( str )
print( "hello", L("hello") )
print( "Current language:", i18n.language )
--]]
-------------------------------------
local json = require("json")
local M = {}
local string_gsub = string.gsub
local string_format = string.format
local string_find = string.find
function string_split(self, sep)
local sep, fields = sep or ":", {}
local pattern = string_format("([^%s]+)", sep)
string_gsub(self, pattern, function(c) fields[#fields+1] = c end)
return fields
end
local i18n = (function()
local I18N = {}
local I18N_mt = { __index = I18N }
local function loadTable(filename, dir)
local path = system.pathForFile( filename, dir or system.DocumentsDirectory)
if path then
local file = io.open( path, "r" )
if file then
local contents = file:read( "*a" )
io.close( file )
return (json.decode(contents))
end
end
print(filename, "file not found")
return nil
end
function I18N.new(locale, dir) -- The constructor
local resource = "strings"
local dir = dir or system.ResourceDirectory
local object = {
language = locale or nil,
strings = {}
}
local isSimulator = system.getInfo('environment') == 'simulator'
local function formatString( str )
str = string_gsub( str:lower(), "-", "_" )
local temp = string_split(str,"_")
str = temp[1]
-- 中文同步 繁體: zh_hant, 簡體:zh_hans
-- iOS9 fixed
local temp2 = temp[2]
if temp2=="tw" or temp2=="hk" then
str = str.."_hant"
elseif temp2=="cn" then
str = str.."_hans"
else
str = str.."_"..temp2
end
return str
end
if object.language==nil then
object.language = ""
if system.getInfo('platformName')=="iPhone OS" or isSimulator then
locale = system.getPreference( "ui", "language" )
else
locale = system.getPreference( "locale", "identifier" )
if not string_find( locale , "zh_" ) then
locale = system.getPreference( "locale", "language" )
end
end
locale = formatString( locale )
object.language = locale
end
if locale=="default" then object.language="" end
local files = {
"locale/"..resource..".i18n",
"locale/"..resource.."_"..object.language..".i18n"
}
local lang = locale
local strmap = {}
local origin = loadTable( files[1], dir )
assert(origin, "Default locale/strings.i18n file must be provide.")
local temp = loadTable( files[2], dir )
if temp then lang = object.language end
strmap = temp or strmap
-- fill in default value
for k,v in next, (origin) do
if not strmap[k] then
strmap[k]=v
end
end
object.strings = strmap
return setmetatable( object, I18N_mt ), (lang=="" and "default" or lang)
end
function I18N:getString(key)
return self.strings[key]
end
return I18N
end)()
M.setLocale = function( ... )
local _i18n
_i18n, M.language = i18n.new(... )
_G.L = function(str)
return _i18n:getString(str) or str
end
return M.language
end
return M
view raw i18n.lua hosted with ❤ by GitHub

Comments

Popular posts from this blog

[Flex] PureMVC standard with Spring extensions

由於上次稍微玩了一下 Robotlegs 依賴注入(DI) 主導的 MVC 框架,而著名也使用依賴注入的 Java / Java EE 的 Spring framework 出了 for ActionScript 的版本,剛好在最近 Spring ActionScript 1.0 正式 release 了(想了解 Spring 是啥咪東東的話請自行找 google 大神),這個版本除了基本框架外,也包含了 Cairngorm 與 PureMVC 的外掛...想當然耳,就拿來測試一下用在 PureMVC 內的感覺囉!! 參考了 官方範例 中 PureMVC 唯二的範例原始檔,以下使用的是「設定檔依賴注入 facade 透過 addConfigSource() 的方式來 init 」:(其實除了 embed 外,都是外部載入) Online Demo with source code 工作環境:FlashBuilder, Flex SDK4 請下載 PureMVC Standard 版本 再下載 Spring ActionScript 最新版本後,除了 spring-actionscript-cairngorm 不需要外,都放到 /src 下(記得只需要 org 開始...),也別忘了lib 內的 swc 檔 copy 到 /libs 下 Spring 的 injection 並不像 Robotlegs 直接來個 [Inject] metadata 的自動化那樣方便,但是其冷血度(檔案的鬆偶程度)更勝後者!如果你要使用設定檔(applicationContext.xml) 來做注入的話,準備工作就挺多的...XD 依照 applicationContext.xml 內設定的方式分別寫入 constructor 或者是 setter 依賴注入(本範例統一使用 setter injection) 為了跟大家都沒關係所以都使用 interface 來處理,所以你會在範例中發現大家都有介面...(並沒有真的研究過 Spring,也許還有其他作法) 準備 compiler 時候要用的 classe。由於在 setter, getter 的寫法上都使用 interface,所以真正用到的 class 需要預先在輸出階段就打包到程式內。 基本上 PureMVC 類 class...

[AIR] JoSi FXGtoLayout

JoSi FXGtoLayout v0.3.0, Adobe AIR 3 runtime 這個又是一個 "就是" 系列懶人小工具,主要是針對 Adobe fxg 格式做分析轉成 Mobile 開發用的視圖程式碼,加速畫面配置使用。 為什麼會製作這個工具,原因主要是本人在使用的 Corona SDK 與 Titanium SDK 都沒有好用的視覺化編輯工具。一般設計師產出 layout 檔會使用 PhotoShop 來製作,在不多花錢的原則下,畫面對齊的基準就是其輸出的 fxg 資料做對應,如果要一筆一筆將資料鍵入,做久也是會膩的,所以花了點時間將這個工具做出來...