[Multi-Language]Menu with proper links

Hi,

I’m new to Grav. I’m considering to build the page with this CMS.
I was looking the for the answer and tried different configuration options but without success.

I have following configuration:

languages:
  supported:
    - pl
    - en
  default_lang: pl
  include_default_lang: false
  include_default_lang_file_extension: true

I have following pages:

pages
    01.First
        default.pl.md
        default.en.md
    02.Second
        default.pl.md

When I open page with pl language, in menu I see:

  • First[/first]
  • Second[/second]

When I open page with en language, in menu I see:

  • First[/en/first]
  • Second[/en/second] :warning:

How can I achieve solution where menu item have link with default language when page in selected language doesn’t exist?

Is it possible with configuration?
Do I need to to use/write some plugin?

1 Like

@pawellabaj, Unfortunately, this is a long standing issue:

You need to set a few things:

  • in user/config/system.yaml (see docs)
    languages:
      ...
      content_fallback:
        pl: pl
        en: en
    
  • And change the way the navigation is created. In Quark, in file /user/themes/quark/templates/macros/macros.html.twig add a check if page is routable:
    {% for p in page.children.visible %}
      {% if p.routable %}             <= added
      ...
      {% endif %}                     <= added
    {% endfor %}
    
1 Like

I tried this, as I found couple threads with that hint.
When using such configuration, when opening page with en language I see only

  • First[/en/first]

I use darkquark theme and in /user/themes/darkquark/templates/macros/macros.html.twig property p.routable is being checked:

<a href="{% if p.routable %}{{ p.url }}{% else %}#{% endif %}" class="{{ active_page }}">
        {{ p.menu }}
      </a>

So it doesn’t work as I expected

1 Like

@pamtbaau , your suggestion regarding macros.html.twig gave me a hint.

I’ve solved problem, but …

I’ve created /user/themes/customdarkquark/templates/macros/macros.html.twig:

{% macro nav_loop(page, config_languages) %}
    {{ dump(config_languages) }}
    {% import _self as macros %}
    {% for p in page.children.visible %}
        {% set active_page = (p.active or p.activeChild) ? 'active' : '' %}
        {% if config_languages.default_lang == p.language %}
            {% if config_languages.include_default_lang %}
                {% set link = '/' ~ p.language ~ p.route %}
            {% else %}
                {% set link = p.route %}
            {% endif %}
        {% else %}
            {% set link = p.url %}
        {% endif %}
        <li>
            <a href="{% if p.routable %}{{ link }}{% else %}#{% endif %}" class="{{ active_page }}">
                {{ p.menu }}
            </a>
            {% if p.children.visible.count > 0 %}
                <ul>
                    {{ macros.nav_loop(p) }}
                </ul>
            {% endif %}
        </li>
    {% endfor %}
{% endmacro %}

I’ve created /user/themes/customdarkquark/templates/partials/navigation.html.twig:

{% import 'macros/macros.html.twig' as macros %}

<ul {{ tree ? 'class="tree"' : '' }}>
    {{ macros.nav_loop(pages, config.system.languages) }}
</ul>

… but this is specific to currently chosen theme.

Coul plugin be created, that will update Page.route property in pages variable?
Where I could read more about it?

No wonder… Your if-statement still creates a menu-item, albeit a non-functional anchor when page is not routable.

If you wrap lines 4-14 inside the if-statement as I’ve shown, it will work as expected in the DarkQuark theme as well.

1 Like

i use |default() for cases like that and it works so good :slight_smile:
it runs when there is no value
example:

lets say there is no fr translate a certain page

{% set defaultLanguage = grav.language.getDefault %}
{% set activeLanguage = grav.language.getActive %}

{{ page[activeLanguage] }}

this will lead nothing since there is no page.fr

but if i use

{{ (page[activeLanguage])|default(page[defaultLanguage]) }}

that will lead it to default language of that page

this code is not complate actually, i just write it that way to make it more understandable

1 Like

@pawellabaj, I’m starting to believe that I’m not understanding what your expectation is…

  1. Do you want to replace a missing en page with a page for the default pl language
  2. Or do you wish to omit the non existing en page from the navigation bar?
    I assumed you expected this behaviour…

ad. 1
If you want to replace the non-existing en page with the pl page you need to set the following:

content_fallback: 
  pl: pl
  en: [en, pl]

No need to change the template in this case.

Note:
I’m not sure if this is a desirable behaviour from the user’s point of view. The user choses the English language because he/she doesn’t understand Polish. Presenting the user a Polish page anyway is not very useful for the user…

My initial interpretation (1) would be more logical IMHO.

1 Like

@Gin , using default looks nice

Yeas, this is the behaviour I’d like to achieve. This is one of the requirement I need to fulfil.

When I set follwoing configuration:

languages:  
  content_fallback:     
    pl: pl     
    en: [en, pl]

I see all pages in menu. In en language I see menu items with following urls:

  • First[/en/first]
  • Second[/en/second]

When I click /en/second link, the page in default (pl) language is opening; in browser address bar there is localhost:8000/en/second.
This is misleading - I clicked link for English page and received Polish one.

:thinking: I could disable menu item link to show that page exists in another language

@pawellabaj,

This is misleading - I clicked link for English page and received Polish one.

The property content_fallback does what it should do: falling back to the content of another language. It doesn’t fallback to a url of a page in another language.

I really don’t see what the use-case is of your approach. As a non Polish speaker/reader, I would not want to be directed to the url of a Polish page, nor do I want to be presented Polish content.

What if I save the the url in my favourites?

  • When saving /en/second showing Polish content, I might see English content in the future when the page gets translated.
  • When saving /pl/second I would never see the English content in the future. Also, I would land on the Polish version of the website, while I don’t understand Polish…

As a non-Polish speaker, I would prefer to not see Polish content ever, I also don’t want to know there is a Polish page, but not in English. I would prefer the first solution I’ve presented. Not falling back to Polish, and don’t show me a url in the navigation if there is no English content.

Please share a use-case that suits your preferred behaviour.

1 Like

I understood it works a little bit different. Now the default behaviour have sense - it works as designed.

Thanks

Please share a use-case that suits your preferred behaviour.

I wanted to achieve behaviour from my first post, but now I need to rethink it :grinning_face: