Skip to content

Latest commit

 

History

History
107 lines (82 loc) · 7.84 KB

File metadata and controls

107 lines (82 loc) · 7.84 KB

Макеты (Layouts). SimpleMVC

Назначение макетов

Макеты (иногда их также называют Шаблонами) нужны, чтобы избежать повторения в коде каждого файла представления тех частей, которые являются общими для многих страниц на сайте, т.е. таких блоков как:

  • хэдер
  • футер
  • меню
  • и др.

Т.е. макет позволяет не дублировать код одинаковых частей, которые есть у разных страниц сайта.

Как работает подсистема макетов

Работа подсистемы Ядра отвечающей за использование макета в основном сосредоточена в реализации метода View->render() (см. исх. код класса View, ранее мы упоминали этот метод в разделе "Представления").

Т.е. в момент, когда в действии контроллера выполняется код вида:

$this->view->render('путь/к/файлу/предстваления');

запускается реализация метода View->render():

public function render($viewFilePath, $layoutPath = '')
{
    if($layoutPath) {
        $layoutPath = $this->layoutsBasePath . $layoutPath; 
    } else {
        $layoutPath = $this->layoutPath;
    }
    
    // Далее начинаем формировать представление
    extract($this->vars); // распаковываем переменные, переданные в представление (VIEW)
    
    ob_start(); // перехватываем поток вывода
    include($this->templateBasepath . $viewFilePath); 
    $CONTENT_DATA = ob_get_contents(); // записываем перехваченное в переменную
    ob_end_clean(); // отключаем перехват
    
    include($layoutPath); // подключаем макет, куда и будет подставлено 
}

-- где фактически происходит следующее:

  • Сначала определяется какой именно путь к файлу макета нужно использовать (путь по умолучанию устанавливается в конструктре данного класса и берется из конфига), после чего это путь записывается в переменную $layoutPath.
  • Далее с помощью стандатрной функции extract() в область видимости разворачиваются переменные, ранее переданные в Представление вызовом addVar() в контроллере.
  • После чего наступает наиболее интересная стадия, с помощью кода:
ob_start(); // перехватываем поток вывода
include($this->templateBasepath . $viewFilePath); 
// записываем перехваченное в переменную
$CONTENT_DATA = ob_get_contents(); 
ob_end_clean(); // отключаем перехват

мы складываем, все что направлялось в стадартный поток вывода -- т.е.:

  • начиная с вызова ob_start(), весь html из файлов представления а также все результаты работы функции echo() не выводятся сразу на экран, а накапливается в специальной области памяти (буфере).
  • Накопленные данные извлекаются из буфера вызовом ob_get_contents() и записываются в переменную $CONTENT_DATA.
  • Буферизация вывода отлючается вызовом функции ob_end_clean();
  • Затем делается включение файл макета:
include($layoutPath); 

Далее рассмотрим пример файла макете и увидим как именно файл макета должен использовать данные, накопленные в $CONTENT_DATA

Файл макета

В качестве пример рассмотрим код макета основного файла макета main.php (исх. код):

<!DOCTYPE html>
<html>
    <?php include('includes/main/head.php'); ?>
    <body> 
        <?php include('includes/main/nav.php'); ?>
        <div class="container">
            <?= $CONTENT_DATA ?>
        </div>
        <?php include('includes/main/footer.php'); ?>
    </body>
</html>

-- здесь мы фактически видим основу тела html страницы, куда подключаются разные части и в том числе выводятся данные полученные в Представлении:

<?= $CONTENT_DATA ?>

Где определяется какой макет будет использоваться

Имя (путь к файлу) используемого макета определяется сразу для всех действий Контроллера в свойстве класса контроллера $layoutPath.

Как создать собственный макет

Чтобы создать собственный макет и подключить его к контроллеру, действуйте так:

  1. Где-нибудь внутри (можно в поддиректории) директории application/views/layouts/ (или иной, все зависит от того, что указано в конфиге) Создайте основной файл вашего макета (тот который будет выводить $CONTENT_DATA и подключать другие части страницы, по аналогии с тем как это делает стандатрный main.php.
  2. Укажите путь к этому макету в $layoutPath вашего контроллера.
  3. Готово! Все действия контроллера будут при вызове $this->view->render() использовать ваш новый макет.

Итоги

  • Система макетов позволяет переиспользовать общие части внешнего вида (такие как хэдер и футер) для разных файлов представлений.
  • Файл макета должен (иначе какой смысл его описывать) обращаться к переменной $CONTENT_DATA и также может делать включения (а может и не делать, если выхотите все описать прямо в нем же) других нужных ему частей.
  • Чтобы указать какой файл макета использовать контроллеру используется свойство контроллера $layoutPath.