How to preview a Wagtail page with translated fields in different languages? - django

I have a multi-language Wagtail website with two languages (English and German) using duplicated fields in my page models, e.g. a text block has two fields, text_de and text_en, and I define text as a translated field following the example in the translating content documentation. (I.e. I am NOT duplicating the whole page tree.) Here's an example how that looks in my code:
[models.py]
class MyPage(Page):
...
text_de = models.CharField(max_length=1024)
text_en = models.CharField(max_length=1024)
text = TranslatedField('text_en', 'text_de')
Everything works perfectly fine, in templates I can just use {{ text }} and depending on the active language (using i18n patterns and LocaleMiddleware) the correct version is displayed.
BUT: I have issues with getting a page preview in both languages.
When an editor creates a draft page in Wagtail admin and clicks on 'preview', then a page preview is shown in the language used within the Wagtail admin, i.e. in the language defined by the current editor's language preferences in his or her account settings.
How could the editor also preview the page in another language (without switching the language in his or her account settings back and forth)?
Is there maybe a way to construct a view that sets a different language before creating the page preview? Or is there another way to solve this?
I've tried to find out when Wagtail/Django decides which language it should serve and found the method get_url_parts of wagtail/admin/core/models, Page class. The page_path returned from this function is suffixed with '/de' or '/en', depending on the editor's account settings.
I can permanently change the language in which a page is displayed using translation.activate(). E.g. if I add translation.activate('en') to the get_context method of the MyPage class, then a MyPage-page and its previews are always shown in English. That's not really helpful.
I tried to construct a view, that first sets the language and then redirects to the preview like this:
[views.py]
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils import translation
def preview_language(request, pk=None, language='en'):
if language == 'de':
translation.activate(language)
else:
translation.activate('en')
return HttpResponseRedirect(reverse('wagtailadmin_pages:preview_on_edit', args=(pk,)))
But the language is set back to the editor's language from the account settings when the redirect is performed. And I am not sure that this is actually the way to go ...
Does anyone have a (different?) idea how to enable editors to easily preview a page with translated fields in different languages?
I am currently using Wagtail 2.4, Django 2.1, Python 3.5.
Any help is greatly appreciated! :-)

Wagtail's "preview modes" feature would probably help here: https://docs.wagtail.io/en/stable/reference/pages/model_reference.html#wagtail.core.models.Page.preview_modes
You could define English and German as two preview modes on your page model, and override the serve_preview method to activate the appropriate translation based on the received mode_name argument.

Related

Django CMS - Multilanguage setup translates plugins in edit mode

I am using django-cms version 3.7.1 with multilanguage setup.
Default and admin user language is set to english 'en', second one is German 'de'.
Everything is running ok (url, editing content for each language), except one detail - admin user language is set to English, so toolbar menu is always English, but when i switch to edit page content in deutch, plugin modal window with editor show german translation for buttons etc.
Is that supposed to work that way? Now plugin text is always changing according to page language (if i add spanish for example, button will be in spanish).
I need plugins to have text in language admin user have in own settings. In this case always English.. even when editing German page.
Does anyone know how to achieve this?
Thanks
Screenshot how it look like in browser

Django multilingual with pages in one language disabling switch

I am developing a website using Django Mezzanine.
I have some pages using a model derived from Mezzanine Page model with translatable fields (using i18n) and this works.
However I have some pages relative to some events in given countries, so they are only in one language, and they use a model derived from Mezzanine Displayable model, without translatable fields but a language attribute.
In the list I tried to put links including the language of the page (like /en/events/event/eventslug ).
I tried to add translation.activate(lang_code) to the view.
This way I get the page in the wanted language (I use {% trans %} template tags).
The problem comes when I visit the page from another language (for example if I am on the filter page in Spanish and go to an English event). Then the language switch (mezzanine form sending a POST request to /i18n/) doesn't work any more (I am locked in English)
The switch still work in private navigation for example as long as I don't visit one of this pages from another language.
How can I fix this?
I am out of ideas as of why...
Update: I changed the urlpattern so it is not i18n anymore (I think it makes more sense) but as I still need translation.activate(lang_code) for the {% trans %} tags my problem is still the same.
The problem came from the fact that if you use translation.activate(language) then you need to use translation.deactivate().
So that would have required the use of a middleware to make it work properly.
However I found the i18next module allowing to override the locale in the template, so I defined the context 'lang_code' in my view and used {% overridelocale lang_code %} in my template.

Can all Django applications add items to a base template

I'm writing a webpage in Django and I have a application called "Website". This application defines some basic views and general layout of the whole site part of which is the navigation bar.
As I add applications responsible for different functionalities I would like to have them add links to that navigation bar. The links should appear not only when using a view from a certain application but in all others as well. The problem here is how to arrange this without the "Website" app knowing about all the other applications?
All Django apps inside one project can be aware of each other. For example, if you had an app called links, you could use models and functions from links to create new content, then use that content in Website. You will need to import the information. For example, to use links from links in your Website views:
# Website.views
from links.models import Link
def myView(request):
links = Link.objects.all()
# do something with the links
context = {'links': links}
return render(request, 'webpage.html', context)
Please excuse my syntax and stuff, I haven't tested this or anything. I hope this explains what you mean. Feel free to ask more, I'll do my best to answer.

Django: language in field description in forms won't change

When I change language on my Django-powered site, everything works fine except the translation of the field descriptions in the forms. The description is still displayed in the old language. Only the forms already visited that session are affected.
It seems like some sort of caching problem, but I don't use any caching (as far as I know) and all other parts of the site behave as expected (templates and random text using django.utils.translaction.ugettext work just fine).
Summarized:
When I open the site and change language, and then visit a form: everything works as expected. All text is translated.
When I visit a form, change language and return to the form: everything is translated, but the form stays in the old language.
Restarting the web server forces the language to change: then Django behaves as in (1) for the current session. Until the language is changed again.
Help is appreciated!
Kind regards,
Patrick
Fixed it by changing
from django.utils.translation import ugettext as _
to
from django.utils.translation import ugettext_lazy as _
for my forms.

How to translate single page in django?

I have only one page i want to translate and im using downloaded application (with locale folder in it).
I want to get output from this app with translated values on one single page.
How can i tell the the template or view to show translated values?
I'm assuming that you want the page to be in a different language than what you have set for your website.
Here is two lines of the code of the middleware which manages languages in our dual-language website but I guess in your case, it can be placed at the beginning of your view function:
django.utils.translation.activate(desired_lang)
request.LANGUAGE_CODE = django.utils.translation.get_language()