CompilerExtension a createComponent

libik
Člen | 89
+
0
-

Ahoj,

zkousim extensions zaregistrovat pres tridu class ProjectsExtension extends \Nette\DI\CompilerExtension.
Extension obsahuje nejake sluzby, to je v pohode, ale taky komponentu.

Lze komponentu nejak vytvorit jinak aniz bych musel sahnout do prezenteru a tam ji vytvaret metodou createComponentProjects() ?
Potrebuju aby byla dostupna v latte pres {control projects}.

Diky :)

CZechBoY
Člen | 3601
+
0
-

Teoreticky vzato můžeš přidat jakýkoliv php kod do afterCompile. k tomu viz třeba kdyby/events rozšíření https://github.com/…xtension.php#L173
Takže si můžeš zaregistrovat callback na Application::onPresenter($application, $presenter), tam si vzít presenter z parametru, vytvořit komponentu a zavolat $presenter->addComponent('projects', $instanceKomponenty);
Tohle celý bych samozřejmě vyčlenil do nějaký třídy, tu zaregistroval do DI a v initialize pouze zavolal danou metodu.

Editoval CZechBoY (26. 9. 2018 17:09)

David Matějka
Moderator | 6378
+
0
-

zhruba takhle:

$builder->addDefinition($this->prefix('myComponentFactory'))
	->setImplement(App\MyComponentFactory::class)
$builder->addDefinition($this->prefix('myPresenter'))
	->setClass(App\MyPresenter::class);
	->addSetup('addComponent', [new Statement($this->prefix('@myComponentFactory::create')), 'myComponent'])

ale spise bych to nedoporucoval, zneprehledni to kod a prijdes napriklad o lazy inicializaci komponent

CZechBoY
Člen | 3601
+
0
-

@DavidMatějka on to asi chtel pro vsechny presentery a ne jen pro jeden

libik
Člen | 89
+
0
-

Staci mi to i pro jeden. V textu stranky vyparsuju zapis pro nacteni komponenty, ktera se mi v tom miste na webu pak vyrenderuje. Ted musim tu komponentu v mem ContentPresenteru vytvorit, ale pokud bych pridaval dalsi extension, zase bych tam musel uvest novou metodu a tomu se chci vyhnout.

libik
Člen | 89
+
0
-

@DavidMatějka zda se, ze tohle reseni funguje, ale jen pro jedno extension, kdyz pridam dalsi, tak prvni hlasi ‚Component with name 'projects‘ does not exist.' Obdobne kdyz pridam treti, vzdy se zaregistruje jen ta posledni.

class ProjectsExtension {
        ...
        $builder->addDefinition($this->prefix('projectsControlFactory'))
            ->setImplement(\App\Projects\Components\IProjectsControlFactory::class);
        $builder->addDefinition($this->prefix('content'))
            ->setClass(\App\FrontModule\Presenters\ContentPresenter::class)
            ->addSetup('addComponent', [new \Nette\DI\Statement($this->prefix('@projectsControlFactory::create')), 'projects']);

class BlogExtension {
        ....
        $builder->addDefinition($this->prefix('blogControlFactory'))
            ->setImplement(\App\Blog\Components\IBlogControlFactory::class);
        $builder->addDefinition($this->prefix('content'))
            ->setClass(\App\FrontModule\Presenters\ContentPresenter::class)
            ->addSetup('addComponent', [new \Nette\DI\Statement($this->prefix('@blogControlFactory::create')), 'blog']);

Extensions zapsane v configu

extensions:
	projects: App\Projects\DI\ProjectsExtension
	blog: App\Blog\DI\BlogExtension
David Matějka
Moderator | 6378
+
0
-

problem bude asi v opakovanem registrovani presenteru. Bud muzes zkusit pred znovu registrovanim presenteru overit, zda uz neni registrovat pres https://api.nette.org/…Builder.html#… nebo jej vubec neregistrovat a spolehat na to, ze jej registruje nette samo. pak ale budes muset presunout to navazani na addSetup do beforeCompile – tam si vytahnes definici presenteru zas pres getByType a zavolas na tom addSetup

libik
Člen | 89
+
0
-

Super, diky, zabralo to (presunuti do beforeCompile).