caching translations for 10days and changing translation url, when translations are changing --> saves server-roundtrip for each translation

This commit is contained in:
Ralf Becker 2014-01-09 15:32:07 +00:00
parent 13572c472a
commit 400240f1e4
7 changed files with 57 additions and 41 deletions

View File

@ -135,14 +135,14 @@ class etemplate_new extends etemplate_widget_template
{ {
if (!in_array($l_app, array($currentapp, 'custom'))) if (!in_array($l_app, array($currentapp, 'custom')))
{ {
$langRequire[$l_app] = array('app' => $l_app, 'lang' => $lang); $langRequire[$l_app] = array('app' => $l_app, 'lang' => $lang, 'etag' => translation::etag($l_app, $lang));
} }
} }
foreach(array($currentapp, 'custom') as $l_app) foreach(array($currentapp, 'custom') as $l_app)
{ {
if (isset(translation::$loaded_apps[$l_app])) if (isset(translation::$loaded_apps[$l_app]))
{ {
$langRequire[$l_app] = array('app' => $l_app, 'lang' => translation::$loaded_apps[$l_app]); $langRequire[$l_app] = array('app' => $l_app, 'lang' => translation::$loaded_apps[$l_app], 'etag' => translation::etag($l_app, translation::$loaded_apps[$l_app]));
} }
} }

View File

@ -378,6 +378,9 @@ class config
} }
} }
} }
// some things need on client-side which are not direct configs
$client_config['phpgwapi']['lang_ctimes_md5'] = md5(json_encode(self::$configs['phpgwapi']['lang_ctimes']));
return $client_config; return $client_config;
} }

View File

@ -428,6 +428,29 @@ class translation
} }
} }
/**
* Get a state / etag for a given app's translations
*
* We currently only use a single state for all none-instance-specific apps depending on lang_ctimes.
*
* @param string $_app
* @param string $_lang
* @return string
*/
static function etag($_app, $_lang)
{
if (!in_array($_app, translation::$instance_specific_translations))
{
$etag = md5(json_encode($GLOBALS['egw_info']['server']['lang_ctimes']));
}
else
{
$etag = md5(json_encode(egw_cache::getCache(egw_cache::INSTANCE, __CLASS__, $_app.':'.$_lang)));
}
error_log(__METHOD__."('$_app', '$_lang') returning '$etag'");
return $etag;
}
/** /**
* Loads translations for an application direct from the lang-file(s) * Loads translations for an application direct from the lang-file(s)
* *

View File

@ -37,9 +37,9 @@ egw.extend('config', egw.MODULE_GLOBAL, function() {
{ {
if (typeof _app == 'undefined') _app = 'phpgwapi'; if (typeof _app == 'undefined') _app = 'phpgwapi';
if (typeof configs[_app] == 'undefined') return null; if (typeof this.configs[_app] == 'undefined') return null;
return configs[_app][_name]; return this.configs[_app][_name];
}, },
/** /**

View File

@ -116,9 +116,10 @@ egw.extend('lang', egw.MODULE_GLOBAL, function() {
{ {
if (typeof lang_arr[_apps[i].app] === "undefined") if (typeof lang_arr[_apps[i].app] === "undefined")
{ {
jss.push(this.webserverUrl jss.push(this.webserverUrl +
+ '/phpgwapi/lang.php?app=' '/phpgwapi/lang.php?app=' + _apps[i].app +
+ _apps[i].app + '&lang=' + _apps[i].lang); '&lang=' + _apps[i].lang +
'&etag=' + (_apps[i].etag || this.config('lang_ctimes_md5')));
} }
apps.push(_apps[i].app); apps.push(_apps[i].app);
} }

View File

@ -457,7 +457,7 @@ egw.extend('links', egw.MODULE_GLOBAL, function() {
this.value = ''; this.value = '';
}); });
// need to load common translations for app-names // need to load common translations for app-names
this.includeJS([this.webserverUrl+'/phpgwapi/lang.php?app=common&lang='+this.preference('lang')], function(){ this.langRequire(window, [{app: 'common', lang: this.preference('lang')}], function(){
select.append(jQuery(document.createElement('option')).attr('value', '').text(self.lang('Add')+' ...')); select.append(jQuery(document.createElement('option')).attr('value', '').text(self.lang('Add')+' ...'));
var apps = self.link_app_list('add'); var apps = self.link_app_list('add');
for(var app in apps) for(var app in apps)

View File

@ -30,23 +30,15 @@ $GLOBALS['egw_info'] = array(
include '../header.inc.php'; include '../header.inc.php';
// use an etag with app, lang and a hash over the creation-times of all lang-files // use an etag with app, lang and a hash over the creation-times of all lang-files
if (!in_array($_GET['app'], translation::$instance_specific_translations)) $etag = '"'.$_GET['app'].'-'.$_GET['lang'].'-'.translation::etag($_GET['app'], $_GET['lang']).'"';
{
$etag = '"'.$_GET['app'].'-'.$_GET['lang'].'-'.md5(serialize($GLOBALS['egw_info']['server']['lang_ctimes'])).'"'; // tell browser/caches to cache for one day, we change url on real modifications
} $expires = 864000; // 10days
else
{
translation::add_app($_GET['app'], $_GET['lang']);
if (!count(translation::$lang_arr))
{
translation::add_app($_GET['app'], 'en');
}
$etag = '"'.$_GET['app'].'-'.$_GET['lang'].'-'.md5(serialize(translation::$lang_arr));
}
// headers to allow caching of one month // headers to allow caching of one month
Header('Content-Type: text/javascript; charset=utf-8'); Header('Content-Type: text/javascript; charset=utf-8');
Header('Cache-Control: public, no-transform'); Header('Cache-Control: public, no-transform, max-age='.$expires);
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');
Header('Pragma: cache'); Header('Pragma: cache');
Header('ETag: '.$etag); Header('ETag: '.$etag);
@ -57,13 +49,10 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
common::egw_exit(); common::egw_exit();
} }
if (!in_array($_GET['app'], translation::$instance_specific_translations)) translation::add_app($_GET['app'], $_GET['lang']);
if (!count(translation::$lang_arr))
{ {
translation::add_app($_GET['app'], $_GET['lang']);
if (!count(translation::$lang_arr))
{
translation::add_app($_GET['app'], 'en'); translation::add_app($_GET['app'], 'en');
}
} }
$content = 'egw.set_lang_arr("'.$_GET['app'].'", '.json_encode(translation::$lang_arr).');'; $content = 'egw.set_lang_arr("'.$_GET['app'].'", '.json_encode(translation::$lang_arr).');';