Добавление ссылок url_for() в Jinja шаблоны Flask многоязычного веб-сайта
На мультиязычном веб-сайте с мультиязычными пробками мы больше не можем использовать <a href="{{ url_for('pages.about') }}">{{ _('About') }}</a>.
Проблема: url_for() в Jinja шаблонах
@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')
Я удалил эти строки, поэтому единственной оставшейся конечной точкой для страниц будет функция page_view:
@pages_blueprint.route('/<slug>', methods=['GET', 'POST'])
def page_view(slug):
...
Потом страницы перестали работать... конечно. В некоторых местах в шаблонах я все еще использовал url_for() для генерации ссылки на страницу. Например, параметр "Подробнее" по-прежнему указывался как "Read More":
<a href="{{ url_for('pages.about') }}">{{ _('Read more') }}</a>
А на странице Регистрация была ссылка:
* {{ _('See our') }} <a href="{{ url_for('pages.privacy_policy') }}" class="link">{{ _('privacy policy') }}</a> {{ _('how we process and protect your personal data.') }}
Оба потерпели неудачу со знаменитостями:
werkzeug.routing.BuildError: Could not build url for endpoint ...
Ничего особенного и да ожидалось, но как решить эту и, что еще важнее, как решить эту проблему на нескольких языках?
Решение: вложенный диктат для каждого выбранного языка
Как я уже говорил в предыдущих статьях, у нас есть две таблицы:
Содержание
Перевод содержания
ContentItem содержит "общее" имя. Например, страница About имеет общее название 'About', а записи ContentItemTranslation содержат заголовок переведенной страницы, для голландского языка это 'Over ons', а производный слизняк - over-ons', для того чтобы обеспечить функцию url_for() необходимыми данными, нам нужно создать словарь со следующей структурой:
{
'About': { 'title': title, 'slug': slug },
'Privacy policy': { 'title': title, 'slug': slug },
...
}
Затем нам нужен контекстный процессор для ввода словаря в шаблон, здесь в качестве имени словаря я использую app_template_slug. В Jinja шаблоне мы можем использовать это следующим образом:
* {{ _('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.') }}
Мы используем "общее" имя, чтобы получить правильное название и слизняк, поэтому здесь нет зависимости от языка. Как и в случае с другими функциями, я создал объект, который заботится о генерации вложенного словаря в функции create_app.
Ссылки / кредиты
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
Подробнее
Flask Jinja2 Multilanguage
Недавний
- Скрытие первичных ключей базы данных UUID вашего веб-приложения
- Don't Repeat Yourself (DRY) с Jinja2
- SQLAlchemy, PostgreSQL, максимальное количество строк для user
- Показать значения в динамических фильтрах SQLAlchemy
- Безопасная передача данных с помощью шифрования Public Key и pyNaCl
- rqlite: альтернатива dist с высокой степенью готовности и SQLite
Большинство просмотренных
- Используя Python pyOpenSSL для проверки SSL-сертификатов, загруженных с хоста
- Использование UUID вместо Integer Autoincrement Primary Keys с SQLAlchemy и MariaDb
- Подключение к службе на хосте Docker из контейнера Docker
- Использование PyInstaller и Cython для создания исполняемого файла Python
- SQLAlchemy: Использование Cascade Deletes для удаления связанных объектов
- Flask Удовлетворительный запрос API проверка параметров запроса с помощью схем Маршмэллоу