CMS Development

SuperHolde
Participant | Elite Partner
Participant | Elite Partner

Custom language switcher / Language switching

SOLVE

Hi,

 

What is the best way to make custom language switcher to the site. My problem is that I have a site with two language versions and my custom language switcher is a bit problematic I would say. It doesn't work in all pages for some reason and in my opinion is it coded in very complicated way. In our site the language versions are changed via url. For example mycompany.fi/ is the main language version and the mycompany.fi/en/ is for the english version of the site. Here is the code how I switch language currently by just changing the url. In the code it checks the url and also if the page has translated_content. After that I put the site_language and other_language to links so by pressing the link it changes the language. 

 

{% if absolute_url is string_containing "/en-us/" %} 
  {% set site_language = 'en'  %} 
  {% set other_language = 'fi' %}
  {% if content.translated_content['fi-fi'] %}
    {% set other_language_url = '/' + content.translated_content['fi-fi'].slug %} 
  {% elif content.translated_content['fi'] %}
    {% set other_language_url = '/' + content.translated_content['fi'].slug %} 
  {% else %}
    {% set other_language_url = '#' %} 
  {% endif %}
{% elif absolute_url is string_containing "/en/" %}
  {% set site_language = 'en'  %}
  {% set other_language = 'fi' %}
  {% if content.translated_content['fi-fi'] %}
    {% set other_language_url = '/' + content.translated_content['fi-fi'].slug %} 
  {% elif content.translated_content['fi'] %}
    {% set other_language_url = '/' + content.translated_content['fi'].slug %} 
  {% else %}
    {% set other_language_url = '#' %} 
  {% endif %}
{% else %}
  {% set site_language = 'fi' %}
  {% set other_language = 'en' %}
  {% if content.translated_content['en-us'] %}
    {% set other_language_url = '/' + content.translated_content['en-us'].slug %} 
  {% elif content.translated_content['en'] %}
    {% set other_language_url = '/' + content.translated_content['en'].slug %} 
  {% else %}
    {% set other_language_url = '#' %} 
  {% endif %}
{% endif %}

I'm wondering is there any other way to make this happen because for me this seems very complicated solution. I would like to know if there is some global variable or something what defines the current language used in the page.

0 Upvotes
1 Accepted solution
piersg
Solution
Key Advisor

Custom language switcher / Language switching

SOLVE

You could try the below.

 

{% set path = request.path|truncate(3, true, '') %}
{% if path is string_containing 'en' %}
{% set site_language = 'en' %} {% set other_language = 'fi' %}
{% else %}
{% set site_language = 'fi' %}
{% set other_language = 'en' %}
{% endif %}
{% if content.translated_content %}
{% for item in content.translated_content %}
{% set other_language_url = "/"~item.slug %}
{% endfor %}
{% else %}
{% set other_language_url = '#' %}
{% endif %}

This gets the first 3 characters of the request path i.e. if the path is /en-us/ or /en/ it'll return '/en' so you don't have to check for both of those.

 

You can do the below if you want to sort these alphabetically 

{% for item in content.translated_content|sort(False, False, 'language') %}

 

It then gets the language code for whatever translated content you have, if it exists, and grabs the associated slug so you again don't have to check for specific codes. You do have to use the other_language_url in the for loop though, can't use a variable set inside a loop outside of said loop. Just add your list items/whatever you're using to display your languages there.

 

View solution in original post

45 Replies 45
ALarsson
Member

Custom language switcher / Language switching

SOLVE

Why is all this ****? Why can't we simply get something like:

 

foreach translations as translation {

  if (translation.current) {

    /* show current language label */

  } else {

     <a href="get_url_for_translated_content(translation)">translation.super_nice_locale_name</a>

  }

}

 

??

 

I've been tearing my hair out for hours to accomplish this simple little thing. I don't want to do a billion conditions over "yeah it might be french, or maybe swedish". This is just stupid. Fix the CMS already and let real programmers, who have to work with this platform whether we want or not, to accomplish simple BASIC things.

 

Sorry if I'm sounding angry, but I am. 😞

 

 

piersg
Key Advisor

Custom language switcher / Language switching

SOLVE

@FelTigre Sorry, small error, I used firstElementChild instead of lastElementChild, will update the above accordingly.

dennisedson
HubSpot Product Team
HubSpot Product Team

Custom language switcher / Language switching

SOLVE

jeez @piersg ...

piersg
Key Advisor

Custom language switcher / Language switching

SOLVE

Hi @FelTigre,

 

The issue with sorting by country is that the country appears last in the language code e.g. 'fr-be' is country: Belgium, language: French, so to sort it by that you'd have to somehow get that substring out of item.language and then sort the list by that substring. It would be easier to do this with JS:

 

var items = document.getElementsByClassName('other-lang');

items = Array.prototype.slice.call(items).sort(function(a, b) {
    return a.lastElementChild.dataset.country.localeCompare(b.lastElementChild.dataset.country);
});

var menu = document.getElementsByClassName('others-lang--menu')[0];
for (var i = 0, length = items.length; i < length; i++) {
    menu.appendChild(items[i]);
}

 

 

For the second question, instead of {% for key, val in codes.items() %} do {% for item in content.translated_content %}.

 

FelTigre
Participant

Custom language switcher / Language switching

SOLVE

@piersg Thank you 😁

I will try this and i'll tell you if it works  😃 

 

FelTigre
Participant

Custom language switcher / Language switching

SOLVE

Hello 🙂 
i'm trying to create a switcher language on blog but i can't sort the languages by country. 

My switcher : 

FelTigre_0-1614874875332.png

and what i want : 

FelTigre_1-1614874939132.png

{% elif group.translations %}

        <ul class="dropdown menu country-list" data-dropdown-menu>

          {% set currLang = locale_name(locale) %}
          {% set codesLang = {'English' : 'en', 'Français - France' : 'fr-fr', 'Français' : 'fr' ,'Français - Luxembourg' : 'fr-lu', 'Français - Belgique' : 'fr-be', 'Nederlands' :'nl', 'Nederlands - België' || 'Nederlands - Belgique' : 'nl-be' } %}
          
          <li class="">
            <a class="lang-select" href="#" data-country="{{ codesLang[currLang]| truncate (2, true, '') }}" data-lang="{{ codesLang[currLang] }}">
              <img class="lang-flag" src="https://ressources.birdee.co/hubfs/Media/Common/{{ codesLang[currLang] }}.svg">
              {{ currLang }}
            </a>
          </li>

          {% for item in group.translations|sort(False, False, 'language') %}
          
            {% if item.language == 'fr' %}
              {% set name = 'Français' %}
              {% set country = 'France' %}
              {% set data = 'fr' %}
            {% elif item.language == 'fr-fr' %}
              {% set name = 'Français - France' %}
              {% set country = 'France' %}
              {% set data = 'fr' %}
            {% elif item.language == 'en' %}
              {% set name = 'English' %}
              {% set country = 'Europe' %}
              {% set data = 'eu' %}
            {% elif item.language == 'fr-be' %}
              {% set name = 'Français - Belgique' %}
              {% set country = 'Belgique' %}
              {% set data = 'be' %}
            {% elif item.language == 'nl-be' %}
              {% set name = 'Nederlands - Belgium' %}
              {% set country = 'Belgique' %}
              {% set data = 'be' %}
            {% elif item.language == 'nl' %}
              {% set name = 'Nederlands' %}
              {% set country = 'Nederlands' %}
              {% set data = 'nl' %}
            {% elif item.language == 'fr-lu' %}
              {% set name = 'Français - Luxembourg' %}
              {% set country = 'Luxembourg' %}
              {% set data = 'lu' %}
            {% endif %}
            <li class="menu desktop-lang">
              <ul class="others-lang--menu">
                <li class="other-lang">
                  <span class="langTitle">
                    <span class="flag">
                      <img src="https://ressources.birdee.co/hubfs/Media/Common/{{ item.language }}.svg" class="dd-selected-image">
                    </span>
                    {{ country }}
                  </span>
                  <a class="lang-option" href="{{ item.absolute_url }}" data-country="{{ data }}" data-lang="{{ item.language }}">
                  {{name}} 
                  </a>
                </li>
              </ul>
            </li>
          {% endfor %}
        </ul>
        {% endif %}

And second question, in the articles, the switcher isn't the same as on blog-archive, how can i display only the languages whose articles are translated : 

{% if content.translated_content|length %}
        <ul class="dropdown menu country-list" data-dropdown-menu>
          {% set currLang = locale_name(locale) %}
          {% set codes = {'English' : 'en', 'Français' : 'fr', 'Français - France' : 'fr-fr', 'Nederlands - Belgium' :'nl-be', 'Français - Luxembourg' : 'fr-lu' } %}
          <li class="">
            <a class="lang-select" href="#"><img class="lang-flag" src="https://ressources.birdee.co/hubfs/{{ codes[currLang] }}.svg" data-country="{{ codes[currLang]| truncate (2, true, '') }}" data-lang="{{ codes[currLang] }}">{{ currLang }}</a>
          </li>
          <li class="menu desktop-lang">
            <ul class="others-lang--menu">
              {% for key, val in codes.items() %}
                
                {% if val == 'fr' || val == 'fr-fr' %}
                  {% set name = 'Français' %}
                  {% set country = 'France' %}
                  {% set data = 'fr' %}
                {% elif val == 'en' %}
                  {% set name = 'English' %}
                  {% set country = 'Europe' %}
                  {% set data = 'eu' %}
                {% elif val == 'fr-be' %}
                  {% set name = 'Français - Belgique' %}
                  {% set country = 'Belgique' %}
                  {% set data = 'be' %}
                {% elif val == 'nl-be' %}
                  {% set name = 'Nederlands - Belgium' %}
                  {% set country = 'Belgique' %}
                  {% set data = 'be' %}
                {% elif val == 'nl' %}
                  {% set name = 'Nederlands' %}
                  {% set country = 'Nederlands' %}
                  {% set data = 'nl' %}
                {% elif val == 'fr-lu' %}
                  {% set name = 'Français - Luxembourg' %}
                  {% set country = 'Luxembourg' %}
                  {% set data = 'lu' %}
                {% endif %}
                {% set URL = "/"~content.translated_content[val].slug || val %}
                <li class="menu desktop-lang">
                  <ul class="others-lang--menu">
                    <li class="other-lang">
                      <span class="langTitle">
                        <span class="flag">
                          <img src="https://ressources.birdee.co/hubfs/{{val}}.svg" class="dd-selected-image">
                        </span>
                        {{ country }}
                      </span>
                      <a class="lang-option" href="{{ URL }}" data-country="{{ data }}" data-lang="{{ val }}">{{key}}</a>
                    </li>
                  </ul>
                </li>
              {% endfor %}
            </ul>
          </li>
        </ul>

 i use the same code 😋 

Thank you very much. 

0 Upvotes
piersg
Key Advisor

Custom language switcher / Language switching

SOLVE

@ScottD22 Cool 👍what was it in the end?

0 Upvotes
ScottD22
Contributor | Diamond Partner
Contributor | Diamond Partner

Custom language switcher / Language switching

SOLVE

I deleted the blog field, re-added it with out the brackets and quote marks and it worked.

piersg
Key Advisor

Custom language switcher / Language switching

SOLVE

Great, glad we got it sorted! 

ScottD22
Contributor | Diamond Partner
Contributor | Diamond Partner

Custom language switcher / Language switching

SOLVE

Thanks for all your help piersg, I owe you a beer.

dennisedson
HubSpot Product Team
HubSpot Product Team

Custom language switcher / Language switching

SOLVE

@piersg is owed a lot of beers by a lot of people 🍻

piersg
Key Advisor

Custom language switcher / Language switching

SOLVE
piersg
Key Advisor

Custom language switcher / Language switching

SOLVE

This is what I've just tested with and it works, giving me the three most recent posts of whatever blog is selected in the editor.

 

{% set blog_id = module.blog_field %}
{% set posts = blog_recent_posts(blog_id, 3) %}
{% for post in posts %}
  {{post}}
{% endfor %}

 

 Are you sure your blog field's id is 'module.blog' and not 'module.blog_field', which is the default, and that you have (blog_id, 3) or (module.blog_field, 3) and not ('{{blog_id}}', 3)?

ScottD22
Contributor | Diamond Partner
Contributor | Diamond Partner

Custom language switcher / Language switching

SOLVE

FIXED.

piersg
Key Advisor

Custom language switcher / Language switching

SOLVE

Sorry, forgot the languageTag:

{% set currLang = content.language.languageTag %}
{% if group.language %}
  {% set currLang = group.language.languageTag %}
{% endif %}
{% if currLang == 'en-us' %}
  {% set currLang = 'USA' %}
{% endif %}

 

ScottD22
Contributor | Diamond Partner
Contributor | Diamond Partner

Custom language switcher / Language switching

SOLVE

 

{% set blog_id = module.blog %}

            {% set posts = blog_recent_posts('{{ module.blog }}', 3) %}
            
            {% for post in posts %}

            <a href="{{ post.absolute_url }}" class="card blog-single">

                {% if post.featured_image %}
                <div style="background-image:url('{{ post.featured_image }}'); background-size: cover;
                            height: 184px;
                            background-repeat: no-repeat;
                            background-position: top center;"
                     loading="lazy">
                </div>
                {% endif %}

                <div class="card-body d-flex flex-column align-items-start">

                    {% for topic in post.topic_list|first %}
                    <span class="tag">{{topic.name}}</span>
                    {% endfor %}

                    <h3>{{ post.name }}</h3>

                    <p>{{ post.meta_description|safe|striptags|truncate(60, False, '&hellip;') }}</p>


                    {% set initialPostWords = post.post_body|striptags|wordcount %}
                    {% set calculatedPostWords = (initialPostWords/100) * 100 %}
                    {% set finishedPostWords = calculatedPostWords|divide(300)|round(2) %}
                    {% set number = finishedPostWords|round %}
                    {% if number < 1 %}
                    {% else %}
                    <div class="d-flex align-items-center read-time">
                        <img src="https://f.hubspotusercontent40.net/hubfs/8149498/clock.svg" loading="lazy" width="18" height="18" alt="clock"/> {{ finishedPostWords|round }} min read
                    </div>
                    {% endif %}

                    <button class="no-style cta pointer">Read the full story</button>

                </div>

            </a>

            {% endfor %}

@piersgYou wouldn't happen to know how to get the language variation for recent posts would you?

 

 

0 Upvotes
piersg
Key Advisor

Custom language switcher / Language switching

SOLVE

@ScottD22 What do you mean by language variation? What language the recent post is written in? Or if the recent post has a translated version?

 

0 Upvotes
ScottD22
Contributor | Diamond Partner
Contributor | Diamond Partner

Custom language switcher / Language switching

SOLVE

@piersgWe have translated the blogs on a client site and I have a custom module ( code above ) on the homepage of the site which grabs 3 recent blog posts. Works great on the www.domain.us version of the site. We also have www.domain.nl site and the module still brings in the english version of the blogs even though I have a selector to switch to the blog ID to the dutch blog.

How can I use the code above to bring through the translated versions of the posts for the dutch site? Thank you. I've tried content.translated.content.absolute_url etc etc but that doesn't seem to work.

piersg
Key Advisor

Custom language switcher / Language switching

SOLVE

@ScottD22 Assuming that module.blog gives you the id correctly, i.e. a number as a string, you just need to change your blog_recent_posts to (no apostrophes, no delimiters):

{% set posts = blog_recent_posts(blog_id, 3) %}

 

0 Upvotes
ScottD22
Contributor | Diamond Partner
Contributor | Diamond Partner

Custom language switcher / Language switching

SOLVE

I tried this but it still outputs the English translation even though the blog ID matches the dutch ID

 

0 Upvotes