I have one server with flask application instance and have several domain which mapped to this server by DNS.
My site must support several languages by host and prefix:
mysite.com - english
mysite.com/fr - franch
mysite.ru - russian
mysite.ru/by - belarusian
localhost or other unknown host without language prefix - default language (english)
I implemented it with double route registration /endpoint and /<lang>/endpoint and reloaded url_for function and it work, but now I must implement custom error pages for abort function:
mysite.com/wrong-url-there - mysite.com/404.html (english)
mysite.com/fr/wrong-url-there - mysite.com/fr/404.html (franch)
mysite.ru/wrong-url-there - mysite.ru/404.html (russian)
mysite.ru/by/wrong-url-there - mysite.ru/by/404.html (belorusian)
And I don't see solution for this. I think my implementation bad and I must improve it. I think I must create one instance of application for each site language root with predefined language for it or use blueprint, but I don't find solution for me yet.
Is anybody can give me advice how resolve this url multilanguages support with flask or wsgi or nginx?
It's in the official doc: http://flask.pocoo.org/docs/patterns/urlprocessors/ (This is basically the same answer as Matthew Scragg's).
I worked on something similar few months back. I modified it a bit and pushed to github. You can do what codegeek suggested if you are unable to make your templates language neutral. With this method you can cut down on the template files needed.
https://github.com/scragg0x/Flask-Localisation-Example
mysite.py
from flask import Flask, Blueprint, g, redirect, request
app = Flask(__name__)
mod = Blueprint('mysite', __name__, url_prefix='/<lang_code>')
sites = {
'mysite.com': 'en',
'myothersite.com': 'fr'
}
@app.url_defaults
def add_language_code(endpoint, values):
values.setdefault('lang_code', g.lang_code)
@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
url = request.url.split('/', 3)
g.lang_code = sites[url[2]]
@mod.url_defaults
def add_language_code(endpoint, values):
values.setdefault('lang_code', g.lang_code)
@mod.url_value_preprocessor
def pull_lang_code(endpoint, values):
g.lang_code = values.pop('lang_code')
@app.route('/')
@mod.route('/')
def index():
# Use g.lang_code to pull localized data for template
return 'lang = %s' % g.lang_code
app.register_blueprint(mod)
tests.py
import os
import unittest
import re
import requests
import urllib2
import json
from mysite import app
class MySiteTestCase(unittest.TestCase):
def setUp(self):
app.config['TESTING'] = True
app.config['SERVER_NAME'] = 'mysite.com'
self.domain = 'http://mysite.com/'
self.app = app.test_client()
def tearDown(self):
pass
def test_en_index(self):
rv = self.app.get('/en/', self.domain)
self.assertEqual(rv.data, 'lang = en')
print self.domain, rv.data
def test_fr_index(self):
rv = self.app.get('/fr/', self.domain)
self.assertEqual(rv.data, 'lang = fr')
print self.domain, rv.data
def test_default(self):
rv = self.app.get('/', self.domain)
self.assertEqual(rv.data, 'lang = en')
print self.domain, rv.data
class MyOtherSiteTestCase(unittest.TestCase):
def setUp(self):
app.config['TESTING'] = True
app.config['SERVER_NAME'] = 'myothersite.com'
self.domain = 'http://myothersite.com/'
self.app = app.test_client()
def tearDown(self):
pass
def test_en_index(self):
rv = self.app.get('/en/', self.domain)
self.assertEqual(rv.data, 'lang = en')
print self.domain, rv.data
def test_fr_index(self):
rv = self.app.get('/fr/', self.domain)
self.assertEqual(rv.data, 'lang = fr')
print self.domain, rv.data
def test_default(self):
rv = self.app.get('/', self.domain)
self.assertEqual(rv.data, 'lang = fr')
print self.domain, rv.data
if __name__ == '__main__':
unittest.main()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With