Model class is defined or can be autoloaded?

https://getkirby.com/docs/developer-guide/plugins/registry

In the docs it says:

// Make sure that the class is defined or can be autoloaded

If a class is defined it’s inside a file that is included in for example a plugin, right?

But it also says “or can be autoloaded”. What does that mean? How do I autoload a class?

Result of the question

What I’m really after is to register a model in a correct way.

Is this correct?

class ProjectPage extends Page {
  public function cover() {
    return $this->image('cover');
  }
}

$kirby->set('page::model', 'project', 'ProjectPage');

Yes, that’s correct. Does it not work for you?

As regards autoloading, see https://secure.php.net/manual/en/language.oop5.autoload.php or composer autoloading: https://getcomposer.org/doc/01-basic-usage.md#autoloading

Ahh, I was confused by the autoload thing in the docs, but I made it work without the namespace with the code above.

However, namespaces is clearly not my strongsuit. I can’t make it work. Do you see what’s wrong here?

<?php
namespace JensTornell\Bricks;
use JensTornell\Bricks as Bricks;
use c;

//$plugins = new Bricks\Plugins();
//$register = new Bricks\Register();

class ProjectPage extends Page {
  public function cover() {
    return $this->image('cover');
  }
}

$kirby->set('page::model', 'project', 'Bricks\ProjectPage');

Also if you see any namespace improvement, I will listen to that as well. :slight_smile:

Your namespace is JensTornell\Bricks not just Bricks. And you need a backslash before Page.

<?php
namespace JensTornell\Bricks;
use c;
class ProjectPage extends \Page {
  public function cover() {
    return $this->image('cover');
  }
}

$kirby->set('page::model', 'project', 'JensTornell\Bricks\\ProjectPage');

I just eyeballed the source code on Github and you are almost there Jens.

Namespaces are useful for group classes under a given name. Let me show you the simplest way we could write your code:

<?php

namespace JensTornell\Bricks;

use c;
use Page;

// this belongs to the same namespace
// PHP will look for JensTornell\Bricks\Plugins
$plugins = new Plugins();
$register = new Register();

class ProjectPage extends Page {
  public function cover() {
    return $this->image('cover');
  }
}

// I think Kirby loader requires full class name
$kirby->set('page::model', 'project', 'JensTornell\Bricks\ProjectPage');

The namespace keyword defines the space in which the current class should belong to. In this case ProjectPage is the class and JensTornell\Bricks is the name of that space. The namespace will be prepended to the classname resulting in JensTornell\Bricks\ProjectPage (this is what you need to give to the register).

You don’t need to use the namespace keyword in a file if is not a class like you have in kirby-bricks.php and the lib/routes.php. You are same removing those.

When you set the namespace, PHP will look for classes inside that name. So without using c as you have above, PHP would look for JensTornell\Bricks\c which obviously doesn’t exist. You can use the use keyword when you need classes from other namespaces. Another option would be to just add a backslash before the class name like \c::get('…'). Remembering, this is for importing a class from outside the namespace you define at the top of the PHP file.

I couldn’t find a class named Bricks so you need to remove every instance of use JensTornell\Bricks as Bricks;.

The one trick I would use to avoid typing full class names is replacing JensTornell\Bricks\ProjectPage inside the register with ProjectPage::class (without quotes) which gives the full class name the register needs.

To better grasp namespaces, take a look at this article by Dayle Rees. I finally understood namespaces after reading that same article a few years ago. No

1 Like

Thank you both for your great replys! :slight_smile:

@texnixe

Your solution worked and as you say, the backslash before Page is really needed. I also found out that the backslash before ProjectPage in the set call is not needed. What is the reason for a backslash in there?

@pedroborges

The Page needed a backslash, so the solution did not fully work. However, you have been digging deep and there are some really interesting approaches in your reply that I will try. It will probably not only help me on this plugin, but in every plugin I create (I have about 50 plugins to maintain). :smiley:

1 Like

My bad that I overlooked the Page class. I have updated my response but used another valid solution to examplify what I said above.

But as @texnixe said, in this case I would also use the backslash since the Page class is used once.

1 Like