如何在Wagtail设置中添加语言切换界面实现本地化?
解决Wagtail设置本地化的语言切换与渲染问题
一、修复管理面板的语言切换功能
Wagtail默认设置界面为单实例设计,要实现多语言切换需调整模型约束并自定义视图与模板:
1. 调整模型唯一约束
修改CompanySettings的Meta类,合并站点、翻译键和语言的唯一约束,确保每个站点每个语言对应一个设置实例:
from django.utils.translation import gettext_lazy as _ from django.db import models from wagtail.contrib.settings.models import BaseGenericSetting, register_setting from wagtail.models import TranslatableMixin @register_setting(icon="doc-full") class CompanySettings(TranslatableMixin, BaseGenericSetting): top_services = models.CharField( _("Top Services"), max_length=250, blank=True, null=True, help_text="add top services separated by comma" ) copyright_text = models.CharField(_("Copyright Text"), max_length=100, blank=True, null=True) panels = [ FieldPanel('top_services'), FieldPanel('copyright_text') ] class Meta: unique_together = (('site', 'translation_key', 'locale'),)
2. 自定义支持多语言的视图集
创建视图集,实现根据请求语言加载对应设置实例,并传递语言列表到模板:
from wagtail.contrib.settings.views import BaseSettingViewSet from wagtail.models import Locale class TranslatableSettingViewSet(BaseSettingViewSet): def get_object(self): # 获取请求指定的语言,默认用当前激活语言 locale_code = self.request.GET.get('locale', None) locale = Locale.objects.get(language_code=locale_code) if locale_code else Locale.get_active() # 获取或创建当前站点+语言的设置实例 obj, created = self.model.objects.get_or_create( site=self.request.site, locale=locale, ) return obj def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 传递所有可用语言和当前语言到模板 context['available_locales'] = Locale.objects.all() context['current_locale'] = self.object.locale return context
注册设置时指定该视图集:
@register_setting(icon="doc-full", viewset=TranslatableSettingViewSet) class CompanySettings(TranslatableMixin, BaseGenericSetting): # 模型代码同上
3. 自定义设置编辑模板
创建模板wagtailcontrib/settings/edit.html覆盖默认模板,添加语言切换下拉框:
{% extends "wagtailadmin/base.html" %} {% load i18n wagtailadmin_tags %} {% block titletag %}{% trans "Settings" %}: {{ setting_name }}{% endblock %} {% block content %} {% trans "Settings" as settings_str %} {% include "wagtailadmin/shared/header.html" with title=settings_str subtitle=setting_name icon=icon %} <!-- 语言切换器 --> <div class="w-flex w-items-center w-mb-4"> <label class="w-mr-2">{% trans "Language:" %}</label> <select id="locale-switcher" class="w-select"> {% for locale in available_locales %} <option value="{{ locale.language_code }}" {% if locale == current_locale %}selected{% endif %}> {{ locale.get_display_name }} </option> {% endfor %} </select> </div> <script> document.getElementById('locale-switcher').addEventListener('change', function() { const locale = this.value; const url = new URL(window.location); url.searchParams.set('locale', locale); window.location.href = url.toString(); }); </script> <div class="w-form"> <form action="{% url view.edit_url_name %}" method="POST" novalidate> {% csrf_token %} {{ edit_handler.render_form }} <div class="w-form-actions"> <button type="submit" class="w-button w-button--primary">{% trans "Save" %}</button> </div> </form> </div> {% endblock %}
完成后,管理面板会显示语言切换下拉框,选择不同语言即可编辑对应版本的设置。
二、模板中本地化渲染设置
若暂时无需修改管理面板,可先通过代码创建多语言实例,再在模板中按需获取:
1. 批量创建多语言设置实例
通过Django Shell或数据迁移为每个语言创建实例:
from myapp.models import CompanySettings from wagtail.models import Site, Locale site = Site.objects.first() locales = Locale.objects.all() # 为每个语言初始化设置 for locale in locales: CompanySettings.objects.get_or_create( site=site, locale=locale, defaults={ 'top_services': "Web Design, Development" if locale.language_code == 'en' else "设计、开发", 'copyright_text': "© 2024 My Company" if locale.language_code == 'en' else "© 2024 我的公司" } )
2. 模板中获取当前语言的设置
使用Wagtail的get_settings标签和TranslatableMixin的get_translation方法:
{% load wagtailsettings_tags %} {% get_settings use_default_site=True %} {% with localized_settings=company_settings.get_translation(request.Locale) %} <div class="top-services">{{ localized_settings.top_services }}</div> <div class="copyright">{{ localized_settings.copyright_text }}</div> {% endwith %}
若当前语言无对应实例,get_translation会自动返回默认语言版本(可通过fallback=False关闭该行为)。
内容的提问来源于stack exchange,提问作者Imtiaz Ahmed
相关产品推荐
相关产品推荐

