Is it possible to translate paths (i18n, gettext_lazy) in RoutablePageMixin-Pages?
I have created a page with RoutablePageMixin and defined a child path. I want to translate this child path based on the active language with gettext_lazy like it works in Django within urlpatterns. I always get 404. Is this even possible or am I missing something?
Here is my Page definition:
class StudyBrowserPage(RoutablePageMixin, TranslatedPage):
page_description = "Weiterleitung zum Studienbrowser"
@path('')
def list_studies(self, request):
studies = Study.objects.all()
return self.render(request, context_overrides={
'studies': studies
})
# here I actually want another parameter, but i tried to keep it simple. So don't mind the uselessness of the function.
@path(_('studie') + '/')
def study_detail_view(self, request):
return self.render(request, template='wagtail_home/study_detail.html')
I have translated the string in my django.po:
msgid "studie"
msgstr "study"
Calling .../studie/
works. .../study/
does not.
Edit: I think I have all the necessary settings in my config:
"context_processors": 'django.template.context_processors.i18n',
USE_I18N = True WAGTAIL_I18N_ENABLED = True
I also have wagtail-localize installed.
It could well be because _('studie')
is still a proxy and not resolved to the lazy string when this is interpreted, or that the English locale is not activated when you are using /study/
.
If it's the first, maybe try assigning the path to a variable then forcing it:
from django.utils.encoding import force_str
from django.utils.translation import gettext_lazy as _
STUDY_PATH = _('studie')
class StudyBrowserPage(RoutablePageMixin, TranslatedPage):
....
@path(force_str(STUDY_PATH) + '/')
def study_detail_view(self, request):
return self.render(request, template='wagtail_home/study_detail.html')
Probably simpler to just declare multiple paths though:
@path('studie/')
@path('study/')
def study_detail_view(self, request):
return self.render(request, template='wagtail_home/study_detail.html')
If you intend that path to be a variable rather than a string literal, then you just need to look for a match to that variable and translate the result.
This is a product page showing a listing of Django model instances (Product
). Each has an sku
attribute that might be unique per locale, or unique fore the product and shared across locales.
The sku
path shows the detail for that product. The product_detail
method looks for a match in the current locale first and uses that if found. If not found in current locale but found in another, it tries to find the translated instance and uses that if found. If no match, or no translation for current locale, then the listing page is returned:
class ProductPage(TranslatablePageMixin, RoutablePageMixin, Page):
parent_page_types = ["home.HomePage"]
subpage_types = []
max_count = 1
intro = RichTextField()
content_panels = Page.content_panels + [
FieldPanel('intro')
]
@path("")
def product_list(self, request):
products = Product.objects.filter(locale_id=Locale.get_active().id, live=True)
return self.render(
request,
context_overrides={
"products": products,
},
template="product/product_list.html",
)
@path("<str:sku>/")
def product_detail(self, request, sku):
active_locale = Locale.get_active()
# only show live products
products = Product.objects.filter(sku=sku, live=True)
if products and products.filter(locale_id=active_locale.id):
# if live product in active locale
return self.render(
request,
context_overrides={
"product": products.first().localized,
},
template="product/product_detail.html",
)
else:
# live product not in active locale
if products:
# product matching sku and live in other locales, try to find product in current locale
# redirect request to product if found and if live else send request to product list instead
translated = products.first().get_translation_or_none(active_locale)
return HttpResponseRedirect(self.url + (translated.sku if (translated and translated.live) else ''))
# no live products matching that sku in this locale, redirect to product list instead
return HttpResponseRedirect(self.url)