picocms / Pico

Pico is a stupidly simple, blazing fast, flat file CMS.
http://picocms.org/
MIT License
3.81k stars 616 forks source link

Implementing conditional navigation menus and footer #564

Closed notakoder closed 3 years ago

notakoder commented 3 years ago

I am trying to create a multi-lingual site keeping the translated content inside a subfolder inside content. The language selectors coded into the twig file and shown at the bottom of all web pages at the footer.

<footer>
    <p>Lorem ipsum</p>
    <p>Lorem ipsum</p>
    <section id="languageSelector">
        <a href="{{ base_url }}/es">Script1</a>
        <a href="{{ base_url }}/fr">Script2</a>
        <a href="{{ base_url }}/xx">Script3</a>
        <a href="{{ base_url }}/yy">Script4</a>
        <a href="{{ base_url }}/zz">Script5</a>
    </section>
</footer>

{{ base_url }}/content/will contain files and folders for the default language while {{ base_url }}/content/fr/ and {{ base_url }}/content/es/ will contain translated content. This is a nice way of managing translated content, but html elements like the header and footer will still be displayed in the default language as written in the index.twig of the theme. I want to display translated header, footer and other elements as well (minus the language selector).

Here's what I was thinking of

if user navigates by clicking on the `{{ base_url }}/es` link at the footer **or** user is moving within {{ base_url }}/es/*  pages

display <nav>Menus in es</nav>
|
|
elseif - same logic for other languages
|
|
else display <nav>default lang</nav>

If the translated languages are more (say 50), the above condition is not ideal since it has to make about 50 conditional check for every page change. So there must be a better way. Or perhaps a better logic altogether? Or perhaps there is already a solution built into Pico for such problems?

PhrozenByte commented 3 years ago

I'm not 100% sure whether I get you right, but you're talking about translating static text inside your Twig templates, correct?

You can use a hidden _lang.md page. Just create a content/en/_lang.md, content/es/_lang.md, content/fr/_lang.md, … with something like the following

---
footer_title: This is the footer's title - in the designated language of course
footer_copyright: (c) 2020 by Lorem Ipsum
---

and use it in your Twig templates as follow

{% set lang = current_page.id|split("/", 1)|first %}
{% set _ = pages[lang ~ "/_lang"].meta %}

<p>{{ _["footer_title"] }}</p>
<p>{{ _["footer_copyright"] }}</p>
notakoder commented 3 years ago

I think you got me right. Not just for the markdown content, but I also want to translate the static elements like header and footer in the twig.

So here's what I did following your instructions,

  1. I created a folder inside content called tm. I created _lang.md file inside it with the following text.
    ---
    footer_title: This is the footer's title - in the designated language of course
    footer_copyright: (c) 2020 by Lorem Ipsum
    ---
  2. I opened the twig template and adding your lines inside the footer element.
    <footer>
    {% set lang = current_page.id|split("/", 1)|first %}
    {% set _ = pages[lang ~ "/_lang"].meta %}
    <p>{{ _["footer_title"] }}</p>
    <p>{{ _["footer_copyright"] }}</p>
    </footer>

    I am not sure what went wrong but visiting {{ base_url }}/tm renders the index.md from the tm folder, but the footer is empty. Viewing the source reveals two empty <p> tags.

PhrozenByte commented 3 years ago

Try the following instead:

{% set lang = current_page.id|split("/")|first %}
notakoder commented 3 years ago

It works! Thanks.

However, this only displays the footer from the _lang.md pages inside translated directories like content/es or content/fr. My original files are in the content directory and I get an empty <p></p> tag while rendering the default index page even if I have a _lang.md in side content.

A workaround is to move the original content to a sub-folder just like the translated content but I prefer keeping the original content in the content folder itself so as to access the website directly on the base url. Is there any way to include the hidden _lang.md from the content directory too?

PhrozenByte commented 3 years ago

Everything is possible :laughing: However, simply moving the default contents to a language-specific folder is way easier.

notakoder commented 3 years ago

:smile:

Yes, it would be way easier, but quite difficult for users as they'd have to choose a language from the base url to access the website, or we'll have write some JS gimmick to auto choose the language according to IP.

You've gone far to help me, I understand that too. :smile:

PhrozenByte commented 3 years ago

You could write a simple Pico plugin to choose the right language (most clients indicate a language preferences in the HTTP request headers) and automatically redirect the user accordingly.

notakoder commented 3 years ago

I use Pico in two websites and this would work for one since the original content is all but written in one language. However the second website contains original work in two languages and can include more in future. Putting them even under a generic folder name like ori (for original) would be highly inaccurate and weird. For this website, I still prefer the method of including the _lang.md in the content folder.

Anyway, I am closing this issue. Thanks for the help. Much appreciated. :smile: One day I will contribute too.