libs/web: rework DynamicList widget
[oweals/luci.git] / libs / web / luasrc / i18n.lua
index 5f0ee8a0110de4c412ff168637ad00afd1db6dfa..816d90310af692298b830b6cbbd8be47ebc1eaae 100644 (file)
@@ -12,9 +12,9 @@ Copyright 2008 Steven Barth <steven@midlink.org>
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
-You may obtain a copy of the License at 
+You may obtain a copy of the License at
 
 
-       http://www.apache.org/licenses/LICENSE-2.0 
+       http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
@@ -26,10 +26,11 @@ limitations under the License.
 
 --- LuCI translation library.
 module("luci.i18n", package.seeall)
 
 --- LuCI translation library.
 module("luci.i18n", package.seeall)
-require("luci.sys")
+require("luci.util")
+require("lmo")
 
 table   = {}
 
 table   = {}
-i18ndir = luci.sys.libpath() .. "/i18n/"
+i18ndir = luci.util.libpath() .. "/i18n/"
 loaded  = {}
 context = luci.util.threadlocal()
 default = "en"
 loaded  = {}
 context = luci.util.threadlocal()
 default = "en"
@@ -45,13 +46,24 @@ end
 -- @param force        Force reload even if already loaded (optional)
 -- @return             Success status
 function load(file, lang, force)
 -- @param force        Force reload even if already loaded (optional)
 -- @return             Success status
 function load(file, lang, force)
-       lang = lang or ""
+       lang = lang and lang:gsub("_", "-") or ""
        if force or not loaded[lang] or not loaded[lang][file] then
        if force or not loaded[lang] or not loaded[lang][file] then
-               local f = loadfile(i18ndir .. file .. "." .. lang .. ".lua")
+               local f = lmo.open(i18ndir .. file .. "." .. lang .. ".lmo")
                if f then
                if f then
-                       table[lang] = table[lang] or {}
-                       setfenv(f, table[lang])
-                       f()
+                       if not table[lang] then
+                               table[lang] = { f }
+                               setmetatable(table[lang], {
+                                       __index = function(tbl, key)
+                                               for i = 1, #tbl do
+                                                       local s = rawget(tbl, i):lookup(key)
+                                                       if s then return s end
+                                               end
+                                       end
+                               })
+                       else
+                               table[lang][#table[lang]+1] = f
+                       end
+
                        loaded[lang] = loaded[lang] or {}
                        loaded[lang][file] = true
                        return true
                        loaded[lang] = loaded[lang] or {}
                        loaded[lang][file] = true
                        return true
@@ -69,30 +81,50 @@ end
 -- @param force        Force reload even if already loaded (optional)
 function loadc(file, force)
        load(file, default, force)
 -- @param force        Force reload even if already loaded (optional)
 function loadc(file, force)
        load(file, default, force)
+       if context.parent then load(file, context.parent, force) end
        return load(file, context.lang, force)
 end
 
 --- Set the context default translation language.
 -- @param lang Two-letter language code
 function setlanguage(lang)
        return load(file, context.lang, force)
 end
 
 --- Set the context default translation language.
 -- @param lang Two-letter language code
 function setlanguage(lang)
-       context.lang = lang
+       context.lang   = lang:gsub("_", "-")
+       context.parent = (context.lang:match("^([a-z][a-z])_"))
 end
 
 --- Return the translated value for a specific translation key.
 end
 
 --- Return the translated value for a specific translation key.
--- @param key  Translation key
--- @param def  Default translation
+-- @param key  Default translation text
 -- @return             Translated string
 -- @return             Translated string
-function translate(key, def)
+function translate(key)
        return (table[context.lang] and table[context.lang][key])
        return (table[context.lang] and table[context.lang][key])
+               or (table[context.parent] and table[context.parent][key])
                or (table[default] and table[default][key])
                or (table[default] and table[default][key])
-               or def
+               or key
 end
 
 --- Return the translated value for a specific translation key and use it as sprintf pattern.
 end
 
 --- Return the translated value for a specific translation key and use it as sprintf pattern.
--- @param key          Translation key
--- @param default      Default translation
+-- @param key          Default translation text
 -- @param ...          Format parameters
 -- @return                     Translated and formatted string
 -- @param ...          Format parameters
 -- @return                     Translated and formatted string
-function translatef(key, default, ...)
-       return translate(key, default):format(...)
-end
\ No newline at end of file
+function translatef(key, ...)
+       return tostring(translate(key)):format(...)
+end
+
+--- Return the translated value for a specific translation key
+-- and ensure that the returned value is a Lua string value.
+-- This is the same as calling <code>tostring(translate(...))</code>
+-- @param key          Default translation text
+-- @return                     Translated string
+function string(key)
+       return tostring(translate(key))
+end
+
+--- Return the translated value for a specific translation key and use it as sprintf pattern.
+-- Ensure that the returned value is a Lua string value.
+-- This is the same as calling <code>tostring(translatef(...))</code>
+-- @param key          Default translation text
+-- @param ...          Format parameters
+-- @return                     Translated and formatted string
+function stringf(key, ...)
+       return tostring(translate(key)):format(...)
+end