Jak na základní makra ve vlastní template factory?
- chikeet
- Člen | 160
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
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
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
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)