Unverified Commit 2362dc86 authored by Tharyrok's avatar Tharyrok
Browse files

Optimize code and full gettext in layout.html

parent 98340b55
#/usr/bin/env python3
# -*- coding: utf-8 -*-
import locale
import re
from flask import Flask, redirect, request, render_template
from flask.ext.babel import Babel, gettext
from flask import Flask, redirect, request, render_template, g
from flask_babel import Babel, gettext
app = Flask(__name__)
app.config['BABEL_DEFAULT_LOCALE'] = 'en'
babel = Babel(app)
LANGUAGE_CODES = ('fr', 'en', 'nl')
# From django.utils.translation.trans_real.to_locale
def to_locale(language, to_lower=False):
"""
Turns a language name (en-us) into a locale name (en_US). If 'to_lower' is
True, the last component is lower-cased (en_us).
"""
p = language.find('-')
if p >= 0:
if to_lower:
return language[:p].lower()+'_'+language[p+1:].lower()
else:
# Get correct locale for sr-latn
if len(language[p+1:]) > 2:
return language[:p].lower()+'_'+language[p+1].upper()+language[p+2:].lower()
return language[:p].lower()+'_'+language[p+1:].upper()
else:
return language.lower()
# From django.utils.translation.trans_real.parse_accept_lang_header
accept_language_re = re.compile(r'''
([A-Za-z]{1,8}(?:-[A-Za-z]{1,8})*|\*) # "en", "en-au", "x-y-z", "*"
(?:\s*;\s*q=(0(?:\.\d{,3})?|1(?:.0{,3})?))? # Optional "q=1.00", "q=0.8"
(?:\s*,\s*|$) # Multiple accepts per header.
''', re.VERBOSE)
def parse_accept_lang_header(lang_string):
"""
Parses the lang_string, which is the body of an HTTP Accept-Language
header, and returns a list of (lang, q-value), ordered by 'q' values.
Any format errors in lang_string results in an empty list being returned.
"""
result = []
pieces = accept_language_re.split(lang_string)
if pieces[-1]:
return []
for i in range(0, len(pieces) - 1, 3):
first, lang, priority = pieces[i : i + 3]
if first:
return []
priority = priority and float(priority) or 1.0
result.append((lang, priority))
result.sort(key=lambda k: k[1], reverse=True)
return result
def normalize_language(language):
return locale.locale_alias.get(to_locale(language, True))
def is_language_supported(language, supported_languages=None):
if supported_languages is None:
supported_languages = LANGUAGE_CODES
if not language:
return None
normalized = normalize_language(language)
if not normalized:
return None
# Remove the default encoding from locale_alias.
normalized = normalized.split('.')[0]
for lang in (normalized, normalized.split('_')[0]):
if lang.lower() in supported_languages:
return lang
return None
def parse_http_accept_language(accept):
for accept_lang, unused in parse_accept_lang_header(accept):
if accept_lang == '*':
break
# We have a very restricted form for our language files (no encoding
# specifier, since they all must be UTF-8 and only one possible
# language each time. So we avoid the overhead of gettext.find() and
# work out the MO file manually.
# 'normalized' is the root name of the locale in POSIX format (which is
# the format used for the directories holding the MO files).
normalized = locale.locale_alias.get(to_locale(accept_lang, True))
if not normalized:
continue
# Remove the default encoding from locale_alias.
normalized = normalized.split('.')[0]
for lang_code in (accept_lang, accept_lang.split('-')[0]):
lang_code = lang_code.lower()
if lang_code in LANGUAGE_CODES:
return lang_code
return None
@babel.localeselector
def get_locale():
lang = None
# HttpAcceptLanguageMiddleware
if lang is None:
lang = parse_http_accept_language(request.headers.get('Accept-Language', ''))
# DefaultLanguageMiddleware
if lang is None:
lang = 'en'
return lang
return request.accept_languages.best_match(['fr', 'en', 'nl'])
@app.route('/')
def language_detection():
lang = None
# HttpAcceptLanguageMiddleware
if lang is None:
lang = parse_http_accept_language(request.headers.get('Accept-Language', ''))
# DefaultLanguageMiddleware
if lang is None:
lang = 'en'
return redirect('/%s' % lang)
@app.route('/en')
def hello_world_en():
return render_template('layout.html', data={"lang": "en"})
@app.route('/fr')
def hello_world_fr():
return render_template('layout.html', data={"lang": "fr"})
return redirect('/%s' % get_locale())
@app.route('/nl')
def hello_world_nl():
return render_template('layout.html', data={"lang": "nl"})
@app.route('/<language>')
def lang_home(language=None):
setattr(g, 'lang', language)
return render_template('layout.html', data={"lang": language})
if __name__ == '__main__':
......
......@@ -490,21 +490,21 @@
<div class="row">
<div class="col-md-6">
<div class="wow fadeInUp" data-wow-delay="0.3s">
<h3>Next meeting</h3>
<h3>{{ gettext('Next meeting') }}<</h3>
<div class="row">
<div id="next-meetings" class="col-md-10 col-md-offset-1">
<p class="meeting">
<strong>When?</strong> December 18th, 2016 - 2pm<br>
<strong>Where?</strong> 123, rue Royale, Brussels.<br>
<strong>What?</strong> <a href="https://wiki.neutrinet.be/neutrinet/pvs/2016/12-18">agenda</a>
<strong>{{ gettext('When?') }}</strong> December 18th, 2016 - 2pm<br>
<strong>{{ gettext('Where?') }}</strong> 123, rue Royale, Brussels.<br>
<strong>{{ gettext('What?') }}</strong> <a href="https://wiki.neutrinet.be/neutrinet/pvs/2016/12-18">agenda</a>
</p>
</div>
</div>
<h3>Previous meetings</h3>
<h3>{{ gettext('Previous meetings') }}</h3>
<div class="row">
<div id="previous-meetings" class="col-md-10 col-md-offset-1">
<p class="meeting">
<a href="https://wiki.neutrinet.be/neutrinet/pvs/home">Our previous meetings</a>
<a href="https://wiki.neutrinet.be/neutrinet/pvs/home">{{ gettext('Our previous meetings') }}</a>
</p>
</div>
</div>
......@@ -512,7 +512,7 @@
</div>
<div class="col-md-6">
<div class="wow fadeInUp" data-wow-delay="0.3s">
<h3>Common meeting locations</h3>
<h3>{{ gettext('Common meeting locations') }}</h3>
<div id="osm"></div>
</div>
</div>
......@@ -529,7 +529,7 @@
<div class="col-lg-8 col-lg-offset-2">
<div class="wow fadeInDown" data-wow-delay="0.4s">
<div class="section-heading">
<h2>Become a member</h2>
<h2>{{ gettext('Become a member') }}</h2>
</div>
</div>
</div>
......@@ -540,12 +540,12 @@
<div class="row">
<div class="col-md-5 col-md-offset-2">
<div class="wow fadeInLeft" data-wow-delay="0.3s">
<h3>It's easy!</h3>
<h3>{{ gettext('It\'s easy!') }}</h3>
<div class="details">
<p>Becoming a member of Neutrinet is simple: pay your annual membership fee (25€ or more) either:</p>
<p>{{ gettext('Becoming a member of Neutrinet is simple: pay your annual membership fee (25€ or more) either:') }}</p>
<ul>
<li>to a member of our administrative council at a <a href="#meetings">meeting</a></li>
<li>to our bank by wire transfer - see the information on the right - and tell us <a href="mailto:contact@neutrinet.be">by email</a>.</li>
<li>{{ gettext('to a member of our administrative council at a <a href="#meetings">meeting</a>') }}</li>
<li>{{ gettext('to our bank by wire transfer - see the information on the right - and tell us <a href="mailto:contact@neutrinet.be">by email</a>.') }}</li>
</ul>
</div>
</div>
......@@ -553,13 +553,13 @@
<div class="col-md-3">
<div class="wow fadeInRight" data-wow-delay="0.3s">
<div class="bank">
<h4>Bank details:</h4>
<h4>{{ gettext('Bank details:') }}</h4>
<p>
Bank: RecordBank<br>
{{ gettext('Bank: RecordBank<br>
Name: Neutrinet ASBL<br>
Communication: cotisation of ...<br>
IBAN: BE52 6528 3497 8409<br>
BIC: HBKABE22<br>
BIC: HBKABE22<br>') }}
</p>
</div>
</div>
......@@ -570,12 +570,12 @@
<div class="wow fadeInUp" data-wow-delay="0.4s">
<div class="details">
<center>
<p><a href="http://www.ejustice.just.fgov.be/cgi_loi/loi_a1.pl?language=fr&la=F&table_name=loi&cn=1921062701&&caller=list&F&fromtab=loi&tri=dd+AS+RANK&rech=1&numero=1&sql=(text+contains+(%27%27))#Art.10" target="_blank">Belgium law</a> requires us to ask you for your <b>first name</b>, <b>last name</b> and <b>home address</b>.</p>
<p>{{ gettext('<a href="http://www.ejustice.just.fgov.be/cgi_loi/loi_a1.pl?language=fr&la=F&table_name=loi&cn=1921062701&&caller=list&F&fromtab=loi&tri=dd+AS+RANK&rech=1&numero=1&sql=(text+contains+(%27%27))#Art.10" target="_blank">Belgium law</a> requires us to ask you for your <b>first name</b>, <b>last name</b> and <b>home address</b>.') }}</p>
</center>
<hr>
<p>While we are not expecting spontaneous unknown new members, we recommended that before becoming a member of the Neutrinet ASBL/VZW you spend a bit of time discovering what we are doing and in the same time letting us know you a bit better :)</p>
<p><b>It is not mandatory to be a member of the ASBL/VZW to contribute and participate in the life of Neutrinet</b> but this is a nice way to support us. It is mandatory if you want to subscribe to one of our services.</p>
<p><i>If you have subscribed to the VPN service, you are already a member and don't need to pay your the membership fee separately.</i></p>
<p>{{ gettext('While we are not expecting spontaneous unknown new members, we recommended that before becoming a member of the Neutrinet ASBL/VZW you spend a bit of time discovering what we are doing and in the same time letting us know you a bit better :)') }}</p>
<p>{{ gettext('<b>It is not mandatory to be a member of the ASBL/VZW to contribute and participate in the life of Neutrinet</b> but this is a nice way to support us. It is mandatory if you want to subscribe to one of our services.') }}</p>
<p>{{ gettext('<i>If you have subscribed to the VPN service, you are already a member and don\'t need to pay your the membership fee separately.</i>') }}</p>
</div>
</div>
</div>
......@@ -588,8 +588,8 @@
<section id="diyisp" class="bigfat diyisp">
<div class="slogan">
<div class="wow bounceInUp black-title" data-wow-delay="0.3s">
<h3>Neutrinet is part of the <a href="http://www.diyisp.org/">diy-isp</a> movement.</h3>
<h4>See some of the other members at <a href="https://db.ffdn.org/">db.ffdn.org</a></h4>
<h3>{{ gettext('Neutrinet is part of the <a href="http://www.diyisp.org/">diy-isp</a> movement.') }}</h3>
<h4>{{ gettext('See some of the other members at <a href="https://db.ffdn.org/">db.ffdn.org</a>') }}</h4>
</div>
</div>
</section>
......@@ -599,7 +599,7 @@
<section id="panda" class="bigfat panda">
<div class="slogan">
<div class="wow fadeInUp" data-wow-delay="0.3s">
<h4>Wannes wanted a panda</h4>
<h4>{{ gettext('Wannes wanted a panda') }}</h4>
</div>
</div>
</section>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment