Routing and breadcrumbs

Hi,

I have a router that redirects each parent/inner-page to a root level, as explained here: Inner pages with custom URLs.

Now, when I use the breadcrumb example mentioned in the docs, it produces links to the “real” URLs, not the routed ones. For example:

financial-translation-services <--- routed page
professional-translation-services/financial-translation-services <--- real URL

Naturally, I would like breadcrumbs to point to the routed URLs and not the “real” URLs. Is there a way to accomplish this? Thanks.

Yes, you can create a page model for those pages, where you overwrite the url() method for those pages. This is not only relevant for the breadcrumb but also for other links to the page.

Edit: Please keep in mind that you have to do this for each template separately, because a page model is tied to a template.

Sounds good. I have a default-has-cta.php template and content files as default-has-cta.txt. When I’m trying to do:

<?php

class default-has-ctaPage extends Page {
  function url() {
    return url($this->uid());
  }
}

?>

I got this error:

ParseError
syntax error, unexpected 'default' (T_DEFAULT), expecting identifier (T_STRING)

Any ideas?

Yep, you can’t use dashes in class names: http://php.net/manual/en/language.oop5.basic.php

Contrary to what we usually suggest, in this case I’d use camelCasing for the file names, but make sure you use this throughout for text files, blueprints, templates, controllers and page models, so that you don’t run into issues with file name compatibility due to case sensitivity on different operating systems. An alternative would be to use underscores.

Great! I changed it to defaulthasctaPage and the page is loading, but not the content. I assume the code in

function url() {
  return url($this->uid());
}

is not running. Took it from here.

What would be the way to overwrite the URL method? For reference, the code for the breadcrumbs is:

<?php foreach($site->breadcrumb() as $crumb): ?>
        <li>
          <a href="<?= $crumb->url() ?>">
            <?= html($crumb->title()) ?>
          </a>
        </li>
 <?php endforeach ?>

Have you changed the template/controller/textfile names?

The code is correct and should work as expected. Since the model overwrites the default method everywhere the page is used, you don’t have to change anything in your template/snippet etc. code.

Yes, renamed the template to defaultHasCta.php and renamed the .txt files to defaultHasCta.txt.

Now, when I create the defaultHasCta.php file in site/models, it triggers this error:

Error
Class 'defaultHasCtapage' not found

The errors is triggered even with an empty defaultHasCta.php. What could be happening here?

Hm, seems it doesn’t work with camelCasing nor with underscores, I’m afraid you have to go for defaulthascta.php.

Edit: I tested this again and found that if you use underscores in your filenames, e.g. model default_has_cta.phpand then in the model file itself camelCasing, it seems to work:

class defaultHasCtaPage extends Page {
  function url() {
    return url($this->uid());
  }
}

Thanks for going the extra mile and testing this! Unfortunately it’s not working on my local version. What I did:

  • changed all .txt files to default_has_cta.txt
  • changed template to default_has_cta.php
  • added model default_has_cta.php with class defaultHasCtaPage extends Page {…

I can’t see any content rendered. An inspection of the page shows that PHP stops at the first occurrence of <?= url() ?> (like in the header navigation).

I’m not sure what I’m doing wrong…

And what is the error message now? The same as before?

This is strange. I now tested this again with an all fresh Starterkit. Renamed all article.extension files to default_has_cta.extension.

The added default_has_cta.php in site/models like this:

<?php

class DefaultHasCtaPage extends Page {
  function url() {
    return url($this->uid());
  }
}

When I open the blog page, all is fine and the urls are as expected.

There’s no error. It just shows the page up to the point where a <?= url() ?> appears. After that, PHP just stops processing the page. Screenshot here: https://cl.ly/2m200d0w2j36

It’s eventually something with the filename. If I delete the model (currently, default_has_cta.php) everything works as expected!

I will just rename this to alternate.php and let you know :slight_smile:

So, not even working with his new change! Worst thing is that I can’t debug even with forcing debug mode in config.php .

  • changed all .txt files to alternate.txt
  • changed template to alternate.php
  • changed blueprint to alternate.yml
  • added model alternate.php inside site/models/ with class AlternatePage extends Page {…

Again, if I remove the model, or rename it, the website works. If I don’t, it just stops loading from the first appearance of <?= url() ?>. Even in those pages where that template+model combination is not used.

Hm, I can’t reproduce this. Why are you using these url() helpers everywhere?

Something seems to be conflicting, but I can’t solve this here, I’m afraid, without access to the project.

Using them for creating absolute paths in navigation, like in:

<ul class="header-links pages-menu">
    <li><a href="<?= url('/professional-translation-services/') ?>">Services</a></li>
    <li><a href="<?= url('/references/') ?>">References</a></li>
    <li><a href="<?= url('/translation-company/') ?>">About Us</a></li>
    <li><a href="<?= url('/contact/') ?>">Contact</a></li>
  </ul>

Please let me know your Kirby version and your PHP version. As an alternative, you could send me the project.

As an alternative, you could use a custom page method that returns the URL for all pages. If you don’t use any subpage URLs, then you can do this:

page::$methods['myUrl'] = function($page) {
  return url($page->uid());
};

If there are some pages that use subpages URLs, you would have to adapt this code with an if statement.

Then replace all occurrences of a $page->url() method in your project with $page->myUrl().

Hi! Just sent you a PM. Thanks.

For anyone running into this: The problem occurs when in a nested structure all subpage folders are omitted from the URL via a route and all these subpages use the same template. Adding a Page model that redefines the URL then causes a PHP error.

More here: https://github.com/getkirby/kirby/issues/640

This can be prevented by using different templates/page models for the different nesting levels.