nerozumim jak vytvorit tridu kterou predam prezenteru
- dehtak
- Člen | 113
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 | 797
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 | 113
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 | 369
Nechces radsi na preklady pouzit jiz naprogramovanou knihovnu https://github.com/…/translation ?
- chemix
- Nette Core | 1310
@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 | 1245
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 | 369
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 | 535
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 | 113
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 | 6445
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 | 113
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)
- David Matějka
- Moderator | 6445
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 | 113
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)
- Kamil Valenta
- Člen | 820
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 | 6445
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/…introduction
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/…dependencies#…
- F.Vesely
- Člen | 369
Doporucuji si tu dokumentaci o ziskavani zavislosti z DI prostudovat celou https://doc.nette.org/…dependencies Jsou tam odpovedi na snad vsechny tve otazky.