Coverage for portality / internationalise.py: 75%
72 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-04 09:41 +0100
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-04 09:41 +0100
1from urllib.parse import urlencode
3from flask import g, request, redirect, url_for, session
4from flask_babel import Babel
6DEFAULT_LOCALE = "en"
7DEFAULT_TIMEZONE = "UTC"
8LANGUAGES = ['en', 'fr']
9INCLUDE_ROUTES = {
10 'apply',
11 'account/login'
12 }
14def locale_middleware_with_query_params():
15 # Get locale from query parameter instead of URL path
16 lang = request.args.get('lang', DEFAULT_LOCALE)
17 if lang not in LANGUAGES:
18 lang = DEFAULT_LOCALE
19 g.lang = lang # Store in flask.g for easy access
20 return None # Continue with request
22def redirect_url(lang: str = DEFAULT_LOCALE):
23 query_params = request.args.to_dict()
24 query_params.pop('lang', None) # remove lang from query params which is not required
25 url_to_redirect = f"/{lang}{request.path}"
26 if query_params:
27 url_to_redirect = f"{url_to_redirect}?{urlencode(query_params)}"
28 return redirect(url_to_redirect)
30def locale_middleware():
31 try:
32 # Only handle GET requests, let POST pass through
33 if request.method != 'GET':
34 return None
36 # Redirect for included routes
37 if request.path and any(request.path.strip('/') == f'{route}' for route in INCLUDE_ROUTES):
38 # update selected language
39 lang = request.args.get('lang')
40 if lang:
41 if lang in LANGUAGES:
42 session['lang'] = lang
43 return redirect_url(lang)
45 if get_url_locale() is None:
46 return redirect_url(get_session_locale())
48 except RuntimeError:
49 pass
50 return None
52def get_url_locale():
53 # Get locale from URL
54 path_parts = request.path.split('/')
55 if len(path_parts) > 1:
56 url_locale = path_parts[1]
57 if url_locale in LANGUAGES:
58 session['lang'] = url_locale
59 return url_locale
60 return None
62def get_session_locale():
63 if 'lang' in session:
64 lang = session.get('lang')
65 if lang in LANGUAGES:
66 return lang
67 session['lang'] = DEFAULT_LOCALE
68 return DEFAULT_LOCALE
70def get_locale():
71 lang = get_url_locale()
72 if lang is None:
73 lang = DEFAULT_LOCALE
75 return lang
77def get_timezone():
78 user = getattr(g, 'user', None)
79 if user is not None:
80 return user.timezone
82 return DEFAULT_TIMEZONE
85def url_for_other_page(endpoint, **kwargs):
86 if 'lang' not in kwargs:
87 kwargs['lang'] = g.get('lang', DEFAULT_LOCALE)
88 return url_for(endpoint, **kwargs)
90def internationalise(app):
91 # Initialize internationalization using Flask-Babel
92 app.config['BABEL_DEFAULT_LOCALE'] = DEFAULT_LOCALE # Default
93 app.config['BABEL_DEFAULT_TIMEZONE'] = DEFAULT_TIMEZONE
94 app.config['LANGUAGES'] = LANGUAGES
95 app.config['BABEL_TRANSLATION_DIRECTORIES'] = "ui/translations"
97 app.babel = Babel(app, locale_selector=get_locale, timezone_selector=get_timezone)
99 # Add locale middleware
100 app.before_request(locale_middleware)
102 # Add to template context
103 app.jinja_env.globals['url_for_other_page'] = url_for_other_page