Po tom co Filip Procházka nastínil svůj koncept řešení problému modulů dostali věci kolem modulů rychlý spád.
I já jsem si vzal z Filipova konceptu inspiraci a vytvořil jsem Nette rozšíření Flame/Modules, které implementuje právě zmíněný koncept + několik dalších fičurek.
Repositář Flame/Modules je vlastně jednoduché (s takřka žádnými nároky na výkon) Nette rozšíření s vlastním extensions instalátorem.
Celé je to postavené na tom, že chceme mít co nejsnadnější distribuci Nette modulů a to jen tak, že zaregistrujeme v composer.json balíček modulu a Composer se o vše ostatní postará sám. A tak to skutečně funguje!
Flame/Modules lze použít samostatně - nezávisle na Flame/Framework. Ale Flame fw tomu přidá trochu syntax cukříku:
bootstrap.php
$configurator = new \Flame\Configurator;
$configurator->createModulesInstaller()
->addConfig(__DIR__ . '/config/extensions.php')
->register();
return $configurator;
TIP: Configurační soubor může být ve formátu NEON
Jediné, co je tedy potřeba v bootstrapu udělat je to, že vytvoříte Modules installer, přidáme configurační soubor, kde je seznam extensions, které chcete zaregistrovat.
TIP: Pokud chcete zaregistrovat pouze jedno rozšíření a nestarat se tak o celý configurační soubor, můžete použít metodu registerExtension($extension)
Konfigurace zapsaná v syntaxi php může vypadat takto:
extensions.php
return array(
'modules' => array(
'REST' => 'Flame\Rest\DI\RestExtension',
'doctrine' => 'Flame\Doctrine\DI\OrmExtension',
'events' => 'Kdyby\Events\DI\EventsExtension',
'Enlan\CategoryModule\DI\CategoryExtension',
'Enlan\UserModule\DI\UserExtension',
'Flame\CMS\AngularModule\DI\AngularExtension'
)
);
Pokud používáte balíček, který je kompatibilní s Flame/Modules, Composer se vám bude starat o konfiguraci extensions sám - bude přidávat/odebírat jednotlivé rozšíření do konfiguračního souboru vzhledem k tomu, co se nachází v composer.json.
Pokud by se vám zdálo, že použítí Modules instalatéru je zbytečné a že by se tedy stačilo spolehnout pouze na dostupný ExtensionsExtension, tak vás musím přesvědčit o opaku.
Takto zaregistrované rozříšení není plnohodnotným rozšířením, protože se nezpracová současně s dalšími rozšířeními zaregistrovanými z bootstrapu, ale až později. A to s sebou nese spoustu omezení, jako např. nemožnost použít IEntityProvider z mého oblíbeného balíčku Kdyby/Doctrine. Takto zpětně zaregistrované rozšíření není dostupné při konfiguraci OrmExtension.
A teď jednotlivě k dostupným rozhraním, které může implementovat vaše rozšíření.
Asi nejkurióznější rozhraní, které můžete použít, pokud jste líní a nechcete se pouštět do konfigurace pomocí php. Metoda getConfigFiles()
vrací pole neon configuračních souborů.
V praxi se však nedoporučuje používat.
Rozhraní, které můžete použít, pokud chcete do šablon zaregistrovat vlastní makra.
Metoda getLatteMacros()
vrací pole s makro sety.
Ukázka:
/**
* Get array of latte macros classes
*
* @return array
*/
public function getLatteMacros()
{
return array(
'Flame\CMS\AngularModule\Templating\AngularMacros'
);
}
Implementujte pokud potřebujete specifikvoat namespace mapping pro daný modul. Ukázka:
/**
* Returns array of ClassNameMask => PresenterNameMask
*
* @see https://github.com/nette/nette/blob/master/Nette/Application/PresenterFactory.php#L138
* @return array
*/
public function getPresenterMapping()
{
return array(
'Angular' => 'Flame\CMS\AngularModule\*Module\Presenters\*Presenter'
);
}}
Asi jedno z nejužitečnějších rozhraní. Implementujte ho pokud má mít vaše rozšíření vlastní routy.
Ukázka:
/**
* Returns array of ServiceDefinition,
* that will be appended to setup of router service
*
* @example
* return array(
* array('Nette\Application\Routers\Route' => array('/', array(
* 'presenter' => 'Homepage',
* 'action' => 'default'
* )))
* );
*/
function getRoutesDefinition()
{
return array(
array('Nette\Application\Routers\Route' => array('/', array(
'module' => 'Enlan',
'presenter' => 'Homepage',
'action' => 'default'
))),
array('AdamStipak\RestRoute' => array('Api:V1', 'json', true))
);
}
Rád bych, aby metoda getRoutesDefinition() vracela pole již nakonfigurovaných rout, aby nebylo třeba této složité konfigurace přes další array. Nette cache něco takového zatím ale nepodporuje.
V plánu je doimplementovat zmíněné ITracyPanelsProvider, ITracyBarPanelsProvider nebo např. ILatteHelpersProvider.
Každý Nette Modul musí mít vlastní rozšíření.
Doporučuji podědit NamedExtension pro snadnější práci a lepší kompatibilitu (není však podmínkou).
TIP: Pokud chcete mít na starost samostatnou registraci extension můžete implementovat rozhraní IDomainExtension a metodu
register(Configurator $configurator)
Pokud chceme, aby se registraci rozšíření postaral sám Composer, musíme v composer.json
definovat sekci extra:
{
"extra": {
"module": {
"class": "Flame\\CMS\\AngularModule\\DI\\AngularExtension",
"name": "Angular"
}
}
}
"name" není nutné specifikovat.
To hlavní je, že nesmíme zapomenout pozměnit "type" daného balíčku ze standartního "library" na "nette-module"
"type": "nette-module",
Kompletní ukázka souboru composer.json
A to je vše!
O všechno ostatní se už postará vlastní composer instalátor.
Pokud chcete i vy vyzkoušet Flame/Modules tak přidejte do svého composer.json:
{
"require": {
"flame/framework": "dev-master",
"flame/modules": "dev-master",
"flame/module-installer": "@dev"
}
}
Pokud se chcete podívat na jednoduchou implentaci Flame/Modules v praxi tak doporučuji Flame\CMS\ErrorModule nebo Flame\CMS\AngularModule. Případně složitější ukázky na Bitbucketu
~~Flame/Modules jsou kompatibilní jen s @dev verzí Nette~~
Flame/Modules jsou nyní plně kompatibilní i s @stable verzí Nette
Za zmínku taktéž stojí pokus o implementaci Modular od @mishak87
Co si o tom myslíte vy? Budete používat Flame/Modules? :-)