基于Flask的双语网站实现:使用或不使用蓝图方案
Hey there! Let's refine your bilingual Flask web app to make it fully functional. I'll walk you through two solid approaches—one that builds on your existing Blueprint setup, and a simpler alternative without Blueprints. Both will handle language switching, valid language checks, and proper multilingual content management.
Your initial code has the right foundation with Blueprints and URL processors, but we need to add language validation, proper content storage, and handle default language routing.
Step 1: Define Supported Languages & Multilingual Content
First, let's create a structured way to store your app's text in different languages. A dictionary works great for small apps; for larger projects, you can later switch to tools like Flask-Babel.
# Supported languages (add more if needed) SUPPORTED_LANGS = {'en', 'zh'} # Multilingual content dictionary MESSAGES = { 'en': { 'hello': 'Hello!', 'about': 'About this app: It\'s a bilingual Flask demo.' }, 'zh': { 'hello': '你好!', 'about': '关于此应用:这是一个双语Flask演示项目。' } }
Step 2: Add Language Validation & Default Handling
Modify your URL preprocessor to check if the provided lang_code is valid. If not, redirect to your default language (e.g., 'en'). Also, add a route for the root path to redirect to the default language.
from flask import Flask, Blueprint, g, redirect, url_for app = Flask(__name__) bp = Blueprint('frontend', __name__, url_prefix='/<lang_code>') # Set default language DEFAULT_LANG = 'en' @bp.url_defaults def add_language_code(endpoint, values): values.setdefault('lang_code', g.lang_code) @bp.url_value_preprocessor def pull_lang_code(endpoint, values): lang_code = values.pop('lang_code') # Validate language code if lang_code not in SUPPORTED_LANGS: return redirect(url_for(f'frontend.{endpoint}', lang_code=DEFAULT_LANG)) g.lang_code = lang_code # Root route redirect to default language @app.route('/') def root(): return redirect(url_for('frontend.hello', lang_code=DEFAULT_LANG)) @bp.route('/') def hello(): # Get the hello message for the current language return MESSAGES[g.lang_code]['hello'] @bp.route('/about') def about(): return MESSAGES[g.lang_code]['about'] # Register the blueprint app.register_blueprint(bp) if __name__ == '__main__': app.run(debug=True)
How This Works
- When a user visits
/zhor/en, the URL preprocessor setsg.lang_codeto the valid language. - If someone tries
/fr(unsupported), they're redirected to/en. - The root path
/automatically sends users to the default language's homepage. - Views pull content from the
MESSAGESdictionary based on the current language.
If your app is small and you don't need the modularity of Blueprints, you can handle language detection directly with a before_request handler.
from flask import Flask, g, request, redirect, url_for app = Flask(__name__) SUPPORTED_LANGS = {'en', 'zh'} DEFAULT_LANG = 'en' MESSAGES = { 'en': { 'hello': 'Hello!', 'about': 'About this app: It\'s a bilingual Flask demo.' }, 'zh': { 'hello': '你好!', 'about': '关于此应用:这是一个双语Flask演示项目。' } } @app.before_request def set_language(): # Get language from URL parameter, or use default lang_code = request.args.get('lang', DEFAULT_LANG) # Validate language if lang_code not in SUPPORTED_LANGS: lang_code = DEFAULT_LANG g.lang_code = lang_code @app.route('/') def hello(): return MESSAGES[g.lang_code]['hello'] @app.route('/about') def about(): return MESSAGES[g.lang_code]['about'] # Optional: Add language switch links in templates (example) # In your template, you can add: # <a href="{{ url_for('hello', lang='en') }}">English</a> # <a href="{{ url_for('hello', lang='zh') }}">中文</a> if __name__ == '__main__': app.run(debug=True)
How This Works
- The
before_requestruns on every request, checking thelangURL parameter (e.g.,/about?lang=zh). - If the parameter is missing or invalid, it falls back to the default language.
- Views use
g.lang_codeto fetch the correct content from theMESSAGESdictionary.
For production or more complex apps, Flask-Babel is the standard tool for internationalization. It lets you store translations in separate .po/.mo files, auto-detect user language from headers, and handle pluralization.
Here's a quick snippet to get you started with Flask-Babel:
from flask import Flask, request from flask_babel import Babel, gettext as _ app = Flask(__name__) app.config['BABEL_DEFAULT_LOCALE'] = 'en' app.config['BABEL_SUPPORTED_LOCALES'] = ['en', 'zh'] babel = Babel(app) @babel.localeselector def get_locale(): # Try to get language from URL, then user settings, then request headers lang = request.args.get('lang') if lang in app.config['BABEL_SUPPORTED_LOCALES']: return lang return request.accept_languages.best_match(app.config['BABEL_SUPPORTED_LOCALES']) @app.route('/') def hello(): return _('Hello!') @app.route('/about') def about(): return _('About this app: It\'s a bilingual Flask demo.')
You'd then create translation files using pybabel commands, which is far more scalable than a dictionary for large apps.
内容的提问来源于stack exchange,提问作者Sadme Rame

