Flame/Modules doplňují svoji chybějící funkcionalitu - nyní je možné definovat vlastní RouteList pro daný Nette modul.
Doposud bylo možné definovat pouze jednotlivé routy a to ve formě polí (array hell). To ovšem nestačilo některým složitějším aplikacím a náročnějším vývojářům. (Mimochodem, Jiřímu děkuji za komentář a podmět k vylepšení.)
Z prvu se zdála myšlenka definice vlastního RouteListu nemyslitelná. Nehledě na to, že konfigurační pole by příliš narostlo a stalo se tak nepřehledným.
Po vytvoření třídy RouteMock a upravením několika řádků ve třídě RouterFactory to však už nebyl problém.
Proč nelze vracet přímo objekt třídy Nette Route se dočtete v článku Nette moduly (a vlastní instalátor) #3
Nyní tedy může vypadat implementace IRouterProvideru následovně:
function getRoutesDefinition()
{
$list = new NetteRouteListMock('App');
$list[] = new NetteRouteMock('/', array(
'module' => 'Enlan',
'presenter' => 'Homepage',
'action' => 'default'
));
$list[] = new RouteMock('AdamStipak\RestRoute', array('Api:V1', 'json', true));
return array($list);
}
nebo bez RouteListu
function getRoutesDefinition()
{
return array(new NetteRouteMock('/', array(
'module' => 'Enlan',
'presenter' => 'Homepage',
'action' => 'default'
)),
new RouteMock('AdamStipak\RestRoute', array('Api:V1', 'json', true))
);
}
Zůstává zachována konfigurace pomocí polí a přibyla konfigurace pomocí Route mocků, které simulují původní Nette Route, RouteList nebo jakýkoliv jiný IRouter.
Jsem si vědom toho, že ani toto řešení není ideální. Jakákoliv lepší řešení uvítám v komentářích.
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? :-)
EDIT: Pokračování článku Nette moduly (a vlastní instalátor) #3
Po delší odmlce konceptu řešení nette modulů použitelně píšu zase. Připravuji kompletní článek, kde bych rád popsal, jak by to mohlo fungovat. Teď bych ale potřeboval poradit s následujícím:
Řešení už nenazývám modulami, protože se to pletlo. Funkce původních Nette modulů zůstává. Rozšiřuji pouze jejich schopnost distribuce (jednoduše řečeno). Balení základních funkcionalit pro aplikaci jsem po vzoru Symfony pojmenoval Bundle (nette way: Addon?). A to je také jediné, čím jsem si u nich inspiroval (yeh).
Aktuální stav řešení si můžete prohlédnout v repozitáři na Githubu.
Pomocí vlastního jednoduchého composer instalátoru Nette budles umějí od minula navíc:
Nicméně teď řeším dilema - Současný instalátor funguje tak, že v composer.json přidáte závislost např. "flame-cms/doctrine-bundle": "@dev"
. Composer balíček vezme a překopíruje do složky app. Zdá se to jako dobrý nápad, ale má to několik "ale".
Například výše zmíněný bundle představuje základní skeleton pro Doctrine nastavení v Nette. Co když DoctrineBundle budu chtít rozšířit o svoje Entity? Do složky DoctrineBundle ve složce app si vytovřím složku Entity, kam je všechny dám. V tom není problém. Problém je ale v tom, že v rootu aplikace mám v .gitignore
něco takového src/app/*Bundle
. To způsobí to, že moje rozšíření se nedostane do gitu, zůstane uložené jen v mé lokální kopii. Takže co s tím?
Možných řešeních je několik:
Nepadá vás nějaké jiný či ideálnější způsob řešení? Nebo jaké z výše jmenovaných vám přijde nejlepší? Nemůžu se rozhodnout.
//EDIT
Článek neodpovídá skutečnostem. Nette moduly jsou stále ve vývoji. Pokračování již brzy.
//EDIT2
Momentálně řeším kde moduly uchovávat
//EDIT3
Aktuální řešení Nette moduly (a vlastní instalátor)
Dnes jsem do svého frameworku Flame přidal několik jednoduchých přesto dost podstatných commits, které vylepšují funkcionalitu základních Nette modulů.
Vize byla jasná - už mě nebavilo stále psát základní části aplikace, jako např. users management pro několik projektů zvlášť. Proto jsem chtěl vytvořit jednoduchý modules management, který mi práci usnadní.
Metoda registerModulesExtension zaregistruje extension modules.
modules: userModule: [%appDir%/UserModule/config/config.neon] settingModule: \Flame\Blog\SettingModule\SettingModule([%appDir%/SettingModule/config/config.neon]) postModule: \Flame\Blog\PostModule\PostModule
Rozšíření modules nabízí volnost syntaxe. Povinný je pouze název modulu.
Každý modul je vlastní extension, což nabízí širokou možnost rozšíření (např. zaregistrovat makra a helpery), který musí být potomek třídy ModuleExtension
Celý tento proces mi dovoluje jednoduše vytvořit aplikaci s následující strukturou:
app - AppModule --- Application --- Backmodule --- FrontModule --- config --- Router - PostModule --- BackModule --- FrontModule --- Entity --- Latte --- Model --- components --- config - SettingModule - UserModule
Konkrétní ukázka na github.com/flame-org/Blog
AppModule je základní modul, který by měla obsahovat každá takhle navržená app, kterou není třeba registrovat do modules extension. Viz bootstrap.php.
Každý modul definuje vlastní smysl v aplikaci, proto není nic jednoduššího než vzít složku UserModule a překopírovat do jiné skvělé aplikace :-)
Plán do budoucna je jasný - nebude dlouho trvat a přestane mě bavit pořád kopírovat jednotlivé moduly, proto chci vytvořit vlastní composer instalátor po vzoru např. juzna/nette-addon-installer, abych se zbavil copy & paste syndromu a vyřešil tak i zároveň dependencis jednotlivých modulů.
Na takto postaveném systému beží i tento bog.
Rád bych také název modules nahradil za addons, aby se to nepletlo s Nette moduly, ačkoliv z nich vlastně vycházejí.
Řešení není konečné a je ještě hodně na čem pracovat, ale myslím, že je to první krůček evoluce. :-)
Přivítám jakékoliv připomínky, názory, či rady v komentářích.
Logický problém: Dual boot – Win7 a Ubuntu, každý na svém oddílu HDD. Když však disk s linuxovým systémem naformátuješ, tak při dalším spuštění počítače či restartování nenabootuješ žádný systém. A proč? GRUB, který se staral o boot má své soubory uložené primárně na linuxovém oddíle a ten se ti povedlo efektivně smazat.
Jednoduše. Na internetu jsem našel spoustu balastu jak GRUB opětovně opravit, ale k čemu? Chci bootovat pouze WIN a ten má svůj vlastní boootovací systém.
Nejdříve v BIOSu musíme nastavit jako první bootování z CD. Pak vložíme instalační DVD win7 a necháme nabootovat CD. Nebudeme však systém znovu instalovat, ale zvolíme možnost: REPAIR YOUR COMPUTER. Následně vybereme jaký windows chceme opravit (pokud jste jich měli nainstalovaných víc), zobrazí se nám tabulka s možnostmi, jak systém opravit. Pro náš účel budeme potřebovat: COMMAND PROMPT.
Tam už stačí jen napsat následující příkaz: BOOTREC.EXE/FIXMBR. Pak už stačí jen systém restartovat a oprava by měla být hotová.
Pzn. Ačkoliv by se mohlo zdát, že bude stačit zvolit Startup repair, tak tomu tak není. Provede celá řada oprav, ale ne ta, kterou potřebujeme.
Kompletní dokumentaci aplikace bootrec.exe najdete na stránkách microsoftu: http://support.microsoft.com/kb/927392
Pokud jste osamělý vývojář a svůj start-up zakládáte ze svého pokoje nebo jen máte malý tým snaživých a podnikavých lidí, pracujících na nové a velké věci, tak právě pro vás mám pár tipů pro úspěšný start-up. Jak poznám, že vás projekt má šanci na úspěch? Odpovězte si na otázku: Co můj projekt uživatelům nabízí? Z pravidla platí, že pokud bude váš projekt řešit i třeba jednoduchý problém, ale kreativně a správně, tak má šanci na úspěch. (Například výuku cizích jazyků netradiční formou – WordBot.cz) 
Výtah z knihy Katedrála a tržiště, která patří ke zlatému fondu světové open-source scény. Eric S. Raymond se v ní zabývá otevřeným vývojem software, který funguje neuspořádaně evolučním vývojem a přesto dokáže být velmi progresivní. Takový vývoj je v knize přirovnáván k tržnici, která na rozdíl od katedrály funguje naprosto spontánně.
Každý dobrý program začíná tím, že řeší potíže samotného programátora.
Protože dobří programátoři vědí co psát. Velcí vědí, co přepsat (a znovu použít).
Pokud máte správný přístup, zajímavé problémy si vás najdou sami.
Když ztratíte zájem program, vaší poslední povinností je předat jej schopnému nástupci.
Pokud jednáte s uživateli jako se spolu-pracovníky, je to ta nejsnazší cesta k rychlému vylepšení kódu a efektivnímu odstraňováni chyb.
Publikuj brzy. Publikuj často. A naslouchej svým zákazníkům.
Pokud máte dostatečně velkou základnu spolu-pracovníků a testerů, téměř každý problém bude rychle charakterizován a jeho řešení bude pro někoho jednoduché.
Promyšlené datové struktury a průměrný kód fungují mnohem lépe než při obrácené konfiguraci.
Pokud zacházíte s vašimi testery, jako by byli vašimi nejcennějším kapitálem, oni se vaším nejcennějším kapitálem skutečně stanou.
Skoro stejně důležité, jako mít dobré nápady, je schopnost rozeznat dobré nápady vašich uživatelů. Občas je to druhé dokonce lepší.
Často to nejzajímavější a nejoriginálnější řešení se zrodí z toho, že si uvědomíte, že vaše chápání problému bylo mylné.
Konstrukční dokonalosti není dosaženo tehdy, když už není co přidat, ale tehdy, když už nemůžete nic odebrat.
Jakýkoliv nástroj by měl být užitečný očekávaným způsobem, ale opravdu velké nástroje se hodí na použití, které jste nikdy neočekával.
Pokud píšete zprostředkovatelský software jakéhokoliv druhu, snažte se vlastní data nijak neměnit a nikdy se nezbavujte žádné informace, pokud vás k tomu nedonutí příjemce.
Bezpečnostní systém je pouze tak bezpečný jako jeho tajemství. Mějte se napozoru před pseudo-tajemstvími.
Pokud chcete pracovat na zajímavém projektu, začněte s tím, že naleznete problém, který zajímá vás osobně.
Pokud má koordinátor projektu k dispozici médium alespoň tak dobré jako internet a dokáže vést bez příkazů, mnoho hlav je nevyhnutelně lepší než jedna.
Pokud byste chtěli coomposer pro správu závislostí ve vašem projektu a nedaří se vám ho nainstalovat klasickým "linuxáckým" příkazem
curl -s http://getcomposer.org/installer | php
a dostáváte error tohoto typu:
#!/usr/bin/env php Some settings on your machine make Composer unable to work properly. Make sure that you fix the issues listed below and run this script again:
The detect_unicode setting must be disabled. Add the following to the end of your
php.ini
: detect_unicode = Off
a nepomáhá ani rozšířený příkaz instalace:
curl -s http://getcomposer.org/installer | php -d detect_unicode=0
Zkuste composer nainstalovat pomocí správce balíčků pro Mac OSX. Postupně zadejte tyto dva příkazy do terminálu:
brew tap josegonzalez/homebrew-php
brew install josegonzalez/php/composer
Composer by měl být nainstalován a plně funkční. Vyzkoušet to můžete zadáním příkazu do teminálu: composer
Zdroj: Oficiální Github projekt
Důvod je jednoduchý - váš Firefox je příliš aktuální pro selenium server.
Pokud se podíváte do oficiální dokumentace, selenium podporuje maximálně Firefox 7. Proto doporučuji váš současný firefox smazat a na internetu si stáhnout "dědička" - firefox 7.
Jak poznám že Selenium nepodporuje mojí verzi Firefoxu?
Jendoduše. Jakmile způstíte test, nastartuje firefox a tam prázdná bílá stránka. Podívejte se do správce doplňků. V záložce Rozšíření by měl být zakázaný selenium web driver zdůvodu nekompatibility.
Edit: @takewara upozornil na to, že stejný problém platí i pro testovací framework JUnit (nečekaně). Díky.
Ano, přesně touho otázkou jsem se nedávno nějaký čas zabýval. Odpověď je až překvapivě jednoduchá a nezabere vám to více, jak dvě minuty.
Já osobně jsem Facebook ID potřeboval ke správnému nastavení pluginu Facebook comments. Kde jsem chtěl vyplnit meta tag pro moderátory komentářů, které jsem chtěl využít na svém projektu WORDBOT.CZ (Nakonec z toho stejně sešlo, rozhodl jsem se pro vlastní komentáře.)
<meta property="fb:admins" content="{YOUR_FACEBOOK_USER_ID}"/>
Nejdřív jsem chvilku „guglil“. Našel jsem několik anglických článků, jak to zázračné Facebook ID získat, Nicméně, všechny postupy byli buď hrozně krkolomné nebo nefungovali. Vzpomněl jsem si, že když jsem řešil přihlašování zase na projektu WORDBOT.cz, zjistil jsem, že oficiální knihovna Facebooku PHP SDK tento parametr velice ochotně nabízí.
Normální uživatel, který nemá žádné potuchy o php a přesto tento údaj potřebuje zjistit si přeci nebude vytvářet nějakou aplikaci… proto jsem to udělal za vás.
Vytvořil jsem jednoduchou Facebook aplikaci, které když povolíte přístup ke svým datům (jinak to bohužel nejde), tak vám ukáže nejen vaše Facebook ID ale i také několik dalších užitečných informací, které Facebook takovým aplikacím nabízí.
Nelekněte se, že zmiňovaná aplikace je v angličtině, ale pro širší veřejnost, jsem se tak rozhodl.
Viz http://facebookid.jsifalda.name/
P.S.: Někteří lidí tvrdí, že Facebook ID je velice cenný údaj, proto s ním nakládejte opatrně. Mohl by se stát, že by ho někdo mohl čemukoliv využít