How to use the ->find() function with translated uris

Hi,

let’s assume, I have a german subpate with the uri ā€œunterseiteā€.
The same page exits in english with the uri ā€œsubpageā€.

The standard language is for example english. Now i want to search for the german subpage in a custom route like this:

# my custom route
# ...

site()->children()->find("unterseite");

#...

But this doesn’t work. Also the following doesn’t work:

# my custom route
# ...

site()->children()->find("unterseite")->content("de");

#...

What should i do? :smiley:

Have you tried findByURI()?

You should always use the UIDs/URIs of the default language in your routes as Kirby doesn’t know which language is active at that stage.

Mhh… Ok…

@texnixe: Now ->findByURI() works for the german uri, but not for the default language in my case.

@lukasbestle: Ok, is there a way to find the find the uri of the default language of a translated url? I don’t want to hard code my routes to much…

What you could try is to call site()->visit('something', 'de') (where something is an arbitrary page) before accessing the page by its localized URI. I haven’t tested this, but maybe Kirby will then know that you are looking for the German version.

I have a approach but it works not correctly. The suggestion of first calling
site()->visit('', 'de');
seems to work.

In the following code i can perform a
site()->children()->findBy('title', 'title of the visited language');
for example.

I found out, that kirby writes a key named url-key in the content files with translated urls. So my approach is, that i first visit the site with the needed language and then search for the url-key:


kirby()->routes(array(
  array(
    'pattern', '(((de|en)/)?((unterseite|subpage)/?(:all)))',
    'action' => function($fullPath, $langPath, $lang, $uri, $firstUriPart, $rest) {

      $lang = ($lang) ? $lang : 'en';

      site()->visit('', $lang);

      # find page if default language is active:
      $page = site()->children()->find($uri);

      # now this is what doesn't work
      if(!$page) $page = site()->children()->findBy('url-key', $uri);

      # but i wonder why, because the following would work:
      # if(!$page) $page = site()->children()->findBy('title', 'title of the translated page');

      if(!$page) go('error');

      # ... more code ...
    }
  )
));

Any ideas why findBy('url-key', '...'); doesn’t work?

Also untested, but the syntax should be just urlkey for the filter (the method names don’t contain dashes).

I’ve just tested it. But it doesn’t seems to work. In the content file the key is written with a dash.

@bastianallgeier: do you have a solution for this problem? Would be very nice. Otherwise i have to hard code the uri of the default language. Works, but is a bit ugly. :slight_smile:

Hello, did you find a way to solve it? I am dealing with the exact same problem…

This should work:

<?php echo $pages->findBy('urlkey', 'projekte')->url() ?>

but only for the page of the specific language. So you would have to wrap it in an if statement.

Sorry, it doesn’t seem to work for me neither…

Here is my code btw:

c::set('routes', array(
	array(
		'pattern' => '(en/|fr/)?(:any)',
		'action' => function ($lng, $slug) {
			$lng = trim($lng, '/');
			
			if ($lng) {
			
				return go(site()->findBy('urlkey', $slug)->children()->first()->url($lng));
				
			} else {
			
				return go(site()->find($slug)->children()->first()->url());
				
			}
			
		}
	)
));

I only tested this in a starterkit, not in a route.

In a multi-language install you have to use $site->visit(). Pls check out the docs.

Edit: I’m not quite sure if that pattern works, I think I’ve seen an issue somewhere … (can’t find it right now, though)

Thank you for your help, Texnixe.

Yes $site->visit() works fine when it’s okay to hard-code everything. But I plus @tobias, it would be great to have a way to query a page object from within a route, in multilanguage.

1 Like