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