Vložení komponenty do html obsahu

d@rkWolf
Člen | 163
+
0
-

Zdravím,
už tu hodinu prohledávám fórum, ale buď se špatně ptám, nebo tu nic není.

Potřeboval bych nějak vložit komponentu k vykreslení do html obsahu, co mám uložený v DB a co se vykresluje v šabloně přes:

{$data->content|noescape}

Jde o to, že mám vytvořenou komponentu, která renderuje vytvořenou fotogalerii(řada 1-x náhledů, v bootstrap gridu s odkazem na velkou fotku do lightboxu)

{control gallery-1}

Používá se multiplier, normálně v latte to funguje, ale potřeboval bych, aby bylo možné tu galerii(nebo třeba několik galerií) vložit kamkoliv do obsahu upravovaném v editoru v administraci, ať už přímo tím kódem {control gallery-X}, nebo nějakým zástupným co prostě půjde uvnitř toho uloženého kódu najít. Něco jako jsou shortcodes ve Wordpressu.

Ve starém systému bez Nette se prostě prohledal obsah na zvolený řetězec(tuším {gal-x}, když se našel, zavolala se funkce, která zjistila, zda taková galerie existuje a pokud jo, vygenerovala celé potřebné html a vrátila ho, to nové html se použilo k nahrazení toho řetězce gal-x a pak se to celé vykreslilo do stránky.

Nemůžu přijít na to, jak tohle udělat s Nette komponentou? Jde to nějak? Nějaký trik, jak to udělat? Asi bych to mohl udělat stejně celý ručně, ale zajímalo by mě, jestli to nejde nějak udělat s tou komponentou, co už jsem si vyrobil, než to dělat celý „znovu“.

Editoval d@rkWolf (29. 4. 2021 17:33)

Martk
Člen | 652
+
+2
-

A co brání to udělat jako v systému bez Nette? Akorát s tím rozdílem, že dáš v preg_replace

function () {
	ob_start();

	$this->getComponent('gallery-1')->render();

	return ob_get_clean();
}
Kamil Valenta
Člen | 756
+
-1
-

V DB budeš mít zástupné znaky.
V presenteru si pak ten text z DB rozparsuješ a zavoláš potřebné továrničky, do hierarchie komponenty přidáš pomocí

$this->addComponent($object, $name);

V latte pak ten text zase rozparsuješ a na vhodných místech zavoláš {control $name}
Ale já to mám bez multiplieru, protože si uživatel u každé komponenty může navolit, jakou šablonou se to vyrenderuje a další parametry, takže každá instance musí existovat ad-hoc.

Kamil Valenta
Člen | 756
+
0
-

Martk napsal(a):

A co brání to udělat jako v systému bez Nette?

IMHO to, že budeš sahat na neexistující komponentu.

Martk
Člen | 652
+
0
-

To byl jen nejjednodušší příklad. Neexistující komponenta se dá vyřešit druhým argumentem

Kamil Valenta
Člen | 756
+
0
-

Pořád asi nerozumím, kde vezmeš potřebný „createComponent“. Rád se inspiruju, ale před rokem jsem lepší řešení nenašel. Někdo se mnou nesouhlasí, ale netuším proč.

David Matějka
Moderator | 6445
+
0
-

Pořád asi nerozumím, kde vezmeš potřebný „createComponent“

předpokládá to, že v té komponentě/presenteru budou příslušné createComponent existovat. (ale to tvé registrování přes addComponent může být také řešení)

Někdo se mnou nesouhlasí, ale netuším proč.

protože nevím, proč bych to měl „V latte rozparzovat a na vhodných místech zavolat {control $name}“, když stačí ten preg_replace_callback, který ukázal @Martk

Kamil Valenta
Člen | 756
+
0
-

Aha, už chápu. Ono slovo „rozparsovat“ možná bylo moc silné. Možná jsem měl říct „zprocesovat“. Už rozumím, že se na to s Martkem díváte z pohledu latte, kde je ten callback alternativa ke {control …}
Já si ty komponenty držím v db samostatně, takže je ani nemusím parsovat z textu, takže mi control vyšel automaticky nejjednodušší.
Spíš mi šlo o způsob, jak se právě vyhnout v presenteru tomu, že:

  • by se musely chystat všechny createComponent, i když zrovna nebudou potřeba (ale pokud jsou ty komponenty dobře napsané, tak to vezme zcela minimální režii, protože se nezavolá render)
  • při rozšíření o nový „widget“ se nesmělo zapomenout na úpravu presenteru
d@rkWolf
Člen | 163
+
0
-

@KamilValenta no já sem to dal do multiplieru, protože když sem hledal, co potřebuju abych mohl komponentu zobrazit „potenciálně“ víckrát, pokaždé sem narazil na „použijte multiplier“… mám jednu galerii připojitelnou v rámci editace stránky(na konec-za obsah), takže v šabloně presenteru dycky může existovat jedno zavolání té komponenty s patřičným ID, co si user k té stránce přiřadil-jenže tam to má napevno na konec.

Teoreticky s tím multiplierem by ani nemělo být potřeba volat v presenteru to addComponent ne?

Mě akorát úplně nenapadá, jak udělat toto: „V latte pak ten text zase rozparsuješ a na vhodných místech zavoláš {control $name}“ (kromě toho, že mi přijde, že to taková akce do šablony úplně nepatří-i když to mě zas až tak netrápí). Vůbec mě nenapadá, jak proměnnou vykreslovat po částech a nacpat mezi to volání {control}, to je v podstatě ta moje původní představa, akorát mě vůbec nenapadá, jak to udělat.

Martk
Člen | 652
+
0
-

@KamilValenta Je to taky řešení, pokud se ti má komponenta zobrazit nahoře nebo dole. Pokud někde v textu, tak upřímně nevím jak probíhá to řešení s {control $name}. Ovšem předpokládám, že si tam stejně musíš tahat všechny továrny, takže to vyjde rychlostně nastejno jako s createComponent

Kamil Valenta
Člen | 756
+
0
-

Ne, ne, to já nepopírám, že když je to uvnitř textu, že není výhodnější nahradit to za výstup renderu. Já jsem měl na mysli hlavně to, že

$this->getComponent('gallery-1')->render();

nijak nevytvoří

createComponentGallery()

Pokud je galerie jediný widget v textu, tak je akceptovatelné vytvořit to natvrdo v presenteru. Já se na to díval tak, že těch widgetů může být více. V mém případě je N-modulů, které ještě mohou být povoleny/zakázány a každý z nich může poskytovat N-komponent, které implementují interface „Widget“. Továrny všechny tahat nemusím, widgety netahám z DI, což je v mém případě daň za tu automatizaci okolo.
S odstupem roku skutečně ale víc oceňuju to, že kdekoliv můžu vytvořit komponentu s interfacem Widget a už nikde nic nepřipisovat…

David Matějka
Moderator | 6445
+
0
-

@KamilValenta pokud budeš mít uvnitř toho createComponentGallery Multiplier, tak gallery-1 fungovat bude.

Kamil Valenta
Člen | 756
+
0
-

To ano, ale musíš createComponentGallery mít. A pak třeba createComponentArticle, createComponentMap…