Přidání vlastního makra do Latte

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
RadaR
Člen | 46
+
0
-

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
+
0
-

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
+
0
-
$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
+
0
-

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.

romiix.org
Člen | 343
+
0
-

Nepáči sa mu, že tam dodávaš string a nie IMacro.

RadaR
Člen | 46
+
0
-

romiix.org napsal(a):

Nepáči sa mu, že tam dodávaš string a nie IMacro.

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
+
0
-

V prvom príspevku používaš metódu addMacroNette\Latte\Macros\MacroSet a na konci addMacroNette\Latte\Compiler.

Riešenie od matej21 ti nefunguje?

Editoval romiix.org (21. 1. 2014 10:00)

RadaR
Člen | 46
+
0
-

romiix.org napsal(a):

V prvom príspevku používaš metódu addMacroNette\Latte\Macros\MacroSet a na konci addMacroNette\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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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)

vvoody
Člen | 910
+
0
-

Kde si mal chybu? Nepoužil si tu istú inštanciu latte pre vytvorenie makra aj pre registráciu filtra?

RadaR
Člen | 46
+
0
-

vvoody napsal(a):

Kde si mal chybu? Nepoužil si tu istú inštanciu latte pre vytvorenie makra aj pre registráciu filtra?

Porovnej výsledný fungující kód s tím mým, co jsem postnul jako první.