Added basic support for translating, so far only on pad.html

This commit is contained in:
Peter 'Pita' Martischka 2011-08-24 18:37:22 +01:00
parent 54d51c96d9
commit 8cceeefa05
8 changed files with 192 additions and 40 deletions

View file

@ -31,7 +31,7 @@ var gzip = require('gzip');
var server = require('../server'); var server = require('../server');
var os = require('os'); var os = require('os');
var padJS = ["jquery.min.js", "pad_utils.js", "plugins.js", "undo-xpopup.js", "json2.js", "pad_cookie.js", "pad_editor.js", "pad_editbar.js", "pad_docbar.js", "pad_modals.js", "ace.js", "collab_client.js", "pad_userlist.js", "pad_impexp.js", "pad_savedrevs.js", "pad_connectionstatus.js", "pad2.js", "jquery-ui.js", "chat.js", "excanvas.js", "farbtastic.js"]; var padJS = ["jquery.min.js", "translate.js", "LANGUAGE", "pad_utils.js", "plugins.js", "undo-xpopup.js", "json2.js", "pad_cookie.js", "pad_editor.js", "pad_editbar.js", "pad_docbar.js", "pad_modals.js", "ace.js", "collab_client.js", "pad_userlist.js", "pad_impexp.js", "pad_savedrevs.js", "pad_connectionstatus.js", "pad2.js", "jquery-ui.js", "chat.js", "excanvas.js", "farbtastic.js"];
var timesliderJS = ["jquery.min.js", "plugins.js", "undo-xpopup.js", "json2.js", "colorutils.js", "draggable.js", "pad_utils.js", "pad_cookie.js", "pad_editor.js", "pad_editbar.js", "pad_docbar.js", "pad_modals.js", "easysync2_client.js", "domline_client.js", "linestylefilter_client.js", "cssmanager_client.js", "broadcast.js", "broadcast_slider.js", "broadcast_revisions.js"]; var timesliderJS = ["jquery.min.js", "plugins.js", "undo-xpopup.js", "json2.js", "colorutils.js", "draggable.js", "pad_utils.js", "pad_cookie.js", "pad_editor.js", "pad_editbar.js", "pad_docbar.js", "pad_modals.js", "easysync2_client.js", "domline_client.js", "linestylefilter_client.js", "cssmanager_client.js", "broadcast.js", "broadcast_slider.js", "broadcast_revisions.js"];
@ -129,8 +129,31 @@ exports.minifyJS = function(req, res, jsFilename)
{ {
async.forEach(jsFiles, function (item, callback) async.forEach(jsFiles, function (item, callback)
{ {
fs.readFile("../static/js/" + item, "utf-8", function(err, data) var fileName = "../static/js/" + item;
//if this is the language file, take the correct one
if(item == "LANGUAGE")
{ {
//skip if this is english, we don't need a language file for that
if(settings.language == "en")
{
fileValues[item] = "";
callback();
return;
}
//replace it with the translation file
fileName = "../translation/" + settings.language + "/pad.json";
}
fs.readFile(fileName, "utf-8", function(err, data)
{
//add this prefix for language files
if(item == "LANGUAGE")
{
data = "var language = '" + settings.language + "'; var translation = {};\ntranslation['" + settings.language + "'] = " + data;
}
fileValues[item] = data; fileValues[item] = data;
callback(err); callback(err);
}); });
@ -269,8 +292,31 @@ exports.minifyJS = function(req, res, jsFilename)
//read all js files //read all js files
async.forEach(jsFiles, function (item, callback) async.forEach(jsFiles, function (item, callback)
{ {
fs.readFile("../static/js/" + item, "utf-8", function(err, data) var fileName = "../static/js/" + item;
//if this is the language file, take the correct one
if(item == "LANGUAGE")
{ {
//skip if this is english, we don't need a language file for that
if(settings.language == "en")
{
fileValues[item] = "";
callback();
return;
}
//replace it with the translation file
fileName = "../translation/" + settings.language + "/pad.json";
}
fs.readFile(fileName, "utf-8", function(err, data)
{
//add this prefix for language files
if(item == "LANGUAGE")
{
data = "var language = '" + settings.language + "'; var translation = {};\ntranslation['" + settings.language + "'] = " + data;
}
fileValues[item] = data; fileValues[item] = data;
callback(err); callback(err);
}); });

View file

@ -57,6 +57,11 @@ exports.abiword = null;
*/ */
exports.loglevel = "INFO"; exports.loglevel = "INFO";
/**
* The language of the user interface
*/
exports.language = "en";
//read the settings sync //read the settings sync
var settingsStr = fs.readFileSync("../settings.json").toString(); var settingsStr = fs.readFileSync("../settings.json").toString();

View file

@ -37,5 +37,8 @@
"abiword" : null, "abiword" : null,
/* The log level we are using, can be: DEBUG, INFO, WARN, ERROR */ /* The log level we are using, can be: DEBUG, INFO, WARN, ERROR */
"loglevel": "INFO" "loglevel": "INFO",
/* The language of the user interface */
"language": "en"
} }

View file

@ -34,5 +34,11 @@
/* This is the path to the Abiword executable. Setting it to null, disables abiword. /* This is the path to the Abiword executable. Setting it to null, disables abiword.
Abiword is needed to enable the import/export of pads*/ Abiword is needed to enable the import/export of pads*/
"abiword" : null "abiword" : null,
/* The log level we are using, can be: DEBUG, INFO, WARN, ERROR */
"loglevel": "INFO",
/* The language of the user interface */
"language": "en"
} }

View file

@ -699,7 +699,7 @@ var paduserlist = (function()
} }
else else
{ {
$("#myusernameedit").addClass("editempty").val("Enter your name"); $("#myusernameedit").addClass("editempty").val(translate("Enter your name"));
} }
if (colorPickerOpen) if (colorPickerOpen)
{ {

47
static/js/translate.js Normal file
View file

@ -0,0 +1,47 @@
//trys to find a translation for the string and returns the translation or the original string
function translate(str)
{
var translated = str;
//return translation if avaiable
if(language != null && translation != null && translation[language][str] != null)
{
translated = translation[language][str];
}
else if(window.console)
{
window.console.log("No " + language + " translation for '" + str + "'");
}
return translated;
}
function DOMTranslate(selector, attribute)
{
//skip translation if its english
if(language === "en")
return;
//loop trough all elements
$(selector).each(function(index, element)
{
//make a jquery object
element = $(element);
//thats a attribute translation
if(attribute != null)
{
element.attr(attribute, translate(element.attr(attribute)));
}
//thats a text translation
else
{
element.text(translate(element.text()));
}
});
}
$(document).ready(function()
{
DOMTranslate(".translate");
});

View file

@ -109,6 +109,8 @@
</li> </li>
</ul> </ul>
<script>DOMTranslate("#editbar a", "title");</script>
</div> </div>
<div id="users"> <div id="users">
@ -120,15 +122,11 @@
<div id="mycolorpicker"> <div id="mycolorpicker">
<div id="colorpicker"></div> <div id="colorpicker"></div>
<!--
<ul id="colorpickerswatches">
</ul>
-->
<span id="mycolorpickersave"> <span id="mycolorpickersave">
<a onclick="closeColorPicker()">Save</a> <a onclick="closeColorPicker()" class="translate">Save</a>
</span> </span>
<span id="mycolorpickercancel"> <span id="mycolorpickercancel">
<a onclick="closeColorPicker()">Cancel</a> <a onclick="closeColorPicker()" class="translate">Cancel</a>
</span> </span>
<span id="mycolorpickerpreview" class="myswatchboxhoverable"></span> <span id="mycolorpickerpreview" class="myswatchboxhoverable"></span>
</div> </div>
@ -181,13 +179,13 @@
<div id="importexport"> <div id="importexport">
<div id="import"> <div id="import">
Import from text file, HTML, PDF, Word, ODT or RTF:<br/><br/> <span id="importtext" class="translate">Import from text file, HTML, PDF, Word, ODT or RTF:</span><br/><br/>
<form id="importform" method="post" action="" target="importiframe" enctype="multipart/form-data"> <form id="importform" method="post" action="" target="importiframe" enctype="multipart/form-data">
<div class="importformdiv" id="importformfilediv"> <div class="importformdiv" id="importformfilediv">
<input type="file" name="file" size="15" id="importfileinput" /> <input type="file" name="file" size="15" id="importfileinput" />
<div class="importmessage" id="importmessagefail"></div> <div class="importmessage" id="importmessagefail"></div>
</div> </div>
<div class="importmessage" id="importmessagesuccess">Successful!</div> <div class="importmessage translate" id="importmessagesuccess">Successful!</div>
<div class="importformdiv" id="importformsubmitdiv"> <div class="importformdiv" id="importformsubmitdiv">
<input type="hidden" name="padId" value="blpmaXT35R" /> <input type="hidden" name="padId" value="blpmaXT35R" />
<span class="nowrap"> <span class="nowrap">
@ -202,13 +200,13 @@
<div id="importexportline"></div> <div id="importexportline"></div>
<div id="export"> <div id="export">
Export current pad as: <span id="exporttext" class="translate">Export current pad as:</span>
<a id="exporthtmla" target="_blank" class="exportlink"><div class="exporttype" id="exporthtml">HTML</div></a> <a id="exporthtmla" target="_blank" class="exportlink"><div class="exporttype translate" id="exporthtml">HTML</div></a>
<a id="exportplaina" target="_blank" class="exportlink"><div class="exporttype" id="exportplain">Plain text</div></a> <a id="exportplaina" target="_blank" class="exportlink"><div class="exporttype translate" id="exportplain">Plain text</div></a>
<a id="exportworda" target="_blank" class="exportlink"><div class="exporttype" id="exportword">Microsoft Word</div></a> <a id="exportworda" target="_blank" class="exportlink"><div class="exporttype translate" id="exportword">Microsoft Word</div></a>
<a id="exportpdfa" target="_blank" class="exportlink"><div class="exporttype" id="exportpdf">PDF</div></a> <a id="exportpdfa" target="_blank" class="exportlink"><div class="exporttype translate" id="exportpdf">PDF</div></a>
<a id="exportopena" target="_blank" class="exportlink"><div class="exporttype" id="exportopen">OpenDocument</div></a> <a id="exportopena" target="_blank" class="exportlink"><div class="exporttype translate" id="exportopen">OpenDocument</div></a>
<a id="exportwordlea" target="_blank" onClick="padimpexp.export2Wordle();return false;" class="exportlink"><div class="exporttype" id="exportwordle">Wordle</div></a> <a id="exportwordlea" target="_blank" onClick="padimpexp.export2Wordle();return false;" class="exportlink"><div class="exporttype translate" id="exportwordle">Wordle</div></a>
<form id="wordlepost" name="wall" action="http://wordle.net/advanced" method="POST" style="margin-left:0px;"> <form id="wordlepost" name="wall" action="http://wordle.net/advanced" method="POST" style="margin-left:0px;">
<div id="hidetext" style=""><textarea id="text" name="text" id="text" style="display:none;">Coming soon!</textarea></div> <div id="hidetext" style=""><textarea id="text" name="text" id="text" style="display:none;">Coming soon!</textarea></div>
</form> </form>
@ -218,14 +216,14 @@
<!-- the embed code --> <!-- the embed code -->
<div id="embed"> <div id="embed">
<div id="embedcode"> <div id="embedcode">
Embed code:<input id="embedinput" type="text" value=""> <span id="embedtext" class="translate">Embed code:</span><input id="embedinput" type="text" value="">
</div> </div>
</div> </div>
<!-- the embed code --> <!-- the embed code -->
<div id="readonly"> <div id="readonly">
<div id="readonlyUrl"> <div id="readonlyUrl">
Use this link to share a read-only version of your pad:<input id="readonlyInput" type="text" value=""> <span id="readonlytext" class="translate">Use this link to share a read-only version of your pad:</span><input id="readonlyInput" type="text" value="">
<img id="readonlyImage" src="" alt="" style="margin: 10px 90px"> <img id="readonlyImage" src="" alt="" style="margin: 10px 90px">
</div> </div>
</div> </div>
@ -237,14 +235,14 @@ Use this link to share a read-only version of your pad:<input id="readonlyInput"
<div id="chaticon"> <div id="chaticon">
<a onClick="chat.show();return false;" <a onClick="chat.show();return false;"
title="Open the chat for this pad"> title="Open the chat for this pad">
<span id="chatlabel">Chat</span> <span id="chatlabel" class="translate">Chat</span>
<div class="buttonicon" style="background-position:0px -102px;display:inline-block;"></div> <div class="buttonicon" style="background-position:0px -102px;display:inline-block;"></div>
</a> </a>
<span id="chatcounter">0</span> <span id="chatcounter">0</span>
</div> </div>
<div id="chatbox"> <div id="chatbox">
<div id="titlebar"><span id ="titlelabel">Chat</span><a id="titlecross" onClick="chat.hide();return false;">-&nbsp;</a></div> <div id="titlebar"><span id ="titlelabel" class="translate">Chat</span><a id="titlecross" onClick="chat.hide();return false;">-&nbsp;</a></div>
<div id="chattext" class="authorColors"></div> <div id="chattext" class="authorColors"></div>
<div id="chatinputbox"> <div id="chatinputbox">
<form> <form>
@ -266,10 +264,10 @@ Use this link to share a read-only version of your pad:<input id="readonlyInput"
<div id="connectionbox" class="modaldialog"> <div id="connectionbox" class="modaldialog">
<div id="connectionboxinner" class="modaldialog-inner"> <div id="connectionboxinner" class="modaldialog-inner">
<div class="connecting"> <div class="connecting">
Connecting... <span class="translate">Connecting...</span>
</div> </div>
<div class="reconnecting"> <div class="reconnecting">
Reestablishing connection... <span class="translate">Reestablishing connection...</span>
</div> </div>
<div class="disconnected"> <div class="disconnected">
<h2 class="h2_disconnect">Disconnected.</h2> <h2 class="h2_disconnect">Disconnected.</h2>
@ -277,49 +275,49 @@ Use this link to share a read-only version of your pad:<input id="readonlyInput"
<h2 class="h2_unauth">No Authorization.</h2> <h2 class="h2_unauth">No Authorization.</h2>
<div id="disconnected_looping"> <div id="disconnected_looping">
<p> <p>
<b>We're having trouble talking to the EtherPad lite synchronization server.</b> <b><span class="translate">We're having trouble talking to the EtherPad lite synchronization server.</span></b>
You may be connecting through an incompatible firewall or proxy server. <span class="translate">You may be connecting through an incompatible firewall or proxy server.</span>
</p> </p>
</div> </div>
<div id="disconnected_initsocketfail"> <div id="disconnected_initsocketfail">
<p> <p>
<b>We were unable to connect to the EtherPad lite synchronization server.</b> <b><span class="translate">We were unable to connect to the EtherPad lite synchronization server.</span></b>
This may be due to an incompatibility with your web browser or internet connection. <span class="translate">This may be due to an incompatibility with your web browser or internet connection.</span>
</p> </p>
</div> </div>
<div id="disconnected_userdup"> <div id="disconnected_userdup">
<p> <p>
<b>You seem to have opened this pad in another browser window.</b> <b><span class="translate">You seem to have opened this pad in another browser window.</span></b>
If you'd like to use this window instead, you can reconnect. <span class="translate">If you'd like to use this window instead, you can reconnect.</span>
</p> </p>
</div> </div>
<div id="disconnected_unknown"> <div id="disconnected_unknown">
<p> <p>
<b>Lost connection with the EtherPad lite synchronization server.</b> This may be due to a loss of network connectivity. <b><span class="translate">Lost connection with the EtherPad lite synchronization server.</b> This may be due to a loss of network connectivity.</span>
</p> </p>
</div> </div>
<div id="disconnected_slowcommit"> <div id="disconnected_slowcommit">
<p> <p>
<b>Server not responding.</b> This may be due to network connectivity issues or high load on the server. <b><span class="translate">Server not responding.</span></b> <span class="translate">This may be due to network connectivity issues or high load on the server.</span>
</p> </p>
</div> </div>
<div id="disconnected_unauth"> <div id="disconnected_unauth">
<p> <p>
Your browser's credentials or permissions have changed while viewing this pad. Try reconnecting. <span class="translate">Your browser's credentials or permissions have changed while viewing this pad. Try reconnecting.</span>
</p> </p>
</div> </div>
<div id="disconnected_deleted"> <div id="disconnected_deleted">
<p> <p>
This pad was deleted. <span class="translate">This pad was deleted.</span>
</p> </p>
</div> </div>
<div id="reconnect_advise"> <div id="reconnect_advise">
<p> <p>
If this continues to happen, please let us know <span class="translate">If this continues to happen, please let us know</span>
</p> </p>
</div> </div>
<div id="reconnect_form"> <div id="reconnect_form">
<button id="forcereconnect">Reconnect Now</button> <button id="forcereconnect"><span class="translate">Reconnect Now</span></button>
</div> </div>
</div> </div>
</div> </div>

47
translation/de/pad.json Normal file
View file

@ -0,0 +1,47 @@
{
"Bold (ctrl-B)":"Fett (Strg+B)",
"Italics (ctrl-I)":"Kursiv (Strg+I)",
"Underline (ctrl-U)":"Unterstrichen (Strg+U)",
"Strikethrough":"Durchgestrichen",
"Toggle Bullet List":"Liste",
"Indent List":"Liste einrücken",
"Unindent List":"Liste ausrücken",
"Undo (ctrl-Z)":"Rückgängig",
"Redo (ctrl-Y)":"Widerholen",
"Clear Authorship Colors":"Autorenfarben entfernen",
"Create a readonly link for this pad":"Erzeuge einen Nur-Lese Link",
"Import/Export from/to different document formats":"Importiere/Exportiere von und zu verschiedenen Dokumentformaten",
"Embed this pad":"Binde dieses Pad in deine Webseite ein",
"Show the history of this pad":"Zeige den Verlauf des Pads",
"Show connected users":"Zeige verbundene Benutzer",
"Cancel":"Abrechen",
"Save":"Speichern",
"Import from text file, HTML, PDF, Word, ODT or RTF:":"Importiere von Text, HTML, PDF, Word, ODT oder RTF:",
"Successful!":"Erfolgreich!",
"Export current pad as:":"Exportiere dieses Pad als",
"HTML":"HTML",
"Plain text":"Reiner Text",
"Microsoft Word":"Microsoft Word",
"PDF":"PDF",
"OpenDocument":"OpenDocument",
"Wordle":"Wordle",
"Embed code:":"Einbett code",
"Use this link to share a read-only version of your pad:":"Nutze diesen Link um mit deinen Freunden eine Nur-Lese zu teilen",
"Chat":"Chat",
"Connecting...":"Verbinde...",
"Reestablishing connection...":"Baue verbindung neu auf...",
"We're having trouble talking to the EtherPad lite synchronization server.":"Wir haben Probleme uns zu verbinden",
"You may be connecting through an incompatible firewall or proxy server.":"",
"We were unable to connect to the EtherPad lite synchronization server.":"",
"This may be due to an incompatibility with your web browser or internet connection.":"",
"You seem to have opened this pad in another browser window.":"",
"If you'd like to use this window instead, you can reconnect.":"",
"Lost connection with the EtherPad lite synchronization server.":"",
"Server not responding.":"",
"This may be due to network connectivity issues or high load on the server.":"",
"Your browser's credentials or permissions have changed while viewing this pad. Try reconnecting.":"",
"This pad was deleted.":"Dieses Pad wurde gelöscht",
"If this continues to happen, please let us know":"Sollte dies wiederholt passieren, informieren sie uns bitte darüber",
"Reconnect Now":"Jetzt neu verbinden",
"Enter your name":"Namen eingeben"
}