Ajout de liens url_for() vers les Jinja modèles d'un site web Flask multilingue
Dans un site web multilingue avec des limaces multilingues, nous ne pouvons plus utiliser <a href="{{ url_for('pages.about') }}">{{{ _('About') }}</a>.
Le problème : url_for() dans les Jinja templates
@pages_blueprint.route('/contact')
def contact():
return page_view('contact')
@pages_blueprint.route('/about')
def about():
return page_view('about')
@pages_blueprint.route('/terms-of-use')
def terms_of_use():
return page_view('terms-of-use')
@pages_blueprint.route('/privacy-policy')
def privacy_policy():
return page_view('privacy-policy')
J'ai supprimé ces lignes pour que le seul point final restant pour les pages soit la fonction page_view :
@pages_blueprint.route('/<slug>', methods=['GET', 'POST'])
def page_view(slug):
...
Puis les pages ont cessé de fonctionner... bien sûr. À certains endroits dans les modèles, j'ai encore utilisé url_for() pour générer le lien vers une page. Par exemple, l'option'Lire la suite' était toujours spécifiée comme :
<a href="{{ url_for('pages.about') }}">{{ _('Read more') }}</a>
Et sur la page Registre, il y avait le lien :
* {{ _('See our') }} <a href="{{ url_for('pages.privacy_policy') }}" class="link">{{ _('privacy policy') }}</a> {{ _('how we process and protect your personal data.') }}
Les deux ont échoué avec le célèbre :
werkzeug.routing.BuildError: Could not build url for endpoint ...
Rien de spécial et oui, on l'attendait, mais comment résoudre cela et surtout, comment résoudre cela de manière multilingue ?
La solution : un dict imbriqué pour chaque langue sélectionnée
La solution n'est pas très difficile, comme je l'ai mentionné dans les billets précédents, nous avons deux tableaux :
ContentItem ContentItem
ContentItemTranslation
ContentItem contient un nom'commun'. Par exemple, la page A propos a un nom commun'A propos', puis les enregistrements ContentItemTranslation contiennent le titre de la page traduite, pour la langue néerlandaise c'est'Over ons' et la balise dérivée est'over-ons'. Pour pouvoir fournir les données appropriées à la fonction url_for() nous devons créer un dictionnaire ayant la structure suivante :
{
'About': { 'title': title, 'slug': slug },
'Privacy policy': { 'title': title, 'slug': slug },
...
}
Ensuite, nous avons besoin du processeur de contexte pour obtenir ce dictionnaire dans le modèle, ici j'utilise app_template_slug comme nom du dictionnaire. Dans le Jinja modèle, nous pouvons l'utiliser de la manière suivante :
* {{ _('See our') }} <a href="{{ url_for('pages.page_view', slug=app_template_slug['Privacy policy']['slug']) }}" class="link">{{ app_template_slug['Privacy policy']['title'] }}</a> {{ _('how we process and protect your personal data.') }}
Nous utilisons le nom " commun " pour obtenir le titre et le slug appropriés, donc rien ne dépend de la langue ici. Comme pour les autres fonctionnalités, j'ai créé l'objet qui prend en charge la génération du dictionnaire imbriqué dans la fonction create_app.
Liens / crédits
Multilanguage fallback revisited and a page footer with multilanguage links
/en/blog/multilanguage-fallback-revisited-and-a-page-footer-with-multilanguage-links
Refining multilanguage: adding language fallback as an option
/en/blog/refining-multilanguage-adding-language-fallback-as-an-option
En savoir plus...
Flask Jinja2 Multilanguage
Récent
- Don't Repeat Yourself (DRY) avec Jinja2
- SQLAlchemy, PostgreSQL, nombre maximal de lignes par user
- Afficher les valeurs des filtres dynamiques SQLAlchemy
- Transfert de données sécurisé grâce au cryptage à Public Key et à pyNaCl
- rqlite : une alternative à haute disponibilité et dist distribuée SQLite
- Dois-je migrer mon Docker Swarm vers Kubernetes ?
Les plus consultés
- Utilisation des Python's pyOpenSSL pour vérifier les certificats SSL téléchargés d'un hôte
- Utiliser UUIDs au lieu de Integer Autoincrement Primary Keys avec SQLAlchemy et MariaDb
- Connexion à un service sur un hôte Docker à partir d'un conteneur Docker
- SQLAlchemy : Utilisation de Cascade Deletes pour supprimer des objets connexes
- Utiliser PyInstaller et Cython pour créer un exécutable Python
- Flask RESTful API validation des paramètres de la requête avec les schémas Marshmallow