Globální nastavení translatoru přes onCreate v config.neon

malinamar
Člen | 12
+
0
-

Zdravím,

Snažím se nastavit translator pro všechny šablony najednou a narazil jsem i na možnost použití onCreate u TemplateFactory (nette.latteFactory) skrze config.neon. Z toho, co jsem se dočetl, tak by to mělo sloužit k nastavení dodatečných „věcí“ po vytvoření template. Tzn. bych nemusel vytvářet vlastní TemplateFactory s přídavkem pro nastavení translatoru.

translator: App\Model\TranslatorManager
    nette.latteFactory:
        setup:
				'@self::onCreate[] = $template->setTranslator(@translator->getTranslator());

Vlastně tedy potřebuji zavolat $template->setTranslator() s TranslatorManager->getTranslator() (což mi vrací translator object).

Nevím ale, jak to správně zapsat nebo jestli to vůbec takto půjde.
Poradíte mi prosím?

Editoval malinamar (3. 3. 2021 9:50)

dsar
Backer | 53
+
0
-
malinamar
Člen | 12
+
0
-

dsar napsal(a):

Look here

I did, but it didn't help me.
Na to jsem koukal, ale nepomohlo mi to.

Marek Bartoš
Nette Blogger | 1171
+
0
-

A jak vypadala tvá implementace, co ti nefungovalo?

malinamar
Člen | 12
+
0
-

Zkoušel jsem více kombinací a dostával jsem chyby typu:

Service 'latte.latteFactory' (type of Latte\Engine): Expected function, method or property name, 'onCreate[] = function(){$template->setTranslator(@translator->getTranslator();)}' given.
Service 'latte.latteFactory' (type of Latte\Engine): Expected function, method or property name, 'onCreate[] = $template->setTranslator(@translator->getTranslator())' given.
Marek Bartoš
Nette Blogger | 1171
+
0
-

Ta syntaxe [self::class, 'doStuff'] v příkladu je důležitá, Nette z ní chápe že se jedná o callback. Ať už jsi to napsal jakkoli, tak tvůj kód Nette bere jako prostý string.

Pokud ten kód vážně chceš psát do stringu (nechceš, IDE ho nechápe), tak můžeš vycházet z tohoto
https://github.com/…xtension.php

Případně můžeš vycházet z tohoto – přepíšeš jen tu část kódu, kterou jsem vyznačil
https://github.com/…xtension.php#…
Takže něco jako $template->setTranslator($container->getByType(\Namespace\Of\Translator::class));

dsar
Backer | 53
+
0
-

Just tried based on the example of latte globals:

<?php

declare(strict_types=1);

namespace App\Extensions;

use Nette\Bridges\ApplicationLatte\DefaultTemplate;
use Nette\Bridges\ApplicationLatte\Template;
use Nette\Bridges\ApplicationLatte\TemplateFactory;
use Nette\DI\CompilerExtension;
use Nette\DI\Definitions\ServiceDefinition;
use Nette\Localization\Translator;

use App\Localization\MyTranslator;

final class LatteTranslatorExtension extends CompilerExtension
{
        public function beforeCompile(): void
        {
                parent::beforeCompile();

                $builder = $this->getContainerBuilder();

                $templateFactoryDefinition = $builder->getDefinitionByType(TemplateFactory::class);
                $translatorClassDefinition = $builder->getDefinitionByType(MyTranslator::class);
                assert($templateFactoryDefinition instanceof ServiceDefinition);
                $templateFactoryDefinition->addSetup(
                        [self::class, 'setTranslator'],
                        [$templateFactoryDefinition, $translatorClassDefinition]
                );
        }


		public static function setTranslator(TemplateFactory $templateFactory, Translator $translator): void
        {
                $templateFactory->onCreate[] = static function (Template $template) use ($translator): void {
                        $template->setTranslator($translator);
                };
        }
}

With this extension, I don't need to set it in beforeRender() anymore:

<?php

declare(strict_types=1);

namespace App\Presenters;

use Nette;
use Nette\DI\Attributes\Inject;
use Nette\Localization\Translator;

abstract class Presenter extends Nette\Application\UI\Presenter
{
	#[inject]
	public Translator $translator;


	public function beforeRender(): void
	{
		$this->template->setTranslator($this->translator);

		parent::beforeRender();
	}
}

Although I need the abstract presenter for other reasons, but less code :-)

malinamar
Člen | 12
+
0
-

Myslím, že to chápu špatně… Myslel jsem, že mi to pomůže nastavit překlad všude. Ale myslím, že tohle je jen latte. A pro to jsem jen nastavil translate filtr se svojí metodou.
I think I am getting this wrong…I thought it will help me set translation everywhere. But, I think thist is just latte. And for that I just set translate filter with my method.

`translatorManager: App\Model\TranslatorManager
nette.latteFactory:
setup:
addFilter(translate, @translatorManager::translateFilter())`

No a teď, nemáte někdo řešení pro nastavení translatoru pro ormuláře?
Now, anyone have solution for setting translator for Forms?

Něco jako:
Something like:
$form->setTranslator()
ale v globalním měřítku? Abych to nemusel psát při každém vytvoření formuláře? Něco jako výchozí nastavení na můj translator?
but in global way? So I won't have to write it down everytime when creating new Form? Like it will be set by default to my translator?

Editoval malinamar (8. 3. 2021 13:46)

dsar
Backer | 53
+
0
-

In the case of Forms, just use a general FormFactory to pass to other form factories

App\Forms\FormFactory.php

<?php

declare(strict_types=1);

namespace App\Forms;

use Nette;
use Nette\Application\UI\Form;
use Nette\Localization\Translator;

final class FormFactory
{
        use Nette\SmartObject;

        private Translator $translator;


        public function __construct(Translator $translator)
        {
                $this->translator = $translator;
        }


		public function create(): Form
        {
                $form = new Form;
                $form->setTranslator($this->translator);
				return $form;
        }
}

App\Forms\LoginFormFactory.php

<?php

declare(strict_types=1);

namespace App\Forms;

use Nette\Application\UI\Form;

final class LoginFormFactory
{
        private FormFactory $formFactory;

        public function __construct(FormFactory $formFactory)
        {
                $this->formFactory = $formFactory;
        }

		public function create(): Form
        {
                $form = $this->formFactory->create();

                $form->addText('email', 'Email')
					->setRequired('Enter your email');

                $form->addPassword('password', 'Password')
					->setRequired('Enter your password');

                $form->addSubmit('submit', 'Login');

                return $form;
        }
}

Editoval dsar (8. 3. 2021 14:41)