Using several template loaders

Wintermute
Member | 11
+
0
-

Hello !

I use Latte as templating system in my PHP framework, Bluebird. I writing a CMS based on my framework : http://lemoncms.tuxfamily.org/

I want to be able to use templates stored in database, as well as template files.

So I wrote a LatteDatabaseLoader class that implements Latte\ILoader and allows to use templates stored in database.
FYI this class uses the Medoo library.

I wrote a LatteCascadingLoader class (that implements Latte\ILoader as well) that allows to use several loaders. FYI I was inspired by an equivalent mechanism in Mustache templating system.

It works quite well, except when I have 2 templates files with the same name in different directories.

I believe that the problem lies in the implementation of the getUniqueId() method in my LatteCascadingLoader class.

Could you help me to write a working implementation of LatteCascadingLoader::getUniqueId() ?

Last edited by Wintermute (2021-01-08 06:42)

David Grudl
Nette Core | 8108
+
+1
-

Let your every loader return unique id, for example:

class LatteDatabaseLoader implements Latte\ILoader
{
	public function getUniqueId( $name ) {
       $val = $this->getValue( 'id', $name );  // or any column
        if ( empty( $val) ) {
            throw new RuntimeException( sprintf( 'Template "%s" does not exist.', $name ) );
        }
         return 'database/' . $name; // return unique name
    }
}

and LatteCascadingLoader then can return inner loader unique id:

class LatteCascadingLoader implements Latte\ILoader
{
	public function getUniqueId( $name ) {
        foreach ( $this->loaders as $loader ) {
            try {
                return $loader->getUniqueId( $name );
            } catch ( RuntimeException $e ) {

            }
        }
        throw $e;
    }
 }

I think it should work.

Wintermute
Member | 11
+
0
-

Hello,

Thanks for your answer.

That's what I did. In order to make it work I also had to extend FileLoader by overriding getUniqueId :

class LatteFileLoader extends Latte\Loaders\FileLoader {

    /**
	 * Returns unique identifier for caching.
	 * @return string
	 */
    public function getUniqueId( $name ) {
        $name = parent::getUniqueId( $name );
        if ( file_exists( $name ) ) {
            return $name;
        }
        throw new RuntimeException();
    }
}

It works well now.

Should I also do the same with the method getReferredName() ? What exactly is the purpose of this method ?

Last edited by Wintermute (2021-01-12 00:54)

Wintermute
Member | 11
+
0
-

Hello,

Eventually I didn't change getReferredName().

It works well.

I pushed all the modifications to my Git repository :

The PageController of my CMS adds a LatteDatabaseLoader in order to use templates stored in database (l. 146).

Do not hesitate to give me your feedback.

Last edited by Wintermute (2021-01-16 01:05)