W odróżnieniu od tego jak to standardowo bywa w różnych frameworkach PHP, tutaj widok nie jest "gołym" szablonem, nakładki typu smarty czy twig też nie mają z moim pomysłem nic wspólnego. Główna idea opiera się na potraktowaniu warstwy widoku jako kodu w pełni obiektowego, a więc korzystającego ze wszystkich korzyści z niego płynących, takich jak dziedziczenie, enkapsulacja itp.
Cała koncepcja opiera się na obiektach, które nazwałem komponentami. Chodzi tu po prostu o pewne odrębne elementy interfejsu - "komponenty" wizualne, rozumiane zupełnie dowolnie, jak np. menu, okno logowania, komentarze, galeria zdjęć czy cokolwiek innego widocznego na ekranie. Każdy z takich komponentów może składać się z zagnieżdżonych innych komponentów, a na samym "dole" znajdują się gotowe komponenty będące zwykłymi tagami HTML (lub w wyjątkowych przypadkach mogą to być też klasyczne szablony). Dzięki takiemu podejściu, budowanie elementów interfejsu jest prostsze, nie prowadzi do duplikowania kodu, no i kod nie wygląda jak oparty na include z PHP 4.x ;]
Moduł powstał przy tworzeniu aplikacji zbudowanej na frameworku kohana, ale bez większych akrobacji można go dopasować do własnych zastosowań.
Link do źródeł: https://github.com/SlawomirOlchawa/components
Ciekawy jestem Waszych opinii odnośnie takiego rozwiązania, odnośnie samego kodu również.
Przy okazji, jeśli ktoś spotkał się z podobnym podejściem w jakimś z frameworków to chętnie dowiem się więcej na ten temat.
Dla lepszego zrozumienia, przykładowe fragmenty kodu:
Widok:
class Component_Category_Info extends Tag_Block { /** * @var Model_Category */ protected $_category; /** * @param Model_Category $category */ public function __construct(Model_Category $category) { parent::__construct(); $this->_category = $category; Helper_Includer::addCSS('media/app/css/category.css'); } /** * @return string */ protected function _render() { $this->addCSSClass('category_info'); $descriptionBlock = new Tag_Block($this->_category->description); $descriptionBlock->addCSSClass('lightBg'); $descriptionBlock->addCSSClass('description'); $this->add($descriptionBlock); return parent::_render(); } }
Kontroler:
class Controller_Category extends Controller_Entity { public function action_index() { $info = new Component_Category_Info($this->_entity); $info->cache($this->_entity->getURL().'/info'); $this->layout->add($info); } }