Шаблоны: правила игры

Фанат

oncle terrible
Команда форума
Так как страница собирается за 1 этап, мы не можем влиять на очередность запуска модулей. В этом главная проблем.
К примеру не совсем очевидно, как подключать только нужные ресурсы (css\js) . Нужные в данном случае это те, чьи модули отработали или отработают и требуют подключения css/js .
Вот! Об этом я и говорил чуть выше
Всегда приятно поговорить с человеком, который на практике юзал свой метод, а не в теории! :)

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

С другой стороны, я пока только обдумываю идею, и проверки практикой у меня самого-то и нету.
 

NeD

Новичок
Вот! Об этом я и говорил чуть выше
Всегда приятно поговорить с человеком, который на практике юзал свой метод, а не в теории! :)

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

С другой стороны, я пока только обдумываю идею, и проверки практикой у меня самого-то и нету.
Как вариант можно рендерить страницу в 2 этапа. Первый этап будет вместо action('users/login') вставлять метку с именем или с id вызываемого модуля, к примеру: '{{users/login}}' . Дальше запускаем модули в том порядке в каком нам надо. Ну а после заменяем метку на результат работы модуля и показываем страничку юзеру.
Но здесь опять не совсем ясно как управлять порядком. Это я опять же под углом своего велосипеда смотрю на проблему.
 

stopkran

Дилетант
Так как страница собирается за 1 этап, мы не можем влиять на очередность запуска модулей.
Да, страница собирается в один проход. Но вы ведь не хотите сказать, что все эти echo сразу идут клиенту? Там ведь наверняка какой-нибудь ob_start в начале. Можно в конце, когда все модули отработали и стали точно известны все css, получить ob_content и "хакнуть" (прописать/переписать <head>).

Хотя мне ближе идея "реальной" обёртки: не выводить сразу всё "как бы наружу", а копить страницу в переменной (ну, точнее, в массиве). А в конце дописать к ней head.
 

stopkran

Дилетант
Ещё одну идею подсказывает Хром (отладчик): объединяйте файлы статики! :) Объединить все 5 (15) css в один, и подключить один раз намертво ко всем шаблонам... Ну, для разработки, ясно море, они все должны отдельно храниться.
 

NeD

Новичок
Да, страница собирается в один проход. Но вы ведь не хотите сказать, что все эти echo сразу идут клиенту? Там ведь наверняка какой-нибудь ob_start в начале. Можно в конце, когда все модули отработали и стали точно известны все css, получить ob_content и "хакнуть" (прописать/переписать <head>).

Хотя мне ближе идея "реальной" обёртки: не выводить сразу всё "как бы наружу", а копить страницу в переменной (ну, точнее, в массиве). А в конце дописать к ней head.
Само собой весь вывод буферизируется. Насчёт хакнуть вариант вполне работоспособен, единственно надо будет модулю подключения css\js знать какие модули отработали. Для этого либо в коде модулей подключать ресурсы самому, либо делать метод для получения отработавших модулей в ядре движка.
Но я на данном этапе решил часть работы по подключению ресурсов перенести в ядро. В итоге управлять подключением js/css можно в конфиге модулей.
Быть может потом пересмотрю своё решение. Надо понять насколько удобен будет текущий вариант.
 

NeD

Новичок
Ещё одну идею подсказывает Хром (отладчик): объединяйте файлы статики! :) Объединить все 5 (15) css в один, и подключить один раз намертво ко всем шаблонам... Ну, для разработки, ясно море, они все должны отдельно храниться.
У меня так и работало сначала. Подключались все ресурсы "включенных" модулей, но это не сильно удобно оказалось на практике.
 

Фанат

oncle terrible
Команда форума
А в конце дописать к ней head.
Проблема в том, что подключением CSS она не ограничивается.
И она имеет гораздо более общее обозначение - данные из подключаемых модулей могут влиять на окончательный вывод.
И решать её тоже надо централизованно, а не отдельными CSS-костылями.

NeD
А всё-таки подумай над отдельным контроллером основного шаблона.
Во всяком случае, это кажется вполне логичным - ведь почему-то у каждого шаблона есть свой контроллер, который отвечает собирает для шаблона данные, а у Главного шаблона - нету. Несправедливость!
В итоге он берет на себя несвойственные шаблону функции по получению данных.
А уж порядок вызова модулей в контроллере задается тупо размещением вызовов одного под другим.
 

NeD

Новичок
Проблема в том, что подключением CSS она не ограничивается.
И она имеет гораздо более общее обозначение - данные из подключаемых модулей могут влиять на окончательный вывод.
И решать её тоже надо централизованно, а не отдельными CSS-костылями.

NeD
А всё-таки подумай над отдельным контроллером основного шаблона.
Во всяком случае, это кажется вполне логичным - ведь почему-то у каждого шаблона есть свой контроллер, который отвечает собирает для шаблона данные, а у Главного шаблона - нету. Несправедливость!
В итоге он берет на себя несвойственные шаблону функции по получению данных.
А уж порядок вызова модулей в контроллере задается тупо размещением вызовов одного под другим.
В моём случае на окончательный вывод, можно используя события. У меня таким образом реализован ACL, защита от CSRF, кеширование, админка и т.д.
(вдруг контроллер страницы переопределил сайдбар?)
Тут можно по-другому подойти к решению таких проблем, вроде переопределения сайдбара. Вообще понятия сайдбара в моей системе нет, но можно написать модуль sidebar, который и будет сам знать, что ему показывать на конкретной странице.
ИМХО, тут надо просто по-другому подходить к решению возникающих проблем.
 

ksnk

прохожий
это кажется вполне логичным - ведь почему-то у каждого шаблона есть свой контроллер, который отвечает собирает для шаблона данные, а у Главного шаблона - нету. Несправедливость!
Вообще-то не так.
Контроллер запрашивает модель, модель поддергивает дополнительные модели, если это надо.
На основании оставленных моделью данных контроллер может выбрать тот или иной шаблон. Если выбранный шаблон содержит "активную" составляющую, она может быть задействована, например, как
PHP:
{{ action ('module/method/param') }}
- вызов главного контроллера приложения. Того-же, который отрабатывает url-запросы, понятно с флагами "внутреннего вызова" и прочими заборчиками...
Данные для подшаблонов отдельно собирать не надо, они уже собраны моделью до вызова главного шаблона. А все активные - дособирают данные по мере надобности.

дополнить обычный твиг новыми функциями (action) достаточно несложно, это описано в документации...
 

ksnk

прохожий
Это я про то, что контроллер, вообще говоря - один единственный на все приложение.
 

AmdY

Пью пиво
Команда форума
caballero
никто никому ничего не должен, главное чтобы решение было эффективным.

NeD
проблему можно решить способом двойного прохода:
первый проходи собирает ищет action(....), вызывает у него метод preAction
затем когда рендерится основная часть у action(....) дёргается сам экшин
 

caballero

Новичок
AmdY
На самом деоле все просто.
все екшены должны отработать ДО рендеринга (включая изменение данных в модели (БД). А потом в результате вычисленного нового состояния (представь что это конечный автомат) контролер страницы (шаблона ) рендерит страницу и если надо подтягивает нужные данные с модели (БД).
 

AmdY

Пью пиво
Команда форума
caballero
вот именно, это не конечный автомат, тиак как может зависеть от модулей расположенных ниже по странице.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
я использую наследование в Смарти 3, оно хорошо решает проблему определения множества блоков - удобнее, чем редактировать кучи разных шаблонов.
наследование не исключает инклюды - они просто становятся редко нужны

наследование не решает проблему конфликта имен, но она решается в 4 строки.

2-шаговой шаблонизации 100 лет в обед, с задачей определения множества блоков за раз она справляется хуже, чем наследование

пре-рендеринг хелперов(экшенов, плагинов) из шаблона - задача нетривиальная, мне это кажется неоправданной сложностью
 

caballero

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

ksnk

прохожий
Давайте определим - "активный элемент" - элемент о данных которого НЕ МОЖЕТ догадаться контроллер до его (элемента) генерации. Статический - тот, о данных которого (способе их получения) контроллер знает (получает из модели). Соответственно и данных для его (активного элемента) генерации никто получить заранее не может. К примеру сайдбар, который выводит прогноз погоды, котировки, поздравления с днем рождения... в зависимости от состояния звезд. Вставляться этот сайдбар должен только в одном месте, в шаблоне, чтобы не размазывать его по нескольким файлам.
Это - условия задачи с активным шаблоном... Хочется дать возможность активному шаблону влиять на весь вывод.

Решением может быть кэширование результатов рендеринга(этапа view) контроллером. При вызове action, на этапе активного рендеринга(без кэша) устанавливается глобальный, с точки зрения контроллера, флаг. При обнаружении этого флага при генерации основного шаблона, контроллер перезапускает рендеринг еще раз, сбросив флаг. За счет кэширования повторной установки флагов не произойдет. Таким образом вызываются только нужные по логике шаблона ветки, лишние активные шаблоны не дергаются. При этом, если активные элементы не используются - никто ничего и не замечает.
 

caballero

Новичок
ksnk
че то мудрено
статические элементы просто часть верстки. Активные зависят от состояния страницы. В любом слкчае контродер вызываетсяф один раз для обработки входящего запроса то есть некоего екшена.
Кеширование тут вообше ни при чем, во всяком случае кешированием контроллер не должен заниматся вообще.
Это функцтя представления и/или модели
и кстати активный шаблон или пассивный сути дела не меняет. просто активных шаблон проще и естественнее для PHP который собственно активным шаблонизатором и является
 

ksnk

прохожий
статические элементы просто часть верстки. Активные зависят от состояния страницы
Что такое состояние страницы? Не определяется ли состояние страниц однозначно данными, которые подаются шаблону на вход? Если определяются - эти элементы статичны, если не определяются - активны. Иначе нет смысла разделять шаблоны по активности.
 

caballero

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

Шаблонизатор (контроллер страницы и т.д.) выполняет отрисовку в зависимости от этого состояния. Например текущий юзер залогинен значит нужно нарисовать верху страницы его ник и email а значит нужно в модели (БД) запросить его данные .
если мы рендерим страницу форума и пользователь может видеть посты - рендерим ему посты. .
если то магазин рендерим корзину товаров если они там есть и т.д.
Отсюда следует что логичнее не подавать данные на вход шаблона, а шаблон запросит те данные которые ему понадобятся\в том или ином месте страницы. Данные уже должны быть готовы и если нужно изменены в зависимости от запроса пользователя (положил товаар в корзину) - то есть всякие екшены должны быть выполнены ДО начаола рендеринга. Иными словами остаемся в классической и всем понятной схеме - пришел HTTP запрос , распарсиили, выполнили обработку данных, сформировали HTML и выдали браузеру.
Все остальное - от лукавого.
Иначе нет смысла разделять шаблоны по активности.
активный и пассивных шаблоны - это архитектурные решения не зависящие от прочей реализации.
 
Сверху