* integrate Marko Samastur's translate.js with gettext and php
 * translate the first JavaScript strings
 * add scripts/i18n.php to generate the list of i18n dictionary
This commit is contained in:
Jan Dittberner 2007-12-01 23:15:26 +00:00
parent 3b234e141d
commit 4a15c5b5b6
15 changed files with 409 additions and 12 deletions

View file

@ -26,19 +26,26 @@
VERSION := 0.2 VERSION := 0.2
PROJECT := davadmin PROJECT := davadmin
SRCFILES := $(wildcard admin/*.php) SRCFILES := $(wildcard admin/*.php)
JSFILES := admin/scripts/autocomplete.js admin/scripts/directories.js \
admin/scripts/users.js
APISRC := $(SRCFILES:,= ) APISRC := $(SRCFILES:,= )
TEMPDIR := $(shell mktemp -t -d davadmin.XXXXXXXXXX) TEMPDIR := $(shell mktemp -t -d davadmin.XXXXXXXXXX)
XSRCFILES := $(patsubst %,$(TEMPDIR)/%,$(SRCFILES)) XSRCFILES := $(patsubst %,$(TEMPDIR)/%,$(SRCFILES))
XJSFILES := $(patsubst %,$(TEMPDIR)/%,$(JSFILES))
TRANSLANG := de TRANSLANG := de
POSRC := po POSRC := po
POFILES := $(foreach lang,$(TRANSLANG),$(POSRC)/$(lang).po) POFILES := $(foreach lang,$(TRANSLANG),$(POSRC)/$(lang)/LC_MESSAGES/$(PROJECT).po)
JSPOFILES := $(foreach lang,$(TRANSLANG),$(POSRC)/$(lang)/LC_MESSAGES/$(PROJECT)js.po)
MOFILES := $(patsubst %.po,%.mo,$(POFILES)) MOFILES := $(patsubst %.po,%.mo,$(POFILES))
JSMOFILES := $(patsubst %.po,%.mo,$(JSPOFILES))
POT=$(POSRC)/$(PROJECT).pot POT=$(POSRC)/$(PROJECT).pot
JSPOT=$(POSRC)/$(PROJECT)js.pot
JSTRANS=$(POSRC)/transjs.txt
.PHONY: all .PHONY: all
all: $(POT) $(MOFILES) $(TEMPDIR)/delete all: $(POT) $(JSPOT) $(JSTRANS) $(MOFILES) $(JSMOFILES) $(TEMPDIR)/delete
$(MOFILES): %.mo: %.po $(MOFILES) $(JSMOFILES): %.mo: %.po
@echo "msgfmt: $@" @echo "msgfmt: $@"
msgfmt -o$@ $< msgfmt -o$@ $<
@ -47,6 +54,11 @@ $(POFILES): %: $(POT)
msgmerge -U $@ $(POT) msgmerge -U $@ $(POT)
touch $@ touch $@
$(JSPOFILES): %: $(JSPOT)
@echo "msgmerge: $@"
msgmerge -U $@ $(JSPOT)
touch $@
$(POT): $(XSRCFILES) po/pot.sed $(POT): $(XSRCFILES) po/pot.sed
@echo "xgettext: $@" @echo "xgettext: $@"
cd $(TEMPDIR) && \ cd $(TEMPDIR) && \
@ -61,12 +73,42 @@ $(POT): $(XSRCFILES) po/pot.sed
fi; \ fi; \
done done
.INTERMEDIATE: $(XSRCFILES) $(JSPOT): $(XJSFILES) po/jspot.sed
@echo "xgettext: $@"
cd $(TEMPDIR) && \
xgettext --default-domain=$(PROJECT)js --language=Java \
--from-code=UTF-8 --keyword="intl.translate" \
--msgid-bugs-address="jan@dittberner.info" -o- $(JSFILES) \
| sed -f $(CURDIR)/po/jspot.sed \
> $(CURDIR)/$@
for pofile in $(JSPOFILES); do \
if test ! -f $(CURDIR)/$${pofile}; then \
cp $(CURDIR)/$@ $(CURDIR)/$${pofile}; \
fi; \
done
$(JSTRANS): $(XJSFILES)
@echo "generate table of translatable string: $@"
cd $(TEMPDIR) && \
xgettext --default-domain=$(PROJECT)js --language=Java \
--from-code=UTF-8 \
--omit-header --keyword="intl.translate" --properties-output \
--no-location -o- $(JSFILES) \
| awk '/^!.+=$$/ { print }' \
| sed 's,.\(.*\)=,\1,g; s,\\=,=,g; s,\\ , ,g' \
> $(CURDIR)/$@
.INTERMEDIATE: $(XSRCFILES) $(XJSFILES)
$(XSRCFILES): $(TEMPDIR)/%: % $(XSRCFILES): $(TEMPDIR)/%: %
@echo "processing: $<" @echo "processing: $<"
mkdir -p $(@D) mkdir -p $(@D)
cp $< $@ cp $< $@
$(XJSFILES): $(TEMPDIR)/%: %
@echo "processing: $<"
mkdir -p $(@D)
cp $< $@
$(TEMPDIR)/delete: $(TEMPDIR)/delete:
rm -rf $(TEMPDIR) rm -rf $(TEMPDIR)

8
README
View file

@ -27,14 +27,18 @@ Please see INSTALL_ for installation instructions.
Used third party code Used third party code
===================== =====================
WebDAVAdmin uses the JQuery Javascript library for DOM manipulations DAVAdmin uses the JQuery Javascript library for DOM manipulations and
and AJAX calls. AJAX calls.
.. _JQuery: http://www.jquery.com/ .. _JQuery: http://www.jquery.com/
Version 1.2.1 of JQuery has been used for developing this software and Version 1.2.1 of JQuery has been used for developing this software and
is bundled in the ``scripts`` directory as ``jquery.js``. is bundled in the ``scripts`` directory as ``jquery.js``.
DAVAdmin uses Marko Samastur's JavaScript i18n library.
.. http://markos.gaivo.net/blog/?p=100.
License License
======= =======

View file

@ -138,7 +138,11 @@ if ($_SESSION["language"]) {
putenv(sprintf("LANG=%s", $_SESSION["language"])); putenv(sprintf("LANG=%s", $_SESSION["language"]));
putenv(sprintf("LANGUAGE=%s", $_SESSION["language"])); putenv(sprintf("LANGUAGE=%s", $_SESSION["language"]));
$_SESSION["locale"] = _setlocale(LC_ALL, $_SESSION["language"]); $_SESSION["locale"] = _setlocale(LC_ALL, $_SESSION["language"]);
bindtextdomain($project, realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . bindtextdomain($project,
realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR .
".." . DIRECTORY_SEPARATOR . "po"));
bindtextdomain($project . "js",
realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR .
".." . DIRECTORY_SEPARATOR . "po")); ".." . DIRECTORY_SEPARATOR . "po"));
textdomain($project); textdomain($project);
?> ?>

View file

@ -27,7 +27,7 @@
*/ */
function handleerror(xmldata) { function handleerror(xmldata) {
if ($('error', xmldata).size()) { if ($('error', xmldata).size()) {
var msg = 'Es ist ein Fehler aufgetreten:\n'; var msg = intl.translate('An error occured:\n');
$('error', xmldata).find('errormsg').each(function(i) { $('error', xmldata).find('errormsg').each(function(i) {
msg += $(this).text(); msg += $(this).text();
}); });
@ -44,9 +44,9 @@ function updateDirectories(xmldata) {
var filecount = $('filecount', xmldata).text(); var filecount = $('filecount', xmldata).text();
var filesize = $('filesize', xmldata).text(); var filesize = $('filesize', xmldata).text();
var maydelete = $('maydelete', xmldata).text(); var maydelete = $('maydelete', xmldata).text();
var htmltext = '<td>' + dirname + '</td><td>' + groups + '</td><td>' + filecount + ', ' + filesize + '</td><td><a id="edit' + dirname + '" class="editlink" href="#" title="Die Gruppenzuordnungen dieses Verzeichnisses bearbeiten"><img class="actionicon" src="images/groups.png" width="16" height="16" alt="Gruppen"/></a>'; var htmltext = '<td>' + dirname + '</td><td>' + groups + '</td><td>' + filecount + ', ' + filesize + '</td><td><a id="edit' + dirname + '" class="editlink" href="#" title="' + intl.translate("Edit this directory's group assignments.") + '"><img class="actionicon" src="images/groups.png" width="16" height="16" alt="' + intl.translate("groups") + '"/></a>';
if (maydelete == '1') { if (maydelete == '1') {
htmltext = htmltext + '<a id="delete' + dirname + '" class="deletelink" href="#" title="Dieses Verzeichnis löschen"><img class="actionicon" src="images/delete.png" width="16" height="16" alt="löschen" /></a>'; htmltext = htmltext + '<a id="delete' + dirname + '" class="deletelink" href="#" title="' + intl.translate("Delete this directory.") + '"><img class="actionicon" src="images/delete.png" width="16" height="16" alt="' + intl.translate("delete") + '" /></a>';
} }
htmltext = htmltext + '</td>'; htmltext = htmltext + '</td>';
$('#dirtable').find('tr#dir' + dirname).empty().append(htmltext); $('#dirtable').find('tr#dir' + dirname).empty().append(htmltext);

52
admin/scripts/i18n.php Normal file
View file

@ -0,0 +1,52 @@
<?php
/**
* JavaScript internationalization code for DAVAdmin.
*
* @author Jan Dittberner <jan@dittberner.info>
* @version $Id$
* @license GPL
* @package DAVAdmin
*
* Copyright (c) 2007 Jan Dittberner
*
* This file is part of DAVAdmin.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
/** Include the internationalization code. */
require_once(".." . DIRECTORY_SEPARATOR . "i18n.inc.php");
textdomain("davadminjs");
$translatable = file(realpath(implode(DIRECTORY_SEPARATOR,
array(dirname(__FILE__), "..", "..",
"po", "transjs.txt"))));
header("Content-Type: application/x-javascript;charset=UTF-8");
if (is_array($translatable)) {
print "i18nDict = ";
$transmap = array();
foreach ($translatable as $sentence) {
$sentence = stripcslashes(stripcslashes(trim($sentence)));
$transmap[$sentence] = _($sentence);
}
print json_encode($transmap);
print ";";
} else {
print "i18nDict = {};";
}
print("\n\nvar intl = new i18n(i18nDict);");
?>

View file

@ -0,0 +1,80 @@
/*
* Helper functions
*/
function stripStr(str) {
return str.replace(/^\s*/, "").replace(/\s*$/, "");
}
// Multiline strip
function stripStrML(str) {
// Split because m flag doesn't exist before JS1.5 and we need to
// strip newlines anyway
var parts = str.split('\n');
for (var i=0; i<parts.length; i++)
parts[i] = stripStr(parts[i]);
// Don't join with empty strings, because it "concats" words
// And strip again
return stripStr(parts.join(" "));
}
/*
* C-printf like function, which substitutes %s with parameters
* given in list. %%s is used to escape %s.
*
* Doesn't work in IE5.0 (splice)
*/
function printf(S, L) {
if (!L) return S;
var nS = "";
var tS = S.split("%s");
for(var i=0; i<L.length; i++) {
if (tS[i].lastIndexOf('%') == tS[i].length-1 && i != L.length-1)
tS[i] += "s"+tS.splice(i+1,1)[0];
nS += tS[i] + L[i];
}
return nS + tS[tS.length-1];
}
/*
* i18n
*/
function i18n(i18n_dict) {
this.i18nd = i18n_dict;
// Change to entity representation non-ASCII characters
this.toEntity = function (str) {
var newstr = "";
for (var i=0;i<str.length; i++) {
if (str.charCodeAt(i) > 128)
newstr += "&#"+str.charCodeAt(i)+";";
else
newstr += str.charAt(i);
}
return newstr;
}
// Return translation, if translation dictionary exists and has a translation.
this.translate = function (str, params) {
var transl = str;
if (this.i18nd && this.i18nd[str])
transl = this.i18nd[str];
return printf(transl, params);
}
this.translateNodes = function () {
var nodes = document.getElementsByTagName("*");
for (var i=0;i<nodes.length;i++)
if (nodes[i].className.match("i18n")) {
var orig = stripStrML(nodes[i].innerHTML);
var transl = this.translate(orig);
// If translation not found, try again with
// entity representation
if (transl == orig) transl = this.translate(this.toEntity(orig));
nodes[i].innerHTML = transl;
}
}
}

View file

@ -32,4 +32,6 @@
<link rel="stylesheet" type="text/css" href="format.css" /> <link rel="stylesheet" type="text/css" href="format.css" />
<link rel="stylesheet" type="text/css" href="dynaform.css" /> <link rel="stylesheet" type="text/css" href="dynaform.css" />
<script type="text/javascript" src="scripts/jquery.js"></script> <script type="text/javascript" src="scripts/jquery.js"></script>
<script type="text/javascript" src="scripts/translate.js"></script>
<script type="text/javascript" src="scripts/i18n.php" ></script>
<body> <body>

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: davadmin 0.2\n" "Project-Id-Version: davadmin 0.2\n"
"Report-Msgid-Bugs-To: jan@dittberner.info\n" "Report-Msgid-Bugs-To: jan@dittberner.info\n"
"POT-Creation-Date: 2007-12-01 21:31+0100\n" "POT-Creation-Date: 2007-12-01 23:35+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"

33
po/davadminjs.pot Normal file
View file

@ -0,0 +1,33 @@
# DAVAdmin JavaScript.
# Copyright (C) 2007, Jan Dittberner
# This file is distributed under the same license as the davadmin package.
# Jan Dittberner <jan AT dittberner.info>, 2007.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: davadmin 0.2\n"
"Report-Msgid-Bugs-To: jan@dittberner.info\n"
"POT-Creation-Date: 2007-12-02 00:05+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: admin/scripts/directories.js:47
msgid "Edit this directory's group assignments."
msgstr ""
#: admin/scripts/directories.js:47
msgid "groups"
msgstr ""
#: admin/scripts/directories.js:49
msgid "Delete this directory."
msgstr ""
#: admin/scripts/directories.js:49
msgid "delete"
msgstr ""

View file

@ -0,0 +1,114 @@
# DAVAdmin.
# Copyright (C) 2007, Jan Dittberner
# This file is distributed under the same license as the davadmin package.
# Jan Dittberner <jan AT dittberner.info>, 2007.
#
msgid ""
msgstr ""
"Project-Id-Version: davadmin 0.2\n"
"Report-Msgid-Bugs-To: jan@dittberner.info\n"
"POT-Creation-Date: 2007-12-01 21:31+0100\n"
"PO-Revision-Date: 2007-12-02 00:01+0100\n"
"Last-Translator: Jan Dittberner <jan@dittberner.info>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: admin/common.inc.php:46
msgid "Invalid call!"
msgstr "Ungültiger Aufruf!"
#: admin/common.inc.php:74 admin/common.inc.php:82 admin/common.inc.php:90
#: admin/common.inc.php:98 admin/common.inc.php:107 admin/common.inc.php:111
#, php-format
msgid "%s is not defined."
msgstr "%s ist nicht definiert."
#: admin/common.inc.php:78
msgid "The specified digest file is not readable and writable."
msgstr "Die angegebene Digest-Datei ist nicht lesbar und schreibbar."
#: admin/common.inc.php:86
msgid "The specified group file is not readable and writable."
msgstr "Die angegebene Gruppendatei ist nicht lesbar und schreibbar."
#: admin/common.inc.php:94
msgid "The specified name mapping file is not readable and writable."
msgstr "Die angebene Mapping-Datei für Namen ist nicht lesbar und schreibbar."
#: admin/common.inc.php:103
msgid "The specified DAV directory is no directory or not accessable."
msgstr "Auf das angegeben DAV-Verzeichnis kann nicht zugegriffen werden."
#: admin/directories.php:114
#, php-format
msgid "%d kBytes"
msgstr "%d kByte"
#: admin/directories.php:130 admin/directories.php:236
#: admin/directories.php:275
#, php-format
msgid "Invalid directory name %s!"
msgstr "Ungültiger Verzeichnisname: %s!"
#: admin/directories.php:227
#, php-format
msgid "There already is a directory entry named %s, but it's not a directory!"
msgstr ""
"Es gibt bereits einen Verzeichniseintrag mit dem Namen %s, aber dieser ist "
"kein Verzeichnis!"
#: admin/directories.php:286 admin/directories.php:307 admin/users.php:344
#: admin/users.php:365 admin/users.php:369
#, php-format
msgid "Unexpected values %s!"
msgstr "Unerwarteter Wert: %s!"
#: admin/directories.php:303
msgid "Delete failed!"
msgstr "Das Löschen ist fehlgeschlagen!"
#: admin/shared.inc.php:42
msgid ""
"The Server is not configured correctly. Please tell your Administrator to "
"set the DavAdminConfDir environment variable."
msgstr ""
"Der Server ist nicht richtig konfiguriert. Bitten Sie Ihren Administrator "
"darum, die Umgebungsvariable DavAdminConfDir zu setzen."
#: admin/shared.inc.php:49
#, php-format
msgid ""
"The server configuration file '%s' doesn't exist. Please create the file "
"with correct settings."
msgstr "Die Serverkonfigurationsdatei '%s' existiert nicht. Bitte legen Sie diese Datei mit den korrekten Einstellungen an."
#: admin/users.php:64 admin/users.php:84 admin/users.php:327
#, php-format
msgid "Invalid user id %s"
msgstr "Ungültige Benutzer-Id %s"
#: admin/users.php:105
msgid "Uid must be numeric."
msgstr "Nutzer-Id muss ein numerischer Wert sein."
#: admin/users.php:108 admin/users.php:115
msgid "Password must be at least 8 characters long."
msgstr "Das Passwort muss mindestens 8 Zeichen lang sein."
#: admin/users.php:112
msgid ""
"Username must be at least 2 characters long and must contain letters and "
"digits only."
msgstr ""
"Der Nutzername muss mindestens zwei Zeichen lang sein und darf nur aus "
"Buchstaben und Zahlen bestehen."
#: admin/users.php:125
msgid ""
"Groups must be a list of group names separated by commas. Group names must "
"consist of letters and digits."
msgstr ""
"Im Feld Gruppen muss eine durch Kommata getrennte Liste von Gruppennamen "
"stehen. Gruppennamen dürfen aus Buchstaben und Zahlen bestehen."

Binary file not shown.

View file

@ -0,0 +1,32 @@
# DAVAdmin.
# Copyright (C) 2007, Jan Dittberner
# This file is distributed under the same license as the davadmin package.
# Jan Dittberner <jan AT dittberner.info>, 2007.
#
msgid ""
msgstr ""
"Project-Id-Version: davadmin 0.2\n"
"Report-Msgid-Bugs-To: jan@dittberner.info\n"
"POT-Creation-Date: 2007-12-02 00:01+0100\n"
"PO-Revision-Date: 2007-12-02 00:01+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: admin/scripts/directories.js:47
msgid "Edit this directory's group assignments."
msgstr "Die Gruppenzuordnungen dieses Verzeichnisses bearbeiten."
#: admin/scripts/directories.js:47
msgid "groups"
msgstr "Gruppen"
#: admin/scripts/directories.js:49
msgid "Delete this directory."
msgstr "Dieses Verzeichnis löschen."
#: admin/scripts/directories.js:49
msgid "delete"
msgstr "löschen"

30
po/jspot.sed Normal file
View file

@ -0,0 +1,30 @@
# Copyright (c) 2007 Jan Dittberner. $Revision$
#
# inspired by Alex Tingle's pot.sed from
# http://blogs.admissions.buffalo.edu/news/wp-content/plugins/eventcalendar3/gettext/pot.sed
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
# Fills in some details in the ec3.pot file.
1,/^$/ {
s/SOME DESCRIPTIVE TITLE/DAVAdmin JavaScript/
s/YEAR THE PACKAGE.S COPYRIGHT HOLDER/2007, Jan Dittberner/
s/PACKAGE/davadmin/
s/FIRST AUTHOR <EMAIL@ADDRESS>, YEAR./Jan Dittberner <jan AT dittberner.info>, 2007./
s/VERSION/0.2/
s/CHARSET/UTF-8/
}

4
po/transjs.txt Normal file
View file

@ -0,0 +1,4 @@
Edit this directory's group assignments.
groups
Delete this directory.
delete