libs/web: prepare template parser, dispatcher and i18n class for upcoming po format change

This commit is contained in:
Jo-Philipp Wich 2009-10-31 15:42:07 +00:00
parent 7f92fa405c
commit 8f2a3f1dcc
4 changed files with 44 additions and 45 deletions

View file

@ -235,6 +235,7 @@ function dispatch(request)
include = function(name) tpl.Template(name):render(getfenv(2)) end; include = function(name) tpl.Template(name):render(getfenv(2)) end;
translate = function(...) return require("luci.i18n").translate(...) end; translate = function(...) return require("luci.i18n").translate(...) end;
striptags = util.striptags; striptags = util.striptags;
pcdata = util.pcdata;
media = media; media = media;
theme = fs.basename(media); theme = fs.basename(media);
resource = luci.config.main.resourcebase resource = luci.config.main.resourcebase

View file

@ -93,42 +93,38 @@ function setlanguage(lang)
end end
--- Return the translated value for a specific translation key. --- Return the translated value for a specific translation key.
-- @param key Translation key -- @param key Default translation text
-- @param def Default translation
-- @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[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 end
--- Return the translated value for a specific translation key and use it as sprintf pattern. --- Return the translated value for a specific translation key and use it as sprintf pattern.
-- @param key Translation key -- @param key Default translation text
-- @param default Default translation
-- @param ... Format parameters -- @param ... Format parameters
-- @return Translated and formatted string -- @return Translated and formatted string
function translatef(key, default, ...) function translatef(key, ...)
return tostring(translate(key, default)):format(...) return tostring(translate(key)):format(...)
end end
--- Return the translated value for a specific translation key --- Return the translated value for a specific translation key
-- and ensure that the returned value is a Lua string value. -- and ensure that the returned value is a Lua string value.
-- This is the same as calling <code>tostring(translate(...))</code> -- This is the same as calling <code>tostring(translate(...))</code>
-- @param key Translation key -- @param key Default translation text
-- @param default Default translation
-- @return Translated string -- @return Translated string
function string(key, default) function string(key)
return tostring(translate(key, default)) return tostring(translate(key))
end end
--- Return the translated value for a specific translation key and use it as sprintf pattern. --- 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. -- Ensure that the returned value is a Lua string value.
-- This is the same as calling <code>tostring(translatef(...))</code> -- This is the same as calling <code>tostring(translatef(...))</code>
-- @param key Translation key -- @param key Default translation text
-- @param default Default translation
-- @param ... Format parameters -- @param ... Format parameters
-- @return Translated and formatted string -- @return Translated and formatted string
function stringf(key, default, ...) function stringf(key, ...)
return tostring(translate(key, default)):format(...) return tostring(translate(key)):format(...)
end end

View file

@ -20,11 +20,12 @@
/* leading and trailing code for different types */ /* leading and trailing code for different types */
const char * gen_code[6][2] = { const char * gen_code[7][2] = {
{ "write(\"", "\")" }, { "write(\"", "\")" },
{ NULL, NULL }, { NULL, NULL },
{ "write(tostring(", " or \"\"))" }, { "write(tostring(", " or \"\"))" },
{ "include(\"", "\")" }, { "include(\"", "\")" },
{ "write(pcdata(translate(\"", "\")))" },
{ "write(translate(\"", "\"))" }, { "write(translate(\"", "\"))" },
{ NULL, " " } { NULL, " " }
}; };
@ -127,7 +128,7 @@ static const char * generate_expression(struct template_parser *data, size_t *sz
int i; int i;
int size = 0; int size = 0;
int start = 0; int start = 0;
int i18n_hasdef = 0; int whitespace = 0;
memset(tmp, 0, T_OUTBUFSZ); memset(tmp, 0, T_OUTBUFSZ);
@ -142,31 +143,35 @@ static const char * generate_expression(struct template_parser *data, size_t *sz
for( i = 0; i < data->outsize; i++ ) for( i = 0; i < data->outsize; i++ )
{ {
/* Skip leading whitespace for non-raw and non-expr chunks */ /* Skip leading whitespace for non-raw and non-expr chunks */
if( !start && isspace(data->out[i]) && (data->type == T_TYPE_I18N || data->type == T_TYPE_INCLUDE) ) if( !start && isspace(data->out[i]) && (data->type == T_TYPE_I18N ||
data->type == T_TYPE_I18N_RAW || data->type == T_TYPE_INCLUDE) )
continue; continue;
else if( !start ) else if( !start )
start = 1; start = 1;
/* Found whitespace after i18n key */ /* Found whitespace after i18n key */
if( (data->type == T_TYPE_I18N) && (i18n_hasdef == 1) ) if( data->type == T_TYPE_I18N || data->type == T_TYPE_I18N_RAW )
{ {
/* At non-whitespace char, inject seperator token */ /* Is initial whitespace, insert space */
if( !isspace(data->out[i]) ) if( !whitespace && isspace(data->out[i]) )
{ {
memcpy(&tmp[size], T_TOK_I18NSEP, strlen(T_TOK_I18NSEP)); tmp[size++] = ' ';
size += strlen(T_TOK_I18NSEP); whitespace = 1;
i18n_hasdef = 2;
} }
/* At further whitespace, skip */ /* Suppress subsequent whitespace, escape special chars */
else else if( !isspace(data->out[i]) )
{ {
continue; if( data->out[i] == '\\' || data->out[i] == '"' )
tmp[size++] = '\\';
tmp[size++] = data->out[i];
whitespace = 0;
} }
} }
/* Escape quotes, backslashes and newlines for plain, i18n and include expressions */ /* Escape quotes, backslashes and newlines for plain and include expressions */
if( (data->type == T_TYPE_TEXT || data->type == T_TYPE_I18N || data->type == T_TYPE_INCLUDE) && else if( (data->type == T_TYPE_TEXT || data->type == T_TYPE_INCLUDE) &&
(data->out[i] == '\\' || data->out[i] == '"' || data->out[i] == '\n' || data->out[i] == '\t') ) (data->out[i] == '\\' || data->out[i] == '"' || data->out[i] == '\n' || data->out[i] == '\t') )
{ {
tmp[size++] = '\\'; tmp[size++] = '\\';
@ -186,12 +191,6 @@ static const char * generate_expression(struct template_parser *data, size_t *sz
} }
} }
/* Found first whitespace in i18n expression, raise flag */
else if( isspace(data->out[i]) && (data->type == T_TYPE_I18N) && (i18n_hasdef == 0) )
{
i18n_hasdef = 1;
}
/* Normal char */ /* Normal char */
else else
{ {
@ -199,16 +198,14 @@ static const char * generate_expression(struct template_parser *data, size_t *sz
} }
} }
/* Processed i18n expression without default text, inject separator */
if( (data->type == T_TYPE_I18N) && (i18n_hasdef < 2) )
{
memcpy(&tmp[size], T_TOK_I18NSEP, strlen(T_TOK_I18NSEP));
size += strlen(T_TOK_I18NSEP);
}
/* Inject trailing expression code (if any) */ /* Inject trailing expression code (if any) */
if( (what & T_GEN_END) && (gen_code[data->type][1] != NULL) ) if( (what & T_GEN_END) && (gen_code[data->type][1] != NULL) )
{ {
/* Strip trailing space for i18n expressions */
if( data->type == T_TYPE_I18N || data->type == T_TYPE_I18N_RAW )
if( (size > 0) && (tmp[size-1] == ' ') )
size--;
memcpy(&tmp[size], gen_code[data->type][1], strlen(gen_code[data->type][1])); memcpy(&tmp[size], gen_code[data->type][1], strlen(gen_code[data->type][1]));
size += strlen(gen_code[data->type][1]); size += strlen(gen_code[data->type][1]);
} }
@ -403,6 +400,11 @@ const char *template_reader(lua_State *L, void *ud, size_t *sz)
data->type = T_TYPE_I18N; data->type = T_TYPE_I18N;
break; break;
case '_':
off++;
data->type = T_TYPE_I18N_RAW;
break;
default: default:
data->type = T_TYPE_CODE; data->type = T_TYPE_CODE;
break; break;

View file

@ -49,7 +49,6 @@
#define T_TOK_START "<%" #define T_TOK_START "<%"
#define T_TOK_END "%>" #define T_TOK_END "%>"
#define T_TOK_SKIPWS "-" #define T_TOK_SKIPWS "-"
#define T_TOK_I18NSEP "\", \""
/* generator flags */ /* generator flags */
#define T_GEN_START 0x01 #define T_GEN_START 0x01
@ -61,7 +60,8 @@
#define T_TYPE_EXPR 2 #define T_TYPE_EXPR 2
#define T_TYPE_INCLUDE 3 #define T_TYPE_INCLUDE 3
#define T_TYPE_I18N 4 #define T_TYPE_I18N 4
#define T_TYPE_CODE 5 #define T_TYPE_I18N_RAW 5
#define T_TYPE_CODE 6
/* parser state */ /* parser state */
struct template_parser { struct template_parser {