For my portfolio site i want all my works, which are structured under works/… to appear without their parent name (so that /works/designproject would become /designproject). This is my attempt at making that happen:
return [
'debug' => true,
'routes' => [
[
'pattern' => '(:any)',
'action' => function($uid) {
$page = page($uid);
if(!$page) $page = page('works/' . $uid);
if(!$page) $page = site()->errorPage();
return site()->visit($page);
}
],
[
'pattern' => 'works/(:any)',
'action' => function($uid) {
go($uid);
}
]
],
];
My issue: some of my works have subpages (in the style of works/designproject/gallery or even works/designproject/gallery/imagepage), which don’t seem to get rerouted and still show with the original works/…
Also it seems that drafts and unlisted pages don’t work properly across the site since i added the routes.
(:any)
only refers to anything until the next slash. so you either need additional routes, or you need to use (:all)
instead of any to handle all possible patterns.
thank you, changing (:any) to (:all) seems to send me to the right link now, but everything beyond the first level after the now removed /works results in the error page, where did i go wrong?
'routes' => [
[
'pattern' => '(:any)',
'action' => function($uid) {
$page = page($uid);
if(!$page) $page = page('works/' . $uid);
if(!$page) $page = site()->errorPage();
return site()->visit($page);
}
],
[
'pattern' => 'works/(:all)',
'action' => function($uid) {
go($uid);
}
]
],
You need to also adapt the first route, otherwise it doesn’t work. But you need to be careful not to return the error page after the first check doesn’t return a page, otherwise all other valid pages will fail. So if no a page, better call $this->next()
.
okay, now manually typing in the links works, but the automatic link includes /works now (if i click on designproject in /works it goes to /works/designproject even though /designproject is also a valid link, and also when i click on gallery in /designproject it turns into /works/designproject/gallery, etc.).
'routes' => [
[
'pattern' => '(:all)',
'action' => function($uid) {
$page = page($uid);
if(!$page) $page = page('works/' . $uid);
if(!$page) $page = $this->next();
return site()->visit($page);
}
],
[
'pattern' => 'works/(:all)',
'action' => function($uid) {
go($uid);
}
],
],
Ok, the problem is that the first route is too greedy, you need to turn their order round, or exclude works/something
from the first route.
And there is also a problem in the first route, should be
'pattern' => '(:all)',
'action' => function($uid) {
$page = page($uid);
if(!$page) $page = page('works/' . $uid);
if ($page) {
return site()->visit($page);
}
$this->next();
}
amazing this seems to work, thank you so much!
going through it a bit more, and it seems that download links on my subpages are not working, which seems to have something to do with the routing. clicking doesnt do anything on firefox and downloads the page html on safari
and also, when i hover over the links that get generated by kirby on the page, they still want to go to the /works/… page, is there a way to change that as well?
okay, i will try to figure that out somehow, will that also solve the issues with the download links?
Probably not, can you give an example of such a download url that does not work?
the issue is online on my page, if you go to struggle | falk, the download link does not work.
okay i just seemingly solved this issue by using a files field instead of trying to get the archive directly from the files section.
anyway, thanks to your help, this is how i seem to have solved my issues:
page model:
<?php
use Kirby\Cms\Page;
class DefaultPage extends Page
{
public function url($options = null): string
{
if ($this->kirby()->multilang() === true) {
if (is_string($options) === true) {
return $this->urlForLanguage($options);
}
return $this->urlForLanguage(null, $options);
}
if ($options !== null) {
return Url::to($this->url(), $options);
}
if (is_string($this->url) === true) {
return $this->url;
}
if ($this->isHomePage() === true) {
return $this->url = $this->site()->url();
}
if ($parent = $this->parent()) {
if ($parent->isHomePage() === true) {
return $this->url = $this->kirby()->url('base') . '/' . $parent->uid() . '/' . $this->uid();
}
// my addition
if ($parent -> uid() === 'works') {
return $this->url = $this -> kirby() -> url('base') . '/' . $this -> uid();
}
return $this->url = $this->parent()->url() . '/' . $this->uid();
}
return $this->url = $this->kirby()->url('base') . '/' . $this->uid();
}
}
routing:
'routes' => [
[
'pattern' => 'works/(:all)',
'action' => function($uid) {
go($uid);
}
],
[
'pattern' => '(:all)',
'action' => function($uid) {
$page = page($uid);
if(!$page) $page = page('works/' . $uid);
if ($page) {
return site()->visit($page);
}
$this->next();
}
],
],
i am open to feedback on whether any of this could be improved, otherwise i am so grateful for all of your help, thank you so much!