Вопрос по View (PHP MVC)?

Приветствую! Перечитал несколько статей по MVC, въехал в суть. Но с View все-таки не совсем понятно. Итак, у меня запускается приложение из index.php, метод route разбирает запрос пользователя и отдает управление одному из методов соответствующего контроллера. И в этом методе уже происходит создание модели и вида, а также передача данных из первого во второе. В качестве кульминации $view->render('template_name'). Но тут что получается. У меня имеется, например, контроллер BlogController. В нем два метода — indexAction, который просто выдает записи из блога и addAction, который выводи форму для добавления записи в блог и обрабатывает ее. Соответственно, мне нужно использоть два разных шаблона. И вот он, вопрос — для каждого действия мне нужно создавать отдельный шаблон, в который будут подставляться переменные? Так это получается непрактично, если у меня будет 5 контроллеров по 5 действий в каждом, это получается уже 25 шаблонов. Или это нормальная практика? Что, если я захочу немного изменить шапку сайта, мне придется изменять все 25 шаблонов?
  • Вопрос задан
  • 7524 просмотра
Решения вопроса 1
vaniaPooh
@vaniaPooh
В Yii есть такое понятие как layout. Он представляет собой макет используемый в большинстве страниц сайта. Внутрь него вставляются файлы с отличиями (собственно, это и есть view). Таким образом макет верстается один раз, а отличия, характерные для каждой страницы помещаются в отдельные файлы. Если, например, речь идет о форме, то можно написать 2 таких файлы — с разметкой формы и с результатами ее обработки. Каким образом генерируются эти файлы — с шаблонизаторами или без не имеет значения.
Ответ написан
Пригласить эксперта
Ответы на вопрос 6
@niko83
Присоединяюсь. Копипаста быть не должно, общие фрагменты во view выносятся в отдельные подключаемые файлы. в CakePHP эта структура называется elements book.cakephp.org/1.2/en/view/97/Elements в других фрэймовках есть свои аналоги
Ответ написан
Комментировать
@egorinsk
Кто мешает вынести общие части (шапка, подвал, сайдбар) в отдельные подшаблоны и инклудить их? Или можно как в джанге, использовать наследование шаблонов, сделать базовый шаблон и расширять его понемножку. Правда. реализацию наследования придется писать самому, так как те шаблонизаторы, вроде Twig, что ее поддерживают, на мой взгляд, неоптимальны и кривоваты.

Также, вопрос, кто запрещает для разных действий использовать (если требуется) один шаблон? Никто не запрещает.

В любом случае, писать по 2 раза/кописпастить код — это неправильно.
Ответ написан
aktuba
@aktuba
Вы не поверите, но иногда на один запрос может быть и десяток вьюшек. Самый простой пример — разный тип возвращаемых данных (xml, html, json, etc.)
Ответ написан
Вообще говоря, да, для каждого действия нужен свой вид/шаблон, причём вид и шаблон считать синонимами можно только с натяжкой. Или даже несколько видов, среди которых контроллер выбирает нужный в данный момент.

Использования наследования и включений шаблонов это следование другим практикам и паттернам непосредственно к MVC отношения не имеющим. Как, кстати, не имеет отношения к MVC и «запускается приложение из index.php, метод route разбирает запрос пользователя и отдает управление одному из методов соответствующего контроллера».

При выборе между наследованием/декорирования и включение посоветовал бы делать упор на первое. Даже без использования шаблонизаторов типа Smarty или Twig оно осуществляется довольно легко с помощью функций ob_*, особенно если достаточно двухуровневого. Метод render может выглядеть примерно так:
ob_start();
require $template;
$content = ob_get_clean();
require 'layout.php';

layout.php так
<html>
<body>
<div id="header">Шапка</div>
<div id="content">
  <?= $content ?>
</div>
</body>
</html>

А blog_index так
<?php foreach($posts as $post): ?>
  <div class="post">
    <h1><?= $post->title ?></h1>
    <?= $post->content ?>
  </div>
<?php endforeach ?>
Ответ написан
int03e
@int03e
Имхо неплохо было бы взять на вооружение REST, выглядеть будет примерно так:
GET /items #=> index
GET /items/1 #=> show
GET /items/new #=> new
GET /items/1/edit #=> edit
PUT /items/1 #=> update
POST /items #=> create
DELETE /items/1 #=> destroy

Соответственно, для new и edit можно использовать один шаблон, а в зависимости от типа запроса дергается разный метод в контролере.
Да, и про лайауты сказали правильно — использовать нужно, дублирование кода это зло.
Ответ написан
Можно так же использовать наследование шаблонов, как в Twig.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы