Jak na základní makra ve vlastní template factory?

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

Zdravím,
používám vlastní template factory pro šablony mailů, a chci, aby šablonám nastavila defaultní makra a helpery a navíc moje vlastní makra a helpery. Smyslem je nemuset se o to starat u každé šablony zvlášť. Vypadá to ale, že defaultní makra v šabloně dostupné nejsou, konkétně mi Laděnka hlásí chybu „Unknown macro {link} in …\emails\forgottenPassword.latte“.

Navíc si nejsem jistá, jestli je v pořádku registrace helperů v metodě setupTemplate, protože jednak nikde nemůžu dohledat třídu Nette\Templating\Helpers a druhak můj helper loader bere dva argumenty, což mi háže chybu stejně jako pokus o registraci přes $template->addFilter(…). Jsem z toho celkem zmatená, nemůžu nikde pořádně dohledat, jak tohle správně dělat v aktuální verzi Nette (mám ~2.2.0 přes composer).

TemplateFactory:

	/** @var \Latte\Engine */
	public $engine;


	public function __construct(){
		$this->engine = new \Latte\Engine;
		$this->engine->onCompile[] = function($latte) {
				\Latte\Macros\CoreMacros::install($latte->getCompiler());
				\Chikeet\CustomMacros::install($this->engine->getCompiler());
			};
		}


	/**
	 * File template factory.
	 * @param string $filePath
	 * @return \Nette\Templating\Template
	 */
	public function createFileTemplate($filePath){
		$template = new \Nette\Templating\FileTemplate($filePath);
		return $this->setupTemplate($template);
	}


	/**
	 * Performs template setup.
	 * @param \Nette\Templating\Template $template
	 * @return \Nette\Templating\Template
	 */
	public function setupTemplate($template){
		$template->registerFilter($this->engine);
		$template->registerHelperLoader('\\Nette\\Templating\\Helpers::loader');
		//$template->registerHelperLoader('\\Chikeet\\CustomFilters::loader');
		return $template;
	}

forgottenPassword.latte:

...
nové heslo pro přístup na web {$webName} si můžete <a href="{link //Homepage:resetPassword, id => $user->id, hash => $user->hash}"> nastavit zde</a>.
...

Budu ráda za nakopnutí, případně inspiraci jak to řešit jinak. Ideálně tak, abych svoje makra a helpery zaregistrovala jednou a víc se o to nemusela starat, bez ohledu na to, jestli jde o šablonu komponenty nebo třeba emailu.

Editoval chikeet (29. 10. 2014 18:31)

David Matějka
Moderator | 6445
+
+5
-

V 2.2 doslo ohledne latte k velkym zmenam k lepsimu, neco se tam vsak dela stale trochu krkolomne (a nekde i trochu krkolomneji nez pred tim). Zkusim to vzit postupne:

1. FileTemplate je deprecated, vubec to nepouzivej. Latte\Engine je urcen primo k renderovani sablony pomoci

$engine->render($cesta_k_sablone, $parametry);

2. Pro vytvoreni latte enginu muzes pouzit tuhle factory, kterou si injectnes. Pak budes mit spravne nastaveny ruzny temp directory atd. A taky to ma vyhodu s makrama a helperama (viz dalsi body)
3. makra muzes registrovat v neonu

nette:
	latte:
		macros:
			- Chikeet\CustomMacros

pak budou dostupna vsude, kde vytvaris engine prave pomoci te factory

4. i filtery (puvodne helpery) se nechaji registrovat globalne, pomoci

services:
	nette.latteFactory:
		setup:
			- addFilter(nazev, callback)

5. Je problem, ze spoustu veci resi TemplateFactory. Je vsak zavisle na controlu. veci jako registraci UIMacros, ruzne cesty apod. budes muset registrovat znova… Ale, viz bod 8

6. Ani registrace UIMacros vsechno nevyresi, pro vytvareni linku je totiz nutne, aby existoval presenter/komponenta. Muzes pouzit nextras/link-factory, ktere to resi. (nebo moje librette/link-builder, kde po registraci extension mas k i dispozici funkcni makro {link})

7. Latte\Engine je sice mozno pouzit primo (jak jsem zminoval v 1), ale mozna budes chtit „hezkou“ sablonu a moznost nastavovat properties pomoci $template->foo = $bar. Pak muzes rucne vytvorit Template a predat ji Latte\Engine

8. Jak jsem zminil, je problem s TemplateFactory – v 2.2 vyzaduje $control parametr. To je vyreseno v masteru, kde je mozno vytvorit sablonu bez controlu. To tedy vytvori onu sablonu z bodu 7, kde budou vsechny mozne parametry, filtry a makra (viz kod te template factory)

Editoval matej21 (30. 10. 2014 0:51)

chikeet
Člen | 160
+
0
-

Díky moc za vyčerpávající odpověď.

Parametry šabloně předávám v poli, takže se obejdu i bez TemplateFactory z nette. Předpokládám, že tím nastavením jsi tam myslel $basePath apod., ale to tam zatím nepotřebuju.

UIMacros už jsem v aktuální verzi Nette nenašla, mám nainstalované CoreMacros + svoje custom makra a pro linky linkBuilder, funguje parádně – díky :-) To mi pro maily stačí. Nakonec mi to celé pěkně zkrátilo kód a vypadá to hezky.

Chvíli mi trvalo přijít na to, že ILatteFactory::create nevytváří šablonu (jak bych čekala), ale Latte\Engine, zbytek šel celkem hladce.

Výsledek vypadá takhle (svoje makra a filtry teď registruju v configu):

class TemplateFactory extends \Nette\Object
{

	/** @var \Latte\Engine */
	private $engine;


	/**
	 * @param \Nette\Bridges\ApplicationLatte\ILatteFactory $latteFactory
	 */
	public function __construct(\Nette\Bridges\ApplicationLatte\ILatteFactory $latteFactory){
		$this->engine = $latteFactory->create();

		$this->engine->onCompile[] = function($latte){
			\Latte\Macros\CoreMacros::install($latte->getCompiler());
		};
	}


	/**
	 * @param string $filePath
	 * @param array $templateVars
	 * @return string
	 */
	public function renderToString($filePath, array $templateVars = []){
		return $this->engine->renderToString($filePath, $templateVars);
	}
}

Jediné, co mi tam chybí k dokonalosti, je registrace loaderu vlastních filtrů, aby nebylo nutné na to myslet při přidávání nových filtrů, ale to třeba časem taky půjde… :-)

David Matějka
Moderator | 6445
+
0
-

filter loadery by mely jit registrovat podobne jako filtry s tim, ze jako nazev se da null, takze neco jako

services:
    nette.latteFactory:
        setup:
            - addFilter(null, loader_callback)
chikeet
Člen | 160
+
0
-

Díky, to mě nenapadlo. Funguje to parádně.

enumag
Člen | 2118
+
0
-

@matej21 Nevím zda o tom víš ale bod 5, závislost TemplateFactory na Control už ve 2.3 není. ;-)

David Matějka
Moderator | 6445
+
0
-

@enumag jj vim, viz bod 8 :)