Параметры в шаблонах

Выкладываем свои наработки
Ответить
Аватара пользователя
aser
Сообщения: 167
Зарегистрирован: 2009.04.02, 14:25
Откуда: Киев

Параметры в шаблонах

Сообщение aser »

Для проекта в одной из моделей стала задача выбора разных шаблонов отображения.
В административной части выбор шаблона должен выглядеть как выпадающий список с существующих шаблонов отображения. Модель реализует 4 разных типа контента и для каждого из типов должен быть свой набор шаблонов.
Расширение назвал viewmanager, почему так не спрашивайте.

Раздумывая куда вставить переменные с описанием шаблона, пришла идея вставлять в phpDoc комментарий прямо в шаблоне.
Пример шаблона с комментарием

Код: Выделить всё

<?php
/**
 * @label Список
 */

<h1>Шаблон</h1>
<p>Текст шаблона</p>
Пример получения списка шаблонов для dropDownList:

Код: Выделить всё

Yii::import('ext.viewmanager.EViewManager');
$vm = new EViewManager;
$vm->listData('events/'.$model->Type);
в шаблон можно так же вставлять параметр @show 0, в данном случаи шаблон не попадет в список.

Получить список шаблонов с доступом к их параметрам:

Код: Выделить всё

Yii::import('ext.viewmanager.EViewManager');
$vm = new EViewManager;
$views = $vm->findAllViews('events/'.$model->Type);
$views[0]->label // Show data from variable of @label
В расширении всего 2 класса:
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;
    }
}
EViewManager проходит папку с шаблонами и папку с текущей темой, ищет все шаблоны в указанной папке и обрабатывает их.

Код: Выделить всё

<?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;
    }
}
P.S. Добавил архив с кодом.
Вложения
viewmanager.zip
(3.44 КБ) 217 скачиваний
Последний раз редактировалось aser 2012.06.15, 14:30, всего редактировалось 1 раз.
AlTiger
Сообщения: 199
Зарегистрирован: 2012.01.15, 18:37

Re: Параметры в шаблонах

Сообщение AlTiger »

а как скачать то? ^_^
Аватара пользователя
aser
Сообщения: 167
Зарегистрирован: 2009.04.02, 14:25
Откуда: Киев

Re: Параметры в шаблонах

Сообщение aser »

Ну классы описаны в посте, добавил, архивом еще.
Ответить