Jaká je syntaxe odkazů v LinkGeneratoru?

maral
Člen | 25
+
0
-

Ahoj, dneska jsem řešil problém s LinkGeneratorem:

$this->linkGenerator->link("//:SomeModule:SomePresenter:action");

Což vyhodilo chybu Invalid link destination ‚//:SomeModule:SomePresenter:action‘.

Načež jsem se dočetl, že odkazy mají stejnou syntaxi, jako v presenterech (což je zvláštní, s presenterem se mi to vygenerovat podařilo), ale vždy se tvoří absolutní adresy. Tak jsem vyřadil //, a dostal jsem další chybu – Presenter name must be alphanumeric string, :SomeModule:SomePresenter is invalid. To mě vedlo k podezření, že moduly LinkGenerator nezná a neumí. Co v to případě dělat jsem ale nikde nenašel. Stejně tak jsem ani varování před těmito výjimkami neviděl ani v dokumentaci, ani na blogu PhpFashion. Vrátil jsem se zpět k Presenteru, ale rád bych tady na fóru viděl nějakou jednoduchou summary, co lze a co ne, tedy jaká omezení LinkGenerator má.

Mohli byste to někdo jednoduše a přehledně sepsat? Díky moc.

CZechBoY
Člen | 3608
+
+2
-

linkgenerator dělá vždy absolutní odkazy, takže // ani : na začátku tam není a neumí to zpracovat.

$this->linkGenerator->link("SomeModule:SomePresenter:action");
Yaromil
Backer | 20
+
0
-

Ahoj,

řeším nyní něco podobného, ale v mém případě se nedaří vygenerovat odkaz na handle, který je v presenteru.

Pokud použiji následující:

<?php
$this->linkGenerator->link("Presenter:handle!");
?>

dostávám zpět Invalid link destination.

Neřešil prosím někdo nebo je zde nějaký pádný důvod, proč by neměl linkGenerator() umět vytvářet odkazy na handle signály?

Díky!

Felix
Nette Core | 1196
+
+2
-

Handler je signal komponenty nebo presenteru, vazany celkem dost na UI. LinkGenerator na druhou stranu je tool pro generovani odkazu do mailu a dalsich podobnych mist v prostredi, kde napr. neni dostupny request, cimz pada pouziti signalu.

:)

Felix
Nette Core | 1196
+
-1
-

Jeste me napada, odkaz na handler podleha strukture ?do=, muzes to teoreticky vyplnit rucne.

Yaromil
Backer | 20
+
0
-

@Felix Díky za odpověď. Jo, zatím odkaz sestavuji ručně, jak uvádíš, ale doufal jsem, že půjde generování odkazu pro handle generovat i právě přes LinkGenerator ;-).

Pořád mi ale přijde, že by LinkGenerator handle mohlo zvládnout také, když to umí vygenerovat odkaz na action, poskládat handle právě z ?do= + parametrů by pro LinkGenerator snad mohlo být reálné ;-), aniž by musel být k dispozici request, ale možná si to představuji moc jednoduše…

Editoval Yaromil (8. 1. 2019 20:34)

CZechBoY
Člen | 3608
+
0
-

Proc to potrebujes? Radsi bych udelal spesl akci, ktera zavola/presmeruje na handle.

Yaromil
Backer | 20
+
0
-

@CZechBoY Díky za radu, zkusím tak, jak píšeš. Ale víceméně jde o to, že mám jednoduchou komponentu gridu, která má mimo jiné sloupec, která je typu odkaz a tam si předávám buď klasickou URL nebo cíl pro ‚Presenter:action‘ a nejednou se hodí, když kvůli potřebě AJAXového požadavku můžu odkazovat na handle. Doposud jsem to ale řešil tak, že si odkaz vytvořím přímo v presenteru, kde Grid definuji a převádám ho tedy jako URL.

Jen by se mi líbilo, kdybych mohl využívat následující při definici Gridu a nemusel myslet na další závislosti:

$grid->addColumnLink('link', 'Link:', 'https://nette.org');
$grid->addColumnLink('link', 'Link:', 'Presenter:action');
$grid->addColumnLink('link', 'Link:', 'Presenter:handle!');

U posledních dvou se pak odkaz generuje právě přes LinkGenerator, ale tam je problém s odkazem na signál / handle. Napadá mě teď ještě, že bych v komponentě Gridu mohl přistoupit k rodičovskému Presenteru a tam vyžít klasicky metodu $presenter->link(), ale nebude to asi už tak „čístý“ řešení.

EDIT: tak s tím Presenterem beru zpět, už jsem to vlastně před časem zkoušel a problém je ten, že když ho v komponentě Gridu chci předat např. do třídy pro vytváření odkazů, dostávám zpět: Component '' is not attached to ‚Nette\Application\UI\Presenter‘; tedy jestli to chápu dobře, že v momentě, kdy potřebuji generovat odkaz, není ještě componenta připojena k presenteru a tedy ho ani nemůžu využít, proto jsem dříve sáhl po LinkGeneratoru.

Editoval Yaromil (9. 1. 2019 10:02)

CZechBoY
Člen | 3608
+
0
-

A proč bys chtěl uvést odkaz na handle? Co ten handle jako dělá? Nedokážu si moc představit že bych uživatele poslal na nějakou stránku a hned by zároveň odeslal formulář nebo jak?

Pošli kod jak se snažíš použít komponentu dřív než je připojena k presenteru… Očekávám nějaký generování odkazu v konstruktoru nebo tak něco. V tom případě odkaz vygeneruj až při renderování (pokud je to možné).

Yaromil
Backer | 20
+
0
-

@CZechBoY V tomhle konkrétním případě komponenta Gridu vytváří v tabulce sloupec s AJAXovým odkazem, který otevře JS lightbox / modalní okno pro editování záznamu v DB. Handle používám právě díky potřebě AJAXového volání.

Dříve jsem to měl vyřešené tak, že jsem odkaz vytvářel až pomocí n:href makra přímo v šabloně Gridu, to fungovalo bez problémů i pro handle, ale od toho jsem musel upustit, protože odkazy nyní potřebuji vytvářet ve vlastní třídě za pomocí \Nette\Utils\Html::el(‚a‘).

Mám to aktuálně funkční, ale hledal jsem nějaké elegantnější řešení (třeba právě pomocí LinkGeneratoru), abych si nemusel odkazy na handle generovat v Presenteru kde se sestavuje komponenta Gridu.

Každopádně děkuji za ochotu!

CZechBoY
Člen | 3608
+
0
-

Na zobrazení nový stránky nemusíš dělat handle, stačí obyčejná akce přece. To že něco je ajax nebo není by nemělo znamenat že použiješ akci nebo handle.

Yaromil
Backer | 20
+
0
-

@CZechBoY Teď nevím, jestli si rozumíme, ale po kliknutí na vygenerovaný odkaz se volá pomocí AJAXu handle (vycházel jsem z dokumentace https://doc.nette.org/…n/presenters#…, kdy je uvedeno, že se používá po potřeby AJAXu) a v tom handlu mám definované něco ve smyslu:

$this->redrawControl(‚projectForm‘);
$this->payload->open_edit_modal = TRUE;

Poslední řádek mi právě pomocí JS otevře lightbox s formulářem pro editaci.

Nechci tedy otevírat novou stránku, ale jen překreslit snippet s formulářem a ten pak zobrazit pomocí JS v lightboxu.

CZechBoY
Člen | 3608
+
0
-

A ten formulář už teda ve stránce je a přes handle ho jen zobrazíš nebo formulář ve stránce ještě není?
Zobrazení lightboxu bych spíš dělal přes javascript než v php. V tom ajaxovém požadavku bych jen vykreslil formulář – což už může být klidně jen akce a žádný handle (protože není co překreslit, je potřeba to teprv poprvé vykreslit).

Milo
Nette Core | 1283
+
0
-

@Yaromil Link potřebuješ vygenerovat až v šabloně a když se šablona vykresluje, komponenta už musí být připojena k presenteru. Takže getPresenter()->link() je správná cesta, jen ji voláš moc brzo. Můžeš to volat rovnou ze šablony, nebo si udělat filtr.

LinkGenerator má pouze router, tedy resolvuje maximálně na úroveň presenteru. On o vnorenych komponentach nic neví.

Milo
Nette Core | 1283
+
0
-

Mimochodem, na makra {link} a {plink} jsi koukal?

Yaromil
Backer | 20
+
0
-

@Milo Díky moc za odezvu. Jo, teď tomu už rozumím, že LinkGenerator není vhodný pro generování všech odkazů. Ono jde jednoduše o to, jak jsem psal výše, že mám univerzální komponentu na generování tabulek / gridů a tam si můžu definovat sloupec jako odkaz, kde se pak automaticky generují na základě něčeho následujícího:

$grid->addColumnLink('link', 'Link', 'Presenter:action') // tady jsem chtěl docílit mít možnost Presenter:handle!
  ->setClass('ajax')
  ->setNewWindow(TRUE)
	  ...
	  ...;

a vzhledem k možnosti různých nastavení odkazů (viz. výše) mi přišlo čistější řešení si pak ve třídě Gridu generovat odkazy pomocí \Nette\Utils\Html::el(‚a‘) než si „zaprasit“ šablonu Gridu kvantem podmínek jen pro potřeby odkazů. Dále je taky dobré, že si můžu např. objekt HTML elementu vytáhnout a dál s ním pracovat.

Každopádně děkuji za radu!

Yaromil
Backer | 20
+
0
-

@CZechBoY Mám to udělané tak, že grid presentuje data z DB a nad každým řádkem pak jde dělat klasické operace ©RUD, kdy mám pro každou takovou operaci handle. Na stránce je skrytý shodný formulář, který se pro CREATE a UPDATE musí vždy upravit:

handleCreate:

  • vyresetuje formulář
  • případně nastaví další nastavení formuláře
  • překreslí snippet formláře
  • přes payload pošle do JS signál, ať zobrazí lightbox s formulářem

handleUpdate:

  • naplní formulář uloženými hodnotami z DB
  • případně nastaví další nastavení formuláře
  • překreslí snippet formláře
  • přes payload pošle do JS signál, ať zobrazí lightbox s formulářem

Pro každý řádek tabulky / akci je tedy formulář nutné nastavit a překreslit, viz. výše.

Když jde o větší formuláře nebo se zobrazení v lightboxu nehodí, pracuji klasicky s renderCreate, renderUpdate, apod.