djangowagtailwagtail-localize

Does wagtail tag {% slugurl 'page' %} work with Wagtail-localize?


I'm building a website with Django, Wagtail and Wagtail Localize.

But when I'm load my website on "https://exemple.com/fr/" the slugurl tags generates links like href="/en/about/"

I followed settings for urls.py :

urlpatterns = urlpatterns + i18n_patterns(
    path("search/", search_views.search, name="search"),
    path("", include(wagtail_urls)),
)

I also added middleware and others setting like LANGUAGES. Page are correctly translated and accessible with urls.

The language code is detected because tag like {% if LANGUAGE_CODE == "fr" %} is working but this slugurl never work and always display "/en/about/" :

<a href="{% slugurl 'about' %}" class="nav-links">about</a>

Navigation isn't very fluid, because when you access a page you have to reselect the language each time. Is slugurl supposed to work with Wagtail-localize?


Solution

  • slugurl will always only return the first page that matches the slug - that slug might also be repeated on each locale, so it needs some care.

    I use a custom templatetag to return the localised page for the first match:

    @register.simple_tag()
    def trans_page_from_slug(slug, specific=False):
        try:
            if specific:
                return Page.objects.live().filter(slug=slug).first().specific.localized
            else:
                return Page.objects.live().filter(slug=slug).first().localized
        except:
            return Page.objects.none()
    

    So even if your French page slug is something like 'a-propos', the templatetag will return the correct translated page for the slug 'about'.

    I guess if you just want the url back, you could use:

    @register.filter()
    def localised_slugurl(slug):
        try:
            return Page.objects.live().filter(slug=slug).first().localized.url
        except:
            return ''
    

    Then your nav link is:

    <a href="{{ 'about'|localised_slugurl }}" class="nav-links">about</a>
    

    That won't change your 'about' label though. For that, you could use the trans_page_from_slug templatetag to return the page, then access the url and title attributes in your link:

    {% trans_page_from_slug "about" as link %}
    <a href="{{ link.url }}" class="nav-links">{{ link.title }}</a>
    

    If your page titles are too long for the nav menu, add an optional menu_title field to your page models and use that where needed. Default to title so you always have a value:

    {{ link.menu_title|default:link.title }}
    

    Just make sure you're returning the specific page from the templatetag if you do this as the base Page model won't include your custom field.