Filtering untranslated pages with Kirby 2.3

I’ve used the custom filter by @moritzz and @texnixe on a lot of Kirby pages.

site/plugins/filters.php:

<?php
// Anything that matches a given language attribute
collection::$filters['languageIs'] = function($collection, $field, $value) {

  foreach($collection->data as $key => $item) {
    if (collection::extractValue($item->content()->language(), $field) != $value) {
      unset($collection->$key);
    }
  }
  return $collection;
};

Menu:

<?php foreach($pages->visible()->filterBy('code', 'languageIs', $site->language()->code()) as $p): ?>
...

TL;DR of the filter: If the page is not translated, don’t list it.

It works flawlessly on installations with Kirby 2.2, but I recently wanted to use it with a 2.3 installation and it won’t list a single page. I made a backup of the old pages where it worked, replaced the Kirby folder with a 2.3 variant and it’s the same issue.

I know Kirby 2.3 introduced the isTranslated() function, but why won’t the old variant work?

Could anybody of you try to replicate this? Thank you! :heart:

@thguenther, this does not seem to work anymore, see this post: Yet another question about not showing untranslated pages

1 Like

Thank you @texnixe, I’ve not seen that topic.

Maybe someone should edit the custom filter post with a disclaimer? “Does not work on Kirby 2.3 and up” or something. It’s ranked pretty high for google searches like “getkirby avoid translation fallback”, “getkirby filter not translated” etc.

Yeah, you are right, I have to make a note to change that. I just haven’t looked into why it doesn’t work anymore.

I couldn’t figure it out either. Weird.

For anyone stumbling over this thread and having the same issues:
I put this in plugins/page-methods.php:

<?php
page::$methods['hasTranslation'] = function($page) {
  $content = f::read( $page->textfile() );
  if(empty($content)) {
    return false;
  }
  else {
    return true;
  }
};

So you can check if a page is translated simply by calling $page->hasTranslation(). Thanks @jenstornell for the idea.

EDIT:

An even simpler approach is to define the page method as a custom pages method like that:

<?php
pages::$methods['onlyTranslated'] = function($pages) {
  return $pages->filter(function($page) {
    $content = f::read( $page->textfile() );
    if( empty( $content ) ) {
      return false;
    }
    return true;
  });
};

That way you can filter the pages with the addition of ->onlyTranslated() just like you do with something like ->visible.

A menu foreach looks a lot cleaner then:

<?php foreach($pages->visible()->onlyTranslated() as $p): ?>
1 Like

Ahh, I thought it was just me. However I would like to have that back in the core as well. :slight_smile:

Added an issue because I had the same problem.

1 Like

You can simplify that code like this:

pages::$methods['onlyTranslated'] = function($pages) {
  return $pages->filter(function($page) {
    return $page->content(site()->language()->code())->exists();
  });
};
```
1 Like

Amazing, thank you @texnixe! That looks way better. :thumbsup: