Class Latte\Macros\MacroSet not found

5 years ago

RadaR
Member | 39
+
0
-

I have problem with David's example for standalone Latte API.

Before, I used whole Nette\Latte somehow like this:

require_once ('Nette/loader.php');

use Nette\Templating\FileTemplate;

$template = new FileTemplate();
$template->setCacheStorage(new Nette\Caching\Storages\PhpFileStorage(ROOT_PATH. 'cache/nette/'));
$template->registerHelperLoader('Nette\Templating\Helpers::loader');
$template->onPrepareFilters[] = function($template) {
    $latte = new Nette\Latte\Engine;
    $template->registerFilter($latte);

    $set = new Nette\Latte\Macros\MacroSet($latte->compiler);

    $set->addMacro(
        'SklkartaNazev',
        '$args = %node.array;echo ($args[0] == \'\' ? $args[1] : $args[0]);'
    );
};

Now, I would like to start using standalone Latte API in similar way. My problems / questions are:

  1. First, I got error message Fatal error: Class ‘Latte\Engine’ not found in…

OK, let's add some classes to my script:

<?php
require_once('Latte/Object.php');
require_once('Latte/Engine.php');
require_once('Latte/Compiler.php');
require_once('Latte/Template.php');
require_once('Latte/ILoader.php');
require_once('Latte/Parser.php');
require_once('Latte/Token.php');
require_once('Latte/Loaders/FileLoader.php');
require_once('Latte/Macros/CoreMacros.php');
require_once('Latte/Macros/MacroSet.php');
require_once('Latte/Macros/BlockMacros.php');
// (This is terrible. I think there is better way to do this...?)

$template = new Latte\Engine;
$template->setTempDirectory(__DIR__. '/cache/nette/');

$template->onCompile[] = function($template) {
    $template->addMacro(
        'SklkartaNazev',
        '$args = %node.array;echo ($args[0] == \'\' ? $args[1] : $args[0]);'
    );
};


$template->test = 'abc';
$template->render('test.htm', array());
?>

But, this is the end. I still got error message Fatal error: Class ‘Latte\Macros\MacroSet’ not found – even so class MacroSet.php is included. It does not work :(

  1. How I add my own custom macros? It's this way correct?
$template->onCompile[] = function($template) {
    $template->addMacro(
        'SklkartaNazev',
        '$args = %node.array;echo ($args[0] == \'\' ? $args[1] : $args[0]);'
    );
};

Unfortunately, I do not understand this http://goo.gl/d5A1u2

3. It's possible to use?

$template->setFile('test.htm');

4. What is variable $parameters? See:

$template->render('test.htm', $parameters);

Last edited by RadaR (2014-04-09 10:17)

5 years ago

Milo
Nette Core | 1126
+
0
-

Ad loading… Use Composer ;) Manual loader will be added. To solve Fatal, load MacroSet.php before CoreMacros.php. Full loadig can looks like:

EDIT: File latte.php exists in Latte repo now.

require __DIR__ . '/Latte/exceptions.php';
require __DIR__ . '/Latte/ILoader.php';
require __DIR__ . '/Latte/IMacro.php';
require __DIR__ . '/Latte/Runtime/IHtmlString.php';
require __DIR__ . '/Latte/Helpers.php';
require __DIR__ . '/Latte/Object.php';
require __DIR__ . '/Latte/Compiler.php';
require __DIR__ . '/Latte/Engine.php';
require __DIR__ . '/Latte/HtmlNode.php';
require __DIR__ . '/Latte/MacroNode.php';
require __DIR__ . '/Latte/Parser.php';
require __DIR__ . '/Latte/PhpWriter.php';
require __DIR__ . '/Latte/Template.php';
require __DIR__ . '/Latte/Token.php';
require __DIR__ . '/Latte/TokenIterator.php';
require __DIR__ . '/Latte/Tokenizer.php';
require __DIR__ . '/Latte/MacroTokens.php';
require __DIR__ . '/Latte/Loaders/FileLoader.php';
require __DIR__ . '/Latte/Loaders/StringLoader.php';
require __DIR__ . '/Latte/Macros/MacroSet.php';
require __DIR__ . '/Latte/Macros/BlockMacros.php';
require __DIR__ . '/Latte/Macros/CoreMacros.php';
require __DIR__ . '/Latte/Runtime/CachingIterator.php';
require __DIR__ . '/Latte/Runtime/Filters.php';
require __DIR__ . '/Latte/Runtime/Html.php';

Last edited by Milo (2014-04-22 11:12)

5 years ago

Milo
Nette Core | 1126
+
+1
-

Add macro… You get Engine in callback. The easist way is to use MacroSet

$engine = new Latte\Engine;
$engine->onCompile[] = function(Latte\Engine $engine) {
    $macroSet = new Latte\Macros\MacroSet($engine->getCompiler());
    $macroSet->addMacro('myMacro', "echo 'FOO';", '');
};

5 years ago

Milo
Nette Core | 1126
+
0
-

Add shortNoEscape It enables/disables ! syntax. So {!$var} will be allowed. But preferred way is to use {$var |noEscape}. It's better readable.

5 years ago

Milo
Nette Core | 1126
+
+1
-

Add render Parameters are “variables” in template.

# Instead of
$template->a = 'aaa';
$template->b = 'bbb';
$template->render();

# use
$params = array('a' => 'aaa', 'b' => 'bbb');
$engine->render('template.latte', $params);

Yeh, it is a new way. If you liked the old behaviour, make your own template like:

class MyTemplate
{
    private $parameters = array();

    public function __set($name, $value)
    {
        $this->parameters[$name] = $value;
    }

    public function & __get($name)
    {
        if (!array_key_exists($name, $this->parameters)) {
            trigger_error("Missing parameter '$name' in template.", E_USER_WARNING);
            return;
        }

        return $this->parameters[$name];
    }

    public function getParameters()
    {
        return $this->parameters;
    }

}

# and
$template = new MyTemplate;
$template->a = 'aaa';

$engine->render('my-page.latte', $template->getParameters());

Maybe there is a simplest way. I'm familiarizing with new API too.

5 years ago

RadaR
Member | 39
+
0
-

Oh, thank you very much for your time!

ad 1) I don't know what Composer is, it's a new for me. But your full-loading-code helped me :)

ad 2) My code now is:

require __DIR__ . '/Latte/exceptions.php';
require __DIR__ . '/Latte/ILoader.php';
require __DIR__ . '/Latte/IMacro.php';
require __DIR__ . '/Latte/Runtime/IHtmlString.php';
require __DIR__ . '/Latte/Helpers.php';
require __DIR__ . '/Latte/Object.php';
require __DIR__ . '/Latte/Compiler.php';
require __DIR__ . '/Latte/Engine.php';
require __DIR__ . '/Latte/HtmlNode.php';
require __DIR__ . '/Latte/MacroNode.php';
require __DIR__ . '/Latte/Parser.php';
require __DIR__ . '/Latte/PhpWriter.php';
require __DIR__ . '/Latte/Template.php';
require __DIR__ . '/Latte/Token.php';
require __DIR__ . '/Latte/TokenIterator.php';
require __DIR__ . '/Latte/Tokenizer.php';
require __DIR__ . '/Latte/MacroTokens.php';
require __DIR__ . '/Latte/Loaders/FileLoader.php';
require __DIR__ . '/Latte/Loaders/StringLoader.php';
require __DIR__ . '/Latte/Macros/MacroSet.php';
require __DIR__ . '/Latte/Macros/BlockMacros.php';
require __DIR__ . '/Latte/Macros/CoreMacros.php';
require __DIR__ . '/Latte/Runtime/Filters.php';

$template = new Latte\Engine;
$template->setTempDirectory(__DIR__. '/cache/nette/');
$template->onCompile[] = function(Latte\Engine $template) {
    $macroSet = new Latte\Macros\MacroSet($template->getCompiler());
    $macroSet->addMacro('myMacro', "echo 'FOO';", '');
};

//$template->test = 'Hello';
$template->render('test.htm', array('test' => 'Hello'));

But there is some problem remains…

New way to passing variables to template. Hmm… honestly, it's sucks :( Old method was better, straightest for me. I have written whole app by old way, I don't want to replace it. Unnecessary work.

I would like to use $template->setFile(path-to-template); But it seems to be not working.

My own macros still not working. When I use {myMacro} in template, I have got the message:
Fatal error: Uncaught exception ‘Latte\CompileException’ with message 'Missing {/myMacro} in test…htm

I thought that Latte API will provide same functionality as in Nette, but this is not the same… :(

Last edited by RadaR (2014-04-09 13:28)

5 years ago

Milo
Nette Core | 1126
+
0
-

RadaR wrote:
New way to passing variables to template. Hmm… honestly, it's sucks :(

It doesn't :) It is just more “low-level”.

Old method was better, straightest for me. I have written whole app by old way, I don't want to replace it. Unnecessary work.

That's because there was a mix between Latte and Template. Now are the Template a Latte separated concepts. Post here how you handled templates with latte in the old way and we can cretate an backward-compatible solution.

My own macros still not working. When I use {myMacro} in template, I have got the message:
Fatal error: Uncaught exception ‘Latte\CompileException’ with message 'Missing {/myMacro} in test…htm

Strange. Show me how do you register the macro and snippet of code from template.

I thought that Latte API will provide same functionality as in Nette, but this is not the same… :(

Latte becomes an alone project. It is great for next development. And I'm curious, why are you upgrading to new Latte API?

5 years ago

RadaR
Member | 39
+
0
-

It doesn't :) It is just more “low-level”.

That's right :)

That's because there was a mix between Latte and Template. Now are the Template a Latte separated concepts. Post here how you handled templates with latte in the old way and we can cretate an backward-compatible solution.

You already propose possible solution by the class MyTemplate. I will consider your suggestion and then I make a decision, what I will do.

Strange. Show me how do you register the macro and snippet of code from template.

My code:

require __DIR__ . '/Latte/exceptions.php';
require __DIR__ . '/Latte/ILoader.php';
require __DIR__ . '/Latte/IMacro.php';
require __DIR__ . '/Latte/Runtime/IHtmlString.php';
require __DIR__ . '/Latte/Helpers.php';
require __DIR__ . '/Latte/Object.php';
require __DIR__ . '/Latte/Compiler.php';
require __DIR__ . '/Latte/Engine.php';
require __DIR__ . '/Latte/HtmlNode.php';
require __DIR__ . '/Latte/MacroNode.php';
require __DIR__ . '/Latte/Parser.php';
require __DIR__ . '/Latte/PhpWriter.php';
require __DIR__ . '/Latte/Template.php';
require __DIR__ . '/Latte/Token.php';
require __DIR__ . '/Latte/TokenIterator.php';
require __DIR__ . '/Latte/Tokenizer.php';
require __DIR__ . '/Latte/MacroTokens.php';
require __DIR__ . '/Latte/Loaders/FileLoader.php';
require __DIR__ . '/Latte/Loaders/StringLoader.php';
require __DIR__ . '/Latte/Macros/MacroSet.php';
require __DIR__ . '/Latte/Macros/BlockMacros.php';
require __DIR__ . '/Latte/Macros/CoreMacros.php';
require __DIR__ . '/Latte/Runtime/Filters.php';

$template = new Latte\Engine;
$template->setTempDirectory(__DIR__. '/cache/nette/');
$template->onCompile[] = function(Latte\Engine $template) {
    $macroSet = new Latte\Macros\MacroSet($template->getCompiler());
    $macroSet->addMacro('myMacro', "echo 'FOO';", '');
};

$template->render('test.htm', array('test' => 'Hello'));

And my template file (it's pretty simple):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
    <title>New document</title>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
</head>
<body>

{$test}
{myMacro}

</body>
</html>

This generate error Fatal error: Uncaught exception ‘Latte\CompileException’ with message 'Missing {/myMacro} in…

EDIT: Huh… I found it! Error say Missing {/myMacro}. I'm blind :) When I alter my template to this:

{myMacro}{/myMacro}

it works. But how I create unpaired macro? I need something like this:

{myMacro $param1, $param2}

Latte becomes an alone project. It is great for next development. And I'm curious, why are you upgrading to new Latte API?

I used Nette only for his Latte templating functions. Latte is perfect and amazing :) I needed any handy templating system and I have choose Latte. I spent about 2–3 months (from november 2013) to remade my project for using Latte. Meanwhile David Grudl make a decision not participate to Nette anymore and split its work into small packages.

Only what I need is Latte. That's why I'm trying “new” Latte API. I thought that Latte API will be the same as Nette\Latte, but without too manyy unneccessary files from whole Nette framework :)

Last edited by RadaR (2014-04-09 22:29)

5 years ago

Milo
Nette Core | 1126
+
0
-

RadaR wrote:

{myMacro}{/myMacro}

it works. But how I create unpaired macro? I need something like this:

{myMacro $param1, $param2}
$macroSet->addMacro('myMacro', "echo 'FOO';"); # just ommit 3rd param

I used Nette only for his Latte templating functions. Latte is perfect and amazing :) I needed any handy templating system and I have choose Latte. I spent about 2–3 months (from november 2013) to remade my project for using Latte. Meanwhile David Grudl make a decision not participate to Nette anymore and split your work into small packages.

Only what I need is Latte. That's why I'm trying “new” Latte API. I thought that Latte API will be the same as Nette\Latte, but without too manyy unneccessary files from whole Nette framework :)

I see. When you will solve back compatibility you can check out current Framework source. Framework uses Latte with new API but it leaves some deprecated classes just for BC purpose.

5 years ago

RadaR
Member | 39
+
0
-

Thank you very much, for your time and your help!