summaryrefslogtreecommitdiff
path: root/talermerchantdemos
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-10-11 15:05:16 +0200
committerChristian Grothoff <christian@grothoff.org>2020-10-11 15:05:16 +0200
commita984947846c7b83d3151fc4987ca615edcb168ef (patch)
treeb03a1524a55d2a0255f0b9c1e56061bca9358e02 /talermerchantdemos
parent1ae0306a3cf2ea27f60b2d205789994d260c2cce (diff)
downloadtaler-merchant-demos-a984947846c7b83d3151fc4987ca615edcb168ef.tar.gz
taler-merchant-demos-a984947846c7b83d3151fc4987ca615edcb168ef.tar.bz2
taler-merchant-demos-a984947846c7b83d3151fc4987ca615edcb168ef.zip
i18n for survey
Diffstat (limited to 'talermerchantdemos')
-rw-r--r--talermerchantdemos/blog/blog.py17
-rw-r--r--talermerchantdemos/blog/templates/base.html.j29
-rw-r--r--talermerchantdemos/blog/templates/confirm_refund.html.j22
l---------talermerchantdemos/donations/translations1
-rw-r--r--talermerchantdemos/survey/survey.py60
-rw-r--r--talermerchantdemos/survey/templates/base.html59
-rw-r--r--talermerchantdemos/survey/templates/base.html.j2115
-rw-r--r--talermerchantdemos/survey/templates/error.html22
-rw-r--r--talermerchantdemos/survey/templates/error.html.j224
-rw-r--r--talermerchantdemos/survey/templates/index.html.j2 (renamed from talermerchantdemos/survey/templates/index.html)12
-rw-r--r--talermerchantdemos/survey/templates/survey_stats.html15
l---------talermerchantdemos/survey/translations1
12 files changed, 217 insertions, 120 deletions
diff --git a/talermerchantdemos/blog/blog.py b/talermerchantdemos/blog/blog.py
index 7112b33..ba6571b 100644
--- a/talermerchantdemos/blog/blog.py
+++ b/talermerchantdemos/blog/blog.py
@@ -61,6 +61,7 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
app = flask.Flask(
__name__, template_folder=BASE_DIR, static_folder=BASE_DIR + "/../static/"
)
+app.debug = True
app.secret_key = base64.b64encode(os.urandom(64)).decode("utf-8")
LOGGER = logging.getLogger(__name__)
@@ -81,7 +82,8 @@ babel = Babel(app)
print("Using translations from:")
print(list(babel.translation_directories))
translations = [str(translation) for translation in babel.list_translations()]
-translations.append('en')
+if not 'en' in translations:
+ translations.append('en')
print("Operating with the following translations available:")
print(translations)
@@ -126,6 +128,19 @@ def index():
target = flask.request.accept_languages.best_match(translations, default)
return flask.redirect("/" + target + "/", code=302)
+##
+# Serve the /favicon.ico requests.
+#
+# @return the favicon.ico file.
+@app.route("/favicon.ico")
+def favicon():
+ LOGGER.info("will look into: " + os.path.join(app.root_path, 'static'))
+ return flask.send_from_directory(
+ os.path.join(app.root_path, 'static'),
+ "favicon.ico",
+ mimetype="image/vnd.microsoft.ico"
+ )
+
@babel.localeselector
def get_locale():
parts = request.path.split('/', 2)
diff --git a/talermerchantdemos/blog/templates/base.html.j2 b/talermerchantdemos/blog/templates/base.html.j2
index 58ce857..1303276 100644
--- a/talermerchantdemos/blog/templates/base.html.j2
+++ b/talermerchantdemos/blog/templates/base.html.j2
@@ -69,8 +69,8 @@
<body>
<header class="demobar" style="display: flex; flex-direction: column;">
- <h1><span class="tt adorn-brackets">Taler Demo</span></h1>
- <h1><span class="it"><a href="{{ env('TALER_ENV_URL_MERCHANT_BLOG') }}">Shop</a></span></h1>
+ <h1><span class="tt adorn-brackets">{{ gettext("Taler Demo")}}</span></h1>
+ <h1><span class="it"><a href="{{ env('TALER_ENV_URL_MERCHANT_BLOG') }}">{{ gettext("Shop") }}</a></span></h1>
<p>{{
gettext("On this page you can buy articles using an imaginary currency.") + "<br>" +
gettext("The articles are chapters from Richard Stallman's book &quot;Free Software, Free Society&quot;.") + "<br>" +
@@ -82,9 +82,9 @@
<nav class="demolist">
<a href="{{ env('TALER_ENV_URL_INTRO', '#') }}">{{gettext("Introduction")}}</a>
<a href="{{ env('TALER_ENV_URL_BANK', '#') }}">{{gettext("Bank")}}</a>
- <a href="{{ env('TALER_ENV_URL_MERCHANT_BLOG', '#') }}" class="active">{{gettext("Essay Shop")}}</a>
+ <a href="{{ env('TALER_ENV_URL_MERCHANT_BLOG', '#') }}">{{gettext("Essay Shop")}}</a>
<a href="{{ env('TALER_ENV_URL_MERCHANT_DONATIONS', '#') }}">{{gettext("Donations")}}</a>
- <a href="{{ env('TALER_ENV_URL_MERCHANT_SURVEY', '#') }}">{{gettext("Tipping/Survey")}}</a>
+ <a href="{{ env('TALER_ENV_URL_MERCHANT_SURVEY', '#') }}" class="active">{{gettext("Tipping/Survey")}}</a>
<!-- a href="{{ env('TALER_ENV_URL_BACKOFFICE', '#') }}">{{gettext("Back-office")}}</a -->
<span class="right">
{{ gettext("English [en]") }}
@@ -102,7 +102,6 @@
</span>
</nav>
</div>
- <!-- <input type="checkbox" class="r"><label>test</label> -->
<section id="main" class="content">
{% block main %}
diff --git a/talermerchantdemos/blog/templates/confirm_refund.html.j2 b/talermerchantdemos/blog/templates/confirm_refund.html.j2
index 09f3730..a371645 100644
--- a/talermerchantdemos/blog/templates/confirm_refund.html.j2
+++ b/talermerchantdemos/blog/templates/confirm_refund.html.j2
@@ -17,6 +17,6 @@
<form action="{{ url_for('refund', order_id=order_id) }}" method="POST">
<input type="text" name="article_name" value={{ article_name}} hidden>
- <input type="submit" value="Request refund">
+ <input type="submit" value="{{gettext("Request refund")}}">
</form>
{% endblock main %}
diff --git a/talermerchantdemos/donations/translations b/talermerchantdemos/donations/translations
new file mode 120000
index 0000000..0a951f7
--- /dev/null
+++ b/talermerchantdemos/donations/translations
@@ -0,0 +1 @@
+../../translations/ \ No newline at end of file
diff --git a/talermerchantdemos/survey/survey.py b/talermerchantdemos/survey/survey.py
index b6a5ceb..140088d 100644
--- a/talermerchantdemos/survey/survey.py
+++ b/talermerchantdemos/survey/survey.py
@@ -1,6 +1,6 @@
##
# This file is part of GNU TALER.
-# Copyright (C) 2017 Taler Systems SA
+# Copyright (C) 2017, 2020 Taler Systems SA
#
# TALER is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
@@ -23,9 +23,14 @@ import base64
import logging
from urllib.parse import urljoin
import flask
+from flask import request
+from flask_babel import Babel
+from flask_babel import refresh
+from flask_babel import force_locale
+from flask_babel import gettext
import traceback
from taler.util.talerconfig import TalerConfig, ConfigurationError
-from ..httpcommon import backend_get, backend_post, fallback_404
+from ..httpcommon import backend_get, backend_post, self_localized
import sys
if not sys.version_info.major == 3 and sys.version_info.minor >= 6:
@@ -37,6 +42,8 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
app = flask.Flask(__name__, template_folder=BASE_DIR)
app.debug = True
app.secret_key = base64.b64encode(os.urandom(64)).decode('utf-8')
+
+LOGGER = logging.getLogger(__name__)
TC = TalerConfig.from_env()
try:
BACKEND_URL = TC["frontends"]["backend"].value_string(required=True)
@@ -47,9 +54,30 @@ except ConfigurationError as ce:
exit(1)
app.config.from_object(__name__)
-LOGGER = logging.getLogger(__name__)
+babel = Babel(app)
INSTANCED_URL = urljoin(BACKEND_URL, f"instances/survey/")
+print("Using translations from:")
+print(list(babel.translation_directories))
+translations = [str(translation) for translation in babel.list_translations()]
+if not 'en' in translations:
+ translations.append('en')
+print("Operating with the following translations available:")
+print(translations)
+
+app.jinja_env.globals.update(self_localized=self_localized)
+
+@babel.localeselector
+def get_locale():
+ parts = request.path.split('/', 2)
+ if (2 >= len(parts)):
+ # Totally unexpected path format, do not localize
+ return "en"
+ lang = parts[1]
+ if lang in translations:
+ return lang
+ return "en"
+
##
# Make the environment available into templates.
#
@@ -80,8 +108,8 @@ def utility_processor():
@app.errorhandler(Exception)
def internal_error(e):
return flask.render_template(
- "templates/error.html",
- message="Internal error",
+ "templates/error.html.j2",
+ message=gettext("Internal error"),
stack=traceback.format_exc()
)
@@ -92,7 +120,7 @@ def internal_error(e):
# @return the favicon.ico file.
@app.route("/favicon.ico")
def favicon():
- print("will look into: " + os.path.join(app.root_path, 'static'))
+ LOGGER.info("will look into: " + os.path.join(app.root_path, 'static'))
return flask.send_from_directory(
os.path.join(app.root_path, 'static'),
"favicon.ico",
@@ -105,7 +133,7 @@ def favicon():
# @param abort_status_code status code to return along the response.
# @param params _kw_ arguments to passed verbatim to the templating engine.
def err_abort(abort_status_code, **params):
- t = flask.render_template("templates/error.html", **params)
+ t = flask.render_template("templates/error.html.j2", **params)
flask.abort(flask.make_response(t, abort_status_code))
##
@@ -127,16 +155,26 @@ def submit_survey():
return flask.redirect(backend_resp["tip_status_url"])
##
-# Serve the main index page.
+# Serve the main index page, redirecting to /<lang>/
#
# @return response object of the index page.
-@app.route("/", methods=["GET"])
+@app.route("/")
def index():
+ default = 'en'
+ target = flask.request.accept_languages.best_match(translations, default)
+ return flask.redirect("/" + target + "/", code=302)
+
+##
+# Serve the internationalized main index page.
+#
+# @return response object of the index page.
+@app.route("/<lang>/", methods=["GET"])
+def start(lang):
return flask.render_template(
- "templates/index.html", merchant_currency=CURRENCY
+ "templates/index.html.j2", merchant_currency=CURRENCY, lang=lang
)
@app.errorhandler(404)
def handler(e):
return flask.render_template(
- "templates/error.html", message="Page not found")
+ "templates/error.html.j2", message=gettext("Page not found"))
diff --git a/talermerchantdemos/survey/templates/base.html b/talermerchantdemos/survey/templates/base.html
deleted file mode 100644
index 2eeace1..0000000
--- a/talermerchantdemos/survey/templates/base.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<!--
- This file is part of GNU TALER.
- Copyright (C) 2014, 2015, 2016 INRIA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
- Foundation; either version 2.1, or (at your option) any later version.
-
- TALER 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 Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
--->
-
-<html data-taler-nojs="true">
-<head>
- <title>Taler Survey Demo</title>
- <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='pure.css') }}" />
- <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='demo.css') }}" />
- <link rel="stylesheet"
- type="text/css"
- href="{{ url_for('static', filename='web-common/taler-fallback.css') }}"
- id="taler-presence-stylesheet"/>
- {% block styles %}{% endblock %}
- {% block scripts %}{% endblock %}
-</head>
-
-<body>
- <div class="demobar">
- <h1><span class="tt adorn-brackets">Taler Demo</span></h1>
- <h1><span class="it"><a href="{{ env('TALER_ENV_URL_MERCHANT_SURVEY') }}">Survey</a></span></h1>
- <p>This is the survey page, which demonatrates how merchants can reward their users by paying directly into their wallet.</p>
- <ul>
- <li><a href="{{ env('TALER_ENV_URL_INTRO', '#') }}">Introduction</a></li>
- <li><a href="{{ env('TALER_ENV_URL_BANK', '#') }}">Bank</a></li>
- <li><a href="{{ env('TALER_ENV_URL_MERCHANT_BLOG', '#') }}">Essay Shop</a></li>
- <li><a href="{{ env('TALER_ENV_URL_MERCHANT_DONATIONS', '#') }}">Donations</a></li>
- <li><a href="{{ env('TALER_ENV_URL_MERCHANT_SURVEY', '#') }}">Survey</a></li>
- <li><a href="{{ env('TALER_ENV_URL_BACKOFFICE', '#') }}">Back-office</a></li>
- </ul>
- <p>You can learn more about Taler on our main <a href="https://taler.net">website</a>.</p>
- </div>
-
- <section id="main" class="content">
- <h1>Taler Survey Demo</h1>
- {% block main %}
- This is the main content of the page.
- {% endblock %}
- <hr />
- <div class="copyright">
- <p>Copyright &copy; 2014&mdash;2017 INRIA</p>
- <a href="/javascript" data-jslicense="1" class="jslicenseinfo">JavaScript license information</a>
- </div>
- </section>
-</body>
-</html>
diff --git a/talermerchantdemos/survey/templates/base.html.j2 b/talermerchantdemos/survey/templates/base.html.j2
new file mode 100644
index 0000000..b6d1c62
--- /dev/null
+++ b/talermerchantdemos/survey/templates/base.html.j2
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<!--
+ This file is part of GNU TALER.
+ Copyright (C) 2014, 2015, 2016, 2020 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Lesser General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+-->
+
+<html data-taler-nojs="true">
+<head>
+ <title>{{ gettext("Taler Survey Demo") }}</title>
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='pure.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='demo.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='navbar.css') }}" />
+ <style>
+ .warn {
+ background-color: #aa393977;
+ padding: 1em;
+ }
+ @keyframes hoveranim {
+ from {left:0;}
+ to {left:1vw;}
+ }
+ @keyframes hoveranimrevert {
+ from {left:1vw;}
+ to {left:0;}
+ }
+ .notice {
+ border-radius: 1em;
+ background: #0333;
+ border-left: 0.3em solid #033;
+ padding-left: 1em;
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ margin-top: 2em;
+ margin-bottom: 2em;
+ }
+ .notice {
+ position: relative;
+ left: 0;
+ animation-name: hoveranimrevert;
+ animation-duration: 1s;
+ }
+ .notice:hover {
+ left: 1vw;
+ animation-name: hoveranim;
+ animation-duration: 1s;
+ }
+ #main a:link, #main a:visited, #main a:hover, #main a:active {
+ color: black;
+ }
+ </style>
+
+ {% block styles %}{% endblock %}
+ {% block scripts %}{% endblock %}
+</head>
+
+<body>
+ <header class="demobar" style="display: flex; flex-direction: column;">
+ <h1><span class="tt adorn-brackets">{{ gettext("Taler Demo") }}</span></h1>
+ <h1><span class="it"><a href="{{ env('TALER_ENV_URL_MERCHANT_SURVEY') }}">{{ gettext("Survey") }}</a></span></h1>
+ <p>{{
+ gettext("This is the Taler survey demonstration.") + "<br>" +
+ gettext("It demonatrates how merchants can reward their users by granting tips.") + "<br>" +
+ gettext("Tipping is a way for offer cash rewards that go directly into a user's wallet.")
+ }}
+ </p>
+ </header>
+ <div style="display:flex; flex-direction: column;" class="navcontainer">
+ <nav class="demolist">
+ <a href="{{ env('TALER_ENV_URL_INTRO', '#') }}">{{gettext("Introduction")}}</a>
+ <a href="{{ env('TALER_ENV_URL_BANK', '#') }}">{{gettext("Bank")}}</a>
+ <a href="{{ env('TALER_ENV_URL_MERCHANT_BLOG', '#') }}" class="active">{{gettext("Essay Shop")}}</a>
+ <a href="{{ env('TALER_ENV_URL_MERCHANT_DONATIONS', '#') }}">{{gettext("Donations")}}</a>
+ <a href="{{ env('TALER_ENV_URL_MERCHANT_SURVEY', '#') }}">{{gettext("Tipping/Survey")}}</a>
+ <!-- a href="{{ env('TALER_ENV_URL_BACKOFFICE', '#') }}">{{gettext("Back-office")}}</a -->
+ <span class="right">
+ {{ gettext("English [en]") }}
+ <!-- <input type="checkbox"> -->
+ <div class="nav">
+ <br>
+ <!--<hr style="width: 100%;">-->
+ {% if lang != 'en' %}
+ <a href="{{ self_localized('en') }}" class="navbtn">English [en]</a><br>
+ {% endif %}
+ {% if lang != 'de' %}
+ <a href="{{ self_localized('de') }}" class="navbtn">Deutsch [de]</a><br>
+ {% endif %}
+ </div>
+ </span>
+ </nav>
+ </div>
+
+ <section id="main" class="content">
+ {% block main %}
+ This is the main content of the page.
+ {% endblock %}
+ <hr />
+ <div>
+ <p>{{ gettext('You can learn more about Taler on our main <a href="{site}">website</a>.').format(site="https://taler.net/") }}</p>
+ <div style="flex-grow:1"></div>
+ <p>Copyright &copy; 2014&mdash;2020 Taler Systems SA</p>
+ </div>
+ </section>
+</body>
+</html>
diff --git a/talermerchantdemos/survey/templates/error.html b/talermerchantdemos/survey/templates/error.html
deleted file mode 100644
index 0d4bd02..0000000
--- a/talermerchantdemos/survey/templates/error.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends "templates/base.html" %}
-{% block main %}
- <h1>An Error Occurred</h1>
-
- <p>{{ message }}</p>
-
- {% if status_code %}
- <p>The backend returned status code {{ status_code }}.</p>
- {% endif %}
-
- {% if json %}
- <p>Backend Response:</p>
- <pre>{{ json }}</pre>
- {% endif %}
-
- {% if stack %}
- <p>Stack trace:</p>
- <pre>
- {{ stack }}
- </pre>
- {% endif %}
-{% endblock main %}
diff --git a/talermerchantdemos/survey/templates/error.html.j2 b/talermerchantdemos/survey/templates/error.html.j2
new file mode 100644
index 0000000..ffc2e1f
--- /dev/null
+++ b/talermerchantdemos/survey/templates/error.html.j2
@@ -0,0 +1,24 @@
+{% extends "templates/base.html.j2" %}
+{% block main %}
+ <h1>{{ gettext("Error encountered") }}</h1>
+
+ <p>{{ message }}</p>
+
+ {% if status_code %}
+ <p>
+ {{ gettext ("The backend returned status code {code}.").format(code=status_code) }}.
+ </p>
+ {% endif %}
+
+ {% if json %}
+ <p>{{gettext("Backend response:")}}</p>
+ <pre>{{ json }}</pre>
+ {% endif %}
+
+ {% if stack %}
+ <p>{{gettext("Stack trace:")}}</p>
+ <pre>
+ {{ stack }}
+ </pre>
+ {% endif %}
+{% endblock main %}
diff --git a/talermerchantdemos/survey/templates/index.html b/talermerchantdemos/survey/templates/index.html.j2
index f40c235..9c9df5b 100644
--- a/talermerchantdemos/survey/templates/index.html
+++ b/talermerchantdemos/survey/templates/index.html.j2
@@ -1,15 +1,15 @@
-{% extends "templates/base.html" %}
-
+{% extends "templates/base.html.j2" %}
{% block main %}
<div>
<p>
- In this page, you can participate in our survey about payment systems
- and get a nice tip - via your Taler wallet - from this shop!
+ {{
+ gettext("On this page, you can participate in our survey about payment systems and receive a tip in return.")
+ }}
</p>
</div>
<div>
<form action="{{ url_for('submit_survey') }}" method="post" class="pure-form pure-form-stacked">
- <legend>What do you prefer?</legend>
+ <legend>{{ gettext("Which payment system do you prefer?") }}</legend>
<fieldset>
<label for="option-taler">
<input id="option-taler" type="radio" name="paypref" value="taler" checked="checked" />
@@ -20,7 +20,7 @@
Visa
</label>
</fieldset>
- <input type="submit" value="Submit Survey" class="pure-button pure-button-primary" />
+ <input type="submit" value="{{ gettext("Submit Survey")}}" class="pure-button pure-button-primary" />
</form>
</div>
{% endblock %}
diff --git a/talermerchantdemos/survey/templates/survey_stats.html b/talermerchantdemos/survey/templates/survey_stats.html
deleted file mode 100644
index 41cb437..0000000
--- a/talermerchantdemos/survey/templates/survey_stats.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends "templates/base.html" %}
-
-{% block main %}
- <div>
- <p>This page shows information about the tipping configuration of the
- merchant. Usually this should not be visible to users.</p>
- <ul>
- <li>Reserve pub: {{ stats['reserve_pub'] }}</li>
- <li>Reserve expiration: {{ prettydate(stats['reserve_expiration']) }}</li>
- <li>Amount available {{ stats['amount_available'] }}</li>
- <li>Amount picked up {{ stats['amount_picked_up'] }}</li>
- <li>Amount authorized {{ stats['amount_authorized'] }}</li>
- <ul>
- </div>
-{% endblock %}
diff --git a/talermerchantdemos/survey/translations b/talermerchantdemos/survey/translations
new file mode 120000
index 0000000..0a951f7
--- /dev/null
+++ b/talermerchantdemos/survey/translations
@@ -0,0 +1 @@
+../../translations/ \ No newline at end of file