Chování (podivné?) linkCurrent, isLinkCurrent v komponentě

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

V administraci potřebuji jeden formulář pro různé jazykové verze (zde zrovna nastavení SEO serepetiček). Přepínání je vizuálně řešeno jako záložky (zobrazení má na starosti komponenta Tabs).

Akorát nejsem schopný zjistit, zda je právě zobrazená stránka active (current), nebo není. Chování metody isLinkCurrent() a property linkCurrent mi není úplně jasný, dává jiné výsledky než bych očekával.

Presenter a vytvoření záložek:

public function renderDefault(){
	$langs = $this->langs->getAvailableLangs();
	foreach($langs as $key => $val){
		$this->getComponent('tabs')->addTab($val, $this->link(':'.$this->getName().':'.$this->getAction(), ['lang' => $val]), 'admin.langs.'.$val);
	}
}

Komponenta Tabs (extends Nette\Application\UI\Control):

/** @var array */
private $items = [];

public function addTab($key, $link, $name){
	if($link){
		$current = $this->getPresenter()->linkCurrent;
	}
	$this->items[$key] = [
		'name' => 			$this->translator->translate($name),
		'link' => 			$link,
		'current' => 		isset($current) ? $current : FALSE,
	];
}

Výsledek testování $this->getPresenter()->linkCurrent:

Vygenerované odkazy záložek:

  • /admin/settings/seo/?lang=cs
  • /admin/settings/seo/?lang=en
  1. Aktuální odkaz: /admin/settings/seo/
  • Záložka CS: /admin/settings/seo/?lang=cs, $current = FALSE, OK
  • Záložka EN: /admin/settings/seo/?lang=en, $current = FALSE, OK
  1. Aktuální odkaz: /admin/settings/seo/?lang=cs
  • Záložka CS: /admin/settings/seo/?lang=cs, $current = TRUE, OK
  • Záložka EN: /admin/settings/seo/?lang=en, $current = FALSE, OK

Další test
Změním generování odkazu záložky tak, že se u výchozího jazyka parametr lang neuvádí:

public function renderDefault(){
	$langs = $this->langs->getAvailableLangs();
	foreach($langs as $key => $val){
		$params = ($key != $this->langs->getDefaultLang()) ? ['lang' => $val] : [];
		$this->getComponent('tabs')->addTab($val, $this->link(':'.$this->getName().':'.$this->getAction(), $params), 'admin.langs.'.$val);
	}
}

Vygenerované odkazy záložek:

  • /admin/settings/seo/
  • /admin/settings/seo/?lang=en

Výsledek testování:

  1. Aktuální odkaz: /admin/settings/seo/
  • Záložka CS: /admin/settings/seo/, $current = TRUE, OK
  • Záložka EN: /admin/settings/seo/?lang=en, $current = FALSE, OK
  1. Aktuální odkaz: /admin/settings/seo/?lang=en
  • Záložka CS: /admin/settings/seo/, $current = TRUE, ??? zde očekávám FALSE
  • Záložka EN: /admin/settings/seo/?lang=en, $current = TRUE, OK

Výsledek testování $this->getPresenter()->isLinkCurrent($link):
No a to už vůbec nechápu. Když $current = $this->getPresenter()->linkCurrent; v metodě addTab() nahradím za $current = $this->getPresenter()->isLinkCurrent($link);, tak získám všude $current = FALSE.

Určitě zase dělám něco špatně nebo jsme něco špatně pochopil, ale opravdu nevím, kde je chyba. Poraďte prosím, děkuji.

Editoval flamengo (27. 8. 2016 13:38)

GEpic
Člen | 566
+
0
-

Argumenty musíš předávat zvlášť v druhém parametru:
https://api.nette.org/…ent.php.html#…

Editoval GEpic (27. 8. 2016 13:43)

flamengo
Člen | 135
+
0
-

@GEpic Díky, to je ono. Metoda isLinkCurrent() šlape v pořádku, ale nevíš, proč to nešlape u $this->getPresenter()->linkCurrent?

GEpic
Člen | 566
+
0
-

Do isLinkCurrent() metody vždy předávám link a argumenty v Nette formátu (‚<Modul:>Presenter:Akce‘), nikoli přímo ‚odkaz‘, který ty generuješ přes $this->link().

K čemu slouží property linkCurrent nevím, vrací boolean, ale nevím čeho.

Editoval GEpic (27. 8. 2016 14:47)

Martk
Člen | 661
+
0
-

@flamengo Nech generování tak jako to máš prvně a nastav v routeru výchozí hodnotu lang na cs. Nebude se ti generovat /admin/settings/seo/?lang=cs, ale jen /admin/settings/seo/ a u /admin/settings/seo/?lang=en by ti u českého jazyka mělo hodit na false.

@GEpic „property“ linkCurrent bere v potaz poslední generovanou url př.

<a n:href="Shop:item id => $id" n:class="$presenter->isLinkCurrent('Shop:basket', [id => $id]) ? active">

je totožné s

<a n:href="Shop:basket id => $id" n:class="$presenter->isLinkCurrent() ? active">

Editoval Antik (27. 8. 2016 16:14)

GEpic
Člen | 566
+
0
-

Antik napsal(a):

@flamengo Nech generování tak jako to máš prvně a nastav v routeru výchozí hodnotu lang na cs. Nebude se ti generovat /admin/settings/seo/?lang=cs, ale jen /admin/settings/seo/ a u /admin/settings/seo/?lang=en by ti u českého jazyka mělo hodit na false.

@GEpic „property“ linkCurrent bere v potaz poslední generovanou url př.

<a n:href="Shop:item id => $id" n:class="$presenter->isLinkCurrent('Shop:basket', [id => $id]) ? active">

je totožné s

<a n:href="Shop:basket id => $id" n:class="$presenter->isLinkCurrent() ? active">

Nemyslel si:

<a n:href="Shop:basket id => $id" n:class="$presenter->linkCurrent ? active">

? :)

Jinak super, taková property pro lenochy, určitě se bude hodit.

Martk
Člen | 661
+
+1
-

Ne :) rozdíl je jen v tom, že moje verze není magická a je o něco rychlejší. Tvoje je získaná přes __get.

GEpic
Člen | 566
+
0
-

Antik napsal(a):

Ne :) rozdíl je jen v tom, že moje verze není magická a je o něco rychlejší. Tvoje je získaná přes __get.

Ah, tak teď už chápu i já… pořád jsem přemýšlel jak spolu linkCurrent as isLinkCurrent() souvisí, když jsem projížděl třídu Component, tak jsem k tomu nedošel.

Editoval GEpic (27. 8. 2016 22:26)

flamengo
Člen | 135
+
0
-

@Antik Zkusil jsem lang dát do routy a jako výchozí hodnotu nastavil cs. Odkazy se generují jak píšeš (samozřejmě hehe):

  • /admin/settings/seo/ – pro CZ verzi
  • /admin/settings/seo/en/ – pro EN verzi

Ale problém je, že $current = $this->getPresenter()->linkCurrent; v metodě addTab() nefunguje, jak má (asi). Tedy vlastně to, co už jsme psal výše a důvod založení této diskuse.

1. Aktuální odkaz: /admin/settings/seo/

  • Záložka CS: /admin/settings/seo/, $current = TRUE, OK
  • Záložka EN: /admin/settings/seo/en, $current = FALSE, OK

2. Aktuální odkaz: /admin/settings/seo/en/

  • Záložka CS: /admin/settings/seo/, $current = TRUE, ??? zde očekávám FALSE
  • Záložka EN: /admin/settings/seo/en/, $current = TRUE, OK

V šabloně to řešit nemůžu, protože záložky mám i víceúrovňové a označení active potřebuji i u nadřazených záložek. Vyřešit to pomocí magické property $current = $this->getPresenter()->linkCurrent by bylo podle mě ideální, ale nefunguje to.

Řešení pomocí metody $current = $this->getPresenter()->isLinkCurrent() funguje, ale to musím metodě addTab() předávat všechny argumenty, ze kterých se skládá odkaz, abych mohl následně v metodě addTab() otestovat, zda se jedná o aktivní odkaz. Ale jinak to asi nepůjde to vypadá.

Nebo tam mám pořád někde nějakou botu a nevím kde.

Martk
Člen | 661
+
+2
-

Zkoušel jsem si vyzkoušet jednoduše toto:

Router

$router = new RouteList;
$router[] = new Route('[<lang=cs>]', 'Homepage:default');

Presenter

dump($this->link('Homepage:default', ['lang' => 'cs']));
dump($this->isLinkCurrent());
dump($this->link('Homepage:default', ['lang' => 'en']));
dump($this->isLinkCurrent());

A funguje vše jak má, když jsem na adrese homepage/default/
cs = true
en = false

homepage/default/en
cs = false
en = true

Předělal jsi toto:

public function renderDefault(){
    $langs = $this->langs->getAvailableLangs();
    foreach($langs as $key => $val){
        $params = ($key != $this->langs->getDefaultLang()) ? ['lang' => $val] : [];
        $this->getComponent('tabs')->addTab($val, $this->link(':'.$this->getName().':'.$this->getAction(), $params), 'admin.langs.'.$val);
    }
}

na

public function renderDefault(){
    $langs = $this->langs->getAvailableLangs();
    foreach($langs as $key => $val){
        $this->getComponent('tabs')->addTab($val, $this->link(':'.$this->getName().':'.$this->getAction(), ['lang' => $val]), 'admin.langs.'.$val);
    }
}

lang musí být v parametru, i když je výchozí

Editoval Antik (28. 8. 2016 14:53)

flamengo
Člen | 135
+
+1
-

@Antik Díky moc, to bylo přesně ono. Takže aby magická property $this->getPresenter()->linkCurrent poznala, že se jedná o aktivní odkaz, tak je třeba vždy uvést všechny parametry přestože jsou v routě nastaveny výchozí hodnoty. Ještě jednou díky.