Het toevoegen van url_for() links naar Jinja sjablonen van een Flask meertalige website
In een meertalige website met meertalige slakken kunnen we geen gebruik meer maken van <a href="{{ url_for('pages.about') }}">{{{ _('Over') }}</a>.
Het probleem: url_for() in Jinja sjablonen
@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')
Ik heb deze regels verwijderd zodat het enige overgebleven eindpunt voor pagina's de page_view functie zou zijn:
@pages_blueprint.route('/<slug>', methods=['GET', 'POST'])
def page_view(slug):
...
Toen stopte de pagina's met werken .... natuurlijk. Op sommige plaatsen in de templates heb ik nog steeds url_for() gebruikt om de link naar een pagina te genereren. Zo werd bijvoorbeeld de 'Lees meer' nog steeds als volgt gespecificeerd:
<a href="{{ url_for('pages.about') }}">{{ _('Read more') }}</a>
En op de Registreer pagina stond de link:
* {{ _('See our') }} <a href="{{ url_for('pages.privacy_policy') }}" class="link">{{ _('privacy policy') }}</a> {{ _('how we process and protect your personal data.') }}
Beiden faalden met de beroemde:
werkzeug.routing.BuildError: Could not build url for endpoint ...
Niets bijzonders en ja, het werd verwacht, maar hoe lost u dit op en belangrijker nog, hoe lost u dit op een meertalige manier op?
De oplossing: een genesteld dictaat voor elke gekozen taal
De oplossing is niet erg moeilijk. Zoals ik in eerdere posten al zei, hebben we twee tabellen:
Inhoud Item
InhoudItemItemItemVertaling van de inhoudItemTranslation
ContentItem bevat een 'gewone' naam. De Over-pagina heeft bijvoorbeeld een gemeenschappelijke naam 'Over' en vervolgens bevat de ContentItemTranslation records de vertaalde paginatitel, voor de Nederlandse taal is dit 'Over ons' en de afgeleide slak is 'over-ons'. Om de juiste gegevens aan de url_for() functie te kunnen leveren, moeten we een woordenboek maken met de volgende structuur:
{
'About': { 'title': title, 'slug': slug },
'Privacy policy': { 'title': title, 'slug': slug },
...
}
Dan hebben we de context processor nodig om dit woordenboek in het sjabloon te krijgen, hier gebruik ik app_template_slug als de naam van het woordenboek. In de Jinja template kunnen we dit op de volgende manier gebruiken:
* {{ _('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.') }}
We gebruiken de 'gewone' naam om de juiste titel en slak te krijgen, dus hier is niets afhankelijk van de taal. Net als bij andere functionaliteiten heb ik het object gemaakt dat zich bezighoudt met het genereren van het geneste woordenboek in de create_app functie.
Links / credits
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
Lees meer
Flask Jinja2 Multilanguage
Recent
- Database UUID primaire sleutels van je webapplicatie verbergen
- Don't Repeat Yourself (DRY) met Jinja2
- SQLAlchemy, PostgreSQL, maximum aantal rijen per user
- Toon de waarden in SQLAlchemy dynamische filters
- Veilige gegevensoverdracht met Public Key versleuteling en pyNaCl
- rqlite: een alternatief voor SQLite met hoge beschikbaarheid en distributed
Meest bekeken
- Met behulp van Python's pyOpenSSL om SSL-certificaten die van een host zijn gedownload te controleren
- Gebruik van UUIDs in plaats van Integer Autoincrement Primary Keys met SQLAlchemy en MariaDb
- Maak verbinding met een dienst op een Docker host vanaf een Docker container
- PyInstaller en Cython gebruiken om een Python executable te maken
- SQLAlchemy: Gebruik van Cascade Deletes om verwante objecten te verwijderen
- Flask RESTful API verzoekparametervalidatie met Marshmallow-schema's