Шаблоны и хелперы

crocodile2u

http://vbolshov.org.ru
Гравицапа:
CakePHP не использую - но предполагаю, что хелперы там, возможно, - то же самое, что я имею в виду (сорри, пока не успел сходить по ссылкам).

fisher
"NativePHP-шаблоны с поддержкой хелперов" - тут все очень просто и я уверен, что чем-то подобным ты пользуешься и сам.

Поясню на примере.
Проблема: нужно отображать новости на разных страницах ресурса (шаблон отображения отдельной новости везде одинаков).
Решение 1: в тех шаблонах, где нужно отображать новости, добавить куски, отвечающие за вывод новостей. Быстро, никаких инклюдов, но плохо поддерживается (дублирование).
Решение 2: создать отдельный шаблон новости и инклюдить его везде, где нужно. Хорошо поддерживается, но потенциально тормозит (инклюды - и скорее всего, в цикле)
Решение 3: создать хелпер. Самый простой вариант - функция, допустим, display_news_piece($newsRow). Тогда инклюд нужен только для того, чтобы заинклюдит функцию, и мы сможем ее использовать там, где пожелаем. Я предпочитаю, однако, хелперы в виде небольших классов-хелперов с небольшим кол-вом методов, при этом сами методы доступны во Вью как методы этого самого Вью - надо только предвартельно зарегистрировать в нем нужный класс(объект) хелпера.

Надеюсь, я понятно изъяснил суть подхода. Если что, пишите - я приведу пример, и, возможно, это будет более понятно.
 

Develar

Новичок
>> Решение 3: создать хелпер
Наследуете от Blitz. Используете __call для перенаправления вызова вашему хелперу.

-~{}~ 28.05.07 18:29:

Мне кажется, проще не усложнять себе процесс разработки, а написать утилиту, которая будет паковать ваши шаблоны/контроллеры.

Вы эту тему читали - http://phpclub.ru/talk/showthread.php?s=&threadid=98055&highlight=blitz
 

fisher

накатила суть
Автор оригинала: crocodile2u
Решение 3: создать хелпер. Самый простой вариант - функция, допустим, display_news_piece($newsRow). Тогда инклюд нужен только для того, чтобы заинклюдит функцию, и мы сможем ее использовать там, где пожелаем. Я предпочитаю, однако, хелперы в виде небольших классов-хелперов с небольшим кол-вом методов, при этом сами методы доступны во Вью как методы этого самого Вью - надо только предвартельно зарегистрировать в нем нужный класс(объект) хелпера.
Надеюсь, я понятно изъяснил суть подхода. Если что, пишите - я приведу пример, и, возможно, это будет более понятно.
да, я понял. это я имел ввиду когда говорил не через жопу. только инклюд по-нормаьлному отдельяет HTML. правильно я понимаю, что в функции-хелпере пусть и лежит всё отдельно но весь HTML перемешан с пхп-кодом?
 

crocodile2u

http://vbolshov.org.ru
fisher
Да, именно так. Но я использую ПХП-шаблоны везде, и для меня хелпер - лишь очередной шаблон, просто оформленный в виде класса.

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

Develar

Новичок
Если у вас в хелпере "весь HTML перемешан с пхп-кодом" то вы можете хелпер делать наследником Blitz, код шаблона загружать используя load (то есть контроллер и шаблон в одном файле - как вы, насколько я понял, представляете себе хелпер). Потом зарегистрировать этот хелпер в еще одном наследнике Blitz, который и будет заниматься парсингом шаблонов и перенаправлять вызов хелперу. При этом надо сделать хелпер одиночкой - http://phpclub.ru/talk/showthread.php?postid=707353#post707353

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

crocodile2u

http://vbolshov.org.ru
блин... я лучше приведу пример того, как я бы использовал хелпер в вышеупомянутом примере с новостями...

PHP:
<?php

/** File: NewsViewHelper.php */
class NewsViewHelper {
     function displayNewsPiece($row)
     {
         ?><h3><?=$row['subject']?></h3> ... <?php
    }
}

/** File: controller.php */
...
$view->registerHelper(new NewsViewHelper());

/** File: template.php */
...
foreach ($this->newsList as $row)
    $this->displayNewsPiece($row);
...

?>
 

Гравицапа

elbirret elcno
crocodile2u
Не думал та тему того, что бы в хелперах код выводить/возвращать в зависимости от настроек? Просто, судя по твоему коду, он у тебя "железно" выводится...
 

crocodile2u

http://vbolshov.org.ru
Гравицапа
Когда мне понадобится возвращать - я с этим справлюсь ;)
И кстати, давай не уходить в офтоп. Тема посящена шаблонизатору Блиц, все-таки..
 

Фанат

oncle terrible
Команда форума
Я вот, решил поучаствовать тоже в дискуссии. И чтобы не уходить от темы про blitz разделил топики

crocodile2u
поглядел я твой пример. всем он хорош. Но отчего-то кажется мне, что вместо
?><h3><?=$row['subject']?></h3> ... <?php
там должно стоять
include "tpl_news_piece.php";
ну ооочень сильно кажется.
в противном случае я просто не понимаю, какое отношение этот винегрет имеет к шаблонам.
 

crocodile2u

http://vbolshov.org.ru
Фанат
Фанат.. если я поставлю там include "tpl_news_piece.php"; - то это будет точнехонько решение №2! Читай внимательно мой первый пост в этом - отделенном - треде! Именно ХТМЛ-код в хелпере - в этом весь смысл решения!

ЗЫ: кстати, почему эта ветка оказалась в форуме "PHPWorld - новости из мира PHP" ?
 

Фанат

oncle terrible
Команда форума
это решение делает бессмысленной саму идею шаблонов.

ну давай проверим идею на двух задачах.
1. два вида отображения.
2. обновление версии скрипта на разных сайтах.

Вотутебя есть страница для печати.
и чо - в своем хелпере ты должен иметь два шаблона?
хня какая-то.

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

crocodile2u

http://vbolshov.org.ru
Здесь лично я всегда помню о том, что "для меня хелпер - лишь очередной шаблон, просто оформленный в виде класса".

И я хочу подчеркнуть здесь "для меня". Мне удобно использовать хелперы именно так. И считать их шаблонами - мне тоже удобно.

Насчет твоих задач.
1. два вида отображения.
У меня есть два решения:
а) два метода в хелпере - displayNewsPiece() и displayNewsPiecePrint().
б) два разных хелпера - и регистрировать тот или иной в зависимости от режима отображения.

2. обновление версии скрипта на разных сайтах.
ээ.. можно подробнее? я не совсем понимаю суть задачи...
 

master_x

Pitavale XXI wieku
Фанат
шаблоны и хелперы не есть одно и то же.
Если понадобится еще один вид отображения можно легко написать еще один класс хелперов.
 

Фанат

oncle terrible
Команда форума
crocodile2u
Ну, я долго думал, как можно дать определение шаблонам без туфтового мямленья про разделение кода и представления.
и пришел к двум практическим задачам, на которых необходимость шаблонов становится четкой и ясной.

допустим, ты написал скрипт.
который поставил на два сайта.
вот, на первом сайте ты решил добавить новую фичу. прогрессивный способ определения IP адреса. и хочешь её добавить на второй сайт.
берешь, и переносишь тот самый "код".
заработает ли он сразу, без каких-либо правок вывода?
 

crocodile2u

http://vbolshov.org.ru
Фанат
хм. не знаю, как в твоей архитектуре - а в моей заработает. ну, то есть, если там вообще был какой-то кусок шаблона, отвечающий за вывод ИП-адреса. Фича, о которой ты говоришь, в моей схеме попала бы в контроллер, а уже из него - в представление. И представлению абсолютно пофиг, каким способом этот ИП определился..
 

dron4ik

Новичок
Решение 2: создать отдельный шаблон новости и инклюдить его везде, где нужно. Хорошо поддерживается, но потенциально тормозит (инклюды - и скорее всего, в цикле)

Да, инклюды тормозят, но т.к. дизайн редко правится, возможно вам подойдёт вариант с компиляцией, например:

основной шаблон index.tpl (так выглядит в базе)
[head]
[yourNews]
[footer]

шаблон index.tpl (так выглядит в файле) - всё вместе - без инклюдов!
<title>Тест</title>
Новость
Конец!

при изменении одного из СОСТОВЛЯЮЩИХ, ОСНОВНЫЕ перегенеряются автоматом
 

Develar

Новичок
>> И представлению абсолютно пофиг, каким способом этот ИП определился
Таким образом, здесь просто путаница в терминологии. Не "очередной шаблон, просто оформленный в виде класса", а именно "представление" - то есть совокупность шаблона (html, blitz) и php - "очередное представление, просто оформленное в виде класса".

Так как это лишь представление, проблема "обновление версии скрипта на разных сайтах" хелпера не касается, ему передали ip или $this->newsList - то есть массив данных - как именно они были получены его не волнует - ему надо только вывести.

Но вот насчет "два вида отображения". Ограничение связи 1-1. На один шаблон один контроллер - если это native php (<h3><?=$row['subject']?></h3>) - проблема не решается - так как это смесь кода и разделить в независимые куски html и php невозможно. Вариант a и b - это все дублирование кода, так как в большинстве случаев либо код контроллера, либо код шаблон повторяется по поведению. Нам ведь не нужно полностью переиначить все - у нас те же данные, и тот же макет страницы. Если это Blitz, то он позволяет разделить представление не только логически на шаблон и контроллер, но и физически, то есть код контроллера у вас дублироваться не будет - ему просто можно подсунуть другой экземпляр Blitz, которым он и будет управлять, - но смысл в этом есть, конечно же, только в случае, если в коде контроллера у вас есть сontrol structures, а не одно echo.
 

WP

^_^
Хыхы. Имхо (а я сьел много собак), хелперы в "классовой" реализации это онанизм без фото. Всё равно что использовать ООП 5 и писать везде кучу global :) Есть два варианта. Либо хелпером обозвать функцию которая может вызываться из шаблона и сама вызывает шаблон для представления своей работы. Среди минусов проигрыш в производительности засчет лишнего вызова display(), а также, как мне кажется, нарушение идеологии. Из шаблонов Imho можно вызывать функции-генераторы html только в тех случаях когда они выводят блоки, которые никак не связаны с остальным шаблоном который их вызывает, т.е. например {module_load name='guestbook'} - это можно. А остальное это компоненты - другая песня.
Я решил что в данном случае имеет смысл хелпером сделать быстровызываемый подшаблон который если надо получает данные из компонентов или assign'еных переменных.
Код:
{helper myhelper ($a,$b)}
{$a}*{$b} = {$a*$b}
{/}
{myhelper(10,15)}<br />
{myhelper b=15 a=10}
{*
10*15 = 150
10*15 = 150
*}
//Со следующего билда в Quicky это будет работать.

-~{}~ 30.05.07 07:10:

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

Фанат

oncle terrible
Команда форума
Кстати, соглашусь, пожалуй, с WP
В смысле поддержки это должен быть геморрой жуткий.

Вообще, решения, ориентированные на
"для меня". Мне удобно
вообще не имеет смысла рассматривать в общественном контексте.
 

crocodile2u

http://vbolshov.org.ru
Фанат
Я говорил про "общественный контекст"? Или "в общественном контексте"? Я рассказал о том, как мне удобно работать, вот и все. Заметьте, я не набрасываюсь а-ля WP с угрозами покусать - на тех, кто думает не так, как я. Я предпочитаю свободу мнений. Чем больше будет альтернатив - тем лучше.
 
Сверху