Helper pro vykreslení fotografíí v albu dle předaného parametru

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

Chtěl bych se optat, jak bych měl vytvořit a zaregistrovat helper, který obdrží objekt nebo ID a dle toho vykreslit dané album fotografíí. Napsal jsem si pro to Továrnu, které předám jen ID a vše mi vykreslí, ale funguje mi to jen jako komponenta.
Budu rád za každou radu.

David Kudera
Člen | 455
+
+2
-

No to je ale správně.. Když se podíváš na helpery (teď správně filtry), tak jsou to jen........... filtry.. Prostě jen převedení na velký písmena a takový podobný věci. Myslím, že určitě nebyly myšlený jako něco, co by mohlo nahradit komponentu.

Čili, komponenta je správně

Tirus91
Člen | 199
+
0
-

@DavidKudera

Dobře, děkuji za informaci, ale jak mohu udělat něco v tomto stylu? To si všude musím dělat tu komponentu? To je trochu nesmyslné ne? To je proti DRY. Jak tedy alespoň na továrnu, abych v presenteru nemusel jak blb dělat neustále createComponentXXXX ?

Dále mi jde i o to, že do příspěvku zadám například [album:1] a ono mi to vypíše komponentu albumu pro dané ID.

David Kudera
Člen | 455
+
0
-

Klidně bych dal hned mezi DRY a komponenty 2 rovnítka ;-)

Stačí si udělat komponentu s generovanou továrničkou pro album. Což je jedna třída dědící od Control, jeden interface pro generované továrničky a jeden záznam v configu. No a pokud to využíváš na hodně místech, tak i jeden createComponent do nějakého BasePresenter nebo traitu.. to je na tobě.

A použít můžeš třeba takhle:

{control album, 1}

ten parametr se předá jednoduše do render metody té komponenty

Tirus91
Člen | 199
+
0
-

@DavidKudera
a v případě toho článků?
Například tam budu mít

<p>Mimochodem, ve Velké Británii současný premiér David Cameron usiluje
o&nbsp;zvýšení investic do&nbsp;obecních bytů, tak proč to nejde v&nbsp;České
republice?</p>
[album:1]
David Kudera
Člen | 455
+
0
-

jo takhle.. Tak to tě jen asi přesměruju tady do jiného vlákna , kde se to nedávno řešilo..

Nebo moment.. Možná mi něco nedochází. Tohle je příspěvek, co máš asi v DB že? A ty tam dáš takhle to [album:1] a ta tvoje továrna to nějak zpracuje? Nebo jak to máš teď teda? Nebo co myslíš vlastně tou továrnou? Jen aby jsme každý nemluvili o něčem jiným ;-)

Tirus91
Člen | 199
+
0
-

@DavidKudera
Ok, rozepíšu to vše nyní jak to mám.

Mám presenter pro celou fotogalerii, kde mám actionAlbum. V latte mám jen

{block content}
{control albumList}

a jako componentu mám

protected function createComponentAlbumList(){
        return $this->albumFactory->create($this->id);
    }

Ta továrna je následující

namespace Tirus\Gallery;

class AlbumFactory extends \Nette\Object {

    /** @var \Nette\Localization\ITranslator * */
    protected $translator;

    /** @var \Tirus\Repository\GalleryAlbumRepository  * */
    protected $albumRepository;

    /** @var \Tirus\Attachments\Storage **/
    protected $storage;

    public function __construct(\Tirus\Repository\GalleryAlbumRepository $albumRepository, \Nette\Localization\ITranslator $translator, \Tirus\Attachments\Storage $storage) {
        $this->translator = $translator;
        $this->albumRepository = $albumRepository;
        $this->storage = $storage;
    }

    public function create($id) {
        $control = new AlbumControl;
        $control->setTranslator($this->translator);
        $control->setAlbumEntity($this->albumRepository->get($id));
        $control->setStorage($this->storage);
        return $control;
    }

}

Toto mi nyní funguje, ale jen jako výpis daného albumu. Chtěl jsem to nějak spojit v jedno abych mohl tuhle komponentu využívat i jinde.

Čeho ještě chci docílit, je to, že vypíšu galerie v příspěvku, kde je tag [album:1]. Ano, příspěvek je v databázi.

David Matějka
Moderator | 6445
+
0
-

vetsinou je zbytecny bezpecnostni riziko spoustet kod z databaze jako latte.
pouzij proste preg_replace_callback a nahrad vyskyty tech [foo:param] tagu za obsah

viz treba tenhle topic

Editoval matej21 (7. 9. 2014 22:19)

David Kudera
Člen | 455
+
0
-

Jo chápu, tak určitě doporučuji používat komponenty jako továrničky ..

No a dál bude potřeba upravit render metodu toho AlbumControl (a taky to celé původní předávání album entity).

public function render($id)
{
	$this->template->album = findAlbumByIdSomehow($id);
	$this->template->render();
}

a pak voláš jen to, jak jsem psal:

{control album, 1}

Takže stačí jen hodit ten createComponentAlbum do base presenteru

no a to použití v db je popsáno v tom vlákně, jak jsem poslal výše. Sice to není úplně nejhezčí, ale asi to funguje (nikdy jsem to nepoužil)

Edit: @matej21 šikovný ;-)

Editoval David Kudera (7. 9. 2014 22:22)

Tirus91
Člen | 199
+
0
-

@matej21
vím jak to myslíš,
např.

<p>nějaký text</p>
[album:1]

bych nahradil za

<p>nějaký text</p>
{control album,1}

a následně toto nechal pro filtry jako |noescape apod..

Máš prosím nějaký nástřel jak nejlépe toto provést?

Tirus91
Člen | 199
+
0
-

@matej21
Děkuji, už mi to jede, ale musím upravit výraz aby mi to bralo i nepovinné argumenty

Jak mám ten regulární výraz upravit, aby mi vzal 0-X argumentů (čísla i texty)?

$template->registerHelper('components', function ($text) {
            $presenter = $this;
            return preg_replace_callback('~\[\*\](\w+)\[\/\*\]~', function($matches) use($presenter) {
                ob_start();
                try {
                    $presenter->getComponent($matches[1])->render();
                } catch (\Exception $ex) {
                    \Tracy\Debugger::log($ex);
                    echo '[component=' . $matches[1] . ']';
                }
                return ob_get_clean();
            }, $text);
        });

Editoval Tirus91 (8. 9. 2014 0:06)

Tirus91
Člen | 199
+
0
-

Budu rád, kdyby mi někdo poradil, jak tuto situaci upravit a dořešit.

$template->registerHelper('components', function ($text) {
            $presenter = $this;
            return preg_replace_callback('~\[\*\](\w+(,\w+(-\w+)*)*)\[\/\*\]~', function($matches) use($presenter) {
                ob_start();
                $component = explode(',', $matches[1]);
                if (!$component) {
                    return null;
                }
                try {
                    if (count($component) > 1) {
                        $presenter->getComponent($component[0])->render($component[1]);
                    } else {
                        $presenter->getComponent($component[0])->render($component);
                    }
                } catch (\Exception $ex) {
                    \Tracy\Debugger::log($ex);
                    echo '[component=' . $matches[1] . ']';
                }
                return ob_get_clean();
            }, $text);
        });

V tuto chvíli mi funguje to co potřebuji, ale nikdy nevím, zda někdy nebudu potřebovat více jak jeden parametr. Také ten regulární výraz není zrovna nejhezčí a vyřešený

Felix
Nette Core | 1247
+
0
-

Zkusil bych to matchnout cely a pak rozdelil podle nejakyho delimiteru.

$subject = 'asd kad [album:1:2:text] asd asd';

preg_match('#\[([^\]]*)\]#gs', $subject, $matches); // album:1:2:text

preg_split('#\:#', 'album:1:2:text', $matches); // [album, 1, 2, text]