Problém s vypsáním odkazu v n:href

Webster.K
Člen | 192
+
0
-

Zdravím všechny, narazil jsem na problém, kdy se snažím vypsat odkazy v cyklu v latte šabloně:

{foreach $rightMenu as $menuRow}
<li><a n:href="$menuRow['presenter']:$menuRow['action'] month:$menuRow['month'], year:$menuRow['year']">{$menuRow['name']}</a></li>
{/foreach}

To o co se snažím jsou automaticky generované odkazy, které se berou většinou z databáze a jsou tvořeny různým typem filtrování. Výsledek by mělo být rychlé menu, které na základě pár informací (presenter/akce, mesic/rok) vytvoří odkaz na tu konkrétní část aplikace. Bohužel končím na: Unexpected ‚:‘ (in ‚…/Home/default.latte‘ on line 47 at column 73).

Vím že to způsobuje dvojtečka v mezi $menuRow[‚presenter‘]:$menuRow[‚action‘] ale naprosto netuším, co udělat pro to, aby tomu nevadila.

Přišel jsem tedy na to, že když odkaz udělám tak, že tam nedám presenter, tedy není tam ani dvojtečka a nechám tam jen akci, tak to funguje tak jak má. Ale stále nevím, jak tímto způsobem odkázat na jiný presenter

Editoval Webster.K (4. 7. 2023 21:52)

m.brecher
Generous Backer | 762
+
-1
-

@WebsterK

Vím že to způsobuje dvojtečka v mezi $menuRow[‚presenter‘]:$menuRow[‚action‘]

V dokumentaci Nette je sice odkaz na akci aktuálního presenteru uveden BEZ dvojtečky:

https://doc.nette.org/…eating-links#…

<a n:href="default">úvodní stránka</a>

ale varianta s dvojtečkou FUNGUJE také (zkoušel jsem na Latte 3.0.6):

<a n:href=":default">úvodní stránka</a>  // funguje také

Pokud máš třeba starší verzi Latte, kde dvojtečka před akcí vadí, tak vyzkoušej ošetřit dvojtečku třeba takhle:

{var $presenter = $menuRow['presenter'] ? $menuRow['presenter'].':' : ''}
<a n:href="$presenter.$menuRow['action'] month:$menuRow['month'], year:$menuRow['year']">{$menuRow['name']}</a>
Marek Bartoš
Nette Blogger | 1177
+
+2
-

@mbrecher tohle je chyba kompilace, ne runtime

@WebsterK Zkus k Latte víc přistupovat jako k PHP a nespoléhej se na to, že stringy bez uvozovek budou vždy fungovat. Toto nejspíš bude fungovat:

<a n:href="$menuRow['presenter'] . ':' . $menuRow['action'] month:$menuRow['month'], year:$menuRow['year']">{$menuRow['name']}</a>

Editoval Marek Bartoš (5. 7. 2023 11:56)

m.brecher
Generous Backer | 762
+
0
-

@MarekBartoš

tohle je chyba kompilace, ne runtime

Já to vnímám jako chybu syntaxe, ale máš zase pravdu – unquoted latte string je ta skutečná příčina.

m.brecher
Generous Backer | 762
+
0
-

@WebsterK

Tak chyba je jak odhalil @MarekBartoš v syntaxi php výrazu uvnitř atributu n:href, tam se snadno dají udělat chyby.

V Latte je sice možné psát stringy i bez uvozovek, ale vede to do obtížně odhalitelných chyb, jak je třeba tato. Stringy v Latte mohou být bez uvozovek, ovšem pouze za splnění celé řady podmínek – viz. dokumentace:

https://latte.nette.org/cs/syntax#…

Latte tedy umí „doplnit“ uvozovky unquoted stringu např. zde:

<a n:href="Homepage:default">Link</a>

ale tady už vyhodí výjimku – protože to není jednoduchý string – obsahuje php proměnnou:

<a n:href="$presenter:default">Link</a>

Jednoduchý string je:

„Jednoduché řetězce jsou ty, které jsou tvořeny čistě z písmen, číslic, podtržítek, pomlček a teček. Nesmí začínat číslicí a nesmí začínat nebo končit pomlčkou. Nesmí být složený jen z velkých písmen a podtržítek, protože pak se považuje za konstantu (např. PHP_VERSION). A nesmí kolidovat s klíčovými slovy: and, array, clone, default, false, in, instanceof, new, null, or, return, true, xor.“

Stačí tedy použít php syntaxi stringů – přesněji syntaxi php výrazu:

<a n:href="$presenter.':default'">Link</a>
MajklNajt
Člen | 471
+
0
-

nebolo by jednoduchšie si tie linky vygenerovať v presenteri cez $this->link(…) a v šablóne ich iba preiterovať a vypísať?

m.brecher
Generous Backer | 762
+
-1
-

@MajklNajt

nebolo by jednoduchšie si tie linky vygenerovať v presenteri cez $this->link(…) a v šablóne ich iba preiterovať a vypísať?

šlo by to, ale je to již lehce za hranou MVC, protože formátování odkazu sice Nette presenter nabízí, ale pokud máme latte šablonu, přehlednější je formátovat odkaz tam. Na to se hodí tag {var}, kde zformátujeme data do přehledných proměnných a ihned použijeme v n:href – třeba takto:

{var
    $presenterAction = $menuRow['presenter'].':'.$menuRow['action'],
    $month = $menuRow['month'],
    $year = $menuRow['year'],
}
<a n:href="$presenterAction, month: $month, year: $year">...</a>
MajklNajt
Člen | 471
+
+3
-

@m.brecher práveže vytvárať takýmto spôsobom odkaz v šablóne, a teda zanášať tam nejakú logiku, je podľa mňa za hranou MVC… ale zrejme to je vec názoru

m.brecher
Generous Backer | 762
+
0
-

@MajklNajt

vytvárať takýmto spôsobom odkaz v šablóne, a teda zanášať tam nejakú logiku

No, nakonec souhlasím, že záleží na úhlu pohledu. Důvody proč je lepší formátovat odkaz v šabloně jsou praktické: a) menší pracnost – konstrukce url odkazů v presenteru je jeden foreach navíc, b) přehlednost – sestavením url odkazu mimo šablonu není pak v šabloně poznat, kam odkaz vede.

Kamil Valenta
Člen | 762
+
+2
-

Jsou chvíle, kdy mi připadá nejpřehlednější:

<a href="{plink $menuRow['presenter'].':'.$menuRow['action'], ['month'=>$menuRow['month'], 'year'=>$menuRow['year']]}">

Je to obdoba přípravy v presenteru pomocí ->link(). Chystání v presenteru začne být peklo ve chvíli, kdy podoba odkazu začne procházet nějakými IFy…

Webster.K
Člen | 192
+
0
-

Díky všem za hodnotné odpovědi. Chyba byla opravdu v tom, co psal @MarekBartoš, upravení o

.':'.

problém vyřešila.

Generovat odkazy nechci někde úplně jinde z několika důvodu (funkce kterou tahám z modelu by to asi zvládla, a mohla by rovnou vytvářet odkazy které si uložím do pole/objektu a nějak s nimi dále pracuji. Problém je hlídání odkud volám – ne že bych to technicky nezvládnul, ale celkový běh programu je o trochu delší a zabere více prostředků – dělat to v latte je z nějakého důvodu rychlejší a navíc pro mě přehlednější). Z databáze se natáhne jen rádek/vice radku kde je vše a nahází do pole které se přes jeden cyklus v šabloně vykreslí.

Jde o část vložené šablony která vykresluje určitý typ menu (jde o Bootstrap btn-group u grafu a přehledu která je na stránce několikrát a ve všech možných přehledech). Tuto šablonu používám, když potřebuji zobrazit jiné měsíce/roky v grafech, ale zároveň ne každý graf je stejný a k němu občas potřebuji připravit úplně jiný přehled (jina šablona reagující na action a další). V praxi tak některé věci se zobrazují jako donut, jiné jako sloupcový a tak dále a mají k sobě pak i různé tabulky pokud tam jsou data. Celkově je to trochu složitější :) a musí to reagovat na data v DB.

Určitě by se tedy dalo vyřešit volání funkce s více parametry a více proměnnými, ale hůře se to pak celé dává do cache. Jednodušší je zavolat funkci která načítá z DB víceméně to samé a já si to jen pres cyklus vezmu z ní ven a sestavím v latte, kde přesně vidím, co jí tam cpu. Jde tam o to, že k nekterym mesicum nejsou od uzivatele vyplnene jeste podrobnejsi data, ktere prave potrebuji vykreslovat v tabulce a jinych typech grafu nez jen rychly zakladni prehled – proto potreba volat jine akce/presentery. A porad je to jen seznam dat z tabulky v DB, kde jen je sloupec presenter a action, takze v menu to jen jednoduse vykresluji a nemusim nekde k tomu neco dohledavat

Editoval Webster.K (9. 7. 2023 13:26)