Jak vypsat stejný vzor hodnot ve více šablonách
- ForestCZE
- Člen | 209
Ahoj, prosím o pomoc. Vytáhnu si uživatele:
Ve třídě UserManager
public function getInfo(string $username)
{
return $this->database->getUsers()->where('username = ?', $username)->fetch();
}
V presenteru bych to měl pak předat do templaty:
$this->template->info = $this->userManager->getInfo('Forest');
Latte:
<table>
<tr><td>Jméno</td> <td></td>{$info->firstname}</tr>
<tr><td>Příjmení</td> <td></td>{$info->lastname}</tr>
<tr><td>Věk</td> <td></td>{$info->age}</tr>
</table>
A tento vzor budu mít pokaždé, akorát že na jedné stránce si ty data vytáhnu podle přihlášeného uživatele a jinde třeba zase podle hledaného uživatele ve formuláři.
Jak to udělat tak, abych to nemusel posílat do templaty v každém presenteru zvlášť a nemusel jsem tu tabulku vkládat do každého latte souboru zvlášť? Nějak to předat, abych mohl mít třeba:
userinfo.latte
{define userinfo}
<table>
<tr><td>Jméno</td> <td></td>{$info->firstname}</tr>
<tr><td>Příjmení</td> <td></td>{$info->lastname}</tr>
<tr><td>Věk</td> <td></td>{$info->age}</tr>
</table>
{/define}
A v těch šablonách, kde to chci vypsat:
{import 'userinfo.latte'}
{innclude userinfo}
Díky předem za rady :)
Editoval ForestCZE (14. 5. 2019 19:01)
- ForestCZE
- Člen | 209
Tak jsem se o něco pokusil:
UserInfoControl.php
<?php
namespace App\FrontModule\Components\UserInfo;
use Nette\Application\UI\Control;
final class UserInfoControl extends Control
{
public function render()
{
$this->template->setTemplate(__DIR__ . '/userinfo.latte');
$this->template->render();
}
}
UserPresenter
protected function createComponentUserInfo()
{
$control = new UserInfoControl;
return $control;
}
Tam, kde to potřebuji:
{control userInfo}
Vyhazuje mi to:
Invoking filters on Template object is deprecated, use getLatte()->invokeFilter().
EDIT: Už vím. Tu render metodu je potřeba upravit takto:
$template = $this->getTemplate();
$template->setFile(__DIR__ . '/userinfo.latte');
$template->render();
Editoval ForestCZE (14. 5. 2019 20:54)
- MajklNajt
- Člen | 502
@ForestCZE tej komponente určite budeš chcieť cez konštruktor predať nejaké závislosti, takže si vytvor na ňu továrničku (stačí interface)
interface IUserInfoControlFactory
{
/** @return App\FrontModule\Components\UserInfo\UserInfoControl */
public function create(): App\FrontModule\Components\UserInfo\UserInfoControl;
}
továrničku zaregistruj v config.neon ako službu
services:
- App\FrontModule\Components\UserInfo\IUserInfoControlFactory
a presenter bude potom vyzerať takto:
/** @var App\FrontModule\Components\UserInfo\IUserInfoControlFactory @inject */
public $userInfoControlFactory;
protected function createComponentUserInfo(): App\FrontModule\Components\UserInfo\UserInfoControl
{
return $this->userInfoControlFactory->create();
}
- ForestCZE
- Člen | 209
MajklNajt napsal(a):
@ForestCZE tej komponente určite budeš chcieť cez konštruktor predať nejaké závislosti, takže si vytvor na ňu továrničku (stačí interface)
interface IUserInfoControlFactory { /** @return App\FrontModule\Components\UserInfo\UserInfoControl */ public function create(): App\FrontModule\Components\UserInfo\UserInfoControl; }
továrničku zaregistruj v config.neon ako službu
services: - App\FrontModule\Components\UserInfo\IUserInfoControlFactory
a presenter bude potom vyzerať takto:
/** @var App\FrontModule\Components\UserInfo\IUserInfoControlFactory @inject */ public $userInfoControlFactory; protected function createComponentUserInfo(): App\FrontModule\Components\UserInfo\UserInfoControl { return $this->userInfoControlFactory->create(); }
Funguje to suprově. Mám teda:
protected function createComponentUserInfo() : UserInfoControl
{
return $this->userInfoControlFactory->create($this->user->getIdentity()->username);
}
Mohu tuto komponentu nějak vytvořit až po zpracování formuláře?
Když mám:
public function searchUserSucceeded(Form $form)
{
$values = $form->getValues();
//zde vytvořit komponentu a do argumentu fce "create" dosadit hodnotu z formuláře
}
Jak na to? Díky :)
- MajklNajt
- Člen | 502
@ForestCZE dynamicky môžeš dosadiť premennú cez multiplier:
protected function createComponentUserInfo() : UserInfoControl
{
return new Nette\Application\UI\Multiplier(function($username) {
return $this->userInfoControlFactory->create($username);
});
}
public function renderShowUserInfo()
{
$this->template->username = $this->user->getIdentity()->username;
}
v šablóne potom
{control userInfo-$username}
Ale nepchaj tú premennú do šablóny hneď po odoslaní formulára! Po úspešnom spracovaní formulára by mal nasledovať redirect – viď napr. https://en.wikipedia.org/…Redirect/Get
EDIT: komponenta sa vytvára až keď ju potrebuješ – v tomto prípade
použitím makra {control ...}
, takže ak jej vytvorenie chceš
podmieniť, môžeš napr. takto:
{ifset $username}
{control userInfo-$username}
{/ifset}
Editoval MajklNajt (15. 5. 2019 9:27)
- ForestCZE
- Člen | 209
MajklNajt napsal(a):
@ForestCZE dynamicky môžeš dosadiť premennú cez multiplier:
protected function createComponentUserInfo() : UserInfoControl { return new Nette\Application\UI\Multiplier(function($username) { return $this->userInfoControlFactory->create($username); }); } public function renderShowUserInfo() { $this->template->username = $this->user->getIdentity()->username; }
v šablóne potom
{control userInfo-$username}
Ale nepchaj tú premennú do šablóny hneď po odoslaní formulára! Po úspešnom spracovaní formulára by mal nasledovať redirect – viď napr. https://en.wikipedia.org/…Redirect/Get
EDIT: komponenta sa vytvára až keď ju potrebuješ – v tomto prípade použitím makra
{control ...}
, takže ak jej vytvorenie chceš podmieniť, môžeš napr. takto:{ifset $username} {control userInfo-$username} {/ifset}
Asi jsme se špatně pochopili. Mám formulář (jedno textové pole), kde vyhledávám uživatele:
protected function createComponentSearchUser()
{
$form = new Form;
$form->addText('username', 'Uživatelské jméno:')
->setRequired('Zadej uživatelské jméno.')
->setAttribute('placeholder', 'Uživatelské jméno')
->setAttribute('autocomplete', 'off')
->setAttribute('spellcheck', 'false');
$form->addSubmit('search', 'Hledat');
$form->addProtection('Vypršel časový limit.');
$form->setMethod('GET');
$form->onSuccess[] = [$this, 'searchUserSucceeded'];
return $form;
}
public function searchUserSucceeded(Form $form)
{
$values = $form->getValues();
$exists = $this->database->getUsers()->where('username = ?', $values['username'])->fetch();
if($exists)
....->create($values['username']); //zde potřebuji předat argument a vytvořit komponentu
}
- MajklNajt
- Člen | 502
@ForestCZE v tom prípade by to malo fungovať tak, ako som
písal – pomocou Multiplier
u a nasetovania do templaty
v searchUserSucceeded
public function searchUserSucceeded(Form $form)
{
$values = $form->getValues();
$exists = $this->database->getUsers()->where('username = ?', $values['username'])->fetch();
if($exists) $this->template->username = $values['username'];
}
{ifset $username}
{control userInfo-$username}
{/ifset}
- ForestCZE
- Člen | 209
MajklNajt napsal(a):
@ForestCZE v tom prípade by to malo fungovať tak, ako som písal – pomocou
Multiplier
u a nasetovania do templaty vsearchUserSucceeded
public function searchUserSucceeded(Form $form) { $values = $form->getValues(); $exists = $this->database->getUsers()->where('username = ?', $values['username'])->fetch(); if($exists) $this->template->username = $values['username']; }
{ifset $username} {control userInfo-$username} {/ifset}
protected function createComponentUserInfo() : UserInfoControl
{
return new Multiplier(function($username){
return $this->userInfoControlFactory->create($username);
});
}
Return value of App\FrontModule\Presenters\ContactsPresenter::createComponentUserInfo() must be an instance of App\Components\UserInfo\UserInfoControl, instance of Nette\Application\UI\Multiplier returned
Chápu, co to znamená, ale nevím, jak to vyřešit. Předem děkuji za pomoc a za trpělivost.
- David Matějka
- Moderator | 6445
multiplier neslouzi k takovemu predavani hodnot do komponent.
v tom searchUserSucceeded proved redirect a to username si uloz do parametru:
$this->redirect('this', ['username' => $values['username']]);
pote v createComponentUserInfo budes mit
protected function createComponentUserInfo() : UserInfoControl
{
return $this->userInfoControlFactory->create($this->getParameter('username'));
}
- ForestCZE
- Člen | 209
David Matějka napsal(a):
multiplier neslouzi k takovemu predavani hodnot do komponent.
v tom searchUserSucceeded proved redirect a to username si uloz do parametru:
$this->redirect('this', ['username' => $values['username']]);
pote v createComponentUserInfo budes mit
protected function createComponentUserInfo() : UserInfoControl { return $this->userInfoControlFactory->create($this->getParameter('username')); }
protected function createComponentUserInfo() : UserInfoControl
{
return $this->userInfoControlFactory->create($this->getParameter('username'));
}
$user_exists = $this->database->getUsers()->where('username = ?', $values['username'])->fetch();
if($user_exists)
{
$this->redirect('this', ['username' => $values['username']]);
$this->template->searched = true;
}
{ifset $searched}
{control userInfo}
{/ifset}
Netuším, co dělám špatně, ale komponenta se nevykreslí.
EDIT: To přesměrování jsem dal pryč a už to funguje. Ono asi není potřeba, protože metoda GET se o to postará.
Editoval ForestCZE (15. 5. 2019 14:28)
- Gavrilo
- Člen | 46
ForestCZE napsal(a):
David Matějka napsal(a):
multiplier neslouzi k takovemu predavani hodnot do komponent.
v tom searchUserSucceeded proved redirect a to username si uloz do parametru:
$this->redirect('this', ['username' => $values['username']]);
pote v createComponentUserInfo budes mit
protected function createComponentUserInfo() : UserInfoControl { return $this->userInfoControlFactory->create($this->getParameter('username')); }
protected function createComponentUserInfo() : UserInfoControl { return $this->userInfoControlFactory->create($this->getParameter('username')); } $user_exists = $this->database->getUsers()->where('username = ?', $values['username'])->fetch(); if($user_exists) { $this->redirect('this', ['username' => $values['username']]); $this->template->searched = true; } {ifset $searched} {control userInfo} {/ifset}
Netuším, co dělám špatně, ale komponenta se nevykreslí.
EDIT: To přesměrování jsem dal pryč a už to funguje. Ono asi není potřeba, protože metoda GET se o to postará.
Pošli celý kód a nie len jeho časť. Pravdepodobne tam vidím chybu.
- MajklNajt
- Člen | 502
@DavidMatějka prečo podľa teba neslúži multiplier na predávanie takejto hodnoty do komponenty? zadanie znelo „tento vzor budu mít pokaždé, akorát že na jedné stránce si ty data vytáhnu podle přihlášeného uživatele a jinde třeba zase podle hledaného uživatele ve formuláři.“, čiže je veľká pravdepodobnosť, že tá komponenta sa vyskytne na stránke aj viackrát, kedy bude multiplier nezbytný… toto je podľa mňa ukážkové použitie multiplieru
- ForestCZE
- Člen | 209
MajklNajt napsal(a):
@DavidMatějka prečo podľa teba neslúži multiplier na predávanie takejto hodnoty do komponenty? zadanie znelo „tento vzor budu mít pokaždé, akorát že na jedné stránce si ty data vytáhnu podle přihlášeného uživatele a jinde třeba zase podle hledaného uživatele ve formuláři.“, čiže je veľká pravdepodobnosť, že tá komponenta sa vyskytne na stránke aj viackrát, kedy bude multiplier nezbytný… toto je podľa mňa ukážkové použitie multiplieru
Vyskytne se pouze jednou na jedné stránce, podruhé úplně na jiné stránce (v jiném presenteru a šabloně).
- David Matějka
- Moderator | 6445
@MajklNajt tak udelas dve komponenty. navic jako hodnotu tam muzes
predat jen [a-z0-9]+
multiplier je primarne urceny v situaci, kdy komponenty vypisujes pres foreach