Administrace v samostatném a přepoužitelném modulu
- dreken
- Člen | 36
Nějakou dobu mi vrtá hlavou, jak si vytvořit univerzální modul pro administraci. Máme několik projektů, ve kterých mám administraci a míra společného kódu je tam obrovská, potřebovali bychom to sjednotit. Zde je základní idea:
- Layout a celkově UX pro administraci jsou všude stejné.
- Přihlašování, správa uživatelů a správa článků je všude stejná.
- Entity jako Admin, AdminNotification apod. jsou všude stejné
- Specifické rozšíření pro konkrétní projekt, například správa objednávek, by šly přidat do administrace jako rozšíření.
Z toho nám vyplynulo, že administraci bychom měli dát do samostatného
modulu. Postupovali jsme podle návodu Petra Kobelky a zprovoznili oddělenou administraci
pod namespace App\AdminModule
.
Tím ale univerzálnost končí a vyvstává několik dalších otázek:
- Jak replikovat tento modul mezi různými projekty, aby kód byl sdílený? Něco na způsob composeru by se hodilo.
- Společný kód, který by bylo potřeba replikovat se nachází i ve www (styly a JS).
- Na jakém principu postavit specifická rozšíření, např. Správa objednávek? Napadá mě to členit do presenterů, ale zase nechci, aby tyto rozšíření byly replikovány do všech projektů.
- Nejdu na to zbytečně složitě, případně nevynalézám znovu kolo?
- Phalanx
- Člen | 310
Kolo nevynalézáš, vlastně se jedná o takový přirozený proces. Nejjednodušší možností je vytvořit si na tu administraci vlastní GIT repozitář a ten si jednoduše spravovat přes composer (kdyžtak si i vyhledej tady na fóru, řešilo se už několikrát).
např:
{
"repositories": [
{"type": "vcs", "url": "git@github.com:clear01/comgate.git" }
]
}
"require": {
"clear01/comgate": "dev-master",
}
Celý článek
https://pehapkari.cz/…ser-balicky/
Pokud používáš Kdyby/Doctrine a případně i translator, pak si ještě vytvoř DI rozšíření, např.
<?php
namespace MyLibrary\DI;
use Kdyby\Doctrine\DI\IEntityProvider;
use Kdyby\Translation\DI\ITranslationProvider;
use Nette\DI\CompilerExtension;
class MyLibraryCoreExtension extends CompilerExtension implements ITranslationProvider, IEntityProvider
{
private $defaults = [
];
/**
* @return array|string[]
*/
public function getTranslationResources(): array
{
return [
__DIR__ . '/../lang',
OTHER_DIR . '/lang', // project languages must be loaded at last (they rewrite vendor libs)
];
}
/**
* Sets the mapping for entities
* @return array Entity mapping
*/
public function getEntityMappings(): array
{
return [ 'App\Model\Entities' => __DIR__ . '/../Model/Entities/' ];
}
public function loadConfiguration(): void
{
$this->validateConfig($this->defaults);
$builder = $this->getContainerBuilder();
$this->compiler::loadDefinitions(
$builder,
$this->loadFromFile(__DIR__ . '/../config/config.neon')['services'],
$this->name
);
}
}
?>
a načti ho v config.neon
extensions:
myLibraryCore: MyLibrary\DI\MyLibraryCoreExtension
Tím si můžeš načítat Entity a překlady přímo z tvé knihovny. Můžeš do té knihovny dát i presentery s view, často se nám to vyplatilo. No a pak ještě přidat třeba různé css a js přes balíčky, ale to už si musíš spravit v závislosti na tom co používáš ty (Bower, Gulp, WebLoader, …).
Editoval Phalanx (13. 12. 2018 11:24)
- Petr Parolek
- Člen | 455
taky jsem nedávno řešil stejný problém a jediné řešení je použít vlastní DI extension. Moc se mi takové řešení líbí. Dokonce má každý extension i svůj router. Viz mé předchozí otázky na foru
- Phalanx
- Člen | 310
@dreken Ano, cokoliv si určíš v rámci projektů. Někdy je vhodnější přidat celou funkčnost a nastavit pár podmínek pro jednotlivé projekty než mít funkčnost rozdělenou (a tím pádem hůře spravovatelnou) do jednotlivých projektů.
Např:
app → AdminModule → presentery + view
vendor → tvoje knihovna → AdminModule → presentery + view