Omitting folder in URLs and prevent people visiting said folder

Hello all, I am in need of a little help.

I have a folder called Authors containing a bio page for each author. I would like people to be able to visit the bio page of each author but not be able to visit the ‘Authors’ page. Also I would like the URL to be /author/joe-bloggs rather than /authors/joe-bloggs. ( I am trying to mimic the Ghost blog system in Kirby).

How can I use routing to achieve this? Will I need a redirect too?

Thanks

Why make things complicated? The easiest way is to call the folder author instead of authors :wink:

Then all you need is a route that redirects author to the error page.

c::set('routes', [
  [
    'pattern' => 'author',
    'action' => function() {
       return go('error', 404);
    }
  ]
]);

Othewise, keeping the current structure, change the pattern to authors and add two more routes that take care of omitting the authors folder and instead use author. See example of omitting the blog folder in the docs.

https://getkirby.com/docs/developer-guide/advanced/routing

3 Likes

Yes that did occur to me but it broke my site because in my article template I have used:

$author = $pages->find('authors/' . $article->author())

<?= $author->title()->html() ?>

Which gives me ‘Bob Meowerly’

If I use:

$author = $article->author()

I get ‘bob-meowerly’.

Any idea how to get around that?

I will read up on routing.

If you call. the folder author instead of authors, you have to change this line:


$author = $pages->find('authors/' . $article->author())

to

$author = $pages->find('author/' . $article->author())

This wouldn’t be necessary, if you saved the uri of the author instead of the uid in your select field

author:
  label: Author
  type: select
  options:
    page: author
    fetch: children
    value: '{{uri}}'

In your template, you could then fetch the author like this:

if($author = $article->author()->toPage()):
  echo $author->title();
}

Note that I use an if statement here to make sure I really have a page object before I call any method like title() etc.

1 Like

Ah thanks texnixe, that is brilliant. I love Kirby support!

One more thing, how do I get the full URL from the URI?

I would like the author name to also link to their bio page.

Once you have the page object, you can use all page methods, including url()

if($author = $article->author()->toPage()):
 echo $author->title();
  echo $author->url();
}
<?php if($author = $article->author()->toPage()): ?>
  <a href="<?= $author->url() ?>"><?= $author->title()->html() ?></a>
<?php endif ?>
1 Like

I really need to learn more about this…

Thanks again :grinning:

You are welcome. Yes, it makes things easier once you have a better understanding of all this stuff…

I have one small issue saving the uri of the author. When I search ‘jane doe’ I get no results. If I search ‘jane’ or ‘doe’ I get the expected results. I imagine this is because of the hyphen in the uri.

Author: author/jane-doe

I am using the plugin search controller with this modification

Is there a solution for this? Perhaps I can save a hidden field with the author title?

Yes, a hyphen is a word character, so john-doe is regarded as one word. Although I must admit I don’t understand why jane or doe yield a result then, if you limit your search to complete words :thinking: However, it should possible to modify the regex or rather add an if-else statement; but yes, you could use a panel.page.update hook to store the title of the field (i.e. the author’s name) in a hidden field.

1 Like