Inner pages with custom URLs


#1

Hi there,

I’m having this site structure:

Industries
  - Life Sciences
    - Pharmaceuticals
      - Drug research Translation 

Now, the default URL:

domain.com/industries/life-sciences/pharmaceuticals/drug-research-translation/

However, I would like this URL:

domain.com/drug-research-translation/

How to do this? Thanks!


#2

This can be achieved with routes.
https://getkirby.com/docs/developer-guide/advanced/routing

If you need more examples, you can find them here in the forum


#3

Thanks! Time to read :nerd_face:


#4

Well, after some reading, I don’t have a clue where to start. Any points? Should I include a URL input field in the blueprint and then somehow make that work with a router?


#5

No, you don’t need anything in your blueprint, routing works automagically. Should be something like this if I haven’t made a mistake:

c::set('routes', array(
  array(
    'pattern' => 'industries/(:any)',
    'action'  => function($uid) {

      $page = page($uid);

      if(!$page) $page = page('industries/life-sciences/pharmaceuticals/' . $uid);
      if(!$page) $page = site()->errorPage();

      return site()->visit($page);

    }
  ),
  array(
    'pattern' => 'industries/life-sciences/pharmaceuticals/(:any)',
    'action'  => function($uid) {
      go('industries/'.$uid);
    }
  )
));

#6

Thanks, @texnixe, great help as always. However, my site structure was just an example, and in fact I will like to have any inner pages render as a root URL page. Consider the following structure:

  • Industries (URL: /industries)
    • Life Sciences (URL: /industries/life-sciences-translation-service)
      • Pharmaceuticals (URL: /industries/life-sciences-translation-service/pharmaceuticals-translations)
        • Drug Research Translation
          • (URL: /industries/life-sciences-translation-service/pharmaceuticals-translations/drug-research translations)

So basically I would like any second, third, and four level page to have a root URL, like:

2nd level
current: (URL: /industries/life-sciences-translation-service)
desired: (URL: /life-sciences-translation-service)

3rd level
current: (URL: /industries/life-sciences-translation-service/pharmaceuticals-translations)
desired: (URL: /pharmaceuticals-translations)

4th level
current: (URL: /industries/life-sciences-translation-service/pharmaceuticals-translations/drug-research translations)
desired: (URL: /drug-research translations)

How can I achieve this? Please note that in the first level, /industries/, we will have /services/, /blog/ and more.


#7

Well, basically like this then


c::set('routes', array(
  array(
    'pattern' => '(:any)',
    'action'  => function($uid) {

      // check if the page exists
      $page = page($uid);

      // then check here each level, so first industries and then each other level and the same for all other pages that have subpages
      if(!$page) $page = page('industries/' . $uid);
      if(!$page) $page = page('industries/life-sciences/' . $uid);
     // etc.
      if(!$page) $page = site()->errorPage();

      return site()->visit($page);

    }
  ),

  array(
    'pattern' => '(:all)/(:any)',
    'action'  => function($uri,$uid) {
      go($uid);
    }
  )
));

Keep in mind that you have to make sure that none of your pages on any level use the same URL, otherwise some of your pages won’t be accessible anymore (for example, if any of the subpages in one of the trees had the same UID as a subpage of one of the other page trees).


#8

Thanks @texnixe! Can you please explain what this part of the code does? I’m fairly new with programming and can’t understand the logic:

      if(!$page) $page = page('industries/' . $uid);
      if(!$page) $page = site()->errorPage();
  1. "if $page doesn’t exist, set $page to industries/ID"
  2. "if $page doesn’t exists, set $page to errorPage"

The !$page is confusing me. Thanks.


#9

Sure:

// we try to get a page by passing the uid to the page helper, this is true if the page exists and false if it doesn't
$page = page($uid);

      // so if $page is not a page (! = not), then we check if we get a page one level down, two levels down etc.
      if(!$page) $page = page('industries/' . $uid);
      if(!$page) $page = page('industries/life-sciences/' . $uid);
      // etc.
      // when after all that we still don't have a page, we redirect to the error page
      if(!$page) $page = site()->errorPage();

For logical operators, see here: http://php.net/manual/en/language.operators.logical.php


#10

Ahh, right. Simple. Thanks @texnixe!