Problem s pouzitim modulu a jejich routovanim

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

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!

Šaman
Člen | 2666
+
0
-

Namespaces v presenterech zvládá až verze 2.1
Co přesně ti to hlásí? Ideálně pošli odhaz na laděnku, nebo link na server.
Případně můžeš ještě poslat tvoji RouteFactory, tam se definují ty routy.

argoneus
Člen | 14
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

@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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

@hAssassin:

  1. 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.
  2. 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
+
0
-

@ 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
+
0
-

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)

argoneus
Člen | 14
+
0
-

Jo, stejna chyba… :(

hAssassin
Člen | 293
+
0
-

evidetne to mas spatne, protoze podle ty url na kterou te to presmeruje to vypada jako kdyby si mel modul Admin a v nem modul Front.

zimmi
Člen | 94
+
0
-

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
+
0
-
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é :-)