diff options
Diffstat (limited to 'talermerchantdemos/blog')
-rw-r--r-- | talermerchantdemos/blog/articles/scrap1_11.html | 1 | ||||
-rw-r--r-- | talermerchantdemos/blog/blog.py | 139 | ||||
-rw-r--r-- | talermerchantdemos/blog/content.py | 13 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/article_frame.html | 13 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/article_frame.html.j2 | 15 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/article_refunded.html | 10 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/article_refunded.html.j2 | 16 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/base.html | 79 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/base.html.j2 | 119 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/confirm_refund.html | 19 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/confirm_refund.html.j2 | 22 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/error.html | 22 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/error.html.j2 | 24 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/index.html | 40 | ||||
-rw-r--r-- | talermerchantdemos/blog/templates/show_refund.html | 28 |
15 files changed, 313 insertions, 247 deletions
diff --git a/talermerchantdemos/blog/articles/scrap1_11.html b/talermerchantdemos/blog/articles/scrap1_11.html index 71c693b..17471df 100644 --- a/talermerchantdemos/blog/articles/scrap1_11.html +++ b/talermerchantdemos/blog/articles/scrap1_11.html @@ -52,4 +52,3 @@ traditional style, please visit <br/> </p> <img alt="song-book-jutta-scrunch-crop" src="/essay/11._The_Free_Software_Song/data/song-book-jutta-scrunch-crop.jpg"/> - diff --git a/talermerchantdemos/blog/blog.py b/talermerchantdemos/blog/blog.py index d6cd3fc..c8315e5 100644 --- a/talermerchantdemos/blog/blog.py +++ b/talermerchantdemos/blog/blog.py @@ -1,6 +1,6 @@ ## -# This file is part of GNU taler. -# Copyright (C) 2014-2017 INRIA +# This file is part of GNU Taler. +# Copyright (C) 2014-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 @@ -24,6 +24,11 @@ import traceback import uuid import base64 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 time import sys from urllib.parse import urljoin, urlencode, urlparse @@ -85,6 +90,34 @@ ARTICLE_AMOUNT = CURRENCY + ":0.5" BACKEND_URL = urljoin(BACKEND_BASE_URL, "instances/blog/") app.config.from_object(__name__) +babel = Babel(app) + +print("Using translations from:") +print(list(babel.translation_directories)) +translations = [str(translation) for translation in babel.list_translations()] +translations.append('en') +print("Operating with the following translations available:") +print(translations) + + +## +# Helper function used inside Jinja2 logic to create a links +# to the current page but in a different language. Used to +# implement the "Language" menu. +# +def self_localized(lang): + """ + Return URL for the current page in another locale. + """ + path = request.path + # path must have the form "/$LANG/$STUFF" + parts = path.split('/', 2) + if (2 >= len(parts)): + # Totally unexpected path format, do not localize + return path + return "/" + lang + "/" + parts[2] + +app.jinja_env.globals.update(self_localized=self_localized) ## @@ -107,7 +140,7 @@ def utility_processor(): # @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)) @@ -120,23 +153,44 @@ def err_abort(abort_status_code, **params): @app.errorhandler(Exception) def internal_error(e): return flask.render_template( - "templates/error.html", message="Internal error", stack=traceback.format_exc() + "templates/error.html.j2", message=gettext("Internal error"), stack=traceback.format_exc() ) ## -# Serve the main index page. +# Serve the main index page, redirecting to /<lang>/ # # @return response object of the index page. @app.route("/") def index(): + default = 'en' + target = flask.request.accept_languages.best_match(translations, default) + return flask.redirect("/" + target + "/", code=302) + +@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" + +## +# Serve the main index page for a particular language. +# +# @return response object of the index page. +@app.route("/<lang>/") +def start(lang): return flask.render_template( - "templates/index.html", merchant_currency=CURRENCY, articles=ARTICLES.values() + "templates/index.html.j2", lang=lang, merchant_currency=CURRENCY, articles=ARTICLES.values() ) -@app.route("/confirm-refund/<order_id>", methods=["GET"]) -def confirm_refund(order_id): +@app.route("/<lang>/confirm-refund/<order_id>", methods=["GET"]) +def confirm_refund(lang, order_id): session_id = flask.session.get("session_id", "") pay_status = backend_get( BACKEND_URL, f"private/orders/{order_id}", params=dict(session_id=session_id) @@ -144,16 +198,16 @@ def confirm_refund(order_id): order_status = pay_status.get("order_status") if order_status != "paid": err_abort( - 400, message="can't refund unpaid article", + 400, message="Cannot refund unpaid article", ) article_name = pay_status["contract_terms"]["extra"]["article_name"] if not refundable(pay_status): return flask.render_template( - "templates/error.html", message="Item not refundable (anymore)" + "templates/error.html.j2", message=gettext("Article is not anymore refundable") ) return flask.render_template( - "templates/confirm_refund.html", article_name=article_name, order_id=order_id + "templates/confirm_refund.html.j2", article_name=article_name, order_id=order_id ) @@ -163,16 +217,15 @@ def confirm_refund(order_id): # # @param order_id the order ID of the transaction to refund. # @return the following errors (named by HTTP response code): -# - 400: no article was asked to be refunded! -# - 401: the refund was asked on a non-payed article. -# - 500: the backend was unable to give response. -# Or, in the successful case, a redirection to the -# "refund URL" is returned; then the wallet will run -# the refund protocol in a transparent way. +# - 400: order unknown +# - 402: the refund was asked on an unpaid article. +# - 302: in the successful case, a redirection to the +# "refund URL" is returned; then the wallet will run +# the refund protocol in a transparent way. @app.route("/refund/<order_id>", methods=["POST"]) -def refund(order_id): +def refund(lang, order_id): if not order_id: - return flask.jsonify(dict(error="Aborting refund: article not payed")), 401 + return flask.jsonify(dict(error="Aborting refund: order unknown")), 400 session_id = flask.session.get("session_id", "") pay_status = backend_get( BACKEND_URL, f"private/orders/{order_id}", params=dict(session_id=session_id) @@ -219,7 +272,7 @@ def render_article(article_name, data, order_id, refundable): err_abort(404, message=m) # the order_id is needed for refunds return flask.render_template( - "templates/article_frame.html", + "templates/article_frame.html.j2", article_file=get_article_file(article_info), article_name=article_name, order_id=order_id, @@ -247,6 +300,25 @@ def post_order(article_name,lang): dict(order=order, refund_delay=dict(d_ms=1000 * 120))) return order_resp +## +# Setup a fresh order with the backend. +# +# @param article_name which article the order is for +# @param lang which language to use +# +def post_order(article_name,lang): + order = dict( + amount=ARTICLE_AMOUNT, + extra=dict(article_name=article_name,lang=lang), + fulfillment_url=flask.request.base_url, + summary="Essay: " + article_name.replace("_", " "), + # 10 minutes time for a refund + refund_deadline=dict(t_ms=1000 * int(time.time() + 10 * 30)), + wire_transfer_deadline=dict(t_ms=1000 * int(time.time() + 15 * 30)), + ) + order_resp = backend_post(BACKEND_URL, "private/orders", dict(order=order)) + return order_resp + ## # Trigger a article purchase. The logic follows the main steps: @@ -267,9 +339,10 @@ def post_order(article_name,lang): # In the successful case, either the article is returned, or # the browser gets redirected to a page where the wallet can # send the payment. -@app.route("/essay/<article_name>") +@app.route("/<lang>/essay/<article_name>") +@app.route("/<lang>/essay/<article_name>/data/<data>") @app.route("/essay/<article_name>/data/<data>") -def article(article_name, data=None): +def article(article_name, lang=None, data=None): # We use an explicit session ID so that each payment (or payment replay) is # bound to a browser. This forces re-play and prevents sharing the article # by just sharing the URL. @@ -279,8 +352,6 @@ def article(article_name, data=None): if not session_id: session_id = flask.session["session_id"] = str(uuid.uuid4()) order_id = None - # Temporary workaround... - lang="en" ## # First-timer; generate order first. if not order_id: @@ -309,12 +380,19 @@ def article(article_name, data=None): if order_status == "paid": refunded = pay_status["refunded"] if refunded: - return flask.render_template( - "templates/article_refunded.html", + return flask.render_template( + "templates/article_refunded.html.j2", article_name=article_name, order_id=order_id, ) - return render_article(article_name, data, order_id, refundable(pay_status)) + response = render_article(article_name, data, order_id, refundable(pay_status)) + response.set_cookie( + "order_id", order_id, path=urllib.parse.quote(f"/essay/{article_name}") + ) + response.set_cookie( + "order_id", order_id, path=urllib.parse.quote(f"/{lang}/essay/{article_name}") + ) + return response # Check if the customer came on this page via the # re-purchase detection mechanism @@ -333,14 +411,17 @@ def article(article_name, data=None): response.set_cookie( "order_id", order_id, path=urllib.parse.quote(f"/essay/{article_name}") ) + response.set_cookie( + "order_id", order_id, path=urllib.parse.quote(f"/{lang}/essay/{article_name}") + ) return response @app.errorhandler(500) def handler(e): return flask.render_template( - "templates/error.html", message="Internal server error") + "templates/error.html.j2", message=gettext("Internal server error")) @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/blog/content.py b/talermerchantdemos/blog/content.py index a0e90dd..fa9ace2 100644 --- a/talermerchantdemos/blog/content.py +++ b/talermerchantdemos/blog/content.py @@ -26,7 +26,7 @@ from pkg_resources import resource_stream, resource_filename LOGGER = logging.getLogger(__name__) NOISY_LOGGER = logging.getLogger("chardet.charsetprober") NOISY_LOGGER.setLevel(logging.INFO) -Article = namedtuple("Article", "slug title teaser main_file extra_files") +Article = namedtuple("Article", "slug title teaser main_file extra_files lang") ## # @var if a article is added to this list, then it will @@ -43,8 +43,9 @@ ARTICLES = OrderedDict() # @param main_file path to the article's HTML file. # @param extra_file collection of extra files associated with the # article, like images and sounds. -def add_article(slug, title, teaser, main_file, extra_files): - ARTICLES[slug] = Article(slug, title, teaser, main_file, extra_files) +# @param lang language of the arcile +def add_article(slug, title, teaser, main_file, extra_files, lang='en'): + ARTICLES[slug] = Article(slug, title, teaser, main_file, extra_files, lang) ## @@ -85,7 +86,7 @@ def add_from_html(resource_name, teaser_paragraph=0, title=None): if title is None: title_el = soup.find("h1", attrs={"class": ["chapter", "unnumbered"]}) if title_el is None: - LOGGER.warning("Can't extract title from '%s'", resource_name) + LOGGER.warning("Cannot extract title from '%s'", resource_name) title = resource_name else: title = title_el.get_text().strip() @@ -97,7 +98,7 @@ def add_from_html(resource_name, teaser_paragraph=0, title=None): teaser = paragraphs[teaser_paragraph].get_text() else: teaser = teaser.get_text() - re_proc = re.compile("^/essay/[^/]+/data/[^/]+$") + re_proc = re.compile("^/[^/][^/]/essay/[^/]+/data/[^/]+$") imgs = soup.find_all("img") extra_files = [] for img in imgs: @@ -114,7 +115,7 @@ def add_from_html(resource_name, teaser_paragraph=0, title=None): else: LOGGER.warning("Image src and slug don't match: '%s' != '%s'" \ % (img['src'].split(os.sep)[2], slug)) - add_article(slug, title, teaser, resource_name, extra_files) + add_article(slug, title, teaser, resource_name, extra_files, 'en') add_from_html("blog/articles/scrap1_U.0.html", 0) diff --git a/talermerchantdemos/blog/templates/article_frame.html b/talermerchantdemos/blog/templates/article_frame.html deleted file mode 100644 index a5050d3..0000000 --- a/talermerchantdemos/blog/templates/article_frame.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "templates/base.html" %} -{% block main %} -{% include "articles/" + article_file %} - -{% if refundable %} -<hr> -<p> - You don't like this article? <a href="{{ url_for('confirm_refund', order_id=order_id) }}">Get a refund</a> within - the first hour after buying it. -</p> -{% endif %} - -{% endblock main %} diff --git a/talermerchantdemos/blog/templates/article_frame.html.j2 b/talermerchantdemos/blog/templates/article_frame.html.j2 new file mode 100644 index 0000000..a878e95 --- /dev/null +++ b/talermerchantdemos/blog/templates/article_frame.html.j2 @@ -0,0 +1,15 @@ +{% extends "templates/base.html.j2" %} +{% block main %} +{% include "articles/" + article_file %} + +{% if refundable %} +<hr> +<p> + {{ + gettext("You did not like this article?") + + gettext("You can <a href="{url}">request a refund</a> within the first hour after buying it.").format(url=url_for('confirm_refund', lang='en', order_id=order_id) + }} +</p> +{% endif %} + +{% endblock main %} diff --git a/talermerchantdemos/blog/templates/article_refunded.html b/talermerchantdemos/blog/templates/article_refunded.html deleted file mode 100644 index 95c4a6b..0000000 --- a/talermerchantdemos/blog/templates/article_refunded.html +++ /dev/null @@ -1,10 +0,0 @@ -{% extends "templates/base.html" %} -{% block main %} - -<h2>Refunded</h2> - -<p>Your payment (order ID <tt>{{ order_id }}<tt>) for the article "{{ article_name }}" has been refunded.</p> - -<p>You won't be able to view it until you pay for it again.</p> - -{% endblock main %} diff --git a/talermerchantdemos/blog/templates/article_refunded.html.j2 b/talermerchantdemos/blog/templates/article_refunded.html.j2 new file mode 100644 index 0000000..34e0a0b --- /dev/null +++ b/talermerchantdemos/blog/templates/article_refunded.html.j2 @@ -0,0 +1,16 @@ +{% extends "templates/base.html.j2" %} +{% block main %} + +<h2>{{ gettext("Refunded") }}</h2> + +<p> +{{ + gettext("Your payment (order ID <tt>{order}<tt>) for the article "{article}" has been refunded.").format(order=order_id,article=article_name) +}} +</p> + +<p> +{{ gettext("You won't be able to view it until you pay for it again.") }} +</p> + +{% endblock main %} diff --git a/talermerchantdemos/blog/templates/base.html b/talermerchantdemos/blog/templates/base.html deleted file mode 100644 index 3d7d0f0..0000000 --- a/talermerchantdemos/blog/templates/base.html +++ /dev/null @@ -1,79 +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> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - {% block meta %}{% endblock %} - <title>Taler Essay Shop 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') }}" /> - <style> - .warn { - background-color: #aa393977; - padding: 1em; - } - .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; - } - #main a:link, #main a:visited, #main a:hover, #main a:active { - color: black; - } - </style> - {% block styles %}{% endblock %} - {% block scripts %}{% endblock %} -</head> - -<body> - <div 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> - <p>On this page you can buy articles using an imaginary currency (for now). - The articles are chapters from Richard Stallman's book "Free Software, Free Society", - which is also - <a href="http://shop.fsf.org/product/free-software-free-society-2/">published by the FSF</a> - and available gratis at <a href="http://www.gnu.org/">gnu.org</a>. - </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', '#') }}">Tipping/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 style="flex-grow:1"></div> - <p>Copyright © 2014—2018 Inria</p> - </div> - - <section id="main" class="content"> - {% block main %} - This is the main content of the page. - {% endblock %} - <hr /> - </section> -</body> -</html> diff --git a/talermerchantdemos/blog/templates/base.html.j2 b/talermerchantdemos/blog/templates/base.html.j2 new file mode 100644 index 0000000..58ce857 --- /dev/null +++ b/talermerchantdemos/blog/templates/base.html.j2 @@ -0,0 +1,119 @@ +<!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> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + {% block meta %}{% endblock %} + <title>{{ gettext("Taler Essay Shop 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">Taler Demo</span></h1> + <h1><span class="it"><a href="{{ env('TALER_ENV_URL_MERCHANT_BLOG') }}">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 "Free Software, Free Society".") + "<br>" + + gettext('The book is <a href="{shop}">published by the FSF</a> and available gratis at <a href="{gnu}">gnu.org</a>.').format(shop="https://shop.fsf.org/product/free-software-free-society-2", gnu="https://www.gnu.org") + }} + </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> + <!-- <input type="checkbox" class="r"><label>test</label> --> + + <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 © 2014—2020 Taler Systems SA</p> + </div> + </section> +</body> +</html> diff --git a/talermerchantdemos/blog/templates/confirm_refund.html b/talermerchantdemos/blog/templates/confirm_refund.html deleted file mode 100644 index 10aaa74..0000000 --- a/talermerchantdemos/blog/templates/confirm_refund.html +++ /dev/null @@ -1,19 +0,0 @@ -{% extends "templates/base.html" %} -{% block main %} - <h1>Refund Article?</h1> - - <p> - Do you want to get a refund for the article <em>{{ article_name }}</em>? After you've requested a refund, - you won't be able to read the article anymore. - </p> - - <p> - You will only be able to receive the refund on the same wallet that you've used to pay - for this article originally. - </p> - - <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"> - </form> -{% endblock main %} diff --git a/talermerchantdemos/blog/templates/confirm_refund.html.j2 b/talermerchantdemos/blog/templates/confirm_refund.html.j2 new file mode 100644 index 0000000..09f3730 --- /dev/null +++ b/talermerchantdemos/blog/templates/confirm_refund.html.j2 @@ -0,0 +1,22 @@ +{% extends "templates/base.html.j2" %} +{% block main %} + <h1>{{ gettext("Confirm refund request for article"))</h1> + + <p> + {{ + gettext("Do you want to get a refund for the article <em>{name}</em>?").format(name=article_name) + + gettext("After you have requested a refund, you won't be able to read the article anymore.") + }} + </p> + + <p> + {{ + gettext ("You will only be able to receive the refund on the same wallet that you have used to pay for this article originally.") + }} + </p> + + <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"> + </form> +{% endblock main %} diff --git a/talermerchantdemos/blog/templates/error.html b/talermerchantdemos/blog/templates/error.html deleted file mode 100644 index 0d4bd02..0000000 --- a/talermerchantdemos/blog/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/blog/templates/error.html.j2 b/talermerchantdemos/blog/templates/error.html.j2 new file mode 100644 index 0000000..ffc2e1f --- /dev/null +++ b/talermerchantdemos/blog/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/blog/templates/index.html b/talermerchantdemos/blog/templates/index.html deleted file mode 100644 index 0159779..0000000 --- a/talermerchantdemos/blog/templates/index.html +++ /dev/null @@ -1,40 +0,0 @@ -{% extends "templates/base.html" %} -{% block main %} - <h1>Essay Shop: Free Software, Free Society</h1> - <div style="font-size: smaller;"> - <p>This is the second edition of <cite>Free Software, Free Society: Selected Essays of Richard M. Stallman.</cite><br> - Free Software Foundation<br> - 51 Franklin Street, Fifth Floor<br> - Boston, MA 02110-1335 - <br> - Copyright © 2002, 2010 Free Software Foundation, Inc. - </p> - - <p>Verbatim copying and distribution of this entire book are permitted - worldwide, without royalty, in any medium, provided this notice is - preserved. Permission is granted to copy and distribute translations - of this book from the original English into another language provided - the translation has been approved by the Free Software Foundation and - the copyright notice and this permission notice are preserved on all - copies. - </p> - <p>ISBN 978-0-9831592-0-9</p> - </div> - - <h2>Chapters</h2> - <div> - Click on an individual chapter to to purchase it. You can - get free, virtual money to buy articles on this page at the <a href="{{ env('TALER_ENV_URL_BANK', '#') }}">bank</a>. - </div> - - <div> - {% for article in articles %} - <div class="notice"> - <h3><a href="{{ url_for('article', article_name=article.slug) }}">{{article.title}}</a></h3> - <p>{{ article.teaser|safe }} <a href="{{ url_for('article', article_name=article.slug) }}">(Pay to read more...)</a></p> - </div> - {% else %} - <em>(No articles available)</em> - {% endfor %} - </div> -{% endblock main %} diff --git a/talermerchantdemos/blog/templates/show_refund.html b/talermerchantdemos/blog/templates/show_refund.html deleted file mode 100644 index 913b6a5..0000000 --- a/talermerchantdemos/blog/templates/show_refund.html +++ /dev/null @@ -1,28 +0,0 @@ -{% extends "templates/base.html" %} - -{% block main %} - -<h1>Refund</h1> - -<div class="taler-installed-hide"> - <p> - Looks like your browser doesn't support GNU Taler payments. You can try - installing a <a href="https://taler.net/en/wallet.html">wallet browser extension</a>. - </p> -</div> - -<div> - - <p> - You can use this QR code to get a refund with your mobile wallet: - </p> - - {{ qrcode_svg | safe }} - - <p> - Click <a href="{{ taler_refund_uri }}">this link</a> to open your system's Taler wallet if it exists. - </p> - -</div> - -{% endblock main %} |