spuštění pluginu na základě renderování textu z DB

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

Předem se omlouvám za delší čtení – v nette se utápím cca jeden týden a snažím se v něm vytvořit (zatím jen) frontend staršího CMS.

Příklad:
Potřeboval jsem někde na stránce vypsat anketu nebo nějaký jiný plugin, takže součástí článku byla speciální syntaxe na zavolání pluginu

Odstavec jedna blablabla
[[plugin pool 22]]
Odstavec dva blablabla...

Což v textu samotného článku nahradilo tuto konstrukci obsahem nějakého templatu a zároveň tuto template naplnilo daty (zkrátka zobraz anketu id 22).

Výsledkem byl článek, uprostřed anketa včetně všech funkčních odkazů apod. (nevím jestli je to zrovna ideální řešení, ale splnilo to co jsem potřeboval)
Protože jsem měl tyto pluginy napsané pro ankety, novinky, kontakt form a nějaké další prvky eshopu, dalo se s tím dělat dost věcí.

A teď k Nette – mám úplně stejný problém. V administraci vytvořím článek a uprostřed něj chci vypsat řekněme anketu. Jak byste tenhle úkol řešili v nette, aby to bylo korektní (rozuměj bezpečné, jednoduché a chytré :)

Napadlo mě něco jako vložit do textu článku kód, který v template zavolá control, např. {control PoolControl}
Nevím ale, jestli vůbec do šablony jde něco takového dynamicky vložit/vypsat současně s textem.

Jak byste podobnou úlohu řešili?
(to co jsme tu popsal je asi docela prasárna (v „obyčejném“ php natož pak v Nette), tak prosím o nějakou inspiraci)

Díky.

Editoval Filip111 (16. 8. 2011 14:43)

Filip Procházka
Moderator | 4668
+
0
-

Neměl by být problém, vygenerované HTML článku prohnat přes Latte šablonu.

$template = $this->createTemplate('Nette\Templating\Template');
$template->setSource($clanek);
$this->template->clanek = $template;

V šabloně pohledu pak třeba:

{!$clanek->render()}

Ale pozor na to, že takový článek by měl být čisté HTML. Pokud tam máš nějaký bordel, který ti tam mohou zanést uživatelé, pak prvně prohnat přes Texy!. Jinak si nikdy nedovolit svévolně vypisovat do šablony s {!$var}, protože tím si tam děláš XSS díry, pokud si nejsi jistý tím, co je ve $var.

Díky tomu, že použiješ metodu presenteru createTemplate, tak tam budeš mít vše potřebné nakofigurované a i přístup k presenteru a komponentám. Můžeš pak mít třeba ve článku

{control poll 21}

A komponentu PollControl, která v render příjme a zpracuje ID

public function render($pollId)
{
	$this->template->poll = $this->pollModel->find($pollId);
	$this->template->render();
}
Filip111
Člen | 244
+
0
-

Tak tohle je mnohem lepší odpověď než jsem čekal…celkem jednoduše a s minimem režie.Snad budu mít večer čas to vyzkoušet. Díky!

Ještě otázka na té obecnější rovině: Je toto „správný“ způsob jak řešit vyvolání nějakého controlu/pluginu v rámci CMS?
Dalo by se to udělat lépe? (a teď už nemám na mysli jenom Nette, ale obecně…)

Editoval Filip111 (16. 8. 2011 15:39)

Filip111
Člen | 244
+
0
-

Zkusil jsem a funguje to bezvadně, ještě jednou díky. Teď už to jen nějak zapouzdřit a ošetřit vstupní HTML.

Vlastně je to první věc, která mě na Nette nadchla protože zafungovala v podstatě napoprvé, velice jednoduše a v controlu mám k dispozici vše co potřebuji…paráda.
Rozběhnout front a admin modul, poprat se s namespace a DI pro mě bylo (a je) utrpení, takže tohle je taková malá odměna.

Filip Procházka
Moderator | 4668
+
0
-

Stačí si nastudovat dokumentaci a občas zabrousit do zdrojáků. Pak je všechno hračka :)

Filip111
Člen | 244
+
0
-

tohle beru jako provokaci :)
(celej tejden nedělam nic jinýho, než čtu dokumentaci, procházim tutoriály, fórum…pravda na zdrojáky Nette jsem se ještě necítil).

Filip Procházka
Moderator | 4668
+
0
-

No asi chvilku trvá, než si to člověk zažije :)

Filip111
Člen | 244
+
0
-

Tak jsem zpátky…zkouším si předat do NewsControl pomocí konstruktoru NewsModel ale nedaří se mi to.

public function __construct(NewsModel $newsModel) {
	parent::__construct();
	$this->newsModel = $newsModel;	// private $newsModel;
    }

Továrnička na komponentu News je v ContentPresenter, kde se pracuje s článeky:

protected function createComponentNews() {
	return new \NewsControl ($this->context->newsModel);
}

Model obsahuje funkce jako:

class NewsModel
{
	public static function fetchAll()
	public static function GetOne($id)
	apod...

Laděnka hlásí, že nepředávám do konstruktoru controlu instanci třídy NewsModel.
Nevím jak iniciovat NewsModel v presenteru – nevím jestli by to měl za mě udělat nějaký model loader nebo jestli to musím udělat sám.
Zkoušel jsem

$this->context->newsModel = new \NewsModel();

ale to končí chybou

Ambiguous class 'FrontModule\FrontBasePresenter' resolution;
defined in C:\_web\nette\sandbox\app\AdminModule\FrontBasePresenter.php and
in C:\_web\nette\sandbox\app\FrontModule\FrontBasePresenter.php

..nevím jestli jdu správnou cestou.

Filip Procházka
Moderator | 4668
+
0
-

Můžeš to udělat ty, třeba v configu. Nebo pomocí modelLoaderu.

A Ambiguous class 'FrontModule\FrontBasePresenter' resolution znamená, že tam máš dvě třídy pojmenované stejně. Dokonce ti to napsalo i cestu, kde je hledat.

Filip111
Člen | 244
+
0
-

Problém s ambiguous class jsem nějak přehlédl…opravoval jsem to už včera na jiném počítači (přejmenováním souboru presenteru). Při synchronizaci na počítač, kde sedím teď tedy vznikl nový presenter, ale zůstal i ten starý…toho jsem si nevšiml.

Každopádně po nějaké době se mi podařilo iniciovat model jak přes config, tak přes model loader.
Díky.

OT: Co prosimtě děláš za práci (nebo školu?) – já mám pocit že jsi placenej za odpovídání na fóru :) Pohotově odpovídáš na každou blbost, kdejakýho začátečníka. Skoro jako tech. support :c)

Filip Procházka
Moderator | 4668
+
0
-

Sbírám bobříky :)

Filip111
Člen | 244
+
0
-

ok, tak v tom případě se budeme „potkávat“ častěji :)

bojovyletoun
Člen | 667
+
0
-

#8 Pozor na konstruktor komponent! měl by volat parent::construct, což dělá, ale s parametry $parent a $name. Pak to může dělat neplechu (ikdyž v uvedeném kódu to bude fungovat ok). Uvedený paramer $newModel pak můžeš předat takto

protected function createComponentNews() {
	$c= new \NewsControl;
	$c->model= $model; //odněkud získáš, třeba new \NewsModel;
        return $c;
}

v dokumentaci o tvorbě komponent –

Editoval bojovyletoun (20. 9. 2011 15:35)

Filip Procházka
Moderator | 4668
+
0
-

@**bojovyletoun**: poslední dobou mám pocit, že ti ukradl účet nějaký radvis.

Uvedený kód je naprosto v pořádku, tvůj je horší. Předávat $name a $parent vůbec nemusíš.

PS: můžeš mi vysvětlit, proč odpovídáš na témata, která jsou evidentně vyřešená?

Editoval HosipLan (20. 9. 2011 15:52)

smasty
Člen | 90
+
0
-

<offtopic>

Filip111: HosipLan síce za odpovedanie na fóre nie je platený, ale snaží sa prekonať Patrika Votočka, na ktorého stráca približne 100 príspevkov ;-)

</offtopic>

Edit: A sorry za vyťahovanie staršieho vlákna, nevšimol som si dátum ;-)

Editoval smasty (20. 9. 2011 15:59)

Filip Procházka
Moderator | 4668
+
0
-

@**smasty**: Můžeš mi vysvětlit, jak to souvisí s tím, že @**bojovyletoun** otevírá měsíce stará vyřešená témata? Copak já tohle dělám?

smasty
Člen | 90
+
0
-

@HosipLan: To s tým nemá nič spoločné… To bola len odpoveď na otázku Filip111 v príspevku #10. Príspevok som rozpísal skôr, ako si napísal príspevok #14… ;-)