Реализация MVC - Шаблоны

 

Всем доброго времени суток. Сегодня мы продолжаем собирать ядро для нашей CMS RS-MINI. По плану реализация абстрактного класса для одной из составляющей схемы проектирования MVCшаблоны. Прежде чем предоставить код этого класса, нужно сказать пару слов, о том какие шаблоны будут существовать в системе. Да и пояснить саму идею, дабы хоть немного понять что к чему.

Давайте начнем с того, какие шаблоны бывают в RS-MINI

Виды шаблонов

В RS-MINI будет три идеологически разных, но одинаково реализованных, типов шаблонов. Давайте я их перечислю:

  1. главный шаблон
  2. шаблон узла
  3. шаблон контроллера

По идеи все эти типы шаблонов будут иметь один и тот же набор методов (базовый класс отвечающий за них — один) разница лишь в месте использования и способе подключения.

В чем смысл главного шаблона? Это тот самый шаблон который вызывает сама система, все остальное вызывается уже из него. Главный шаблон является эдакой точкой входа и подключается на всех страницах сайта, стало быть это самое лучшее место для размещение сквозных элементов верстки, таких как:

  • шапка
  • главное меню
  • контентная область (обычно без контента)
  • футер

Шаблоны узла призваны определить количество колонок сайта. Как известно, сайт может быть:

  • одно колоночным
  • двух колоночным
  • трех колоночным
  • n колоночным

В большинстве случаев даже смешанный вариант (главная страница из одной колонки, внутренни из двух, трех). Этот тип шаблонов тоже может не содержать контента.

Подключается он, как понятно из названия, к узлу. Что подразумевается под словом узел? Например у нас есть адрес /about/feedback/. Это ни что иное как иерархия из трех узлов:

  1. корень
  2. узел about
  3. узел feedback

Шаблон контроллера — это маленьким кусочком html кода, наполненные контентом. Например за вывод этого текста который Вы сейчас читаете и за меню в правой части страницы отвечает шаблон контроллера. За двух колоночное отображение страницы (статья в центре меню справа) нужно благодарить узловой шаблон. А за шапку, контентную область (в которой разместилась двух колоночная сетка) и футер (контент в футоре тоже результат работы шаблона контроллера) отдельное спасибо главному шаблону.

Данный вид шаблонов подключается непосредственно к контроллеру. Кстати контроллеры могу и не иметь шаблона.

Код класса abstractview.class.php

С точки зрения реализации, ризницы между этими шаблона нет вообще, по этому за все разнообразия будет отвечать один базовый класс, вот его код (файл называется abstractview.class.php и лежит в /rs-mini/core/)

<?php

/*
 * @package RS-MINI
 * @copyright (c) 2015 Alexey Glumov aka Rio-Shaman (support@rio-shaman.ru)
 * @license GNU General Public License version 2; see LICENSE.txt
 *
 */
 
namespace core;

if(!defined('RS-MINI')) die();

/*
 * abstractview v 1.0
 *
 * абстрактный класс для шаблонов
 *
 */

abstract class abstractview
{
    /*
     * объект дома
     *
     * @var    - object
     * @access - protected
     */
    
    protected $dom;
    
    /*
     * объект выбранного шаблона для запуска (заполняется с помощью вызова
     * метода getTpl())
     *
     * @var    - object
     * @access - private
     */
    
    private $currentTpl;
    
    /*
     * список (массив) шаблонов
     *
     * @var    - array
     * @access - private
     */
    
    private static $tplList;

    /*
     * конструктор
     *
     * @access - public
     *
     * @param object dom - объект класса dom
     */
    
    public function __construct($dom)
    {
        $this->dom = $dom;
    }
    
    /*
     * метод объявляет массив с объектами шаблонов
     * вызывается один раз из view.class.php
     *
     * @access - public
     *
     * @param array tplList - массив с шаблонами
     */
    
    public function setTplList(&$tplList)
    {
        self::$tplList = $tplList;
    }
    
    /*
     * метод получает шаблон по имени
     *
     * @access - public
     * @return - сам себя
     *
     * @param string name - имя шаблона
     */
    
    public function getTpl($name)
    {
        // сбрасываем свойства выбора шаблона
        $this->currentTpl = FALSE;
        
        // если вызываемый шаблон существует
        if (isset(self::$tplList[$name]))
            // перенесим его объект в свойство выбора
            $this->currentTpl = self::$tplList[$name];
            
        return $this;
    }
    
    /*
     * запуск шаблона (!!!вызов производить только через этот метод)
     *
     * @access - public
     *
     */

    public function run()
    {
        // если выбор был сделан
        if ($this->currentTpl)
            // получаем ответ шаблона
            $this->currentTpl->getResponse();
            
        // в противном случае ничего не произойдет
    }
    
    /*
     * получить ответ шаблона
     *
     * @access - public
     *
     */

    public function getResponse()
    {
        
    }
}

тут мы имеем три свойства

  • dom — свойство будет хранить объект с данными, которые были сформированы контроллерами. Передается этот объект через контсруктор
  • currentTpl — будет хранить в себе объект шаблона который необходимо вызвать. Значение для этого свойства назначается с помощью метода getTpl()
  • tplList — статичное свойство. Содержит массив (список) всех объектов шаблона который необходимы для сборки страницы. Назначается с помощью метода setTplList(). Этот метод будет вызываться из ядра

и пять методов

  • __construct() — куда же без него. Как написано выше суть метода объявить свойство dom
  • setTplList() — переносит список шаблонов из ядра (того места где список был собран) в статичное свойство tplList.
  • getTpl() — метод отыскивает среди списка объект шаблона по имени (имя передается в виде параметра) и сохраняет найденный шаблон в свойстве currentTpl
  • run() — метода запуска шаблона. Если до вызова этого метода в свойство currentTpl было передан объект шаблона, то метод run() вызовет метод getResponse из объекта лежащего в свойстве currentTpl
  • getResponse() — сердце класса. В нем будет храниться html код шаблона. Данный метод подвержен полиморфизму, то есть именно его нужно будет пересоздать в дочернем классе

Если Вы внимательно посмотрите код, то увидите что метод run() вызывает метод getResponse() из свойства currentTpl. Как я написал выше в этом свойстве будет храниться выбранный объект шаблона (по имени). Может возникнуть вопрос, зачем вообще все это надо? Почему html код будет храниться в методе getResponse() а не в методе run()? И почему при всем этом вызов должен происходить через метод run() когда логичнее было вызывать метод getResponse()? Все это нужно для того чтобы шаблоны можно было вызывать вот так:

$this->getTpl('имя шаблона')->run();

при таком вызове, нам не нужно беспокоится о том что шаблона с таким именем нет. В этом случае просто ничего не произойдет (я так в комментариях к методу run() и написал Улыбаюсь) По началу задумано было вызывать шаблоны прям из свойства tplList, вот так:

$this->tplList['имя шаблона']->getResponse();

Но так как шаблон мог не существовать пришлось бы писать вот так:

if (isset($this->tplList['имя шаблона']))
    $this->tplList['имя шаблона']->getResponse();

Уверен на 100% большинству данный способ сборки покажется неадекватным. Я уже говорил, что этот подход можно отнести к категории костыль, но меня он устраиваем чуть менее чем полностью Улыбаюсь

Заключение

В общем-то в этом классе практически ничего сложного нет, тем не менее, если Вам что-то не понятно, обязательно задавайте вопросы.

Результат работы, можно как всегда скачать в конце этой статьи.

Всего Вам наилучшего, у меня все!

Прикрепленные файлы

 

Возможно Вам будут интересны следующие заметки

Комментарии (0)

Ваше имя *
Сайт
Ваш E-mail *
Ваше сообщение *
 
К данной статье пока нет комментариев.