coderedcorp / coderedcms

Wagtail + CodeRed Extensions enabling rapid development of marketing-focused websites.
https://www.coderedcorp.com/cms
Other
681 stars 133 forks source link

Internationalization / i18n / translation support #57

Open ahwebd opened 5 years ago

ahwebd commented 5 years ago

Hello, how i18n is handled in coderedcms? Is there an easy way to integrate wagtailtrans with coderedcms? Many thanks.

vsalvino commented 5 years ago

i18n support is definitely lacking. The code does use the built-in Django translation tools as much as possible when displaying strings or text in the UI, models, etc. But that is about it. We currently do not have any translations available, but would be happy to accept pull requests with those.

Definitely needs more research.

ahwebd commented 5 years ago

Tried content translation with wagtailtrans and it is working fine, here is what I have done: Installed and configured wagtailtrans: https://wagtailtrans.readthedocs.io/en/latest/getting_started.html#installation

Created an abstract class from "TranslatablePage":

from wagtailtrans.models import TranslatablePage
class TranslatablePageAbstract(TranslatablePage):
    class Meta:
        abstract = True

Added the previous class as a parent to coderedcms pages: Example:

class ArticlePage(TranslatablePageAbstract, CoderedArticlePage):

Suggest adding documentation about this.

vsalvino commented 5 years ago

I'm actually surprised that works. I would expect an issue about having multiple parent pages. Glad that you got it working! I will have to try it out.

If you end up building a site with coderedcms and wagtailtrans, I would appreciate if you could write a blog post about the experience.

ahwebd commented 5 years ago

I was trying and exploring coderedcms, unfortunately I think it is not exactly what I need, it is assuming that I will use bootstrap in the frontend (while I am using another framework) and it has some mixing between content and design.

Anyway I used the same method with wagtailtrans and puput and it is also working fine.

vsalvino commented 5 years ago

I also want to check out puput. We plan to add theme support in the future, which will allow you to easily swap out front-end frameworks. Keep an eye out!

pascalthivierge commented 4 years ago

Hi! I'm a little bit stuck on how to make a multilingual website... I tried multiple modules, like Wagtailtrans, Wagtail Modeltranslation, Wagtail-Localize... and simply duplicating page tree... Nothing works. In fact, Wagtail Model translation worked well, but could not detect browser language and redirect root page to corresponding i18n_pattern. Does anyone know where to find how to do it succesfully?

pascalthivierge commented 4 years ago

Here are the steps I followed to make Model Translation works with CodeRedCMS:

  1. Installed module : $ pip install wagtail-modeltranslation

  2. Added 'wagtail_modeltranslation' to INSTALLED_APPS before all apps in base.py:

    INSTALLED_APPS = [
    'wagtail_modeltranslation',
    'wagtail_modeltranslation.makemigrations',
    'wagtail_modeltranslation.migrate',
    
    'website',
    ...
    ]
  3. Added 'django.middleware.locale.LocaleMiddleware' to MIDDLEWARE in base.py:

    MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
    ]
  4. Ensured i18n was enabled in base.py :

    USE_I18N = True

  5. Defined available languages in base.py :

    ...
    from django.utils.translation import gettext_lazy as _
    ...
    
    LANGUAGE_CODE = 'en'
    
    LANGUAGES = [
    ('en', _('English')),
    #('fr', _('French')), # uncommented after first migration
    ]
  6. Added few variables in base.py :

    ...
    USE_TZ = True
    
    WAGATAILMODELTRANSLATION_TRANSLATE_SLUGS = True
    WAGTAILMODELTRANSLATION_LOCALE_PICKER = False
    MODELTRANSLATION_DEBUG=True
    ...
  7. Added i18n patterns to urls.py :

    ....
        #re_path(r'', include(codered_urls)), # commented out
    
    # Alternatively, if you want CMS pages to be served from a subpath
    # of your site, rather than the site root:
    #    re_path(r"^pages/", include(codered_urls)),
    ]
    
    urlpatterns += i18n_patterns(
        # These URLs will have /<language_code>/ appended to the beginning
    
        re_path(r'', include(codered_urls)),
        prefix_default_language=True, # to get prefix even in english
    )
    ...
  8. Created translation.py at root folder of website app :

    from modeltranslation.translator import TranslationOptions
    from modeltranslation.decorators import register
    from .models import WebPage
    
    @register(WebPage)
    class WebPageTR(TranslationOptions):
        fields = (
            'body',
        )
  9. Modified models.py as follow :

    ...
    from wagtail.core.fields import StreamField
    from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel
    from coderedcms.models import (  
    ...
    
    class WebPage(CoderedWebPage):
        """
        General use page with featureful streamfield and SEO attributes.
        Template renders all Navbar and Footer snippets in existance.
        """
        class Meta:
            verbose_name = 'Web Page'
    
        template = 'coderedcms/pages/web_page.html'
    
        body_content_panels = []
    
        content_panels = CoderedWebPage.content_panels + [
            StreamFieldPanel('body'),
        ]
    
  10. Run python manage.py makemigrations followed by python manage.py migrate

  11. Run python manage.py sync_page_translation_fields

  12. Since adding to a existing site, run python manage.py update_translation_fields

Everything works well as it should. The root page redirect to slug with language prefix. I get 404 error page as it should when I enter wrong URL.

  1. Rerun steps 10 to 12, after uncommenting French language in base.py.

Now, the root page doesn't detect and redirect with the appropriate language prefix. And I do not get any 404 error page when I enter a wrong URL.

If I enter a valid slug with proper language prefix, it works very well.

Anyone has a solution for the root redirect?

vsalvino commented 4 years ago

@plascual I don't think that feature exists. You will probably have to implement it yourself. A good place to do this might be in before_serve_page hook. Check the browser's language from the request object and return an HTTP redirect instead of the page response.

https://docs.wagtail.io/en/v2.8.1/reference/hooks.html#page-serving

However you might want to consider having the user select their language instead, in case they are using an English browser but prefer to read in French, for example.

pascalthivierge commented 4 years ago

I will have a look at this.

But what I don't understand, is why the root redirect works when only one language is set? It stop working as soon as I activate another one.

pascalthivierge commented 4 years ago

ModelTranslation module seems to break the way CodeRedCMS defines sitemap.xml, or vice-versa.

I have two languages defined in base.py. The /sitemap.xml splits into /en/sitemap.xml and /fr/sitemap.xml. The namespace is now omitted. I think it should be declared before adding i18n_patterns in url.py.

Wagtail with i18n patterns is supposed to detect browser language. Might CodeRedCMS be responsible for breaking this process? Also, 404 errors doesn't return 404.html as it usually should.

vsalvino commented 4 years ago

Regarding sitemap, yes I would imagine the sitemap should be declared above the i18n patterns in urls.py.

As far as the browser detection, I really have no experience with wagtail model translation. I will see if I can look into it whenever I have spare time. I would recommend pointing you to CoderedPage in coderedcms/models/page_models.py. This is our base page that has most of the special logic. Particularly the render, get_context, etc. methods might help give you some clues.

You can also troubleshoot by created a page model that inherits from Wagtail's Page, not from a coderedcms model, and see if it has the same problem. For example:

class TestPage(Page):
    ...

Another idea is that the wagtail-cache middleware might be affecting it, if it is caching the pages before they are redirected? Try removing wagtail-cache from the middleware or set WAGTAIL_CACHE = False in your settings.

vsalvino commented 3 years ago

For anyone following this issue, Wagtail 2.11 (now included in coderedcms 0.20) seems to have added a lot of internationalization abilities. Please report back if you have any experience with this in coderedcms.

https://wagtail.io/blog/wagtail-211-internationalisation-and-more/