Skip to content
This repository has been archived by the owner on Aug 24, 2020. It is now read-only.

Commit

Permalink
Merge pull request #28 from jdavid/master
Browse files Browse the repository at this point in the history
Internationalization
  • Loading branch information
tamasd committed Aug 30, 2017
2 parents 4bc99b1 + 649f2fc commit dcd3044
Show file tree
Hide file tree
Showing 23 changed files with 1,582 additions and 55 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ assets/*
dist
public/*
test.toml

.*.swp
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,9 @@ docker: preparedocker

rebuildsearch:
go build -o wh-rebuildsearch cmd/wh-rebuildsearch/main.go

gettext:
python gettext.py
msgmerge -U locales/en.po locales/messages.pot
msgmerge -U locales/fr.po locales/messages.pot
npm run stonejs -- build --merge locales/*.po js/messages.json
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ If unsure, leave them empty.
* `googleanalyticsaccount`: enables Google Analytics.
* `mailchimp`: mailchimp-related configuration. If set, new users will be added to a mailing list.
* `metricsaddresses`: comma separated whitelist of addresses from where the `/metrics` endpoint is accessible
* `languages`: list of languages for the user interface

## Build & Run

Expand Down
3 changes: 2 additions & 1 deletion config.json.sample.full
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@
"listid": "",
"datacenter": ""
},
"googleanalyticsaccount": ""
"googleanalyticsaccount": "",
"languages": ["en"]
}
46 changes: 46 additions & 0 deletions gettext.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import os
import re


HEADER = r"""# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-07-20 17:40+0200\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"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
"""


if __name__ == '__main__':
rexp = re.compile('(.*?[^a-zA-Z0-9_]|^)(t|N_)\("(.*?)"[\)|,]')

pot = open('locales/messages.pot', 'w')
pot.write(HEADER)

msgs = {}
for root, dirs, files in os.walk('js'):
for filename in files:
if filename.endswith('.js'):
filename = os.path.join(root, filename)
for line_no, line in enumerate(open(filename)):
source = '%s:%d' % (filename, line_no + 1)
for match in rexp.finditer(line):
msgs.setdefault(match.group(3), []).append(source)

for msg in sorted(msgs):
pot.write('\n')
for source in sorted(msgs[msg]):
pot.write('#: %s\n' % source)
pot.write('msgid "{}"\nmsgstr ""\n'.format(msg))
14 changes: 7 additions & 7 deletions js/client/walkthrough/autotitle.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import $ from "jquery";
import {capitalizeFirstLetter, split} from "util";
import {t} from "t";
import {t, N_} from "t";
import Translator from "client/walkthrough/translator";

class AutoTitle {
Expand All @@ -25,8 +25,8 @@ class AutoTitle {
const [sentence, paragraph, params] = this.locatorToSentence(command, locator);
const verb = this.commandToVerb(command);

params["@verb"] = t(verb);
params["@value"] = value;
params["verb"] = t(verb);
params["value"] = value;

return [t(sentence, params), t(paragraph, params)];
}
Expand All @@ -47,10 +47,10 @@ class AutoTitle {

linkSentenceGenerator(command, prefix, argument) {
return [
"@verb on @argument",
N_("{verb} on {argument}"),
"",
{
"@argument": argument,
"argument": argument,
},
];
}
Expand All @@ -59,10 +59,10 @@ class AutoTitle {
const elem = Translator.instance().translate(prefix+"="+argument);
const label = this.getLabel(elem);
return [
"@verb in @label",
N_("{verb} in {label}"),
"",
{
"@label": label,
"label": label,
},
];
}
Expand Down
5 changes: 3 additions & 2 deletions js/client/walkthrough/bubble.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {MAXIMUM_ZINDEX} from "util";
import editDialog from "client/walkthrough/editdialog";
import EventAbsorber from "client/walkthrough/eventabsorber";
import LocatorGenerator from "client/walkthrough/locator_generator";
import {t} from "t";

class Bubble {

Expand Down Expand Up @@ -111,7 +112,7 @@ class Bubble {

this.nextButton = $("<a />")
.attr("href", "#")
.text("Next")
.text(t("Next"))
.addClass("wtbubble-button")
.addClass("wtbubble-next")
.addClass("wtbubble-button")
Expand All @@ -130,7 +131,7 @@ class Bubble {
.attr("href", "#")
.addClass("wtbubble-edit")
.addClass("wtbubble-button")
.text("Edit")
.text(t("Edit"))
.click(function (event) {
event.preventDefault();
that.editdialog = new editDialog(that.step, that.contentWrapper);
Expand Down
3 changes: 2 additions & 1 deletion js/client/walkthrough/editdialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import $ from "jquery";
import Bubble from "client/walkthrough/bubble";
import {t} from "t";

class editDialog {

Expand Down Expand Up @@ -217,7 +218,7 @@ class editDialog {
this.controller.client.getSuggestions(this.step.cmd, this.step.arg0, this.step.arg1, function (data) {
suggestionwrapper
.show()
.append($("<p/>").text("Suggestions: "));
.append($("<p/>").text(t("Suggestions: ")));
for (var i in data) {
if (data.hasOwnProperty(i)) {
$("<p />")
Expand Down
12 changes: 6 additions & 6 deletions js/client/walkthrough/executor.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import Controller from "client/walkthrough/controller";
import Bubble from "client/walkthrough/bubble";
import CommandDispatcher from "client/walkthrough/command_dispatcher";
import Translator from "client/walkthrough/translator";
import {t} from "t";
import {t, N_} from "t";
import URI from "URIjs";
import {getdata} from "util";

Expand Down Expand Up @@ -130,13 +130,13 @@ class Executor {
},
waiting: (tries, remainingtries) => {
const message = step.canEdit ?
"The @number. bubble is not found. Go to the !editlink form to repair it. Technical info: @locator" :
"The @number. bubble is not found. Report it to the owner.";
N_("The {number}. bubble is not found. Go to the {editlink} form to repair it. Technical info: {locator}") :
N_("The {number}. bubble is not found. Report it to the owner.");
if ((tries-remainingtries) > 10) {
this.client.showError("locator-fail", t(message, {
"@number": this.controller.state.stepIndex + 1,
"@locator": step.highlight,
"!editlink": `<a href="/walkthrough/${this.controller.state.walkthrough}" target="_top">edit walkthrough</a>`, // TODO replace this with a proper router generated link
"number": this.controller.state.stepIndex + 1,
"locator": step.highlight,
"editlink": `<a href="/walkthrough/${this.controller.state.walkthrough}" target="_top">edit walkthrough</a>`, // TODO replace this with a proper router generated link
}));
}
error = true;
Expand Down
9 changes: 5 additions & 4 deletions js/client/walkthrough/recorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import EventAbsorber from "client/walkthrough/eventabsorber";
import Util from "client/walkthrough/util";
import LocatorGenerator from "client/walkthrough/locator_generator";
import AutoTitle from "client/walkthrough/autotitle";
import {N_} from "t";

class Recorder {

Expand Down Expand Up @@ -107,7 +108,7 @@ class Recorder {

if (!Util.isInputElement(clickedElement)) {
const locator = LocatorGenerator.instance().generate(clickedElement);
const [title, description] = AutoTitle.instance().titleAndDescription("click", locator);
const [title, description] = AutoTitle.instance().titleAndDescription("click", locator); N_("Click");
this.client.saveStep("click", locator, null, title, description);
this.animateRecordedElement(clickedElement);
}
Expand Down Expand Up @@ -149,7 +150,7 @@ class Recorder {
let title, description;
switch (tagName) {
case "select":
[title, description] = AutoTitle.instance().titleAndDescription("select", locator, value);
[title, description] = AutoTitle.instance().titleAndDescription("select", locator, value); N_("Select");
this.client.saveStep("select", locator, "value=" + value, title, description);
this.animateRecordedElement(element);
break;
Expand All @@ -160,7 +161,7 @@ class Recorder {
this.client.enablePasswordParameter();
}
const value = ispw ? "[password]" : value;
[title, description] = AutoTitle.instance().titleAndDescription("type", locator, value);
[title, description] = AutoTitle.instance().titleAndDescription("type", locator, value); N_("Type");
this.client.saveStep("type", locator, value);
this.animateRecordedElement(element);
break;
Expand All @@ -169,7 +170,7 @@ class Recorder {
var valueDom = $(element.html());
valueDom.find(".walkthrough-eventabsorber-hover").removeClass("walkthrough-eventabsorber-hover");
var finalValue = $("<div />").append(valueDom).html();
[title, description] = AutoTitle.instance().titleAndDescription("type", locator, finalValue);
[title, description] = AutoTitle.instance().titleAndDescription("type", locator, finalValue); N_("Type");
this.client.saveStep("type", locator, finalValue, title, description);
this.animateRecordedElement(element);
} else {
Expand Down
4 changes: 2 additions & 2 deletions js/components/connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ class Connect extends React.Component {
const url = `/api/auth/${provider.id}/connect?token=${csrfToken}`;
return (
<div key={provider.id} className={"col-xs-10 col-xs-offset-1 provider-"+provider.id}>
<a href={url} className="btn btn-primary btn-block">{t("Log in with @label", {"@label": provider.label})}</a>
<a href={url} className="btn btn-primary btn-block">{t("Log in with {label}", {"label": provider.label})}</a>
</div>
);
});

const signupButton = (!DISABLE_REGISTRATION && this.props.password && !this.props.signup) ? (
<span>New to WalkHub? <a href="#" className="register-link" onClick={this.props.signupClick}>{t("Register")}</a></span>
<span>{t("New to WalkHub?")} <a href="#" className="register-link" onClick={this.props.signupClick}>{t("Register")}</a></span>
) : null;

let signinForm = null;
Expand Down
3 changes: 2 additions & 1 deletion js/components/embedcodebuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import React from "react";
import EmbedCode from "components/embedcode";
import {noop} from "form";
import {t} from "t";
import {t, N_} from "t";
import URI from "URIjs";

class EmbedCodeBuilder extends React.Component {
Expand Down Expand Up @@ -47,6 +47,7 @@ class EmbedCodeBuilder extends React.Component {
let advancedSettings = null;
if (this.props.enableAdvanced && !this.props.showCode) {
if (this.props.showAdvanced) {
N_("none"); N_("bottom right"); N_("bottom left"); N_("top right"), N_("top left");
const positions = ["none", "bottom-right", "bottom-left", "top-right", "top-left"].map((position) => {
const label = t(position.replace("-", " "));
return (
Expand Down
2 changes: 1 addition & 1 deletion js/components/profileedit.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class ProfileEdit extends React.Component {
return (
<div key={provider.id} className="row">
<div className="col-xs-6">
{t("%label log in", {"%label": provider.label})}
{t("{label} log in", {"label": provider.label})}
</div>
<div className="col-xs-6">
<a href={url} className="btn btn-default btn-sm profile-edit-button">{t("Connect")}</a>
Expand Down
10 changes: 5 additions & 5 deletions js/components/wrappers/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import UserActions from "actions/user";
import connectToStores from "alt/utils/connectToStores";
import flux from "control";
import {noop} from "form";
import {t} from "t";
import {t, N_} from "t";
import {capitalizeFirstLetter} from "util";
import RouterActions from "actions/router";
import OuterClassActions from "actions/outerclass";
Expand All @@ -45,12 +45,12 @@ if (WALKHUB_ANNOUNCEMENT) {
let menuItems = {
navbar: {
left: [
{path: "https://github.com/Pronovix/walkhub-service", label: "Download from GitHub"},
{path: "https://github.com/Pronovix/walkhub-service", label: N_("Download from GitHub")},
],
right: [
{path: "/search", label: "Search"},
{path: "/profile/me", label: "My Profile", loggedin: true},
{path: "/record", label: "Record", loggedin: true},
{path: "/search", label: N_("Search")},
{path: "/profile/me", label: N_("My Profile"), loggedin: true},
{path: "/record", label: N_("Record"), loggedin: true},
{path: "/connect", icon: "log-in", loggedin: false},
{path: "/api/auth/logout?token=CSRF_TOKEN", icon: "log-out", loggedin: true},
],
Expand Down
4 changes: 2 additions & 2 deletions js/components/wrappers/record.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ class RecordWrapper extends React.Component {
noop(evt);
const title = this.state.title ?
this.state.title :
t("Walkthrough on @domain", {
"@domain": URI(this.state.startingUrl).hostname(),
t("Walkthrough on {domain}", {
"domain": URI(this.state.startingUrl).hostname(),
});
const runner = this.getRunner();
if (runner.getName() === "popup") {
Expand Down
Loading

0 comments on commit dcd3044

Please sign in to comment.