Jak odeslat URL parameter ve formulari
- MrAndy
- Člen | 12
Dobry den,
mam formular na multilanguage webu
protected function createComponentManageQuestion(): Form
{
$form = new Form();
$form->addHidden('locale',$this->translator->getLocale());
$form->addHidden('object',0);
$form->addTextArea('question');
$form->addTextArea('explanation');
$form->addSubmit('sendForm')->setHtmlAttribute('id','sendForm');
$form->addSubmit('sendFormApprove')->setHtmlAttribute('id','sendFormApprove');;
$form->onSuccess[] = [$this, 'saveQuestionAndAnswers'];
return $form;
}
parameter locale standartne predavam pres url
$this->link(‚Question:manage‘, [$question->id, ‚locale‘
⇒ $this->locale]).
Vychozi jazyk je CS, kdyz odeslu formular s EN verze tak se vzdy odesle na
default.
Jde mu nejak predat ten parameter locale, jinak nez resenim v hidden inputu?
Dekuji
- MrAndy
- Člen | 12
MajklNajt napsal(a):
otázkou je, na čo potrebuješ
locale
posielať? nie je jednoduchšie si ho vytiahnuť až vsaveQuestionAndAnswers
?
zpracovani v ‚saveQuestionAndAnswers‘ je spise nouze.
Jde o to ze locale pro web beru z routeru, takze kdyz jsem na url
/en/manage a odeslu formular tak se mi odesle na
/namage a tim padem se mi prepne web do default
locale a ja to pak musim zbytecne osetrovat podruhe.
- nightfish
- Člen | 519
MrAndy napsal(a):
kdyz jsem na url/en/manage
a odeslu formular tak se mi odesle na/manage
Tohle mi přijde jako hlavní problém – potřebuješ se dostat do stavu,
kdy se ti formulář odešle na /en/manage
. Obvykle se to děje
automaticky. Pokud ne, tak buď někde natvrdo nastavuješ /manage
a nebo ti nefunguje správně router (v takovém případě ideálně dodej
ukázku svých routovacích pravidel).
- MrAndy
- Člen | 12
nightfish napsal(a):
MrAndy napsal(a):
kdyz jsem na url/en/manage
a odeslu formular tak se mi odesle na/manage
a nebo ti nefunguje správně router (v takovém případě ideálně dodej ukázku svých routovacích pravidel).
priznam se ze to je zcela mozne, s routerem jeste nejsem kamarad
public static function createRouter(): RouteList
{
$router = new RouteList;
$router->addRoute('[<locale=cs cs|en>/]panel/<presenter>/<action>[/<id>]', 'Panel:Home:default');
$router->addRoute('[<locale=cs cs|en>/]<presenter>/<action>[/<id>]', 'Home:default');
return $router;
}
- m.brecher
- Generous Backer | 873
@MrAndy
Vychozi jazyk je CS, kdyz odeslu formular s EN verze tak se vzdy odesle na default. Jde mu nejak predat ten parameter locale, jinak nez resenim v hidden inputu?
Ano, na podobný problém narazí časem každý – není jednoduché pochopit jak donutit formulář aby v URL konkrétně v atributu action poslal nějaké parametry. Lidi pak ze zoufalství cpou parametry do input hidden. Lepší je akceptovat koncepci signálů Nette a nejít proti srsti.
Nette je poměrně striktní co se týče signálů komponent a formulářů. Signál lze odesílat POUZE A JEDINĚ na aktuálním requestu. Co je to aktuální request? Ten je odvozen z url které dorazilo na server. Patří tam modul, presenter, action a některé parametry, ale ne všechny. Jenom tzv. parametry akce – tedy parametry které si do některé z metod akce v presenteru napíšeme:
public function actionUpdate(int $id) // toto $id je parametr započítaný do aktuálního requestu
{
.......
}
Takže stručně řečeno je aktuální request:
aktuální presenter
aktuální akce
parametry uvedené v některé z metod akce
Navíc do aktuálního requestu, která signály respektují patří PERSISTENTNÍ parametry které se definují v presenteru
use Nette\Application\Attributes\Persistent; // bacha!! tohle tam musí být
class MyPresenter extends Presenter
{
#Persistent
public string $lang = 'cs'; // bacha !! musí být public, jinak to nefunguje !!
}
Takže ideální v Tvém případě je definovat si $lang jako persistentní parametr. Ale bacha, definuj ho v plném rozsahu platnosti v aplikaci, tedy ideálně v BasePresenteru, což je abstraktní předek všech presenterů a ostatní final presentery z něj dědí. Nebo budeš muset ručně deklarovat persistentní parametr ve VŠECH presenterech, což je spousty práce a to přece nechceš :).
Editoval m.brecher (24. 3. 2023 15:08)
- m.brecher
- Generous Backer | 873
@nightfish
Tohle mi přijde jako hlavní problém – potřebuješ se dostat do stavu, kdy se ti formulář odešle na /en/manage. Obvykle se to děje automaticky. Pokud ne, tak buď někde natvrdo nastavuješ /manage a nebo ti nefunguje správně router (v takovém případě ideálně dodej ukázku svých routovacích pravidel).
Tohle určitě není problém routeru, ale striktní implementace signálů v Nette. Jediný rozumný způsob je nastavit parametr $lang jako persistentní napříč všemi presentery. Pak je to úplně jednoduché.
- MrAndy
- Člen | 12
m.brecher napsal(a):
@MrAndy
Takže ideální v Tvém případě je definovat si $lang jako persistentní parametr. Ale bacha, definuj ho v plném rozsahu platnosti v aplikaci, tedy ideálně v BasePresenteru, což je abstraktní předek všech presenterů a ostatní final presentery z něj dědí. Nebo budeš muset ručně deklarovat persistentní parametr ve VŠECH presenterech, což je spousty práce a to přece nechceš :).
locale mam definovane „globalne“
ale kdyz se kouknu do form action tak vidim ze odkazuje na adresu bez
locale,
muj BasePresenter
<?php declare(strict_types = 1);
namespace App;
use Nette;
use Contributte;
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
public $locale;
/** @var Nette\Localization\ITranslator @inject */
public $translator;
/** @var Contributte\Translation\LocalesResolvers\Session @inject */
public $translatorSessionResolver;
public function __construct(
Nette\Localization\ITranslator $translator,
)
{
$this->translator = $translator;
}
public function beforeRender(){
parent::beforeRender();
$this->locale = $this->translator->getLocale();
$this->template->locale = $this->locale;
}
}
- Kcko
- Člen | 470
MrAndy napsal(a):
m.brecher napsal(a):
@MrAndy
Takže ideální v Tvém případě je definovat si $lang jako persistentní parametr. Ale bacha, definuj ho v plném rozsahu platnosti v aplikaci, tedy ideálně v BasePresenteru, což je abstraktní předek všech presenterů a ostatní final presentery z něj dědí. Nebo budeš muset ručně deklarovat persistentní parametr ve VŠECH presenterech, což je spousty práce a to přece nechceš :).
locale mam definovane „globalne“
ale kdyz se kouknu do form action tak vidim ze odkazuje na adresu bez locale,muj BasePresenter
<?php declare(strict_types = 1); namespace App; use Nette; use Contributte; abstract class BasePresenter extends Nette\Application\UI\Presenter { public $locale; /** @var Nette\Localization\ITranslator @inject */ public $translator; /** @var Contributte\Translation\LocalesResolvers\Session @inject */ public $translatorSessionResolver; public function __construct( Nette\Localization\ITranslator $translator, ) { $this->translator = $translator; } public function beforeRender(){ parent::beforeRender(); $this->locale = $this->translator->getLocale(); $this->template->locale = $this->locale; } }
Doplň si persistentní notaci, jak Ti řekl m.brecher, pak se Ti to bude přenášet, ideálně s výchozí hodnotou.
- MrAndy
- Člen | 12
doplnil jsem to tam
router jsem zmenil na
$router->withModule('Panel')->addRoute('[<locale=cs cs|en>/]panel/<presenter>/<action>[/<id>]', 'Home:default');
$router->withModule('Api')->addRoute('[<locale=cs cs|en>/]api/<presenter>/<action>[/<id>]', 'Home:default');
$router->addRoute('[<locale=cs cs|en>/]<presenter>/<action>[/<id>]', 'Home:default');
a funguje to perfektne, nechapu vubec jak, ale dela to presne to co od toho ocekavam :-)
@mbrecher Diky
@Kcko Diky