Problem s pouzitim modulu a jejich routovanim
- argoneus
- Člen | 14
Zdravim, mam tuto strukturu ve slozce „app“:
GlobalModule
- Presenters
- BasePresenter
- ErrorPresenter
- Templates
- Error
FrontModule
- Presenters
- HomepagePresenter
- Templates
- Homepage
Jenze kdyz otevru localhost, tak to hlasi, ze nemuze najit HomepagePresenter.php. Nejspise spatne chapu moduly a zaroven nevim, jak je spravne naroutovat. Take nevim, zda se maji vyuzivat namespacy v teto situaci a jak. Nasmeruje me nekdo prosim spravnym smerem?
Predem dekuji!
- argoneus
- Člen | 14
On bude ten problem prave v routovani, ja uprimne moc nevim, jak pracovat s routerem, kdyz mam nejake moduly jako prave v tomhle pripade, v dokumentaci jsem o tom moc nenasel.. Takze nastaveni routeru je defaultni jako v sandboxu.
Chyba je obycejna:
Cannot load presenter ‚Homepage‘, class ‚HomepagePresenter‘ was not
found in ‚cesta/app/presenters/HomepagePresenter.php‘.
Editoval argoneus (12. 6. 2013 23:39)
- Šaman
- Člen | 2666
Njn, tak to musíš do routeru (v RouteFactory) přidat modul.
<?php
$router = new RouteList();
$router[] = new Route('index.php', 'Front:Homepage:default', Route::ONE_WAY);
$router[] = new Route('<module>/<presenter>/<action>[/<id>]', 'Front:Homepage:default');
?>
Mimochodem stejně tak budeš muset rozšířit všechny linky mimo aktuální modul.
//edit: Teď se dívám na tu tvoji strukturu presenterů a mám obavu, že
jsi buď nepochopil funkci modulů, anebo já nepochopil tu tvou strukturu.
Modul je něco jako část aplikace, řekněmež frontend a odděleně třeba
administrace, nebo samostatná fotoknihovna. Ten tvůj GlobalModule vůbec nemá
smysl, to není logická část aplikace.. Rozhodně není běžné, aby od sebe
dědily třídy v různých modulech. Moduly mají oddělit určité
logické/programovací celky.
Editoval Šaman (13. 6. 2013 0:03)
- vitkutny
- Člen | 73
Předpokládám že máš výchozí routy ze sandboxu, podle chyby se ti
snaží načíst presenter který není umístěný v žádném modulu.
Začni přepsáním routy
$router[] = new Route('index.php', 'Homepage:default', Route::ONE_WAY);
ta se spouští jako první když příjdeš na stránku a slouží k přesměrování na výchozí presenter… v tomto případě se přesměruje na Homepage:default mimo moduly.. aby přesměrovala do modulu Front:
$router[] = new Route('index.php', 'Front:Homepage:default', Route::ONE_WAY);
pro modul si vytvoř routelist
$front = $router[] = new RouteList('Front');
$front[] = new Route('front/<presenter>/<action>',array(
'presenter' => 'Homepage',
'action' => 'default',
));
- argoneus
- Člen | 14
@Saman: No, bylo to mysleno tak, ze mam moduly Front a Admin a nad nima je nejakej „globalni“ prostor, kterej je pro oba spolecnej…
Jestli to spravne chapu, tak bych mel v tom pripade teda mit strukturu jako:
Site:
- Front
- Admin
Pricemz v Site bude Basepresenter a tak? Nebo i to je spatne?
@vitkutny: Jakoze kazdej modul ma svuj vlastni Router? Nebo jak presne bude fungovat ten $front?
Editoval argoneus (13. 6. 2013 0:17)
- Šaman
- Člen | 2666
BasePresenter bude nad nimi, není součástí modulů. Samozřejmě může mít každý modul i svůj FrontBasePresenter.. Presentery jsou (skoro obyčejné) třídy, mohou dědit odkud chtějí a na moduly to nemá vliv. Moduly jsou klíčové jen při routerování, tedy pro presentery na které se ná odkázat.
- hAssassin
- Člen | 293
Module Site mit muzes, ale je to trochu zbytecny. Bude ti stacit takovato struktura:
app
-AdminModule
- presenters
- BasePresenter
- ErrorPresenter
- templates
- Error
- FrontModule
- presenters
- BasePresenter
- HomepagePresenter
- templates
- Homepage
- presenters
- BasePresenter
Kazdopadne nechapu Šamana co mysli tim, ze:
Namespaces v presenterech zvládá až verze 2.1
, protoze to je
blbost a namespaces musis uvadet (ona to uplna blbost neni, ale s tim ze
vlastni namespaces zvlada az 2.1). Ale pokud chces pouzivat
moduly, musis presentery v danym modulu mit v namespace onoho modulu. Mrkni do
examples/Modules-Usage
a snad to pochopis, jen bacha (na gitu je to
uz prave pro verzi 2.1).
Takze pokud pouzivas starsi verzi, tak kazdy presenter v modulu musi mit
namespace <Name>Module a ty co v zadny modulu nejsou, nebudou mit ani
namespace, ale pak se na ne musis odvolavat globalne, napr.
\BasePresenter
(to je ten ze slozky app/presenters
).
Struktura vc. namespaces pak bude takovato:
app
-AdminModule
- presenters
- BasePresenter // namespace AdminModule; extends \BasePresenter
- DefaultPresenter // namespace AdminModule; extends \BasePresenter
- templates
- Error
- FrontModule
- presenters
- BasePresenter // namespace FrontModule; extends \BasePresenter
- HomepagePresenter // namespace FrontModule; extends \BasePresenter
- templates
- Homepage
- presenters
- BasePresenter // (zadne namespace) extends \Nette\UI\BasePresenter
Pokud ti to fungovat nebude, bude potreba jeste upravit router, ale nejdriv to zkus a kdyztak rekni, co ti to hazi za chybu.
PS: router bys mel upravit podobne jako v bootstrpu danyho prikladu nejak takto:
$container->router[] = new Route('index.php', 'Front:Default:default', Route::ONE_WAY);
$container->router[] = $adminRouter = new RouteList('Admin');
$adminRouter[] = new Route('admin/<presenter>/<action>', 'Default:default');
$container->router[] = $frontRouter = new RouteList('Front');
$frontRouter[] = new Route('<presenter>/<action>[/<id>]', 'Default:default');
@Šaman > co znamena prosimte toto:
Presentery jsou (skoro obyčejné) třídy, mohou dědit odkud chtějí
?
Neni to dalsi nesmysl? Resp. ano, muzou dedit odkud chteji (treba z Marsu, nebo
Venuse) a na moduly to mit vliv nebude, ale bude ti pak vubec neco spravne
fungovat (router, sablony, …)?
Editoval hAssassin (13. 6. 2013 9:27)
- argoneus
- Člen | 14
No, tak jsem router zkusil udelat nejak takto:
/**
* @return Nette\Application\IRouter
*/
public function createRouter()
{
$router[] = $frontRouter = new RouteList('Front');
$frontRouter = new Route('index.php', 'Homepage:default');
$frontRouter = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');
$router[] = $adminRouter = new RouteList('Admin');
$adminRouter = new Route('admin/<presenter>/<action>[/<id>]', 'Homepage:default');
return $router;
}
A hlasi to
Unable to create service 'router', value returned by factory is not Nette\Application\IRouter type.
Od toho kodu se to vubec nelisi, ne? Jediny rozdil je, ze ja na to mam routerFactory a nemam to primo v bootstrapu
Editoval argoneus (13. 6. 2013 13:13)
- hAssassin
- Člen | 293
jediny rozdil tam je vracis pole a ne IRouter
jak je pozadovano.
$router[]
ti vytvori pole a prida ti to do nej novy prvek. Ale ty
nejdriv musis vytvorit instanci routeru, ktera ma pretizeny operator
[]
a proto se chova jako pole. Takze to oprav na:
/**
* @return Nette\Application\IRouter
*/
public function createRouter()
{
$router = new RouteList(); // !!! toto ti tam chybi
$router[] = $frontRouter = new RouteList('Front');
$frontRouter = new Route('index.php', 'Homepage:default');
$frontRouter = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');
$router[] = $adminRouter = new RouteList('Admin');
$adminRouter = new Route('admin/<presenter>/<action>[/<id>]', 'Homepage:default');
return $router;
}
Editoval hAssassin (13. 6. 2013 15:08)
- Šaman
- Člen | 2666
@hAssassin:
- Aha, díky za objasnění těch NS presenterů. Moduly už jsem dlouho nepoužíval, takže jsem myslel, že všechny presentery nesmí být v NS. Je to jeden z důvodů, proč používám verzi 2.1.
- Myslím tím, že je úplně jedno, v jakém modulu je nějaký BasePresenter, nebo jiné abstraktní třídy. Konkrétní presenter (na který vedou odkazy) může dědit odkudkoliv, ale sám musí dodržovat konvence, aby fungovalo routování. Konkrétně to byla (noční, tak možná zmatená) odpověď na poznámku o globálním prostoru nad moduly, který by obsahoval i BasePresenter. Odpověď zní, že BasePresenter může být skutečně kdekoliv (jak v adresářové, tak NS struktuře) a na funkci poděděných konkrétních presenterů to nebude mít vliv (pokud ony sami budou pravidla NS a adresáře dodržovat).
Editoval Šaman (13. 6. 2013 17:18)
- argoneus
- Člen | 14
@ hAssassin:
Porad to nefunguje, ted kdyz prijdu jen na localhost, tak to hlasi
No route for HTTP request.
, a kdyz na
localhost/index.php
, tak me to presmeruje na
http://localhost/admin/front.homepage/
a stejna chyba, jako v tom
prvnim. :(
Je potreba nejak upravovat config.neon? Momentalne to mam tak, ze mam
BasePresenter venku z modulu, v modulech mam HomepagePresenter, ten se na nej
odvolava jako na \BasePresenter
a je v namespacu
FrontModule
.
Editoval argoneus (13. 6. 2013 21:14)
- Šaman
- Člen | 2666
Zkoušel jsi ten kód, co jsem posílal já?
Jak jsem psal, už nějakou dobu jsem moduly neřešil a Nette se stále
vyvíjí dost hekticky, ale kdysi se to řešilo takto. Samostatné routery pro
různé moduly budeš řešit až budeš chtít dělat složitější
routování a aliasy, tohle by mělo být minimalistické přidání modulu do
základního routeru.
Editoval Šaman (13. 6. 2013 22:08)
- zimmi
- Člen | 94
Existuje ve verzi < 2.1 nějaký způsob, jak mít
- app
- front
- admin
a používat namespace AppName\FrontModule;
a
namespace AppName\AdminModule;
? Tedy abych v adresáři app měl
třeba obecný BasePresenter v namespace AppName;
.
A v adresářích front a admin pak ty výše zmíněné
namespace? Díky.
- jsvelta
- Člen | 39
app -AdminModule - presenters - BasePresenter // namespace AdminModule; extends \BasePresenter - DefaultPresenter // namespace AdminModule; extends \BasePresenter - templates - Error - FrontModule - presenters - BasePresenter // namespace FrontModule; extends \BasePresenter - HomepagePresenter // namespace FrontModule; extends \BasePresenter - templates - Homepage - presenters - BasePresenter // (zadne namespace) extends \Nette\UI\BasePresenter
Nemal by DefaultPresenter a HomepagePresenter dediť z BasePresenter vo svojom namespace? Teda nie extends \BasePresenter, ale extends BasePresenter.
Inak nevidím zmysel mať \AdminModule\BasePresenter a \FrontModule\BasePresenter.
Verím, že je to len chybka, ale aby to bolo jasné :-)