Přidání vlastního makra do Latte
- RadaR
- Člen | 46
Sice si připadám, že poněkud „tapetuju“, ale nenašel jsem zde na fóru aktuální a kloudně fungující postup, jak přidat vlastní makro do Latte.
Používám Latte samostatně a inicializuji jej takto:
<?php
use Nette\Templating\FileTemplate;
$template = new FileTemplate();
$template->setCacheStorage(new Nette\Caching\Storages\PhpFileStorage('cache/nette/'));
$template->registerHelperLoader('Nette\Templating\Helpers::loader');
$template->onPrepareFilters[] = function($template) {
$template->registerFilter(new Nette\Latte\Engine);
};
?>
Postupoval jsem podle popisu Šablony – vlastní makra a zplodil něco takového:
<?php
$latte = new Nette\Latte\Engine;
// vytvoříme si sadu
$set = new Nette\Latte\Macros\MacroSet($latte->compiler);
// do sady přidáme makro
$set->addMacro(
'pokus', // název makra
"echo 'POKUS abc'" // PHP kód nahrazující otevírací značku
);
?>
Tento kód projde bez chyby, ale když se v šabloně pokusím makro zavolat {pokus}, dozvím se, že „Uncaught exception ‚Nette\Latte\CompileException‘ with message 'Unknown macro {pokus} in …“
Z toho co jsem hledal, jsem vyrozuměl, že musím makro nejprve zaregistrovat. A tuším problém v tom, že znovu vytvářím „new Nette\Latte\Engine“… ale s tím už si nevím rady.
Editoval RadaR (20. 1. 2014 14:52)
- David Matějka
- Moderator | 6445
nejjednodussi zpusob je vytvorit si vlastni macroset (viz treba CoreMacros,
dulezita je metoda install)
a registrovat v neonu
nette:
latte:
macros:
- MyMacroSet
- Jan Tvrdík
- Nette guru | 2595
$template->registerHelperLoader('Nette\Templating\Helpers::loader');
$template->onPrepareFilters[] = function($template) {
$latte = new Nette\Latte\Engine();
$compiler = $latte->getCompiler();
$compiler->addMacro(...);
$template->registerFilter($latte);
};
- RadaR
- Člen | 46
Jan Tvrdík napsal(a):
$template->registerHelperLoader('Nette\Templating\Helpers::loader'); $template->onPrepareFilters[] = function($template) { $latte = new Nette\Latte\Engine(); $compiler = $latte->getCompiler(); $compiler->addMacro(...); $template->registerFilter($latte); };
Díky, toto vypadalo nadějně, ale když jsem to hodil do skriptu
<?php
use Nette\Templating\FileTemplate;
$template = new FileTemplate();
$template->setCacheStorage(new Nette\Caching\Storages\PhpFileStorage('cache/nette/'));
$template->registerHelperLoader('Nette\Templating\Helpers::loader');
$template->onPrepareFilters[] = function($template) {
$latte = new Nette\Latte\Engine();
$compiler = $latte->getCompiler();
$compiler->addMacro(
'pokus', // název makra
"echo 'pokus'" // PHP kód nahrazující otevírací značku
);
$template->registerFilter($latte);
};
?>
tak v případě, že mám někde v šabloně zavolané to makro, dostanu chybovou hlášku: „Catchable fatal error: Argument 2 passed to Nette\Latte\Compiler::addMacro() must implement interface Nette\Latte\IMacro, string given, called in C:\xampp\htdocs…“
Koukal jsem na metodu Nette\Latte\Compiler::addMacro a to má dva parametry: ($name, IMacro $macro) – ale z chybového hlášení jsem nepochopil, co se mu nelíbí na tom druhém parametru.
- RadaR
- Člen | 46
romiix.org napsal(a):
Nepáči sa mu, že tam dodávaš
string
a nieIMacro
.
Tak až natolik si to přeložit dokážu :) Ale spíš nechápu, co tam mám poslat za parametr, čili jak ten problém vyřešit.
V příkladu se také posílají samé stringy, viz:
<?php
$set->addMacro(
'try', // název makra
'try {', // PHP kód nahrazující otevírací značku
'} catch (\Exception $e) {}' // kód nahrazující uzavírací značku
);
?>
- romiix.org
- Člen | 343
V prvom príspevku používaš metódu addMacro z Nette\Latte\Macros\MacroSet a na konci addMacro z Nette\Latte\Compiler.
Riešenie od matej21 ti nefunguje?
Editoval romiix.org (21. 1. 2014 10:00)
- RadaR
- Člen | 46
romiix.org napsal(a):
V prvom príspevku používaš metódu addMacro z Nette\Latte\Macros\MacroSet a na konci addMacro z Nette\Latte\Compiler.
Riešenie od matej21 ti nefunguje?
Aha, už ten rozdíl vidím – míchám hrušky s jablky :( Nicméně mne to stále není jasné.
Ad matej21 – přiznám se, že jsem jeho radu nepochopil. Nějak z toho koukání do te třídy nejsem moudrý.
- romiix.org
- Člen | 343
Vytvor obdobnú triedu ako je CoreMacros,
nazvime ju napr. MyMacroSet
.
Objekt zaregistruj v konfigurácií takto:
nette:
latte:
macros:
- MyMacroSet
Prepísal som ti to isté čo matej21 len v zelenom :) Ak si niektorému z krokov nepochopil, spýtaj sa konkrétne naň.
- RadaR
- Člen | 46
romiix.org napsal(a):
Prepísal som ti to isté čo matej21 len v zelenom :) Ak si niektorému z krokov nepochopil, spýtaj sa konkrétne naň.
Já jsem si až včera zjišťoval, co je to neon. Jak jsem uvedl hned na začátku – používám Latte samostatně. Je použití neonu, pokud chci vlastní makra, nutné?
- romiix.org
- Člen | 343
Ou, to sa ospravedlňujem. Prehliadol som že Lette používaš samostatne. NEON slúži na konfiguráciu pri použití s Nette.
Latte som samostatne nikdy neskúšal a ani na to teraz nemám čas, takže len v rýchlosti riešenie čo mi napadlo:
<?php
use Nette\Templating\FileTemplate;
$latte = new Nette\Latte\Engine;
$set = new Nette\Latte\Macros\MacroSet($latte->compiler);
$set->addMacro(
'pokus', // název makra
"echo 'POKUS abc'" // PHP kód nahrazující otevírací značku
);
$template = new FileTemplate();
$template->setCacheStorage(new Nette\Caching\Storages\PhpFileStorage('cache/nette/'));
$template->registerHelperLoader('Nette\Templating\Helpers::loader');
$template->onPrepareFilters[] = function($template)use($latte) {
$template->registerFilter($latte);
};
?>
Alebo použiť riešenie
od Honzu Tvrdíka s tým, že do addMacro dodáš hotový objekt s interfaceom
IMacro
.
Sorry, ale keďže s tým nemám žiadne skúsenosti, je to iba také hádanie.
- RadaR
- Člen | 46
Perfektní – tohle funguje! Díky moc! :) Tohle bych dohromady asi sám nedal.
Možná by bylo vhodné to nějak připsat do dokumentace k vlastním makrům?
- romiix.org
- Člen | 343
Ktoré z toho ti funguje?
Do dokumentácie to môžeš dopísať aj sám tak, aby si to nabudúce podla toho vedel spraviť (a s tebou ostatní);)
Prípadne mi pošli text a môžem to tam poslať ja.
- RadaR
- Člen | 46
Funguje mi bez problémů tvůj poslední příspěvek s kódem.
To vložení do dokumentace nechám na tobě a připsal bych k tomu následující text:
Pokud používáte Latte samostatně, vlastní makro lze zavést tímto kódem:
<?php
use Nette\Templating\FileTemplate;
$latte = new Nette\Latte\Engine;
$set = new Nette\Latte\Macros\MacroSet($latte->compiler);
$set->addMacro(
'mojemakro', // název makra
"echo 'moje makro'" // PHP kód nahrazující otevírací značku
);
$template = new FileTemplate();
$template->setCacheStorage(new Nette\Caching\Storages\PhpFileStorage('cache/nette/'));
$template->registerHelperLoader('Nette\Templating\Helpers::loader');
$template->onPrepareFilters[] = function($template)use($latte) {
$template->registerFilter($latte);
};
?>
Edit: ten kód jsem ještě zkusil upravit takto a bez problémů také funguje, ale snad mi místní borci dokáží říct, je-li toto řešení optimálnější, než to předchozí?
<?php
use Nette\Templating\FileTemplate;
$template = new FileTemplate();
$template->setCacheStorage(new Nette\Caching\Storages\PhpFileStorage('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(
'mojemakro', // název makra
"echo 'moje makro'" // PHP kód nahrazující otevírací značku
);
};
?>
Editoval RadaR (21. 1. 2014 13:01)