Struktura aplikace Modul/Submodul

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

Dlouho jsem hledala, jak řešit router pro aplikaci dělenou na moduly a submoduly. Něco málo jsem našla, ale nic z toho se mi moc nelíbilo. Nakonec jsem se dopracovala k celkem jednoduchému řešení.
Tak snad to někomu pomůže.

Struktura aplikace např.:

App
  Modules
    PagesModule
      AdminModule
        Presenters
        Templates
      FrontModule
        Presenters
        ...
    XyModule
    ...

Struktura aplikace a tvar url:

  • Modules/XxxModule/AdminModule/Presenters/XxxPresenter – url: admin/Xxx/edit/2
  • Modules/XxxModule/FrontModule/Presenters/XxxPresenter – url: Xxx/view/2

RouterFactory.php:

class RouterFactory {
  public $submodule;
  /**
   * @return \Nette\Application\IRouter
   */
  public function createRouter() {
    $router = new Route('[<submodule>/]<module>/<presenter>[/<action>][/<id>]', array(
      'submodule' => array(
        Route::VALUE => 'Front',
        Route::FILTER_IN => array($this, 'submoduleFilter'),
        Route::FILTER_OUT => array($this, 'submoduleFilter'),
      ),
      'module' => array(
        Route::FILTER_IN => array($this, 'moduleFilterIn'),
        Route::FILTER_OUT => array($this, 'moduleFilterOut'),
      ),
      'presenter' => 'default',
      'action' => 'default',
      'id' => NULL
    ));
    return $router;
  }

  public function submoduleFilter($submodule) {
    $this->submodule = ($submodule == 'admin' ? 'Admin' : 'Front');
  }

  public function moduleFilterIn($module) {
    return ucfirst($module).':'.$this->submodule;
  }
  public function moduleFilterOut($module) {
    list($module) = $this->submodule.':'.$module[0];
    return strtolower($module);
  }
}

Všechny výchozí presentery se musí jmenovat defaultPresenter.

config.neon
 – mapping: *: App\Modules\*Module\Presenters\*Presenter

Odkazy
<a n:href=„:Products:Admin:Default:“>Spravovat produkty</a>

Další úpravy
\vendor\nette\application\src\Application\UI\Presenter.php – upravit následující:
funkce formatLayoutTemplateFiles(): $list = array(„$dir/templates/@$layout.latte");
funkce formatTemplateFiles(): return array(“$dir/templates/$this->view.latte");

Editoval santara (8. 12. 2014 12:38)

Miroslav Skopal
Člen | 5
+
0
-

Trochu opráším tohle téma… Chtěl bych něčeho podobného docílit, ale u nového nette už to nejde takto použít, nevíte někdo jak to přepsat aby to fungovalo i v novém nette?

Martk
Člen | 661
+
+4
-
$admin = new RouteList('Admin');
$admin[] = new Route('admin/<module>/<presenter>/<action>', [...]);

$front = new RouteList('Front');
//...
Miroslav Skopal
Člen | 5
+
0
-

O téhle možnosti vím, ale jde mi právě o tu strukturu jak je uvedená v prvním příspěvku, když použiji RouteList, tak potřebuji ještě nějak přehodit Admin/ModuleXY na ModuleXY/Admin atd…

Martk
Člen | 661
+
+1
-
application:
	mapping:
		Admin: Module*\Admin\*Presenter
Merfinder
Člen | 35
+
0
-

Zdravím, já to opráším ještě jednou :-) …mě by zajímalo jak funguje přihlašování v takovéto struktuře? Nyní mám menší aplikaci klasika AdminModule a FrontModule a do adminu se přihlašují přes presenter Sign. Což se dostanu do toho admin modulu. Teď hledám trochu lepší řešení do budouciho spravování. Ale trochu si lámu hlavu nad tím jak funguje ten Module/admin a Module/front. Mohl by mi to někdo nastínit? Nebo třeba odkaz pokud se to někde řešilo? Nikde jsem zatím odpověď nenašel, díky

CZechBoY
Člen | 3608
+
0
-

Já dávám přihlasování normálně do Public modulu – u tebe asi Front.

Merfinder
Člen | 35
+
0
-

No jde o to, že chci aby ty moduly šly copy-paste a nemělo to vliv na běh aplikace. Mám třeba

-App/
	-DefaultModule/
		-AdminModule
		-FrontModule
	-ArticleModule/
		-AdminModule
		-FrontModule

a chci front nechat normálně jako veřejnou, žádné přihlašování nic… když dám k adrese /admin dostal bych se na stránku s loginem do aplikace… napadlo mě, že udělat např. SecuredPresenter a od toho dědit jen ten BaseAdminPresenter v -AdminModule, ale nevím jestli je to dobré řešení, zda existuje něco jednoduššího pro budoucí rozšiřování?

CZechBoY
Člen | 3608
+
0
-

Můžeš si do adminmodulu klidně dát nějakej presenter, kterej podědí nějakej veřejnej presenter. Nebo ho povolit pro všechny role.

Hurass
Člen | 114
+
0
-

@Merfinder ve tvém případě bych si vytvořil BasePresenter, od kterého by dědil AdminBasePresenter a FrontBasePresenter. Všechny Front Presentery ve všech modulech bych dědily od FrontBasePresenter a Admin Presentery zase od AdminBasePresenter. Případně by ještě modul mohl mít další úroveň FrontBasePresenter a AdminBasePresenter pokud by to bylo potřeba.

Merfinder
Člen | 35
+
0
-

Jo to je celkem dobrý nápad, díky :) …ještě mám problém s přesměrováním pokud uživatel není přihlášen, chci udělat nějaké globální přihlašování, nějaký LoginPresenter a pokud není lognutej v adminu tak ho to hodí na login stránku…jenže z toho modulu mi to nejde přesměrovat do -App/templates/login, lze to nějak řešit v tom redirectu?

CZechBoY
Člen | 3608
+
0
-

Co je App/templates/login? Jestli je to public stránka tak ji dej do public modulu, nebo ne?

Merfinder
Člen | 35
+
0
-

No jde o to že jsem si udělal SecuredPresenter, který dědí od BasePresenteru a tyto oba se nachází v App/presenters …pak mám DefaultModule/Presenters kde se nachází globální presentery pro DefaultModule a zde mám AdminBasePresenter a FrontBasePresenter …jelikož chci zabezpečit admin sekci tak AdminBasePresenter dědí od toho SecuredPresenter, kam jsem dal to, pokud není přihlášený uživatel tak ho to redirectne na login …a SignPresenter mám taky v App/Presenters …jenže pokud ten AdminBasePresenter dědí ten SecuredPresenter a v něm je redirect(‚Sign:in‘) tak to samozřejmě nejde, protože bych musel z toho modulu vystoupat ven a to nevím jak udělat

CZechBoY
Člen | 3608
+
+1
-
$this->getPresenter()->redirect(':AbsolutniModul:Presenter:akce');
Merfinder
Člen | 35
+
0
-

No teď jsem tam dal

$this->getPresenter()->redirect(':Sign:in');

což by mělo brát z App/presenters ne? když to má dělat redirect z App/DefaultModule/AdminModule do App/presenters, ale hlásí to No route for Sign:in()

routy mám takto

$router = new RouteList();
        $router[] = new Route('index.php', 'Default:Front:Default:default');
        $router[] = new Route('admin/<presenter>/<action>[/<id>]', array(
            'module' => 'Default:Admin',
            'presenter' => 'Default',
            'action' => 'default',
        ));

        $router[] = new Route('<presenter>/<action>[/<id>]', array(
            'module' => 'Default:Front',
            'presenter' => 'Default',
            'action' => 'default',
        ));

        return $router;