formát URL handle komponenty
- d@rkWolf
- Člen | 167
Prosím, poradil by někdo? Vytvořil jsem si komponentu k zobrazování mapy(potřebuju ju trochu upravenou zobrazit na 2 místech) a mám problém s url, co vytváří handle v té komponentně. Linky, co se vytvoří v šabloně komponenty vypadají takto:
domena/contact?mapsComponent-slug=australia&do=mapsComponent-Country
- Jak tu generovanou adresu upravit na něco normálního(nejlíp tak jenom ?country=australia)? Nedaří se mi na nic přijít, zkoušel sem to nějak vložit do routru, ale buď to neudělalo nic, nebo to crashlo… Mám to nastavené při kliku na provádění ajaxem(Naja) a takto se mi to při kliku na odkaz propíše do url.
- Jak to url potom přenést do té komponenty v případě, že to někdo zadá do adresního řádku? Chtěl bych, aby to bylo přístupné, když se třeba pošle odkaz emailem. Můžu je vzít v Presenteru přes getParameters, ale kam co pak dát?
Dík za radu.
IMapsComponentFactory
<?php
interface IMapsComponentFactory
{
/**
* @return MapsComponent
*/
public function create(): MapsComponent;
}
?>
MapsComponent
<?php
class MapsComponent extends UI\Control
{
/** @var string $templateFile */
private $templateFile = __DIR__ . '/MapsComponent.latte';
public $country;
public $locations = [];
...constructor předává translator, naplní to $locations sezname z DB...
public function handleCountry(string $slug)
{
foreach ($this->locations as $country) {
if ($country->slug === $slug) {
$this->country = $country->id;
}
}
$this->template->countryId = $this->country;
if ($this->presenter->isAjax()) {
$this->redrawControl('mapLeft');
} else {
$this->redirect('this');
}
}
public function render()
{
$this->template->countries = $this->locations;
$this->template->setFile($this->templateFile);
$this->template->render();
}
...
}
?>
MapsComponent.latte
<?php
...
<ul class="list-unstyled">
<li n:foreach="$countries as $country">
<a class="ajax" n:href="Country, $country->slug" rel="nofollow">{$country->name}</a>
</li>
</ul>
...
?>
presenter
<?php
final class ContactPresenter extends BasePresenter
{
...
protected function createComponentMapsComponent(): MapsComponent
{
return $this->MapsComponentFactory->create();
}
...
}
?>
a v default.latte už jen {control mapsComponent}
- Milo
- Nette Core | 1283
Parametry mapsComponent-slug=australia
a
do=mapsComponent-Country
představují stav komponenty, který se
přenáší v URL. A jejich jméno vzniká automaticky podle toho, jak je
komponenta připojena do stromu komponent. Ty se tak vůbec o URL starat
nemusíš a píšeš jen handle metody. Tuhle celou automatiku nemusíš
použít a stav komponenty budeš udržovat ručně.
Komponenta
final class MapsControl ...
{
private $slug;
public function setSlug(?string $slug)
{
# validace
$this->slug = $slug;
}
}
Presenter:
public function actionXyz(string $slug = null): void
{
$this['mapsComponent']->setSlug($slug);
}
A parametr slug
už si v URL naroutuješ, jak je potřeba.
V komponentě potřebuješ potom vytvářet URL na změnu země. To se dá
udělat buď přes presenter $this->presenter->link(...)
nebo
{plink ...}
ale komponenta přestane být znovupoužitelná.
Řešením je předat si do komponenty callback, který URL generuje.
Komponenta:
public function __construct(..., callable $urlGenerator)
{
...
}
Továrna:
interface IMapsComponentFactory
{
public function create(callable $urlGenerator);
}
Presenter:
protected function createComponentMapsComponent(): MapsComponent
{
return $this->mapsComponentFactory->create(function (string $country) {
return $this->link('xyz', ['slug' => $country]);
});
}
- d@rkWolf
- Člen | 167
@Milo Já úplně netuším, jak to pak ale naroutovat? Ty stránky, co v nich ta komponenta bude se mi routují přes výchozí routu:
<?php
$router->withModule('Front')
->addRoute('[<locale=en en|cs>/]<presenter>[/<action>[/<id>]]', [
'presenter' => 'Homepage',
'action' => 'default',
'id' => null,
]);
?>
Netuším, jak to tam přidat, aby to vypadalo nějak takto třeba domena/kontakt?country=australia?
Jako já bych se asi i bez té url obešel, ale z nějakého důvodu se mi adresa toho handle teď s Najou propisuje do adresy, tahleta věc byla dřív použitá s nette.ajax na staré verzi a tam se to do adresy nepropisovalo.
Editoval d@rkWolf (20. 5. 2020 11:06)
- Milo
- Nette Core | 1283
Aha. Tak to byl ode mě trochu overengineering :-)
Zkus tomu linku přidat atribut data-naja-history="off"
- d@rkWolf
- Člen | 167
No jako ona se mi ta možnosti s funkčním linkem a history líbí, ale mám problém s rozchozením routování, systému routování v Nette furt nějak nemůžu přijít na kloub(teď sem zrovna zjistil, že mi web crashne, když někdo zadá domena/abc.abc, nechápu proč, dle mě je to normální neexistující adresa a mělo by vypadnout 404, ne 500)… Pravděpodobně to vyzkouším, ale napřed to zprovozním bez toho, zkusím tam dát to history=off a toto zařadím do pole upgradů.
Editoval d@rkWolf (21. 5. 2020 20:10)