nerozumim jak vytvorit tridu kterou predam prezenteru

dehtak
Člen | 80
+
0
-

Zdravim, Bud sem blbej nebo nevim.
Kdyz zadam do neonu do service nejakou tridu dejme tomu Lang

declare(strict_types=1);

namespace Factory;
use Nette;

class Lang{
    public $lang;
	public function __construct($request){
         $this->lang='cs';

    }

    public function getLang(){
        return $this->lang;
    }
}
services:
	router: Factory\Router::createRouter
	- Factory\Lang(@http.request)

a pote v prezenteru v constructoru dam

function __construct(Lang $lang) {
   }

tak mi to vyhodi chybovou hlasku
Service ‚application.17‘ (type of App\AdminModule\Presenters\TestPresenter): Class App\AdminModule\Presenters\Lang needed by $lang in __construct() not found. Check type hint and ‚use‘ statements. search►

Co delam blbe ?
Mohl by mi nekdo na nakym jednoduchym prikladu ukazat jak dat sluzbu do neonu a jak si ji pak vytahnout ? Z manualu sem to nepochopil.

Editoval dehtak (20. 4. 2020 11:21)

Mysteria
Člen | 791
+
+1
-

Máš špatně namespace, tvoje třída je \Factory\Lang a v preseneteru máš Lang (bez use, tzn. \App\AdminModule\Presenters\Lang).
Takže buď uprav function __construct(Lang $lang) { na function __construct(\Factory\Lang $lang) { nebo ji naimportuj.
Btw editor ti to určitě taky musí podtrhávat, že používáš neexistující třídu.

dehtak
Člen | 80
+
0
-

Aha diky uz to frci. Jeste jedna vec me zajima
jak v ty tride lang (ted jiz translator) zjistim jmeno prezenteru abych mohl nacist prislusnej lang, popripade slozku kde se prezenter nachazi ?
Dejme tomu ze mam prezenter test

declare(strict_types=1);
namespace  App\AdminModule\Presenters;
use Nette;
use Translator;
final class TestPresenter extends Nette\Application\UI\Presenter{
    function __construct(Translator $translator) {}
    public function renderDefault(){}
}

a u prezenteru mam slozku langs kde jsou jazyky napriklad test.cs test.it
Chci aby to fungovalo automaticky aby si nasel translator podle jmena prezenteru jazyk ve slozce langs a nemusel volat $translator->set(‚test‘)

F.Vesely
Člen | 363
+
+1
-

Nechces radsi na preklady pouzit jiz naprogramovanou knihovnu https://github.com/…/translation ?

dehtak
Člen | 80
+
0
-

To bych mohl ale ja se chci s nette vic seznamit, lepe ho pochopit a to se nejlip nauci clovek na prikladech , nez stahovanim hotovych trid

chemix
Nette Core | 1220
+
+1
-

@dehtak nevim zda to umi contributte\tranlator ale tyto knihovny lze brat i jako neprebernou studnici napadu, a hotovych reseni k nauceni a pochopeni. Ne jen k „tupemu stahovani“ … Urcite bych mrknul do nich zda se to tam nejak snazi resit.

Jinak se obavam ze nejake magicke – samose – je prave s DI vec, co moc nechces. IMHO cesta je, si do te tve tridi predat neco, co tu danou inforamci vi z prvni ruky. Mozna samotny presenter? (sam nevim zda to jde) Spis se snazim nastinit princip a snad nejsem moc daleko od pravdy ;-)

Nevim kdo tuhle informaci zna? Nette Application Request?

Felix
Nette Core | 1137
+
0
-

dehtak napsal(a):

To bych mohl ale ja se chci s nette vic seznamit, lepe ho pochopit a to se nejlip nauci clovek na prikladech , nez stahovanim hotovych trid

LangDetector

Soubor app/Model/LangDetector.php.

namespace App\Model;

class LangDetector
{
}

Registrace sluzby

Soubor config.neon.

services:
  - App\Model\LangDetector

Presenter

Soubor app/Presenters/HomePresenter.php.

namespace App\Presenters;

use Nette\Application\UI\Presenter;
use App\Model\LangDetector;

class HomePresenter extends Presenter
{

  private LangDetector $detector;

  public function __constructor(LangDetector $detector)
  {
    $this->detector = $detector;
  }

  public function actionDefault()
  {
    \Tracy\Debugger::dump($this->detector);
  }

}
F.Vesely
Člen | 363
+
+2
-

Podle me neni dobry napad, aby Translator byl nejak zavisly na Presenteru. Translator muzes pouzivat k prekladu formularu, komponent, emailu, atd.

Pokud nechces stale psat v kazdem Presenteru $translator->set(...), tak si muzes udelat nejakej BasePresenter, od ktereho budou vsechny ostatni dedit a v nem pouzit treba metodu startup a v ni mit $this->translator->set($this->name).

petr.pavel
Člen | 504
+
0
-

dehtak napsal(a):

jak v ty tride lang (ted jiz translator) zjistim jmeno prezenteru abych mohl nacist prislusnej lang, popripade slozku kde se prezenter nachazi ?

a u prezenteru mam slozku langs kde jsou jazyky napriklad test.cs test.it
Chci aby to fungovalo automaticky aby si nasel translator podle jmena prezenteru jazyk ve slozce langs a nemusel volat $translator->set(‚test‘)

Taky mi nepřijde dobrý nápad odvozovat jazyk podle jména presenteru. Mohl bys rozvést, proč to tak máš?

Jazyk bývá volitelný uživatelem, tudíž stejný presenter se chová různě podle hodnoty v url (doméně / cestě / query), kterou si přes routu promítneš do PresenterRequestu, který se ti promítne do presenteru, ale vyžádat si ho můžeš i jinde. Nebo se volba uloží do v session/cookie, kterou si zase můžeš vyžádat rovnou v LangDetectoru – ale jestli je to indexovaný web, tak url by mělo odpovídat jazyku a vracet vždy stejný obsah (SEO).

Jestli názvem presenteru nemyslíš název třídy, ale výraz následně přeložený přes Route::FILTER_TABLE na název třídy, tak co třeba globálním Route::FILTER_IN / Route::FILTER_OUT řešit překlad toho výrazu / názvu presenteru i detekci jazyka?

dehtak
Člen | 80
+
0
-

sablony se take odvozujou od nazvu prezenteru kdyz mam prezenter home musim mit i sablonu home.latte proc nemit i jazyk home.cs jde pouze o jazyky pro sablonu. Kdybych to mel v jednom souboru tak treba nejaka pidi stranka kde mam jen pouze 2 slova pro preklad by natahavala zbytecne velkej soubor se vsema vetama a slovama. Proto to chci delat takhle.

Jeste me zajima jedna vec kdyz dam do neonu do service tridu a v ty tride dam bdump(‚promena‘) jako by ta trida nebyla vubec nactena. Az kdyz si ji vytahnu v konstruktoru v prezenteru tak se teprv aktivuje Jde to nejak udelat aby se trida nacetla automaticky bez toho abych ji zadaval v konstruktoru ? Chova se to strasne divne. Udelal jsem tridu translator dal ji do neonu a v contruktoru dal Translator $translator $this->translator = $translator;
jenze pak ve funkci beforeRender je $this->translator null

Editoval dehtak (22. 4. 2020 13:29)

David Matějka
Moderator | 6427
+
+2
-

Jeste me zajima jedna vec kdyz dam do neonu do service tridu a v ty tride dam bdump(‚promena‘) jako by ta trida nebyla vubec nactena. Az kdyz si ji vytahnu v konstruktoru v prezenteru tak se teprv aktivuje

Ano, to je feature, DI kontejner vytváří jen ty služby, které jsou potřebné.

Jde to nejak udelat aby se trida nacetla automaticky bez toho abych ji zadaval v konstruktoru?

z jakého důvodu to potřebuješ, aby se to vždy spouštelo?

Chova se to strasne divne. Udelal jsem tridu translator dal ji do neonu a v contruktoru dal Translator $translator $this->translator = $translator; jenze pak ve funkci beforeRender je $this->translator null

ten konstruktor máš v presenteru nebo kde? nedáváš to náhodou do base presenteru a pak v konkrétním presenteru přepisuješ konstruktor?

dehtak
Člen | 80
+
0
-

jj v base presenteru v construktoru, ano potrebuju aby se to spoustelo furt.
Tak jinak, jde o tridu detect lang ktera podle request detekuje jazyk. Takhle bych musel pokazde psat v prezenteru
$langs= [cz,de,en];
$lang = $request->detectLanguage($langs);
$translator->set($lang);

jde mi o to abych mel ten translator byl uz pripravenej uz s detekovanym jazykem a uz si ho jen zavolal $translator = new Translator ;
a nebo si ho vytah v konstruktoru;
Takze ta trida kterou chci aby se spustela automaticky je detectLang a ten translator si pak z ni jen vytahne jazyk; Popripade kdybych chtel udelat nakej prepinac jazyku tak chci vytahnou z detect lang dostupne jazyky;

Editoval dehtak (22. 4. 2020 16:33)

Mysteria
Člen | 791
+
0
-

Pokud ji chceš spouštět vždy, tak použij tag run.

services:
	-
		factory: \App\Model\LangDetector
		tags: [run]
David Matějka
Moderator | 6427
+
0
-

ale pro to není potřeba, aby se to spouštělo samo – od toho je DI. Pokud někdo bude potřebovat translator, tak se vytvoří ta jeho instance a detekuje se jazyk. pokud jej nebude potřeba, tak je zbytečný jej vytvářet a spouštět.

dehtak
Člen | 80
+
0
-

To mate pravdu, dobre tak jeste jinak, zapomente na vsechno co jsem psal predtim.
Kdyz si udelam jakoukoliv tridu a chci treba do constuktoru dosadit databazi musim to dat do neonu jinak se tam ta databaze nedosadi; jenze pak nemuzu volat new Trida odkudkoliv chci. Musim zavolat new trida($this->db) a dosazovat tu databazi rucne bez toho aby byla zadana v neonu;
s tema construktorama je to tam dost divny. Treba

 nejakaTrida extends Control{
 function __construct(Nette\Database\Connection $db)
}

Jde mi o pohodlny psani nechci porad neco dosazovat z prezenrteru tridam chci aby si to ty tridy ziskaly sami a ja uz jen tu tridu zavolal. Neco v nete musi bejt ale nevim co.
Take jsem si vsim ze construtor v base prezenteru neni vzdy volan !!!

Editoval dehtak (22. 4. 2020 21:06)

dehtak
Člen | 80
+
0
-

Mysteria napsal(a):

Pokud ji chceš spouštět vždy, tak použij tag run.

services:
	-
		factory: \App\Model\LangDetector
		tags: [run]

To mi vyhodilo chybu Tag ‚run‘ used in service ‚lang‘ definition is deprecated

Editoval dehtak (22. 4. 2020 21:11)

Kamil Valenta
Člen | 481
+
0
-

dehtak napsal(a):

Jde mi o pohodlny psani nechci porad neco dosazovat z prezenrteru tridam chci aby si to ty tridy ziskaly sami a ja uz jen tu tridu zavolal. Neco v nete musi bejt ale nevim co.

Jsou dvě možnosti:

  • vytvářet si objekty ručně pomocí new, ale pak musíš také ručně dosadit všechny závislosti
  • vytvářet si objekty jako service v neonu, a v dalších třídách si je jen vyžádat (konstruktorem, nebo inject anotací, nebo inject metodou…)

Take jsem si vsim ze construtor v base prezenteru neni vzdy volan !!!

Je volán vždy, když request odbavuje presenter, který z toho base dědí.

David Matějka
Moderator | 6427
+
0
-

Nevytvarej instanci ručně, od toho je právě DI, že si požádáš o tu závislost (třeba v konstruktoru) a DI ti ji předá. A ty se nemusíš starat, jaké závislosti má ta daná třída doporučuji si přečíst úvod do DI v dokumentaci https://doc.nette.org/…cy-injection

Co se týče konstruktoru v base presenteru, tak pokud ten konstruktor prekryjes v konkrétním presenteru a nezavolas jej, tak se opravdu nezavola – tak funguje php a snad všechny další jazyky, co znají koncept tříd a dědičnosti.

V base presenteru (a obecně i v konkrétních presenterech) z toho důvodu raději používej inject anotaci https://doc.nette.org/cs/3.0/di-usage#…

F.Vesely
Člen | 363
+
0
-

Doporucuji si tu dokumentaci o ziskavani zavislosti z DI prostudovat celou https://doc.nette.org/cs/3.0/di-usage Jsou tam odpovedi na snad vsechny tve otazky.