URL generator: TODO
- Honza Marek
- Člen | 1664
K vytvoření odkazu je nyní potřeba presenter. Pokud ale chci generovat odkaz v cli nebo v cronovém scriptu například pro odesílaný mail, musím adresu skládat ručně.
Komplikaci to přináší obecně i v modelech, kde pokud chci zjistit url adresu, musím postupovat zhruba takto:
class MujSuperModel
{
public function getItemInfo(Item $item, Presenter $presenter)
{
$link = $presenter->link('Link:default', ['id' => $item->getId()]);
return ['name' => $item->getName(), 'link' => $link];
}
}
Bylo by tedy dobré vytváření odkazů separovat do speciální třídy, která by byla dostupná v DI kontejneru jako služba.
Nemáte někdo chuť to implementovat?
- Filip Procházka
- Moderator | 4668
Pokud chceš generovat url v CLI, můžeš použít Kdyby/Console, které mimo jiné tohle řeší :)
Editoval Filip Procházka (13. 3. 2013 21:46)
- David Grudl
- Nette Core | 8228
Ke generování odkazů slouží $router->constructUrl(), kterému se předá Nette\Application\Request a souřasné URL.
- Honza Marek
- Člen | 1664
Pak by to tedy chtělo z presenteru vyčlenit
„ApplicationRequestFactory“, aby třeba v šablonách makra link
nepotřebovaly presenter. Vim, že se podle něj pozná, co to je třeba odkaz
na this, ale to by se dalo nahradit nějakým textovým scope –
Front:Homepage:default-komponenta-podkomponenta
. Pokud by scope
nebyl k dispozici, bylo by potřeba do „url generatoru“ (který by vznikl
jako malinká třída spojující router a ApplicationRequestFactory) dát
v parametru absolutní cestu.
- Panda
- Člen | 569
Prozatím jsem vyčlenil RequestFactory
, poté ještě
vytvořím LinkFactory
– název se mi moc nelíbí, jak byste to
pojmenovali vy?
Aktuální stav je k nahlédnutí v mém forku Nette, větev
app-request-factory
: https://github.com/…uest-factory
Testy: https://travis-ci.org/jsmitka/nette
- Patrik Votoček
- Člen | 2221
Panda napsal(a):
… poté ještě vytvořím
LinkFactory
– název se mi moc nelíbí, jak byste to pojmenovali vy?
LinkGenerator
?
- Panda
- Člen | 569
Prozatím jsem použil LinkGenerator
, ale asi to přejmenuji na
UrlGenerator
. Díky všem za názory. :-)
Ještě jsem narazil na jeden drobný detail – pro vygenerování URL je potřeba mít k dispozici současné URL. To je v pohodě při běhu na webu, ale bude dělat problémy při použití například v konzoli – vygenerované URL samozřejmě nebude odpovídat.
Řešení mě napadla dvě:
- Pštrosí algoritmus – strčit hlavu do písku a neřešit to s tím,
že bude na programátorovi, aby dodal programově správné referenční URL (=
zavolá si
setRefUrl()
nad instancí URL generatoru). To detailně zdokumentovat. - Konfigurace referenčního URL v sekci Nette – pokud kontejner při
vytváření služby detekuje, že nejsou k dispozici
$_SERVER['HTTP_HOST']
ani$_SERVER['SERVER_NAME']
, použije referenční URL nastavené v konfiguračním souboru. Když URL nebude nastavené – bude se chovat jako v prvním případě.
Trošku problém by mohl být s tím, že router na první pohled vyžaduje
cestu ke skriptu (např. http://example.com/subdir/index.php
) a asi
se to bude chovat podivně, pokud zadám třeba jen
http://example.com/subdir
– budu muset vyzkoušet, jak se
jednotlivé routery chovají.
- Panda
- Člen | 569
Přemýšlím, jestli je úplně vhodný nápad to URL podvrhovat už v
Http\RequestFactory
… LinkGenerator
vůbec
nepotřebuje celý request, stačí mu jen URL, takže zatím
fallbackRefUrl
vyhodnocuji při vytváření služby. A URS se
nastavuje v konfiguráku.
Další na řadě bude integrace do šablon, aby bylo možné makro
{link}
používat jen s instancí LinkGeneratoru
a
nebyla potřeba instance komponenty/presenteru.
Editoval Panda (19. 3. 2013 23:47)
- Panda
- Člen | 569
Makra {link}
a {plink}
jdou používat i bez
komponenty/presenteru, stačí nastavit šabloně proměnnou
$_linkGenerator
a nenastavit
$_control
/$_presenter
. Pokud bude komponenta/presenter
nastavená, použije se (například kvůli makru {ifCurrent}
).
Díky tomu by mělo být vše zpětně kompatibilní.
Možná ještě vrátím zpátky makro {plink}
tak, aby
používalo jen presenter a nikoliv $_linkGenerator
– pokud budu
chtít používat odkazy bez presenteru, dává mi větší smysl všechno hnát
přes {link}
. Co myslíte?
Ještě přemýšlím, zda nepřidat nastavení proměnné
$_linkGenerator
do API. Takové
$template->setLinkGenerator($linkGen);
by se mi celkem líbilo. Navíc se bude $_linkGenerator
používat jen při samostatném použití, pokud je šablona vázaná na
komponentu či presenter, nemá jeho nastavování smysl, takže by to bylo
přehlednější.
- hrach
- Člen | 1838
Je treba zasadne od sebe odlisit dve veci. Latte a Templates. Mozna by nebylo od veci, kdyby generovani linku se provadelo pres helper.
- Latte by compilovalo
{link }
do volani helperu na template - Nebylo by treba zadne nove api
- Presenter by registroval do helperu plink sebe, do linku linkGenerator
- programator bez presenteru by si registroval jen link helper
- jedinou otazkou zustava, co pak s ifCurrent
Editoval hrach (21. 3. 2013 10:26)
- Panda
- Člen | 569
Použití helperu je určitě dobrý nápad, zmíněné makro
{ifCurrent}
by bylo asi možné vyřešit použitím dalšího
helperu. Jen by to byl takový helper nehelper, protože například helper pro
link by bylo možné použít i bez makra ({$destination|link}
),
zatímco tento by vracel jen true
/false
.
Ještě drobnost: jak helpery pojmenovat? Použít rovnou link
a
plink
, kde hrozí, že už někdo helper s takovým názvem bude
používat, nebo je prefixovat podtržítkem: _link
,
_plink
? Nette žádné takové interní helpery nemá, takže si
nejsem jistý, jakou cestou jít. Lepší by bylo asi _link
…
Každopádně helper asi zkusím do večera implementovat.
- Honza Marek
- Člen | 1664
Jestli mi projde tohle, tak se stejně budou šablony vyrábět úplně jinak (i když metody createTemplate zůstanou).
- Panda
- Člen | 569
Důležitá je ta část „nevolá rodičovskou metodu“, tzn. není tam
parent::createTemplate()
. popř.
Control::createTemplate()
. K registraci helperů ti volání
metody předka nevadí.
Jde mi o to, jestli může existovat nějaký opodstatněný scénář, kdy původní metoda z Nette není volána.