Vytváření různých šablon pro jednu komponentu
- vymak
- Člen | 92
Ahoj chtěl bych se zeptat jaký je správný postup při vytváření různých šablon v jedné komponentě. Nyní to mám navrhnuté takhle:
BaseControl:
class BaseControl extends Control
{
private $name;
public function setName($name)
{
if (!$name) {
$this->name = NULL;
return;
}
if ($name === 'render') {
return;
}
$replaced = Strings::replace($name, '/render/');
$this->name = $replaced;
}
/**
* @return ITemplate
*/
protected function render()
{
$class = new ClassType($this);
$path = $class->shortName;
$path[0] = Strings::lower($path[0]);
$dir = '';
if ($class->inNamespace()) {
$dir = $class->namespaceName . '/';
}
$template = $this->template;
$template->setFile(APP_DIR . '/components/templates/' . Strings::webalize($dir, '/') . Strings::replace($path, '/Control/') . $this->name . '.latte');
return $template;
}
V případě že je v komponentě pouze klasická metoda render() vše funguje bez problémů. Jakmile chci ale použít například ještě renderOther() řeším to takhle:
class PartnersControl extends BaseControl implements IComponent
{
public function render()
{
$this->name = NULL;
$template = parent::render();
$template->render();
}
public function renderOther()
{
$this->name = __FUNCTION__;
$template = parent::render();
$template->render();
}
}
Takhle to sice funguje, ale pokud se render volá až pod renderOther použije se nastavený
$this->name
Musím jej tedy v klasické metodě render smazat. Napadlo mě řešení, že by se v mé třídě BaseControl v metodě render zjišťovalo jaká metoda jej zavolala, ale netuším jestli je to z technického hlediska vůbec možné.
Tedy něco jako:
class BaseControl extends Control
{
private function returnName($name)
{
$replaced = Strings::replace($name, '/render/');
return $replaced;
}
/**
* @return ITemplate
*/
protected function render()
{
$methodWhichCall = get_method_which_call_this(); // tady tohle právě nevím zdali nějak lze
$name = $this->returnName($methodWhichCall);
$class = new ClassType($this);
$path = $class->shortName;
$path[0] = Strings::lower($path[0]);
$dir = '';
if ($class->inNamespace()) {
$dir = $class->namespaceName . '/';
}
$template = $this->template;
$template->setFile(APP_DIR . '/components/templates/' . Strings::webalize($dir, '/') . Strings::replace($path, '/Control/') . $name . '.latte');
return $template;
}
- Šaman
- Člen | 2666
Tohle není dobré. Metoda render() má za úkol vykreslit pohled (klidně
echem), nikoliv vrátit šablonu. Jestli ti jde o to, abys nemusel pokaždé
nastavovat soubor šablony, vytvoř si na to vlastní metodu a tu pak volej,
nebo nevolej, jak budeš potřebovat. Ale bude to průhledné a
srozumitelné.
Už jsem to řešil, měl jsem i podobná řešení, jako ty (až na to, že
render pokaždé vykresloval, nic nevracel), ale zatím nejsrozumitelnější mi
přišlo tohle
Ty jiné pohledy nejsou vůbec běžné, takže při tvorbě nového pohledu
s vlastní šablonou už ten jeden řádek
$template->setFile(__DIR__ . '/foo.latte');
moc nezdrží a
čitelnost výrazně zlepší. Render metoda hledá soubor podle konvence,
ostatní to musí specifikovat explicitně (a i ta render se dá přepsat na
jiný soubor explicitně).
Editoval Šaman (14. 9. 2014 17:08)