Jak udělat podporu více šablon pro jeden modul – přepínání designu uživatelem?
- neznamy_uzivatel
- Člen | 115
Ahoj,
potřeboval bych umožnit v jednom modulu uživateli přepnout na jiné
šablony.
Mám strukturu:
app/EshopModule
/presenters
/templates
/blue
/Index/Default.latte
@layout.latte
/red
/Index/Default.latte
@layout.latte
BaseEshopPresenter.php
IndexPresenter.php
Jak udělat, aby nette hledalo v těch složkách blue a red?
Něco jako $this->setTemplate(‚red‘); // :)
Zkoušel jsem různé setView, apod, ale nějak mi to nejde, seskládá to
„špatně“ cestu k souboru, tzn.
místo:
/app/EshopModule/presenters/templates/blue/Index/Default.latte (což bych
potřeboval s blue jako „přepínatelné“)
mi to seskládá:
app\EshopModule\presenters\templates\Index\red\.latte'
- Michal Vyšinský
- Člen | 608
Ahoj,
něco takového dělám v https://github.com/…ework/themes
(můžeš to třeba rovnou použít nebo nabrat inspiraci)
Edit: právě jsem updatnul dokumentaci a vydal verzi 2.1.0 :)
Editoval Michal Vyšinský (14. 6. 2015 11:40)
- David Matějka
- Moderator | 6445
muzes prekryt metody formatLayoutTemplateFiles a formatTemplateFiles v presenteru: https://api.nette.org/…esenter.html#…
- buffus
- Člen | 101
Ahoj,
David Matějka napsal(a):
muzes prekryt metody formatLayoutTemplateFiles a formatTemplateFiles v presenteru: https://api.nette.org/…esenter.html#…
Mohl bych poprosit o malé rozvinutí, jak udělat v praxi překrytí těch Nette metod? Snažím se navrhnou aplikaci, ve které by si mohl Admin zvolit z několika málo přednastavených šablon (template-A, -B, -n). To vše při společných Front/*/Presenterech (logika aplikace stejná, jen různé vizuální kabáty).
Nejdříve mi stačilo ve Front/BasePresenter.php
nastavit
$this->layout
např. na = "template-A"
(vytažené
z db)
protected function beforeRender()
{
$this->layout = $setting->layout // Z db "template-A" nebo "template-B"
}
a Nette dohledalo výchozí @template-X.latte. To bylo super, ale teď
bych potřeboval pro každou „tempate-X“ vlastní adresář, ve kterém
budou pro každou šablonu konkrétní template-A/*/*.latte
šablony.
Mám adresářový strom:
app
├── bootstrap.php
├── ...
├── modules
│ ├── Admin ...
│ ├── Base ...
│ └── Front
│ ├── BasePresenter.php
│ ├── ErrorPresenter.php
│ ├── HomepagePresenter.php
│ ├── PostPresenter.php
│ ├── templates
│ │ ├── @template-A.latte
│ │ ├── @template-B.latte
│ │ ├── @template-N.latte
│ │ ├── template-A
│ │ │ ├── Error
│ │ │ ├── Homepage
│ │ │ └── Post
│ │ ├── template-B
│ │ │ ├── Error
│ │ │ ├── Homepage
│ │ │ └── Post
│ └── ...
└── ...
Co znamená překrýt metody format*
? Je kód,
co tu ukazuji níže správně? On funguje, ale nejsem si jistý, jestli je
postup OK.
Do Front/BasePresenter.php
jsem zkopíroval original Nette
metody (api)
formatLayoutTemplateFiles()
aformatTemplateFiles()
a do řádků komentovaných // add $this->layout
jsem do
cesty přidal /$this->layout/
/**
* Formats layout template file names.
* @return array
*/
public function formatLayoutTemplateFiles()
{
$name = $this->getName();
$presenter = substr($name, strrpos(':' . $name, ':'));
$layout = $this->layout ? $this->layout : 'layout';
$dir = dirname($this->getReflection()->getFileName());
$dir = is_dir("$dir/templates") ? $dir : dirname($dir);
$list = array(
"$dir/templates/$this->layout/$presenter/@$layout.latte", // add $this->layout
"$dir/templates/$this->layout/$presenter.@$layout.latte", // add $this->layout
);
do {
$list[] = "$dir/templates/@$layout.latte";
$dir = dirname($dir);
} while ($dir && ($name = substr($name, 0, strrpos($name, ':'))));
return $list;
}
/**
* Formats view template file names.
* @return array
*/
public function formatTemplateFiles()
{
$name = $this->getName();
$presenter = substr($name, strrpos(':' . $name, ':'));
$dir = dirname($this->getReflection()->getFileName());
$dir = is_dir("$dir/templates") ? $dir : dirname($dir);
return array(
"$dir/templates/$this->layout/$presenter/$this->view.latte", // add $this->layout
"$dir/templates/$this->layout/$presenter.$this->view.latte", // add $this->layout
);
}
Je výše uvedený postup v pořádku?
Předem děkuji.
Editoval buffus (22. 9. 2015 8:35)
- Unlink
- Člen | 298
Prekrytie (overriding) metódy znamená, že v potomkovi upravuješ
implementáciu nejakej metódy, ktorá je implementovaná v predkovi → https://en.wikipedia.org/…d_overriding
Čiže správne si to pochopil.
Čo sa týka tej tvojej implementácie, tak ono sa to dá značne zjednodušiť, pretože tamto je strašne univerzálne.
Tú štruktúru by som ale trochu poupravil:
app
├── bootstrap.php
├── ...
├── modules
│ ├── Admin ...
│ ├── Base ...
│ └── Front
│ ├── BasePresenter.php
│ ├── ErrorPresenter.php
│ ├── HomepagePresenter.php
│ ├── PostPresenter.php
│ ├── templates
│ │ ├── template-A
│ │ │ ├── Error
│ │ │ ├── Homepage
│ │ │ ├── Post
│ │ │ └── @layout.latte
│ │ ├── template-B
│ │ │ ├── Error
│ │ │ ├── Homepage
│ │ │ ├── Post
│ │ │ └── @layout.latte
│ └── ...
└── ...
Na názov témy by som nezneužíval atribút layout ale v base presentery
si sprav napr.
protected $theme;
A potom by tá implementácia mohla vyzerať nejako takto (netestované)
/**
* Formats layout template file names.
* @return array
*/
public function formatLayoutTemplateFiles()
{
$name = $this->getName();
$presenter = substr($name, strrpos(':' . $name, ':'));
$dir = dirname($this->getReflection()->getFileName());
return = array(
"$dir/templates/$this->theme/$presenter/@layout.latte",
"$dir/templates/$this->theme/@$layout.latte"
);
}
/**
* Formats view template file names.
* @return array
*/
public function formatTemplateFiles()
{
$name = $this->getName();
$presenter = substr($name, strrpos(':' . $name, ':'));
$dir = dirname($this->getReflection()->getFileName());
return array(
"$dir/templates/$this->theme/$presenter/$this->view.latte",
);
}