А как вы во view передаете данные?

гемоглобин

Новичок
Вы передаете сразу объект или набор конкретных переменных? А если view содержить в себе подвью или что-то в этом духе?
Если объект, то допустимо ли, чтобы запрос к базе шел прямо в момент рендеринга? Например, есть статьи и комментарии к ним. В классе Arcticle заложен метод getComments() который подгружает коменты из базы через какой-нибудь объект commentsStorage. И этот getComments вызывается прямо во вью

<?php foreach ($article->getComments() as $comment): ?>
<?= htmlspecialchars($comment) ?>
<?php endforeach ?>
 

Фанат

oncle terrible
Команда форума
А если view содержиT в себе подвью или что-то в этом духе?
Отличный вопрос.
Вот только к передаче данных в шаблон он особого отношения не имеет. С этим-то, как раз, проблем нет. Понято что отдельными переменными будет долго, а массив или объект - в самый раз.

А вот "Если объект, то допустимо ли, чтобы запрос к базе шел прямо в момент рендеринга?" - это ключевой вопрос современности.

Собственно, это проблема "активные vs. пассивные шаблоны", которая некоторое время назад активно обсуждалась.

Тогда у меня своего мнения не было, а сейчас вот сформировалось.
Подходы можно условно разделить на 4 группы:
- самый эээ... прямолинейный: "юзай ob_* функции". Т.е. ответ - "да, можно обращаться к базе, когда уже идет рендеринг".
- самый хитро... умный - SSI: если вдуматься, то пост-парсинг сгенерированного ХТМЛ-а решает нам кучу проблем. Естественно, такой парсинг ударяет по производительности (ведь нжинкс, веместо того, чтобы просто отдать страницу, должен сначала разобрать ее по буковке и найти инструкции SSI, сделать подзапросы к модулям и собрать из ответов готовую страницу), но, говорят, падение совсем незначительное. Зато какой профит! Проблема в одном из блоков не ложит нам весь сайт, получается истинно блочная структура, скорость генерации основной страницы уменьшается.
- самый очевидный: блочные шаблоны. прямое следствие п.2., по аналогии с которым вспоминаем "не-РНР шаблоны". Ведь перед ними такая проблема вообще не стоит - у них парсинг не объединен с выводом, как в пхп. Сначала идет предварительный парсинг шаблона, а потом только его вывод. На этапе парсинга не проблема найти включение блоков, отпарсить их тоже, а потом только начинать вывод.
- самый, на мой взгляд, православный, но и самый муторный - в основном контроллере страницы поочередно вызываются все контроллеры блоков, отдают свои сгенерированные хтмл-и, и их содержимое вставляется в основной шаблон. Здесь проблема в том, что каждый блок приходится дублировать два раза - один раз упоминая его в шаблоне. а второй - вызывая его в контроллере. Во всех остальных случаях достаточно блок обозначить только в шаблоне.
На мой вкус - это не такая уж и беда. В конце концов, все остальные данные мы тоже по два раза прописываем, сначала получение в контроллере, а потом вывод в шаблоне.
 

Redjik

Джедай-мастер
Фанат
Когда работал в студии, у нас был 4ый вариант, хотя Xslt вполне позволял сделать все по 3му.
Сейчас, в разработках на yii, без зазрения совести включаю кэшируюшиеся виджеты в шаблон(например блок новостй на главной или главное меню), и не заморачиваюсь правильно это или нет с точки зрения философии MVC.
 

d1gi

Новичок
да, 4-ый вариант самый православный ;) но тогда как должен выглядеть "основной контроллер"? по пусти это получается некий "управляющий" котроллер и как его можно называть, чтобы понятно было? :) может быть какой-то Mapper.
 

Фанат

oncle terrible
Команда форума
да, 4-ый вариант самый православный ;) но тогда как должен выглядеть "основной контроллер"?
Имеется в виду основной контроллер данной страницы, а не какой-то центральный.
Скажем, страница отображения списка новостей генерируется контроллером списка новостей. Но при этом на этой странице езе отображается форма логина, список последних комментариев к новостям, опрос.

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

Если вдуматься, то это сильно мутроно. Скажем, форма логина рисуется вообще на всех страницах. И что - в каждом контроллере ее писать? Как-то этот процесс должен быть автоматизирован...
 

rotoZOOM

ACM maniac
А как насчет механизма виджетов? Каждый сниппет - это виджет (контроллер/модель + вью). Список виджетов указан для каждой страницы.
Контроллер страницы считывает список, попутно вызывая инициализацию каждого виджета, а шаблон по списку забирает готовое вью (естественно, это общий функционал для контроллеров страниц).
У меня такой механизм в одном проекте был, в принципе достаточно удобно. Можно динамически раскидывать виджеты на разные страницы.
 

Фанат

oncle terrible
Команда форума
Где указан? В шаблоне или контроллере? вообще-то, это собственно вопрос, который был задан изначально.
а уж как его обозвать - подшаблоном или виджетом - дело десятое
 

rotoZOOM

ACM maniac
Наверняка реализаций может быть несколько, я расскажу только как было в моем проекте.

В БД для этих целей было 4 таблицы:
1. pages {id, url_mask} - описание страницы
2. widgets {id, alias, description, enabled, public} - описание виджета (типа класс)
3. widget_object {id, widget_id, content} - описание конкретного инстанса виджета (типа объект класса), content - это сериализованный массив с параметрами для виджета
4. widget_layout {id, page_id, layout_type, position, widget_object_id} - это, собственно, таблица связки между страницами и инстансами виджетов

widget_layout.layout_type - тип расположения виджета на странице - блок (сверху, снизу, слева, справа и т.д.)
widget_layout.position - позиция виджета относительно других в этом блоке.

Далее, контроллер каждой страницы вызывал контроллер виджетов, который по url формировал, загружал и инициализировал список виджетов (блоки готовой информации для вью).
А в каждом шаблоне прописывались места, куда помещать список виджетов, предназначенных для этого блока:
PHP:
...
<div id="top-widget-block">
    <?php WidgetController::instance()->outputBlockWidgets (WidgetController::LAYOUT_TOP) ?>
</div>
...
Поиск по урлу осуществлялся по самому близкому к текущему.
Например, если текущий урл: http://site.com/articles/kak_naduvat_sharik/, а таблица pages содержит следующие записи:
id | url_mask
---+-------------------------------------------
1 | /
2 | /about/
3 | /articles/
4 | /articles/comments/
....

То для нашего урла выберется страница с id=3.
Вот, как то так.
 

Фанат

oncle terrible
Команда форума

Absinthe

жожо
rotoZOOM да.
Иногда приходится, для тех же шаблонов: base(), escape(), filter()

Хотя я бы их в неймспейс запихал.
 

Фанат

oncle terrible
Команда форума
rotoZOOM
Вызов глобальной функции.
С одной стороны, я понимаю программистов, которые так пишут. И даже находят это естественным.
С другой - это же ужасно.

Ну ладно, я согласен на
PHP:
<?php widget::output(1) ?>
Но писать три раза слово виджет при вызове виджета - моё естество бунтует.
 

alekciy

Новичок
rotoZOOM
Дефолтные используются? Т.е. вызываемые для любой страницы?

Как делается выборка в url_mask? Через LIKE?
 

rotoZOOM

ACM maniac
Дефолтные используются?
Виджеты? нет.
Как делается выборка в url_mask? Через LIKE?
Нет, вычитывается все, а потом подбирается PHP'ом (у меня всего разных типов страниц штук 5).

Фанат на вкус и цвет ... Первое слово Widget - в названии класса, второе в названии функции, вот тут я согласен можно его опустить, так как и так это виджетконтроллер, а третий раз - это константа этого же класса. :)
 

Absinthe

жожо
а третий раз - это константа этого же класса
Кстати Widget::LAYOUT_TOP в любом случае лучше, чем просто строка 'top': запоминать не надо, IDE подскажет. Т.е. я отрицательно отношусь к магическим константам.
Правда в java это красивее сделано: enum.
 
Сверху