Как работать с шаблонами для сайтов MVC? - PullRequest
6 голосов
/ 01 декабря 2008

Я пометил это как PHP, но только потому, что я буду использовать код PHP, чтобы показать мою проблему.

Итак, у меня есть такой код для контроллера:

switch ($page)
{
    case "home":
        require "views/home.php";
        break;
    case "search":
        require "views/search.php";
        break;
}

Очевидно, что есть больше страниц, но это должно проиллюстрировать мою проблему. Существует общий заголовок, навигация и нижний колонтитул для обеих этих страниц (и для всех страниц сайта). Должен ли я использовать несколько операторов require? Мое первое предположение будет:

switch ($page)
{
    case "home":
        require "templates/header.php";
        require "templates/navigation.php";
        require "views/home.php";
        require "templates/footer.php";
        break;
    case "search":
        require "templates/header.php";
        require "templates/navigation.php";
        require "views/search.php";
        require "templates/footer.php";
        break;
}

Каким-то образом моя кишка говорит мне, что это неправильно.

Ответы [ 7 ]

5 голосов
/ 01 декабря 2008

Контроллер должен просто установить данные для вида и выбрать, какой вид отображать. Представление должно отвечать за макет страницы, включая общие страницы. Мне нравится твой первый образец, а не второй.

1 голос
/ 01 декабря 2008

Да, вы должны разделить верхний и нижний колонтитулы и т. Д.

Для конкретного примера, который вы показываете, разве это не сработает лучше?

    require "templates/header.php";
    require "templates/navigation.php";
    require "views/$page.php";
    require "templates/footer.php";

(где $ page - это «дом», «поиск» и т. Д.)

0 голосов
/ 06 июня 2013

Если все ваши имена файлов соответствуют вашему запросу / запросу страницы, как показано в вашем примере, тогда вам просто нужна одна строка, а не оператор switch:

require "templates/header.php";
require "templates/navigation.php";
require 'views/' . $page . '.php'; // <-- one-liner
require "templates/footer.php";
0 голосов
/ 09 декабря 2008

Я согласен с tvanfosson и хочу объяснить, почему и как это относится к MVC.

Проблема с вашим вторым примером заключается в том, что контроллер имеет представление о том, как строится представление. В строгом смысле контроллер собирает входные данные для представления и передает их ему, и ничего более.

Практический способ думать об этом, если представление меняется, в зависимости от требований приложения или самих входных данных. Например, если генерируемое представление предназначено для всплывающего окна JavaScript, оно может (и, вероятно, будет) использовать другой набор верхних и нижних колонтитулов, CSS, мета и т. Д. Во втором примере все, что предоставляется контроллеру , Во-первых, это представление, которое знает, как создать представление, и это именно то, что нужно.

Чтобы продолжить мой пример, представьте, что всплывающее окно JavaScript изменено, чтобы быть полным представлением страницы, или реорганизовано для AJAX (или вопрос pop-up / page / AJAX определяется входными данными, такими как скрытый элемент в поле). Теперь вы разрываете контроллер, потому что вид изменился. Это не так много, что вы нарушили MVC, но вам не следовало беспокоиться об этом.

0 голосов
/ 03 декабря 2008

Вы повторяете код. Это почти никогда не хорошая идея. Чтобы быть ближе к вашему первоначальному примеру, что-то вроде этого, безусловно, будет предпочтительнее:

require "templates/header.php";
require "templates/navigation.php";

switch ($page) {
    case "home":
        require "views/home.php";
        break;
    case "search":
        require "views/search.php";
        break;
}

require "templates/footer.php";

Трудно дать больше советов, не зная больше о вашем архитектурном подходе. Например, было бы желательно иметь эту часть контроллера, которая просто подготавливает вывод, в самом центральном месте и начинать буферизацию вывода перед включением шаблонов представления. Таким образом, вы можете сохранить выходные данные в переменной, которую, возможно, захотите обработать, прежде чем возвращать ее содержимое в ответ HTTP.

0 голосов
/ 01 декабря 2008

Вот упрощенная версия того, как я делаю шаблоны с моим текущим проектом, если он используется:

class Template {
    var $pagename = 'index';

    function __construct() {
        $this->pagename = basename($_SERVER['SCRIPT_NAME'], '.php');
        register_shutdown_function(array($this, 'do_output'));
    }

    function do_output() {
        $this->header();
        $this->display($this->pagename);
        $this->footer();
    }

    function __call($template, array $params) {
        call_user_func(array($this, 'display'), $template, params);
    }

    function display($template, array $params = null) {
        include "templates/$template.php";
    }
}

Идея заключается в том, что вы можете написать "include 'Template.inc'; new Template;" и он организует автоматический запуск do_output () в конце скрипта. Из этого осталось несколько вещей, таких как метод передачи переменных в шаблон.

Вы упомянули, что не используете PHP, и там есть несколько PHP-измов: register_shutdown_function () гарантирует, что шаблоны будут вызываться перед деструкторами объекта, но после основного скрипта, и вызовами $ this-> header () / footer () - это вызовы магических функций, которые просто отображают ('header') и display ('footer'), они должны быть переопределены.

Конечно, нет ничего плохого в использовании переключателя, как в примере, который вы опубликовали, но вам не нужны верхние / нижние колонтитулы внутри каждого оператора case. Нечто подобное сделало бы то же самое:

require "templates/header.php";
require "templates/navigation.php";
switch ($page)
{
    case "home":
        require "views/home.php";
        break;
    case "search":
        require "views/search.php";
        break;
}
require "templates/footer.php";

... или вы могли бы заменить switch () чем-то, основанным на имени файла, как я использовал выше, если это работает так, как настроены ваши страницы. Переключение - это самый безопасный способ, если вы планируете делать это через параметры URL.

0 голосов
/ 01 декабря 2008

Если вы используете прямые страницы PHP в качестве шаблонов, вы можете установить глобальную переменную / сессию для хранения нужной страницы. У вас будет php-страница с «основным шаблоном», которая включает элементы верхнего и нижнего колонтитула, а затем вызывает включение для страницы $. Примерно так в контроллере:

$_SESSION['page'] = sanitize_input($_GET['page']);
require "templates/main.php";

и затем в файле шаблона main.php:

require "templates/header.php";
require "templates/navigation.php";
require "views/{$_SESSION['page']}.php";
require "templates/footer.php";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...