Language icon instead of text and conditional logic question

I have two questions related to languages:

  1. I have the following code in my header.php for switching between existing languages (excluding the currently active one):
    <nav class="languages">
      <ul>
        <?php foreach($kirby->languages()->not($kirby->language()) as $language): ?>
        <li<?php e($kirby->language() == $language, ' class="active"') ?>>
          <a href="<?= $page->url($language->code()) ?>" hreflang="<?php echo $language->code() ?>">
            <?= html($language->name()) ?>
          </a>
        </li>
        <?php endforeach ?>
      </ul>
    </nav>   

How can I show a flag unicode emoji instead of the name such as :de:?

  1. The following code always links to the error page, no matter if I am on a translated page or not:
    <nav class="languages">
      <ul>
      <?php foreach($kirby->languages()->not($kirby->language()) as $language): ?>
        <li<?php e($kirby->language() == $language, ' class="active"') ?>>
          <a href="<?php e($page->content($language->code())->language() != $site->language($language->code()), page('error')->url($language->code()), $page->url($language->code()))?>"><?php echo $language->code(); ?></a>
        </li>
      <?php endforeach ?>
      </ul>
    </nav>

Why is that and how can I fix it?

Thanks in advance.

$site->language

Is not a valid method. You probably want $kirby->language().

I copied that directly from Switching languages in the frontend | Kirby CMS and also changing “site” to “kirby” didn’t solve the problem.

The documentation is definitely wrong there, a leftover from Kirby 2, I assume.

and calling $language on the content object doesn’t make sense either.

What exactly do you want to compare here?

I just started with Kirby today and wanted to show a specific page always if there is no translation for the current page available.

You can check if a content translation exists with:

if ($page->translation('en')->exists()) {
  // do stuff
}
1 Like

Thanks, I will give it a try!
Do you also have a solution in mind for the visual representation of the available language instead of showing the name?

Sorry, I’m totally against using flags for language switchers, because flags are no language representations (Why flags do not represent languages – Flags are not languages).

But if you absolutely want, you can of course integrate icons instead of strings or additionally.

1 Like

Thanks for pointing that out, didn’t thought about it.
Just out of curiosity and to learn more about Kirby: how would it be possible?

That depends, you can just use svg files and directly include them in the html. Or use other image types in an image tag. Or even emojis.

How could I do this without a hard-coded language but a dynamic logic? Whenever there is a translation available other than the currently active language?

Regarding the svg or emoji I wasn’t sure where and if to include in the mentioned code.

You need a way to assign available icons to your languages. If you want this to be dynamic, i.e. have icons for all possible languages, then you need of course a lot of icons.

You can create a connection between languages and icons by filename, e.g. en_US.svg or create an array of matching language code values/icon names in your config, for example.

Then grab the icon from this information in your loop. Again, as @pixelijn already pointed out, I don’t think it’s a good idea.

If you have a look at large companies, none of them uses flags anymore these days.

Sorry, but the question was related to the code snippet of @pixelijn which is a hard-coded for English. I would like to know how to do this universally (whenever there is a a translation available other than the active language).

Ah, you mean this one?

Inside your loop, you have access to the $language object, so you can replace en with $language->code()(as you already did in your original code).

That throws up an error message “Call to a member function code() on null”:

    <nav class="languages">
      <ul>
      <?php if ($page->translation($language->code())->exists()):?>
        <?php foreach($kirby->languages()->not($kirby->language()) as $language): ?>
        <li<?php e($kirby->language() == $language, ' class="active"') ?>>
          <a href="<?= $page->url($language->code()) ?>" hreflang="<?php echo $language->code() ?>">
            <?= html($language->name()) ?>
          </a>
        </li>
        <?php endforeach ?>
      <?php endif ?>
      </ul>
    </nav>   

You are calling this before $language is defined, this has to go inside the loop

Thanks, that did the trick but how would I show a Headline “Languages” only once and only if there are other languages available?
As the if clause is now part of the foreach loop it would appear as many times as there are languages available.

You would have to filter your languages collection by whether a translation exists first, then check if the collection has items, and only then go into the loop.

@texnixe Can you please update / fix the guide for Switch C as @pixelijn has mentioned?

Sure done.

1 Like