Class Latte\Macros\MacroSet not found
- RadaR
- Member | 46
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:
- 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 :(
- 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)
- Milo
- Nette Core | 1283
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)
- Milo
- Nette Core | 1283
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';", '');
};
- Milo
- Nette Core | 1283
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.
- RadaR
- Member | 46
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)
- Milo
- Nette Core | 1283
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?
- RadaR
- Member | 46
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)
- Milo
- Nette Core | 1283
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.