libs/web: if current language is a regional dialect, fall back to generic language...
[project/luci.git] / libs / web / luasrc / i18n.lua
1 --[[
2 LuCI - Internationalisation
3
4 Description:
5 A very minimalistic but yet effective internationalisation module
6
7 FileId:
8 $Id$
9
10 License:
11 Copyright 2008 Steven Barth <steven@midlink.org>
12
13 Licensed under the Apache License, Version 2.0 (the "License");
14 you may not use this file except in compliance with the License.
15 You may obtain a copy of the License at
16
17         http://www.apache.org/licenses/LICENSE-2.0
18
19 Unless required by applicable law or agreed to in writing, software
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
24
25 ]]--
26
27 --- LuCI translation library.
28 module("luci.i18n", package.seeall)
29 require("luci.util")
30
31 table   = {}
32 i18ndir = luci.util.libpath() .. "/i18n/"
33 loaded  = {}
34 context = luci.util.threadlocal()
35 default = "en"
36
37 --- Clear the translation table.
38 function clear()
39         table = {}
40 end
41
42 --- Load a translation and copy its data into the translation table.
43 -- @param file  Language file
44 -- @param lang  Two-letter language code
45 -- @param force Force reload even if already loaded (optional)
46 -- @return              Success status
47 function load(file, lang, force)
48         lang = lang and lang:gsub("_", "-") or ""
49         if force or not loaded[lang] or not loaded[lang][file] then
50                 local f = loadfile(i18ndir .. file .. "." .. lang .. ".lua") or
51                         loadfile(i18ndir .. file .. "." .. lang .. ".lua.gz")
52
53                 if f then
54                         table[lang] = table[lang] or {}
55                         setfenv(f, table[lang])
56                         f()
57                         loaded[lang] = loaded[lang] or {}
58                         loaded[lang][file] = true
59                         return true
60                 else
61                         return false
62                 end
63         else
64                 return true
65         end
66 end
67
68 --- Load a translation file using the default translation language.
69 -- Alternatively load the translation of the fallback language.
70 -- @param file  Language file
71 -- @param force Force reload even if already loaded (optional)
72 function loadc(file, force)
73         load(file, default, force)
74         if context.parent then load(file, context.parent, force) end
75         return load(file, context.lang, force)
76 end
77
78 --- Set the context default translation language.
79 -- @param lang  Two-letter language code
80 function setlanguage(lang)
81         context.lang   = lang:gsub("_", "-")
82         context.parent = (context.lang:match("^([a-z][a-z])_"))
83 end
84
85 --- Return the translated value for a specific translation key.
86 -- @param key   Translation key
87 -- @param def   Default translation
88 -- @return              Translated string
89 function translate(key, def)
90         return (table[context.lang] and table[context.lang][key])
91                 or (table[context.parent] and table[context.parent][key])
92                 or (table[default] and table[default][key])
93                 or def
94 end
95
96 --- Return the translated value for a specific translation key and use it as sprintf pattern.
97 -- @param key           Translation key
98 -- @param default       Default translation
99 -- @param ...           Format parameters
100 -- @return                      Translated and formatted string
101 function translatef(key, default, ...)
102         return translate(key, default):format(...)
103 end