Nastavenie obsahu šablony z reťazca, miesto súboru ($template->setFile())

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

Ahoj David, ahoj komunita

Ak by sa to hodilo viacerým a pomohlo to, tak by som chcel navrhnúť možnosť zadať obsah templaty z reťazca:

Ako existujúca metóda:
$template->setFile() určí súbor so šablónou
Napríklad metóda:
$template->setString() alebo $template->setContent() by nastavila šablonu z reťazca

Čo mňa konkrétne vedie k tomu requestu ? Nasledovná situácia: využívam NMail a ako telo správ používam Nette šablony. Rád by som šablony uložil v databáze, aby bolo ľahké ich meniť (v administrácii projektu) a rovno používať po vytiahnutí z databáze, miesto súborov.

Editoval jardo (5. 11. 2009 22:28)

Ondřej Mirtes
Člen | 1536
+
0
-

Když by sis podědil BaseTemplate (a nazval svoji třídu třeba StringTemplate), tak by to určitě nějak šlo. BaseTemplate slouží jako základ pro vlastní implementace šablon, Template (která je potomkem BaseTemplate) už pracuje se soubory.

Prozkoumal jsem zdroják a IMHO stačí pracovat s metodou compile a napsat si vlastní metodu render. Ale zvaž, jestli není lepší mít šablony stále v souborech a v CMS naprogramovat editaci souborů.

Ale pozor, tím, že umožníš uživateli přístup k šablonám, mu dáváš dost velkou zbraň a i bezpečnostní díru.

Editoval LastHunter (5. 11. 2009 22:45)

jardo
Člen | 17
+
0
-

LastHunter napsal(a):

Když by sis podědil BaseTemplate (a nazval svoji třídu třeba StringTemplate), tak by to určitě nějak šlo. BaseTemplate slouží jako základ pro vlastní implementace šablon, Template (která je potomkem BaseTemplate) už pracuje se soubory.

Prozkoumal jsem zdroják a IMHO stačí pracovat s metodou compile a napsat si vlastní metodu render. Ale zvaž, jestli není lepší mít šablony stále v souborech a v CMS naprogramovat editaci souborů.

Ale pozor, tím, že umožníš uživateli přístup k šablonám, mu dáváš dost velkou zbraň a i bezpečnostní díru.

Díky za radu, pozerám na to a myslím, že tak by som to spraviť mohol.
Tej bezpečnostnej diery som si samozrejme vedomý, ale k tomuto bude mať prístup len najvyšší prihlásený administrátor.

Petr Motejlek
Člen | 293
+
0
-

No, ono zase až tak špatné není, že si zákazník může měnit šablony sám. Obvykle ho nenecháte měnit to, co jde na web, ale třeba faktury by si měnit mohl.

Přidávat do Template setString() je IMHO hloupost, protože Template sám cachuje předkompilovanou šablonu přes Nette\Cache. S šablonou z databáze, resp. stringu by to šlo blbě (necachovalo by se). Je lepší si extendnout BaseTemplate a udělat si pro vlastní databázi šablon třídu, která bude schopná si z databáze např. zjistit, že je potřeba přegenerovat cache, protože byla šablona změněná v databází, atp. Dokonce si myslím, že klidně pak můžeš uživatelovi např. říct, jaký proměnný a makra může použít v té šabloně, že mu třeba budeš ignorovat <?php ?> bloky atd. ;) Prostě extendovat je lepší ^^.

David Grudl
Nette Core | 8147
+
0
-

Template by se správně mělo jmenovat FileTemplate (ale z historických důvodů je to Template, nicméně nad aliasem FileTemplate uvažuju) a tudíž skutečně je čistým řešením vytvořit StringTemplate jakožto potomka BaseTemplate. V ní stačí implementovat metodu render()

class StringTemplate extends BaseTemplate
{
	public $content;

	/**
	 * Renders template to output.
	 * @return void
	 */
	public function render()
	{
		$cache = Environment::getCache('StringTemplate');
		$key = md5($this->content);
		$content = $cache[$key];
		if ($content === NULL) { // not cached
			if (!$this->getFilters()) {
				$this->onPrepareFilters($this);
			}

			$cache[$key] = $content = $this->compile($this->content);
		}

		$this->__set('template', $this);
		/*Nette\Loaders\*/LimitedScope::evaluate($content, $this->getParams());
	}
}
Jarda
Člen | 25
+
0
-

Zdravím Vás,
snažil jsem se implementovat tuto StringTemplate. Funguje OK, akorát se mi nepodařilo docílit spolupráce s layouty. Do Base presenteru jsem zkopíroval metodu createTemplate() z Presenteru a akorát jsem změnil vytvoření šablony.

<?php
protected function createTemplate()     {
   $template = new StringTemplate;
//... zbytek je stejný jako v Presenter
?>

Snažil jsem se zkoumat kod, zjistil jsem, že o layout se stará presenter a pak se zavolá render na šabloně, ale moudrý z toho nejsem.

Kod šablony načítám z dtb. Layouty mám standardně uloženy jako soubory. Může to takhle fungovat?

Předem díky za rady

Honza Kuchař
Člen | 1662
+
0
-

@David: Nechceš StringTemplate přidat do distribuce? Klidně bych předělal Template → FileTemplate. A template bych dělal nějak takto:

class Template extends FileTemplate {}

Aby to bylo zpětně kompatibilní.

//EDIT: Nebo alespoň přidat do doplňků. Tady na fóru to už dost zapadlo.

Editoval honzakuchar (28. 2. 2010 12:54)

tgif
Člen | 8
+
0
-

Implementovala sem si class StringTemplate extends BaseTemplate (Davidovo reseni), na 1. pohled vse funguje. Pokud do sablony pridam promene {!$xyz} tak se vypise jeji obsah, negeneruje mi to ale linky pokud do $xyz predam string <a href=„{link setfoto! , ‚cz‘}“>jídelna</a>. Svadel bych to na escapovani znaku, ale uz to nevidim.

Honza Kuchař
Člen | 1662
+
0
-

Budeš si muset předat do šablony proměnnou $presenter a $control, což se normálně při použití v Controlu děje automaticky. Viz https://api.nette.org/…rol.php.html#58 a bude ti vše jasné. :-)