В административной части выбор шаблона должен выглядеть как выпадающий список с существующих шаблонов отображения. Модель реализует 4 разных типа контента и для каждого из типов должен быть свой набор шаблонов.
Расширение назвал viewmanager, почему так не спрашивайте.
Раздумывая куда вставить переменные с описанием шаблона, пришла идея вставлять в phpDoc комментарий прямо в шаблоне.
Пример шаблона с комментарием
Код: Выделить всё
<?php
/**
* @label Список
*/
<h1>Шаблон</h1>
<p>Текст шаблона</p>
Код: Выделить всё
Yii::import('ext.viewmanager.EViewManager');
$vm = new EViewManager;
$vm->listData('events/'.$model->Type);
Получить список шаблонов с доступом к их параметрам:
Код: Выделить всё
Yii::import('ext.viewmanager.EViewManager');
$vm = new EViewManager;
$views = $vm->findAllViews('events/'.$model->Type);
$views[0]->label // Show data from variable of @label
EViewItem, Объект хранит данные о шаблоне, его название, путь и параметры.
Код: Выделить всё
<?php
/**
* Created by JetBrains PhpStorm.
* Date: 14.06.12
* Time: 14:59
*
* This is the class for information of the view
*/
class EViewItem
{
protected $_param;
protected $_path;
protected $_name;
public function __get($name)
{
$getter='get'.$name;
$getterUcfirst = 'get'.ucfirst(strtolower($name));
if(method_exists($this,$getter))
return $this->$getter();
else if(method_exists($this,$getterUcfirst))
return $this->$getterUcfirst();
else if(isset($this->_param[strtolower($name)]))
return $this->_param[strtolower($name)];
throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
array('{class}'=>get_class($this), '{property}'=>$name)));
}
/**
* Checks if a property value is null.
* Do not call this method. This is a PHP magic method that we override
* to allow using isset() to detect if a component property is set or not.
* @param string $name the property name or the event name
* @return boolean
*/
public function __isset($name)
{
$getter='get'.$name;
$getterUcfirst = 'get'.ucfirst(strtolower($name));
if(method_exists($this,$getter))
return $this->$getter()!==null;
else if(method_exists($this,$getterUcfirst))
return $this->$getterUcfirst()!==null;
else if(isset($this->_param[strtolower($name)]))
return true;
return false;
}
public function __construct($path, $name) {
$this->setPath($path);
$this->setName($name);
$this->getViewParams();
}
public function setName($name)
{
$this->_name = $name;
}
public function getName()
{
return $this->_name;
}
public function setPath($path)
{
$this->_path = $path;
}
public function getPath()
{
return $this->_path;
}
public function setParam($param,$value)
{
$this->_param[$param]=$value;
}
public function getParam($param) {
}
/**
* Get variables from first comment in the view file
* Find the section firstly strips the /** from the start and *\/ from the end of the comment
* and parse each line to get variables out.
* @return array
*/
public function getViewParams() {
if($this->_param!==null)
return $this->_param;
$content = file_get_contents($this->getPath());
$comment=$lines=null;
if(preg_match('#/\*\*(.*)\*/#s', $content, $comment) === false)
return $this->_param=array();
if(preg_match_all('#^\s*\*(.*)#m', $comment[0], $lines) === false)
return $this->_param=array();
foreach($lines[1] as $line) {
$this->parseLine($line);
}
return $this->_param;
}
/**
* Get the variable and save them in the param property
* @param $line
* @return bool
*/
private function parseLine($line)
{
$line = trim($line);
if(empty($line)) return false;
if(strpos($line, '@') === 0) {
$param = trim(substr($line, 1, strpos($line, ' ') - 1)); //Get the parameter name
$value = trim(substr($line, strlen($param) + 2)); //Get the value
if($this->setParam($param, $value)) return true; //Parse the line and return false if the parameter is valid
}
return false;
}
}
Код: Выделить всё
<?php
/**
* Created by JetBrains PhpStorm.
* Date: 14.06.12
* Time: 14:30
*
* View manager
*/
Yii::import('application.extensions.viewmanager.EViewItem');
class EViewManager {
/**
* Return array with objects of view
*
* @return array
*/
public function findAllViews($basePath)
{
$viewPath = Yii::app()->getViewPath().DIRECTORY_SEPARATOR.$basePath;
$views = $this->findAllViewsByPath($viewPath);
if(($theme=Yii::app()->getTheme())!==null) {
$viewPath = $theme->getViewPath().DIRECTORY_SEPARATOR.$basePath;
$views = array_merge($views,self::findAllViewsByPath($viewPath));
}
return $views;
}
/**
* Return array with objects of view by path
*
* @static
* @param $viewPath path to views
* @return array return array with objects of view or empty array when find nothing
*/
public function findAllViewsByPath($viewPath)
{
$views = array();
if(!file_exists($viewPath))
return $views;
if ($handle = opendir($viewPath)) {
while (false !== ($entry = readdir($handle))) {
if (is_file($viewPath.DIRECTORY_SEPARATOR.$entry)) {
$fileInfo = explode('.',$entry,2);
if($fileInfo[1]!='php')
continue;
$views[$fileInfo[0]]=new EViewItem($viewPath.DIRECTORY_SEPARATOR.$entry,$fileInfo[0]);;
}
}
closedir($handle);
}
return $views;
}
public function listData($basePath,$name='name',$vale='label') {
$views = $this->findAllViews($basePath);
$listData = array();
foreach($views as $view) {
if(!isset($view->show) || (int)$view->show!=0)
$listData[$view->$name]=isset($view->$vale)?$view->$vale:$view->$name;
}
return $listData;
}
}