view release on metacpan or search on metacpan
0.29.3 2020-02-28 09:57:50 +0100 Tobias Oetiker <tobi@oetiker.ch>
- do not translate empty strings
0.29.2 2020-02-27 14:14:03 +0100 Tobias Oetiker <tobi@oetiker.ch>
- fix popup instanciation with new YAML config
0.29.1 2020-02-21 16:55:09 +0100 Tobias Oetiker <tobi@oetiker.ch>
- callbackery.locale.MTranslation was missing from MANIFEST and
thus from distro
0.29.0 2020-02-21 15:37:33 +0100 Tobias Oetiker <tobi@oetiker.ch>
- trm with placeholder and arguments work now trm('Hello %1',$name)
- in qooxdoo frontend code, use this.xtr(backendData) to translate
backend data.
* make sure to update your makefile according to the sample in
mojolicious-automake to get xgettext support for extracting
translatable strings
* 4878b5b - (tag: v0.13.0) Fighting circular references (9 months ago) <Tobias Oetiker>
* 7547c30 - update PERL_MODULES (10 months ago) <Tobias Oetiker>
* 7d871b9 - (tag: v0.12.9) fix deprecated route syuntax (no more braces) (10 months ago) <Tobias Oetiker>
* d22bf7e - update template PERL_MODULES (10 months ago) <Tobias Oetiker>
* 36e18d1 - (tag: v0.12.8) updated dependncy to require latest qooxdoo plugin (10 months ago) <Tobias Oetiker>
* 71ba760 - widen tests (10 months ago) <Tobias Oetiker>
* 33507d2 - fix cpanmin.us link (10 months ago) <Tobias Oetiker>
* 1716124 - Update README.md (10 months ago) <Tobias Oetiker>
* 3cda105 - Update README.md (10 months ago) <Tobias Oetiker>
* b6b2deb - (tag: v0.12.7) search templates in templates/system (11 months ago) <Tobias Oetiker>
* 1253847 - (tag: v0.12.6) localize $_ before loading locales since this function modifies $_ (11 months ago) <Tobias Oetiker>
* aa50217 - simplify table change detection (12 months ago) <Tobias Oetiker>
* dc13afc - (tag: v0.12.5) new String is not a good thing ... stick with just String (1 year ago) <Tobias Oetiker>
* e65abe4 - add missing Makefile (1 year ago) <Tobias Oetiker>
* b0ff480 - (tag: v0.12.3) fix user object for up and downloads (1 year, 1 month ago) <Tobias Oetiker>
* 88ba138 - (tag: v0.12.2) auto build source version (1 year, 1 month ago) <Tobias Oetiker>
* 5898387 - add a cache-control header for all requests but those going for the resource files. (1 year, 1 month ago) <Tobias Oetiker>
* bd53c60 - (tag: v0.12.0) v0.12.0 (1 year, 2 months ago) <Tobias Oetiker>
* 4e0dfba - additional types supported for table columns: - string - number including format option (1 year, 2 months ago) <Tobias Oetiker>
* 8d5425f - qxclass changes (1 year, 2 months ago) <Tobias Oetiker>
* 6494665 - local class (1 year, 2 months ago) <Tobias Oetiker>
lib/CallBackery.pm
lib/CallBackery/qooxdoo/callbackery/config.json
lib/CallBackery/qooxdoo/callbackery/Manifest.json
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/Application.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/Config.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/__init__.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/MHistoryRelaxedEncoding.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/RemoteTableModel.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/Server.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/__init__.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/locale/MTranslation.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/test/DemoTest.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/theme/Appearance.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/theme/Color.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/theme/Decoration.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/theme/Font.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/theme/Theme.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/Busy.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/Card.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/Desktop.js
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/Footer.js
lib/CallBackery.pm view on Meta::CPAN
=head1 DESCRIPTION
Configure the mojo engine to run our application logic as webrequests arrive.
=head1 ATTRIBUTES
=cut
# load the two modules to have perl check them
# having a non-C locale for number will wreck all sorts of havoc
# when things get converted to string and back
use POSIX qw(locale_h);
setlocale(LC_NUMERIC, "C");
setlocale(LC_TIME, "C");
use Mojo::Base 'Mojolicious';
use Mojolicious::Plugin::Qooxdoo;
use Mojo::URL;
use Mojo::JSON;
use Mojo::Util qw(hmac_sha1_sum);
use Mojo::File qw(path);
use File::Basename;
use CallBackery::Config;
use CallBackery::Plugin::Doc;
lib/CallBackery.pm view on Meta::CPAN
=cut
=head2 startup
Mojolicious calls the startup method at initialization time.
=cut
sub startup {
my $app = shift;
# having a non-C locale for number will wreck all sorts of havoc
# when things get converted to string and back
setlocale(LC_NUMERIC, "C");
setlocale(LC_TIME, "C");
weaken($app);
$app->config->postProcessCfg();
my $gcfg = $app->config->cfgHash->{BACKEND};
if ($gcfg->{log_file}){
if (open my $file, '>>', $gcfg->{log_file}){
$app->log->handle($file);
}
else {
$app->log->debug("Opening $gcfg->{log_file}: $!");
}
lib/CallBackery/Config.pm view on Meta::CPAN
=cut
sub getTranslations {
my $self = shift;
my $cfg = shift || {};
my %lx;
my $path = $cfg->{path} // $self->app->home->rel_file("share");
my $po = new Locale::PO();
for my $file (glob(File::Spec->catdir($path, '*.po'))) {
my ($volume, $localePath, $localeName) = File::Spec->splitpath($file);
my $locale = $localeName;
$locale =~ s/\.po$//;
my $lang = $locale;
$lang =~ s/_.+//;
local $_; # since load_file_ashash modifies $_ and does not localize it
my $href = Locale::PO->load_file_ashash($file, 'utf8');
for my $key (keys %$href) {
my $o = $href->{$key};
my $id = $po->dequote($o->msgid);
my $str = $po->dequote($o->msgstr);
next unless $id;
$lx{$locale}{$id} = $str;
}
}
return \%lx;
}
=head2 postProcessCfg
Post process the configuration data into a format that is easily used
by the application.
lib/CallBackery/GuiPlugin/AbstractTable.pm view on Meta::CPAN
my $self = shift;
my $args = shift;
my $data = $self->getTableData({
formData => $args,
firstRow => 0,
lastRow => $self->getTableRowCount({ formData=>$args })
});
# Use the (translated) table headers in row 1.
# Or the keys if undefined.
my $loc = CallBackery::Translate->new(localeRoot=>$self->app->home->child("share"));
$loc->setLocale($self->user->userInfo->{lang} // 'en');
my $tCfg = $self->tableCfg;
my @titles = map {
$_->{label}
? ((ref $_->{label} eq 'CallBackery::Translate')
? $loc->tra($_->{label}[0])
: $_->{label})
: $_->{key};
} @$tCfg;
lib/CallBackery/Translate.pm view on Meta::CPAN
@EXPORT_OK = qw(trm);
=head1 NAME
CallBackery::Translate - gettext po file translation functionality
=head1 SYNOPSIS
use CallBackery::Translate qw(mtr);
my $loc = CallBackery::Translate->new(localeRoot=>$dir);
$loc->setLocale('de');
$loc->tra("Hello %1","Tobi");
trm("Mark but for translation but return original");
=head1 DESCRIPTION
Read translations from gettext po files and translate incoming data.
=cut
has 'localeRoot';
=over
=item C<setLocale>($locale);
Load the translations strings for $locale. First try the full name and
then top-up with only the language part.
=cut
my %lx;
sub setLocale {
my $self = shift;
my $locale = shift;
if ($lx{$locale}){
$self->{_lx} = $lx{$locale};
return;
}
my $lang = $locale;
$lang =~ s/_.+//;
for my $file ($lang,$locale){
my $mode = 'id';
if (open my $fh, '< :encoding(utf8)', $self->localeRoot.'/'.$file.'.po'){
my $key;
my %var;
while (<$fh>){
chomp;
/^msg(id|str)\s+"(.*)"/ && do {
$var{$1} = $2;
$key = $1;
next;
};
/^"(.*)"/ && do {
$var{$key} .= $1;
next;
};
/^\s*$/ && $var{id} && do {
$lx{$locale}{$var{id}} = $var{str};
next;
}
}
$lx{$locale}{$var{id}} = $var{str} if $var{id} and $var{str};
}
}
$self->{_lx} = $lx{$locale};
}
=item C<tra>(str[,arg,arg,...])
Translate string into the curent language.
=cut
sub tra {
my $self = shift;
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/Application.js view on Meta::CPAN
*/
members : {
main : function() {
// Call super class
this.base(arguments);
// include the xtr call so that we can use frontend translation
// on backend strings.
qx.Class.patch(qx.ui.table.columnmodel.Resize,
callbackery.locale.MTranslation);
qx.Class.patch(qx.ui.core.Widget,
callbackery.locale.MTranslation);
// Enable logging in debug variant
if (qx.core.Environment.get("qx.debug")) {
// support native logging capabilities, e.g. Firebug for Firefox
qx.log.appender.Native;
// support additional cross-browser console. Press F7 to toggle visibility
qx.log.appender.Console;
}
var rpc = callbackery.data.Server.getInstance();
var root = this.getRoot();
root.set({
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/Application.js view on Meta::CPAN
/* give the History object a more relaxed attitude towards encoding stuff */
qx.Class.patch(qx.bom.History,callbackery.data.MHistoryRelaxedEncoding);
qx.bom.History.getInstance().addListener('changeState', this.__changeLanguage, this);
this.__changeLanguage();
rpc.callAsyncSmart(function(baseCfg){
var cfg = callbackery.data.Config.getInstance();
cfg.setBaseConfig(baseCfg);
if (baseCfg.TRANSLATIONS){
var t = baseCfg.TRANSLATIONS;
var lm = qx.locale.Manager.getInstance();
for (var lang in t) {
lm.addTranslation(lang, t[lang]);
}
}
if (baseCfg.COLORS){
qx.Theme.define('callbackery.theme.CustomColor',{
colors: baseCfg.COLORS
});
var colorTheme = qx.theme.manager.Color.getInstance().getTheme();
qx.Theme.patch(colorTheme,callbackery.theme.CustomColor);
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/Application.js view on Meta::CPAN
},
registerPlugin: function(type, func) {
return callbackery.ui.Plugins.getInstance().register(type, func);
},
__changeLanguage: function() {
var urlCfg = callbackery.data.Config.getInstance().getUrlConfig();
if (urlCfg.lang) {
qx.locale.Manager.getInstance().setLocale(urlCfg.lang);
}
},
getFooterWidget : function() {
return callbackery.ui.Footer.getInstance();
},
getHeaderWidget : function() {
return callbackery.ui.Header.getInstance();
}
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/RemoteTableModel.js view on Meta::CPAN
Utf8Check: äöü
************************************************************************ */
/**
* An {@link qx.ui.table.model.Remote} implementation for accessing
* accessing Messreihen on the server.
*/
qx.Class.define('callbackery.data.RemoteTableModel', {
extend: qx.ui.table.model.Remote,
include: [callbackery.locale.MTranslation],
/**
* Create an instance of Rpc.
*/
construct: function(cfg, getParentFormData) {
this.base(arguments);
this._getParentFormData = getParentFormData;
var that = this;
var ids = [];
var labels = [];
var types = {};
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/Server.js view on Meta::CPAN
* @return {var} the method call reference.
*/
callAsync: function(handler, methodName) {
if (methodName == 'login'){
// arguments.callee.base.apply(this, arguments);
arguments.callee.base.apply(this, arguments);
return;
}
var origArguments = arguments;
var origThis = this;
var localeMgr = qx.locale.Manager.getInstance();
var newArgs = Array.prototype.slice.call(arguments);
newArgs[0] = function(ret, exc, id) {
if (exc) {
switch (exc.code) {
case 6:
let login = callbackery.ui.Login.getInstance();
login.addListenerOnce('login', (e) => {
let ret = e.getData();
origThis.setSessionCookie(ret.sessionCookie);
origArguments.callee.base.apply(origThis, origArguments);
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/Server.js view on Meta::CPAN
try {
handler(ret, exc, id);
}
catch(e) {
if (window.console){
window.console.error("Error while running CallAsync Handler","ret:",ret,"exc",exc,"id",id,"e",e);
}
}
};
newArgs.push({
qxLocale: localeMgr.getLocale()
});
arguments.callee.base.apply(this, newArgs);
},
/**
* A variant of the asyncCall method which pops up error messages
* generated by the server automatically.
*
* Note that the handler method only gets a return value never an exception
* It just does not get called when there is an exception.
*
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/locale/MTranslation.js view on Meta::CPAN
/* *************************************************
Copyright: 2019 OETIKER+PARTNER AG
License: GNU GPL 3
Authors: Tobias Oetiker <tobi@oetiker.ch>
************************************************** */
/**
* Translation helper which can process backend translatable objects
*/
qx.Mixin.define("callbackery.locale.MTranslation", {
members: {
/**
* override the regular tr with this magic version which is able to handle
* data coming in from the backend. This is for backward compatibility.
* Better use the xtr call as this will not trigger the translation
* string extraction.
*/
tr: function() {
return this.xtr.apply(this,arguments);
},
/**
* Translate incoming data. Do NOT mark the string for translation
* use the tr function for this. xtr is meant for backend strings.
*/
xtr: function(messageId,varargs) {
var nlsManager = qx.locale.Manager;
if (messageId == ''){
return '';
}
if (messageId instanceof Array) {
return nlsManager.tr.apply(nlsManager, messageId);
}
if (messageId instanceof qx.data.Array) {
return nlsManager.tr.apply(nlsManager, messageId.toArray());
}
return nlsManager.tr.apply(nlsManager, arguments);
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/form/DateTime.js view on Meta::CPAN
// dateField.setTextSelection(0,0);
}, this);
this.addListener("focusout", function(e) {
dateField.fireNonBubblingEvent("focusout", qx.event.type.Focus);
}, this);
// initializes the DateField with the default format
this._setDefaultDateFormat();
// adds a locale change listener
this._addLocaleChangeListener();
},
/*
*****************************************************************************
EVENTS
*****************************************************************************
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/form/DateTime.js view on Meta::CPAN
__dateFormat : null,
__formatter : null,
/**
* Get the shared default date formatter
*
* @return {qx.util.format.DateFormat} The shared date formatter
*/
getDefaultDateFormatter : function()
{
var format = qx.locale.Date.getDateFormat("medium").toString();
if (format == this.__dateFormat) {
return this.__formatter;
}
if (this.__formatter) {
this.__formatter.dispose();
}
this.__formatter = new qx.util.format.DateFormat(format, qx.locale.Manager.getInstance().getLocale());
this.__dateFormat = format;
return this.__formatter;
}
},
/*
*****************************************************************************
MEMBERS
*****************************************************************************
*/
members :
{
__localeListenerId : null,
/**
* @lint ignoreReferenceField(_forwardStates)
*/
_forwardStates : {
focused : true,
invalid : true
},
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/form/DateTime.js view on Meta::CPAN
* Sets the default date format which is returned by
* {@link #getDefaultDateFormatter}. You can overrride this method to
* define your own default format.
*/
_setDefaultDateFormat : function() {
this.setDateFormat(qx.ui.form.DateField.getDefaultDateFormatter());
},
/**
* Checks for "qx.dynlocale" and adds a listener to the locale changes.
* On every change, {@link #_setDefaultDateFormat} is called to reinitialize
* the format. You can easily override that method to prevent that behavior.
*/
_addLocaleChangeListener : function() {
// listen for locale changes
if (qx.core.Environment.get("qx.dynlocale"))
{
this.__localeListenerId =
qx.locale.Manager.getInstance().addListener("changeLocale", function() {
this._setDefaultDateFormat();
}, this);
}
},
/*
---------------------------------------------------------------------------
PUBLIC METHODS
---------------------------------------------------------------------------
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/form/DateTime.js view on Meta::CPAN
}
catch (ex) {
// do nothing if the former date could not be parsed
}
},
// property apply routine
_applyPlaceholder : function(value, old) {
var p = value.split("@");
// this.getChildControl("datefield").setPlaceholder(qx.locale.Manager.tr(p[0]));
this.getChildControl("datefield").setPlaceholder(this.xtr(p[0]));
if (p[1] != null) {
this.getChildControl("timefield").setPlaceholder(p[1]);
}
},
/*
---------------------------------------------------------------------------
WIDGET API
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/form/DateTime.js view on Meta::CPAN
*/
isEmpty: function()
{
var value = this.getChildControl("datefield").getValue();
return value == null || value == "";
}
},
destruct : function() {
// listen for locale changes
if (qx.core.Environment.get("qx.dynlocale"))
{
if (this.__localeListenerId) {
qx.locale.Manager.getInstance().removeListenerById(this.__localeListenerId);
}
}
}
});
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/form/renderer/NoteForm.js view on Meta::CPAN
})
} catch (err) {
msg.info(that.tr("Copy failed"), copyFailMsg);
}
});
}
that._row += 2;
that._connectVisibility(item, label);
// store the names for translation
if (qx.core.Environment.get("qx.dynlocale")) {
that._names.push({
name: names[i], label: label, item: items[i]
});
}
})();
} // end context
let bounds = this.getBounds();
if (bounds) {
this._updateForm(bounds.width);
}