Controller without template file?

Today I wanted to start with controllers. The controllers match the templates.

I have a controller called:

find-us.php

I have a blueprint called:

find-us.yml

I have no template, but the template name if it existed would have been find-us.php. Instead I’m using the Patterns plugin with if-statements to do different stuff with different templates.

Is there a way around it? Can I use a controller without having a template file?

Update - Workaround

I found a workaround that I don’t really like but it works. I create the find-us.php template and in that file I load the default template. Then it remembers the variables from the controller.

Code in find-us.php:

<?php echo tpl::load(kirby()->roots()->templates() . DS . 'default.php', array(), false );

You are welcome to add better suggestions to this problem.

No, Kirby loads the controller with the filename of the template that is used, not the intended template:

//kirby.php

 /**
   * Tries to find a controller for
   * the current page and loads the data
   *
   * @return array
   */
  public function controller($page, $arguments = array()) {

    $file = $this->roots->controllers() . DS . $page->template() . '.php';

    if(file_exists($file)) {

      $callback = include_once($file);

      if(is_callable($callback)) return (array)call_user_func_array($callback, array(
        $this->site(),
        $this->site()->children(),
        $page,
        $arguments
      ));

    }

Is that the best behaviour? I cannot think of when you would possibly want a default controller if the template file does not exist. What do you think?

I don’t really understand what you mean? You don’t have to have any controller at all, controllers are optional. All you need to have, is the default.php template.

I see now that I wrote it a little weird. I’ll try to explain better.

If the template that I use, only have a blueprint and not a template file, then the controller can’t match it because it does not exist (it only exists as blueprint). Instead it looks for a controller for the default template.

I think that is a little bit weird. I think it should match the indended template instead because that is what is setup in the blueprint as well as content. Then if the template file exists or not is not so important, I think.

What I try to say is, it should look at the blueprint and the content instead of the physical template file. Then it would still know what controller to use, not dependent of the physical template file.

Or is there any cases that we want it to fallback to look for the default controller (if it exists)?

As far as I can tell, it does not fall back to a default controller, in fact, Kirby uses the controller of the page that displays the page content, like the home controller if you build a single page website with only the home.php template and some snippets. Using patterns instead of snippets does not make any difference in this context.

I also do not get why you would want a controller based on intendedTemplate?

The controller is there to abstract stuff away from the template. In very simplified terms: Taking a lot of the PHP (logic) out of the template and just leave the display parts (HTML). That is a controller for an actual template.

What would you put into a controller for intendedTemplate? That controller would prepare things for a non-existent output/template. That leaves me confused.

And one more thing: If you were to call the intended template for each subpage within your templated page, you would end up with several different controllers for a single template, which does not really make sense, and you would have to be very careful with your logic (variables), so as not to end up with conflicting ones.

@texnixe @distantnative

Alright, you win! :slight_smile:

@distantnative I will explain how my code work, just so you know it from my perspective.

I use the Patterns plugin so I don’t use templates and snippets very much (almost not at all). Everything goes through the default-template and then into a pattern.

Then I have some if statements to find out what indended template is used. That way it builds a like a page template depending on the intended template and some other parameters. It works really great.

I’m using the workaround for now and it works fine, so I’m probably just going to leave it like that.

Thank you both!

Instead of using if statements in the default template, you could still use different templates that reference the patterns. I think this is more robust and easier to understand. But as long as it works for you, your solution is fine too. :slight_smile:

2 Likes

That was my thinking as well. Especially if the site becomes bigger, it will help to keep an overview of what elements are doing what.

Or if you want to be able to “change templates” via using patterns depending on user selection in the panel, you could still use templates or snippets to organize your patterns and call the snippets/templates in your main template, but then in those snippets, reference the patterns that belong to a “virtual template”.

1 Like

I’ll try that approach. Maybe it’s more in line of how it’s ment to work anyway.