Omitting parts of URLs

I tried this example [Omitting the blog folder in URLs][1], and it works great for content structure like this:

../content/blog/page/page.txt

But I need to get it working for a more nested structure like this:

../content/blog/subdir/page/page.txt

How is this done?
Thank you so much!
[1]: http://getkirby.com/docs/advanced/routing#omitting-the-blog-folder-in-urls

1 Like

Sorry I haven’t had time to set up an example and test it, but try something like this in your config.php:

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

      $page = page($uid);
      if(!$page) $page = page($subdir. '/' . $uid);
      if(!$page) $page = page('blog/' . $subdir. '/' . $uid);
      if(!$page) $page = site()->errorPage();

      return site()->visit($page);
    }
  ),
  array(
    'pattern' => 'blog/(:any)/(:any)',
    'action'  => function( $subdir, $uid ) {
      
      return go( $subdir . '/' . $uid );
    }
  ),
));

Thanks that did the trick for subdirs, but now I’m stuck with the problem that it won’t work for the non-subdirs.

Here is what I tried without luck:

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

      $page = page($uid);
      if(!$page) $page = page($subdir. '/' . $uid);
      if(!$page) $page = page('clients/' . $subdir. '/' . $uid);
      if(!$page) $page = site()->errorPage();

      return site()->visit($page);
    }
  ),
  array(
    'pattern' => 'clients/(:any)/(:any)',
    'action'  => function($subdir, $uid ) {
      
      return go($subdir . '/' . $uid);
    }
  ),
  array(
    'pattern' => '(:any)',
    'action'  => function($uid) {

      $page = page($uid);

      if(!$page) $page = page('clients/' . $uid);
      if(!$page) $page = site()->errorPage();

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

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

So you have some posts inside /blog and some inside /blog/subdir/ ?

I think it would help if you provide an example of the file structure of your /content folder

It starts to get messy, but it sounds like you mean:


'pattern' => '(:any)/(:any)',
'action'  => function($subdir, $uid) {

  $stub = 'clients';
  $page = page($uid);
  if(!$page) $page = page($subdir. '/' . $uid); // something/else
  if(!$page) $page = page($stub . '/' . $subdir. '/' . $uid); // clients/something/else
  if(!$page) $page = page($stub . '/' . $uid); // clients/else
  if(!$page) $page = site()->errorPage();

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

My folder structure is as following (with my desired URLs below):

Page 1:
../content/admin/
http://view.mxr.at/admin/

Page 2:
../content/clients/client-a/
http://view.mxr.at/client-a/

Page 3:
../content/clients/client-a/page-a/
http://view.mxr.at/client-a/page-a/

I just tried your code and Page 1 (of course) and Page 3 are working fine. Only Page 2 is redirecting me to the error page. How can I bugfix this?

Thanks!

1 Like

I tried it on mine and the following works. However I believe there is a bug because it should have worked by just replacing :any with :all and using just one varialbe, instead of doing (:any)(:all)

c::set('routes', array(
   array(
      'pattern' => 'clients/(:all)',
      'action'  => function($uid) {
         go($uid);
      }
   ),
   array(
      'pattern' => '(:any)(:all)',
      'action'  => function($u1,$u2) {
         $page = page($u1.$u2);

         if(!$page) $page = page('clients/' . $u1.$u2);
         if(!$page) $page = site()->errorPage();

         return site()->visit($page);
      }
   )
));
4 Likes

Works!! Thank you so much!