Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python flask web application with multilanguages support by host and prefix

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?

like image 457
tbicr Avatar asked Apr 30 '26 16:04

tbicr


2 Answers

It's in the official doc: http://flask.pocoo.org/docs/patterns/urlprocessors/ (This is basically the same answer as Matthew Scragg's).

like image 135
Stefane Fermigier Avatar answered May 04 '26 13:05

Stefane Fermigier


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()
like image 38
Matthew Scragg Avatar answered May 04 '26 14:05

Matthew Scragg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!