#1 25. 9. 2009 13:04
- David Grudl
- Administrator

- Registrovaný: 8. 2. 2005
- Příspěvky: 4050
- Web
[2009–09–25] Adresářová struktura a moduly
Odstraněn jeden dávný pohrobek a úprava adresářové struktury.
Pohrobkové proměnné
Pohrobkem jsou proměnné prostředí:
templatesDir– používáno jako proměnná Presenter z Application, nemá co dělat v EnvironmentpresentersDir– používáno jako proměnná PresenterLoaderu z Application, nemá co dělat v EnvironmentcomponentsDiramodelsDir– se v „novodobé historii“ nejspíš nikdy na nic nepoužívalo
Proměnné jsem tedy odstranil, i když z důvodu zpětné kompatibility
k proměnným templatesDir a presentersDir metody
Presenter::formatLayoutTemplateFiles() a
formatTemplateFiles() stále přihlížejí.
Možná zpětná nekompatibilita: pokud vaše aplikace či
komponenty tyto proměnné používají. Rychlý workaround je přidat do
config.ini:
[common] variable.templatesDir = %appDir%/templates variable.presentersDir = %appDir%/presenters variable.componentsDir = %appDir%/components variable.modelsDir = %appDir%/models
Moduly
Doporučená adresářová struktura pro moduly je zavádějící a pojmenování jmenných prostorů presenterů v PHP 5.3 nevhodné. Proč?
Především jde o to si uvědomit, co znamená modul. Rozhodně to není
(jen) seskupení více presenterů! Základním a vždy přítomným modulem je
totiž samotná aplikace (adresář app). Ta obsahuje model,
presentery, šablony, komponenty, nebo pravidla routování. A může obsahovat
další submoduly, respektive samotná aplikace se může stát (byť po drobné
úpravě) submodulem v jiné aplikaci.
Příklad: aplikaci nette.org tak mohu poskládat z modulů
wiki + fórum, kde fórum se skládá z modulů frontend a backend.
Stará adresářová struktura tenhle pohled spíš zamlžovala, protože
modul nepředstavoval jeden adresář obdobný adresáři app, ale
byl roztříštěn do více adresářů. Nová struktura naopak moduly do
vlastních adresářů sjednocuje:
app/
ForumModule/
model/
presenters/
HomepagePresenter.php (v PHP 5.3 třída ForumModule\HomepagePresenter)
templates/
WikiModule
FrontendModule/
...
BackendModule/
...
models/
temp/
bootstrap.php
Ve výchozím nastavení se pro šablony používá stará adresářová
struktura, nastavením Presenter::$oldModuleMode =
FALSE se aktivuje nová adresářová struktura. Třídy
presenterů se sice dohledávají jen dle nové adresářové struktury, ovšem
RobotLoader je stejně dohledá kdekoliv, takže by se změna neměla projevit.
Dále v PHP 5.3 se jako název jmenného prostoru už nepoužívá jen název
modulu, ale je doplněn o příponu Module.
Poznámka: jde samozřejmě o vývojovou záležitost a komentáře jsou vítány. Zároveň připomínám, že se bavíme čistě o „doporučené struktuře“, tj. každý můžete používat jakoukoliv jinou strukturu.
Offline
#2 25. 9. 2009 13:37
- Ondřej Mirtes
- Moderator

- Místo: Praha
- Registrovaný: 8. 1. 2009
- Příspěvky: 1357
- Web
Re: [2009–09–25] Adresářová struktura a moduly
Nová doporučená adresářová struktura – hezké :) Ale dělá mi
starost ta složka models – co když chci jednu třídu
využívat ve více modulech? Např. UserModel – ve WebModule slouží např.
k registraci uživatelů a v AdminModule k jejich editaci a mazání.
Nechtěl bych pro to dělat dvě třídy.
Mimochodem, jak řešíte šablony pro komponenty? Klasika je asi dávat je
do /controls/Name/, zkrátka k PHP třídě dané komponenty, ale
co kdybych to chtěl mít oddělené? Např. pro to, kdybych měl na hostingu
jednu centrální složku pro všechny Nette komponenty, které by využívalo
více webů, ale každý by samozřejmě potřeboval vlastní šablonu?
Offline
#3 25. 9. 2009 13:57
- David Grudl
- Administrator

- Registrovaný: 8. 2. 2005
- Příspěvky: 4050
- Web
Re: [2009–09–25] Adresářová struktura a moduly
LastHunter napsal(a):
Nová doporučená adresářová struktura – hezké :) Ale dělá mi starost ta složka
models– co když chci jednu třídu využívat ve více modulech? Např. UserModel – ve WebModule slouží např. k registraci uživatelů a v AdminModule k jejich editaci a mazání. Nechtěl bych pro to dělat dvě třídy.
Tomu přece nic nebrání.
Mimochodem, jak řešíte šablony pro komponenty? Klasika je asi dávat je do
/controls/Name/, zkrátka k PHP třídě dané komponenty, ale co kdybych to chtěl mít oddělené?
Obvykle do app/components (resp. module/components)
dávám komponenty specifické pro konkrétní aplikaci/modul, do
libs/components zase komponenty sdílené více weby nebo pro
komponenty z repozitáře.
Použití vlastní šablony v komponentě už pak spíš záleží na
implementaci komponenty. Takže třeba sdílená komponenta v
libs/components má v app/components potomka
s vlastní šablonou.
Offline
#4 25. 9. 2009 16:04
- Ondřej Mirtes
- Moderator

- Místo: Praha
- Registrovaný: 8. 1. 2009
- Příspěvky: 1357
- Web
Re: [2009–09–25] Adresářová struktura a moduly
OK :) Co lze teď použít namísto templatesDir? Myslel jsem, že tak teď
začne fungovat appDir, ale ta mi vede stále pouze do /app/ a ne
do /app/WebModule. Potřebuju pro pro určení cesty
WebLoaderu.
Offline
#5 25. 9. 2009 16:05
- edke
- Člen

- Místo: Kosice
- Registrovaný: 22. 9. 2008
- Příspěvky: 182
Re: [2009–09–25] Adresářová struktura a moduly
David Grudl wrote:
Především jde o to si uvědomit, co znamená modul. Rozhodně to není (jen) seskupení více presenterů! Základním a vždy přítomným modulem je totiž samotná aplikace (adresář
app). Ta obsahuje model, presentery, šablony, komponenty, nebo pravidla routování. A může obsahovat další submoduly, respektive samotná aplikace se může stát (byť po drobné úpravě) submodulem v jiné aplikaci.
Mna by zaujimalo prave to routrovanie. Ako konkretne sa da (ak sa da) v novej strukture rozdelit pre jednotlive moduly ?
Offline
#6 25. 9. 2009 16:23
- Honza Marek
- Moderator

- Místo: Kladno
- Registrovaný: 31. 3. 2007
- Příspěvky: 1281
- Web
Re: [2009–09–25] Adresářová struktura a moduly
LastHunter napsal(a):
OK :) Co lze teď použít namísto templatesDir? Myslel jsem, že tak teď začne fungovat appDir, ale ta mi vede stále pouze do
/app/a ne do/app/WebModule. Potřebuju pro pro určení cesty WebLoaderu.
Můžeš si ty proměnné nastavit v configu ostatně jako píše David v úvodním příspěvku.
Offline
#7 25. 9. 2009 16:32
- David Grudl
- Administrator

- Registrovaný: 8. 2. 2005
- Příspěvky: 4050
- Web
Re: [2009–09–25] Adresářová struktura a moduly
edke napsal(a):
Mna by zaujimalo prave to routrovanie. Ako konkretne sa da (ak sa da) v novej strukture rozdelit pre jednotlive moduly ?
Těch možností je víc, jedna taková může počítat s tím, že modul si umí routy vytvořit sám. Bude na to mít třeba továrničku: (jen koncept, psáno z hlavy)
class ForumModule {
public static function createRouter($prefix = 'forum/')
{
$router = new MultiRouter;
$router[] = new Route("$prefix<presenter>/<action>", array(
'module' => 'forum',
'presenter' => 'Home',
'action' => 'default',
);
$router[] = new Route(...);
$router[] = new Route(...);
return $router;
}
}
a pak v bootstrapu:
$application = Environment::getApplication();
$router = $application->getRouter();
// nastavíme vlastní routy aplikace
$router[] = new Route(...);
// připojíme i routy modulů, tj. třeba fóra na extra subdoméně
$router[] = ForumModule::createRouter('//forum.example.com/');
$application->run();
Offline
#8 25. 9. 2009 17:09
- Panda
- Nette guru

- Místo: Děčín 32
- Registrovaný: 4. 7. 2008
- Příspěvky: 386
Re: [2009–09–25] Adresářová struktura a moduly
Osobně používám následující způsob (momentálně je napsaný pro staré rozmístění modulů, fungovat ale bude nezávisle na adresářové struktuře):
Pro každý modul mám třídu, která dědí od abstraktní třídy
BaseModule:
<?php
abstract class BaseModule extends Object
{
public function setupRouter(IRouter $router) { }
public function setupPermission(SitePermission $permission) { }
public function setupHooks(SiteHooks $hooks) { }
// ...
}
?>
V dané třídě překryji požadované metody:
<?php
class PageModule extends BaseModule
{
public function setupRouter(IRouter $router)
{
$router[] = new PageRoute('<uri>', array(
'presenter' => 'Page',
'action' => 'default'
));
}
public function setupPermission(SitePermission $permission)
{
$permission->addResource('Page');
$permission->addPrivilege('Page', array('edit', 'create'));
}
public function setupHooks(SiteHooks $hooks)
{
$hooks->add('Blocks', 'PageModule::blocksEntry');
$hooks->add('Dashboard/Blocks', 'PageModule::dashboardEntry');
$hooks->add('AdminMenu', 'PageModule::setupAdminMenu');
}
// ...
}
?>
V config.ini mám seznam modulů, které si přeji načíst:
[common] modules[] = Admin modules[] = Page modules[] = News modules[] = Gallery modules[] = Article modules[] = Document
Třída SiteApplication (potomek Application, je
nastavený v config.ini jako service pro
Nette\Application\Application) mi vše načte a spustí ve
správný čas:
<?php
class SiteApplication extends Application
{
protected $modules;
/**
* @var Cache
*/
protected $cache;
protected $hooks;
public function run()
{
$this->cache = Environment::getCache('Application');
$modules = Environment::getConfig('modules');
foreach ($modules as $module)
$this->loadModule($module);
$this->setupRouter();
$this->setupHooks();
// Requires database connection
$this->onRequest[] = array($this, 'setupPermission');
// ...
// Run the application!
parent::run();
$this->cache->release();
}
protected function loadModule($module)
{
$class = $module . 'Module';
$this->modules[$module] = new $class;
}
protected function setupRouter()
{
if (Environment::isProduction() && isset($this->cache['router'])) {
$this->setRouter($this->cache['router']);
} else {
SiteRoute::initialize();
$router = $this->getRouter();
// Homepage
$router[] = new SiteRoute('<? (index\.(php|html?))?>', array(
'presenter' => 'Homepage',
'action' => 'default',
), Route::ONE_WAY);
// Modules routes
foreach ($this->modules as $module)
$module->setupRouter($router);
// Default route
$router[] = new SiteRoute('<presenter>/<action>/<id>', array(
'presenter' => 'Homepage',
'action' => 'default',
'id' => NULL,
));
$this->cache->save('router', $router);
}
}
public function setupPermission()
{
// ...
}
protected function setupHooks()
{
if (Environment::isProduction() && isset($this->cache['hooks'])) {
$this->hooks = $this->cache['hooks'];
} else {
$this->hooks = new SiteHooks();
foreach ($this->modules as $module)
$module->setupHooks($this->hooks);
$this->cache->save('hooks', $this->hooks);
}
}
// ...
}
?>
Celá moje aplikace je napsaná tak, aby podporovala několik propojených
webů běžících na jediné instalaci, takže možnost definovat moduly
v rámci sekce config.ini je pro mě klíčová.
Pomůžeš-li jednomu člověku, pomůžeš tím celému světu.
– Talmud
Offline
#9 25. 9. 2009 19:18
- David Grudl
- Administrator

- Registrovaný: 8. 2. 2005
- Příspěvky: 4050
- Web
Re: [2009–09–25] Adresářová struktura a moduly
Panda napsal(a):
Osobně používám následující způsob (momentálně je napsaný pro staré rozmístění modulů, fungovat ale bude nezávisle na adresářové struktuře):
Máš to napsané výborně, v podstatě podobnou cestou půjde vývoj modulů v Nette. Moduly včetně Application budou implementovat IModule. Ještě nevím, jestli to pojmou i jako komponenty. Moduly si budou také určovat vlastní ErrorPresenter.
Offline
#10 27. 9. 2009 17:09
Re: [2009–09–25] Adresářová struktura a moduly
Jak ale zde řešit když mám několik modulů a jednu administraci jak udělat aby byl jeden globální @layout.phtml pro admina. Struktura je
CoreModule
- AdminModule
- presenters
- templates
- @layout.phtml << ten layout globálně pro admina
- FrontModule
- presenters, templates
PageModule
- AdminModule
- presenters
- templates (zde bez @layout.phtml a nebo dědit @layout.phtml v CoreModule)
- FrontModule
- presenters, templates
doufám že to někdo pochopil, diky
Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítání
Twitter: http://twitter.com/MartinSadovy
Offline
#11 27. 9. 2009 17:57
- vlki
- Nette guru
- Registrovaný: 30. 6. 2008
- Příspěvky: 239
Re: [2009–09–25] Adresářová struktura a moduly
No, tak uděláš layout v Core a v těch rozšířeních Admina jen něco jako …
{extends '../../CoreModule/AdminModule/@layout.phtml'}
Nebo na tom je něco špatného?:)
Offline
#12 27. 9. 2009 18:11
Re: [2009–09–25] Adresářová struktura a moduly
To co jsi napsal mě napadlo hned (to jsem ještě nepsal příspěvek) ale otázka jde to zglobalizovat jestli že se jmenuje stejně modul ( = AdminModule) ? Tak jo udělám v AdminBasePresenteru funkci formatLayoutTemplateFiles a hotovo :D
Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítání
Twitter: http://twitter.com/MartinSadovy
Offline
#13 28. 9. 2009 12:02
- simon
- Člen
- Registrovaný: 7. 10. 2008
- Příspěvky: 173
Re: [2009–09–25] Adresářová struktura a moduly
Zdravim, nova adresarova struktura se mi moc libi a proto jsem si ji implementoval. Nevim si vsak rady s ErrorPresenterem. Predpokladam ze bude mit kazdy modul vlastni. Nevim vsak jak to nastavit. Kdyz dam do bootstrapu
<?php
$application->errorPresenter = 'Error';
$application->catchExceptions = true;
?>
tak mi to nefunguje a zobrazuje se jen bila stranaka. a v logu je
[28-zář-2009 11:57:45] PHP Fatal error: Uncaught exception ‚BadRequestException‘ with message ‚Cannot load presenter 'Portal:Asdfasdf‘, class ‚Portal_AsdfasdfPresenter‘ was not found in ‚/home/simon/Workspace/php/nette/project/baskytara_com/html/../app/PortalModule/presenters/AsdfasdfPresenter.php‘.' in /home/simon/Workspace/php/nette/project/baskytara_com/libs/Nette/Application/Application.php:150 Stack trace: #0 /home/simon/Workspace/php/nette/project/baskytara_com/app/bootstrap.php(108): Application->run() #1 /home/simon/Workspace/php/nette/project/baskytara_com/html/index.php(16): require(‚/home/simon/Wor…‘) #2 {main}
[28-zář-2009 11:58:07] PHP Fatal error: Uncaught exception ‚ApplicationException‘ with message ‚An error occured while executing error-presenter‘ in /home/simon/Workspace/php/nette/project/baskytara_com/libs/Nette/Application/Application.php:181 Stack trace: #0 /home/simon/Workspace/php/nette/project/baskytara_com/app/bootstrap.php(108): Application->run() #1 /home/simon/Workspace/php/nette/project/baskytara_com/html/index.php(16): require(‚/home/simon/Wor…‘) #2 {main}
chapu ze se nedari najit error presenter ale nevim jak to napravit. predem diky
Offline
#14 28. 9. 2009 12:16
- simon
- Člen
- Registrovaný: 7. 10. 2008
- Příspěvky: 173
Re: [2009–09–25] Adresářová struktura a moduly
Jeste dodam ze problem je tato vyjimka:
Cannot load presenter ‚Error‘, class ‚ErrorPresenter‘ was not found in ‚/home/simon/Workspace/php/nette/project/baskytara_com/html/../app/presenters/ErrorPresenter.php‘.
Na tom umisteni samozrejme presenter neni. Nevim tedy jak nette donutit aby presenter hledalo v adresari s modulem.
Offline
#15 28. 9. 2009 18:56
- David Grudl
- Administrator

- Registrovaný: 8. 2. 2005
- Příspěvky: 4050
- Web
Re: [2009–09–25] Adresářová struktura a moduly
Predpokladam ze bude mit kazdy modul vlastni.
To ano, ale zatím to ještě není implementované. Takže se používá
jeden presenter a modul se zapíše pomocí
dvojteček $application->errorPresenter = 'Admin:Error';
Offline
#16 29. 9. 2009 14:40
- Juan
- Člen
- Registrovaný: 11. 4. 2009
- Příspěvky: 55
Re: [2009–09–25] Adresářová struktura a moduly
V souvislosti s adresářovou strukturou obecně bych se chtěl zeptat, kam byste umístili následující:
1. V adresáři libs mám knihovnu
Texy. Vytvořil jsem si poděděnou třídu, ve které mám handler
pro zvýranění syntaxe pomocí FSHL. Ten rovnou registruji do
Texy:
class TexyFshl extends Texy
Vím, že toto by asi šlo přidat třeba do BasePresenteru, ale není nějaké lepší řešení, kam to umístit?
2. Funkce getId a getPath, které
používám jako masku pro routování. Kam je dát?
Nehodilo by se mít pro tyto případy v app/ ještě nějakou
další složku?
Editoval Juan (29. 9. 2009 14:41)
Offline
#17 1. 10. 2009 17:55
- Juan
- Člen
- Registrovaný: 11. 4. 2009
- Příspěvky: 55
Re: [2009–09–25] Adresářová struktura a moduly
Nic? Tak se zeptám ještě jinak… Např. do které složky je nejvhodnější umístit vlastní router?
Offline
#18 1. 10. 2009 19:22
- Honza Kuchař
- Moderator

- Místo: Brno
- Registrovaný: 12. 8. 2007
- Příspěvky: 1285
- Web
Re: [2009–09–25] Adresářová struktura a moduly
To záleží čistě na tobě.
Třeba si vytvoř novou složku v app/ nebo do libs/. Nette tě nijak neomezuje.
Offline
#19 2. 10. 2009 0:09
- kravčo
- Moderator

- Místo: Bratislava
- Registrovaný: 15. 6. 2008
- Příspěvky: 564
Re: [2009–09–25] Adresářová struktura a moduly
Napríklad ja mám vlastné routre v adresári app/routers.
Pokiaľ používaš RobotLoader so štandardným nastavením
%appDir% + %libsDir%, tak ich natiahne sám, ak ho
nepoužívaš, tak ich načítaj ručne…
Offline
#20 2. 10. 2009 12:10
- Juan
- Člen
- Registrovaný: 11. 4. 2009
- Příspěvky: 55
Re: [2009–09–25] Adresářová struktura a moduly
Díky, přesně tak to používám. Jen mi šlo o to, jestli je to ona „Best Practise“…
Offline
#21 22. 10. 2009 19:58
Re: [2009–09–25] Adresářová struktura a moduly
Po nějaké době jsem updatoval na novou dev revizi a s tím jsem
i přeorganizoval adresáře podle prvního Davidova postu. Jenže se mi něco
pokazilo, protože se mi namísto celé stránky vykreslí jen šablona
aktuálního view. Chybí tedy celý @layout. Netušíte někdo co je špatně?
soubor s layoutem mám
v app\FrontModule\templates\@layout.phtml
Offline
#22 22. 10. 2009 20:25
- Ondřej Mirtes
- Moderator

- Místo: Praha
- Registrovaný: 8. 1. 2009
- Příspěvky: 1357
- Web
Re: [2009–09–25] Adresářová struktura a moduly
na1k napsal(a):
Po nějaké době jsem updatoval na novou dev revizi a s tím jsem i přeorganizoval adresáře podle prvního Davidova postu. Jenže se mi něco pokazilo, protože se mi namísto celé stránky vykreslí jen šablona aktuálního view. Chybí tedy celý @layout. Netušíte někdo co je špatně? soubor s layoutem mám v
app\FrontModule\templates\@layout.phtml
Nový systém počítá s tím, že používáš „nové šablony“ –
s makry {block} a {extends}. Doporučuji shlédnout
přednášku: http://blip.tv/file/2514636
Offline
#24 1. 11. 2009 11:56
- Jerry123456789
- Člen

- Registrovaný: 29. 12. 2008
- Příspěvky: 37
Re: [2009–09–25] Adresářová struktura a moduly
Šmankote, jak tak koukám na Pandův příklad komplexní aplikace, zjišťuju že se mám eště dst co učit :D
Ale chtělo by to nějaký howto na komplexitu, tohle bych vymejšlel dlouho. Taky by mě zajímalo třeba když máš třídu *Module jak to zapasuješ do MVP? Nebo jsou moduly (*Module, ne adresář) jen na router/permissions…?
42
Offline
#25 12. 11. 2009 14:55
Re: [2009–09–25] Adresářová struktura a moduly
Zdravim, zalíbil se mi Pandův přístup. Něco takového jsem chtěl udělat, ale nevěděl jsem jak přidat další vrstvu do životního cyklu, takže nápad zaregistrovat si vlastní třídu pro Application je parání!
Bohužel jsem nedokázal pochopit jaký význam mají tvoje ‚Hooks‘ v modulech, snažim se nato přijit už dva týdny ale furt jsem nic nevymyslel :( kdyby ses mohl ještě trochu rozepsat o tom tvém příkladu byl bych ti myslím nejenom já vděčný :)
Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítáni
Offline
- Úvodní stránka
- » Changelog
- » [2009–09–25] Adresářová struktura a moduly


