spuštění pluginu na základě renderování textu z DB
- Filip111
- Člen | 244
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
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
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
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
Stačí si nastudovat dokumentaci a občas zabrousit do zdrojáků. Pak je všechno hračka :)
- Filip111
- Člen | 244
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
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
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)
- bojovyletoun
- Člen | 667
#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
@**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
<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
@**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?