formulář a routy
- TeeBee87
- Člen | 14
Zdravím. Snažím se vytvořit routu pro detail produktu.
Url by měla vypadat takto: http://shop.cz/…/sporak-bily.
Na stránce je formulář s objednáním produktu.
Pokud použiju SimpleRouter a do action formuláře přidám category a product,
tak vše funguje jak má.
<?php
$router[] = new SimpleRouter(array(
'presenter' => 'Default',
'action' => 'default',
));
$form->setAction($form->getAction() . '&category='.$categoryUrl.'&product='.$productUrl);
?>
Nedaří se mi ale zprovoznit formulář s pěknými url. Vždycky v action formuláře dostanu No route for Default:detail(do=buy-submit).
<?php
$router[] = new Route('<category>/<product>', array(
'presenter' => 'Default',
'action' => 'detail'
));
?>
Stejně je to i se signály. Pokud na detailu produktu použiju handleNeco, tak to zahlásí, že neexistuje routa. Proč se to nedá za otazník http://shop.cz/…/sporak-bily?do=.. jako vždy? Co dělám špatně?
Díky za jakoukoli radu.
php 5.3.0
nette 0.9.2
- redhead
- Člen | 1313
měl bys to dělat přes metodu link:
$form->setAction($this->link("Presenter:action", $categoryUrl, $productUrl));
//nebo parametry jmenovitě
$form->setAction($this->link("Presenter:action", array('category' => $categoryUrl, 'product' => $productUrl));
Editoval redhead (29. 12. 2009 14:26)
- Ondřej Mirtes
- Člen | 1536
Já si myslím, že bys to měl dělat jinak. Tohle není podle MVC. Čeho
chceš dosáhnout? :) Přesměrování na výsledek bys měl nejspíš
provádět v submitovací metodě formuláře, kde už to jde nějak hezky
(přes $this->redirect()
).
A v routách ti nejspíš chybí taková ta obecná:
$router[] = new Route('<presenter>/<action>', array(
'presenter' => 'Default',
'action' => 'default',
));
- TeeBee87
- Člen | 14
Ondřej Mirtes napsal(a):
Já si myslím, že bys to měl dělat jinak. Tohle není podle MVC. Čeho chceš dosáhnout? :) Přesměrování na výsledek bys měl nejspíš provádět v submitovací metodě formuláře, kde už to jde nějak hezky (přes
$this->redirect()
).A v routách ti nejspíš chybí taková ta obecná:
$router[] = new Route('<presenter>/<action>', array( 'presenter' => 'Default', 'action' => 'default', ));
Kdybych použil tuto routu tak mi nebude fungovat url ve tvaru kategorie/produkt. Chci dosáhnout toho, aby bylo možné odeslat formulář z url: domaci-spotrebice/sporak-bily nejlépe tak, že se za tuto url přidá parametr do – z toho stavu už pak přesměruji zpět třeba pomocí $this->redirect(‚this‘);
- TeeBee87
- Člen | 14
redhead napsal(a):
měl bys to dělat přes metodu link:
$form->setAction($this->link("Presenter:action", $categoryUrl, $productUrl)); //nebo parametry jmenovitě $form->setAction($this->link("Presenter:action", array('category' => $categoryUrl, 'product' => $productUrl));
Díky! Tohle mě nenapadlo. Nevíš ještě prosím jak do action formuláře dostat elegantně parametr, aby se tento formulář zpracoval? (?do=addProduct-submit)
- Ondřej Mirtes
- Člen | 1536
Kouzlo Nette je ale v tom, že by ses o URL neměl starat – nevidíš sám, jak je to kostrbaté?
Pokud tuto routu dáš jako poslední, tak ti nic nepožere a vše bude fungovat, jak má. Možná ale chyba v její absenci není, nevím.
Formuláře jsou myšleny tak, že odeslaný (a validní formulář) ti
zpracuje metoda, která je nejčastěji ve stejném Presenteru jako továrnička
daného formuláře (aby to bylo pěkně pohromadě). Po úspěšném
zpracování formuláře můžeš uživatele poslat, kam chceš, pomocí
$this->redirect()
která jako parametry přebírá cílový
Presenter:action a jejich parametry – stejně jako makro {link}
v šablonách.
Předpokládám, že ta cílová adresa stejně závisí na hodnotách,
které uživatel ve formuláři odešle, takže je nemůžeš nastavit
v továrničce, kam $form->setAction()
patří.
- TeeBee87
- Člen | 14
<?php
$router[] = new Route('kosik', array(
'presenter' => 'Default',
'action' => 'basket'
));
$router[] = new Route('<category>/<product>', array(
'presenter' => 'Default',
'action' => 'detail'
));
?>
Odkaz na detail produktu dělám takto:
<a href=„{plink Default:detail, ‚category‘ ⇒ $product->categoryUrl, ‚product‘ ⇒ $product->url}“>{$product->name}</a>
Pokud na stránce s košíkem vytvořím formulář má action takovou:
kosik?do=buy-submit
Pokud formulář vytvořím na stránce s detailem produktu dostanu: error: No
route for Default:detail(do=buy-submit)
Proč? Mám chybu v routách? Pokud na detailu produktu vytovořím url ručně – v RoutingDebuggeru se to matchne dobře.
Tady jsou všechny routy:
<?php
$router[] = new Route('index.php', array(
'presenter' => 'Default',
'action' => 'default',
), Route::ONE_WAY);
$router[] = new Route('', array(
'presenter' => 'Default',
'action' => 'default'
));
$router[] = new Route('kontakty', array(
'presenter' => 'Default',
'action' => 'contact'
));
$router[] = new Route('kosik', array(
'presenter' => 'Default',
'action' => 'basket'
));
$router[] = new Route('admin/<action>', array(
'presenter' => 'Admin',
'action' => 'default'
));
$router[] = new Route('<category>', array(
'presenter' => 'Default',
'action' => 'products'
));
$router[] = new Route('<category>/<product>', array(
'presenter' => 'Default',
'action' => 'detail'
));
?>
- Ondřej Mirtes
- Člen | 1536
Tuhle vymaž:
$router[] = new Route('', array(
'presenter' => 'Default',
'action' => 'default'
));
A tuhle dej na konec:
$router[] = new Route('<presenter>/<action>', array(
'presenter' => 'Default',
'action' => 'default',
));
Mělo by to začít fungovat líp.
A určitě by tam šly udělat i další optimalizace :) Máš holt spoustu věcí narvaných v DefaultPresenteru.
Editoval Ondřej Mirtes (29. 12. 2009 18:48)
- TeeBee87
- Člen | 14
Ondřej Mirtes napsal(a):
Tuhle vymaž:
$router[] = new Route('', array( 'presenter' => 'Default', 'action' => 'default' ));
A tuhle dej na konec:
$router[] = new Route('<presenter>/<action>', array( 'presenter' => 'Default', 'action' => 'default', ));
Mělo by to začít fungovat líp.
A určitě by tam šly udělat i další optimalizace :) Máš holt spoustu věcí narvaných v DefaultPresenteru.
Dík! Jsi profík ;)
- dotTwelve
- Člen | 167
Mam podobny problem, asi taky bude chybka nekde v routach.
Na vypisu produktu mam formular, pro ktery nenastavuji setAction a defaultne se
nastavi: /produkty/show/5?do=orderForm-submit
ale potrebuji:
produkty/plavani-a-opalovani/bikiny?do=orderForm-submit
, nebo jeste
lepe produkty/plavani-a-opalovani/bikiny/objednat
. Po odeslani
stejne presmeruji pomoci $this->redirect('this')
takze na te url
ani tolik nezalezi.
V sablone odkazuji takto:
{plink Products:show, $category => $category->id, $id => $product->id}
Zde je muj kompletni router:
<?php
Route::addStyle('#cs-presenter', 'presenter');
Route::addStyle('#cs-action', 'action');
Route::setStyleProperty('#cs-presenter', Route::FILTER_TABLE, array(
'uvod-strana' => 'Default',
'historie' => 'History',
'prodejny' => 'Shops',
'kontakt' => 'Contact',
'produkty' => 'Products'
));
Route::setStyleProperty('#cs-action', Route::FILTER_TABLE, array(
'hity-sezony' => 'hits'
));
$router[] = new Route('admin/<presenter>/<action>/<id>', array(
'module' => 'Admin',
'presenter' => 'Default',
'action' => 'default',
'id' => NULL
));
Route::addStyle('#category');
Route::setStyleProperty('#category', Route::FILTER_IN, 'getCategoryId');
Route::setStyleProperty('#category', Route::FILTER_OUT, 'getCategoryName');
function getCategoryId($url) {
$id = new CategoriesModel;
return $id->getIdByUrl($url);
}
function getCategoryName($id) {
$name = new CategoriesModel;
return $name->getUrlById($id);
}
Route::addStyle('#product');
Route::setStyleProperty('#product', Route::FILTER_IN, 'getProductId');
Route::setStyleProperty('#product', Route::FILTER_OUT, 'getProductName');
function getProductId($url) {
$id = new ProductsModel;
return $id->getIdByUrl($url);
}
function getProductName($id) {
$name = new ProductsModel;
return $name->getUrlById($id);
}
$router[] = new Route('hity-sezony', array(
'module' => 'Front',
'presenter' => 'Products',
'action' => 'hits',
'category' => NULL
));
$router[] = new Route('produkty/<category #category>', array(
'module' => 'Front',
'presenter' => 'Products',
'action' => 'default',
'category' => NULL
));
$router[] = new Route('produkty/<category #category>/<id #product>', array(
'module' => 'Front',
'presenter' => 'Products',
'action' => 'show',
'category' => NULL,
'id' => NULL
));
$router[] = new Route('<presenter #cs-presenter>/<action #cs-action>/<id>', array(
'module' => 'Front',
'presenter' => 'Default',
'action' => 'default',
'id' => NULL
));
$router[] = new Route('', array(
'module' => 'Front',
'presenter' => 'Default',
'action' => 'default',
), Route::ONE_WAY);
?>
Diky za jakekoliv nakopnuti…
Editoval dotTwelve (6. 7. 2010 18:23)