Switching languages with a specific order?

Hi there, I’m wondering if there is a way to sort languages with a specific order in a language switch navigation? When I use this snippet, everything works fine, but the order is alphabetical and I need a custom order > default language, secondary, third. I also tried flip() but the result is not what I want.
Ideally I would define the order in /site/languages/... like this:

return [
  'code' => 'en',
  'default' => true,
  'direction' => 'ltr',
  'locale' => 'en_Us',
  'name' => 'English',
  'order' => '1'
];

Any help is much appreciated :wink:

Doesn’t look like you can add a custom property like this nor is it possible to use the map() method like you can with other collections.

So I came up with this:

<?php

$langOrder = ['fr', 'de', 'en'];
$languages = $kirby->languages();
$orderedLanguages = new Kirby\Cms\Languages();

foreach($langOrder as $code) {
  $language = $languages->findBy('code', $code);
  $orderedLanguages->add($language);

}
foreach($orderedLanguages as $language) {
  echo $language->code();
}

Maybe not ideal, but works.

2 Likes

Thanks @texnixe, I guess my case in not so common :wink: When I try to implement your solution I get this error Call to a member function code() on null on this part:

foreach($orderedLanguages as $language) {
  echo $language->code();
}

Any idea?
Thanks in advance

What do you get if you do

foreach($orderedLanguages as $language) {
  dump($language);
}

I tested the code before I posted it, so it worked for me…

Your snippet works! The error came from the third language set to a wrong code name :no_mouth:
Thank you very much!

In case someone else is interested by the full snippet:

<?php

$langOrder = ['en', 'fr', 'de'];
$languages = $kirby->languages();
$orderedLanguages = new Kirby\Cms\Languages();

foreach($langOrder as $code) {
  $language = $languages->findBy('code', $code);
  $orderedLanguages->add($language);

}

foreach($orderedLanguages as $language) {
  $language->code();
}
?>

<nav>
  <ul>
    <?php foreach($orderedLanguages as $language): ?>
      <li <?php e($kirby->language() == $language, ' class="active"') ?>>
        <a href="<?= $page->url($language->code()) ?>"><?= html($language->name()) ?></a>
      </li>
    <?php endforeach ?>
  </ul>
</nav>

2 Likes