Методы и совершенстование шаблонизации

fixxxer

К.О.
Партнер клуба
Ну, твиг не чемпион по скорости (хотя для замены самого тормозного из частоиспользуемых методов есть сишный вариант, с ним заметно шустрее) - хотя и не медленный.
Зато написан хорошо и легко расширяется.
Регулярками, конечно, производительности не получишь: все современные движки компилирующие - т.е. генерируют php-код с теми самыми <?=$var?> и инклюдами. Кстати, между инклюдом и евалом разница очень большая, если установлен опкод-кэшер (а он на нормальном продакшене установлен всегда).
 

С.

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

Quieteroks

Новичок
fixxxer
Я использую два разных метода подстановки переменных и ради подстановки в шаблон двух трех переменных, не хочется большой шаблонизатор.
В любом случае php цикл или if отработают быстрее чем шаблонный.

С.
А чего вы такой грубый то?
Вы каждый раз пишите заново расчет факториала или функцию для его расчета написали?
Я вроде не говорил что хочу мега крутой шаблонизатор написать и всех заставить его использовать.
Хочу написать ту самую функцию, которая заменит мне постоянное сравнение двух переменных и напишу!
Вы шаблонизаторы переварили и теперь только include и <?=$content;?> используете что ли?
 

fixxxer

К.О.
Партнер клуба
В любом случае php цикл или if отработают быстрее чем шаблонный.
одинаково

твиг, смарти итд скопилируют все в точно такой же if / foreach.

хочешь совсем маленький - вот тебе мой написанный на коленке блицеэмулятор
http://symbi.org/files/BlitzEmu/
меняешь евал на инклюд, прикручиваешь кэш шаблонов - вуаля
 

Фанат

oncle terrible
Команда форума
ФанатЯ понял Вас
Что я хочу.
Один единственный шаблон. menu.tpl
Содержимое
PHP:
<ul class="menu">
    <!-- row start -->
    <li><a href="{link}" title="{title}">{title}</a></li>
    <!-- row end -->
</ul>
Ничего ты не понял, даже близко.
Вот твой шаблон:
PHP:
<ul class="menu">
<? foreach ($news as $row): ?>
  <li>
    <a href="<?=$row['link']?>" title="<?=$row['title']?>"><?=$row['title']?></a>
  </li>
<? endforeach ?>
</ul>
инклюдишь этот файл в главный шаблон сайта.
Всё. Никакого <?=$content?>

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

Я кстати тут же вопрос давно поднимал, что в момент внедрения в шаблон добавляется неизвестный символ...
НЕ ПОВЕРЮ, что тебе тогда же про BOM не ответили.
Вообще, боязнь инклюдов - это настолько смешно, что аргументом против PHP шаблонизатора быть не может. Такие аргументы есть, несомненно. Но "неизвестные символы в момент внедрения" к ним точно не относятся.

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

С.

Продвинутый новичок
Хочу написать ту самую функцию, которая заменит мне постоянное сравнение двух переменных и напишу!
Ну так ради бога. Функцию написать можно. Шаблонизатор-то писать для этого зачем?

Если говорить про <select>, вот тебе простейшая реализация с функцией, дешево и сердито:
PHP:
<select name="MyOption"><?=Options($myOptions,$myCurrent)?></select>
Где практически на все случаи жизни:
PHP:
function Options($array,$current=null)
{
  $options= '';
  foreach ($array as $value=>$label)
  {
    $selected= ($value==$current ? 'selected' : ''); 
    $options.= '<option value="'.$value.'" '.$selected.'>';
    $options.= $label;
    $options.= '</option>';
  {  
  return $options;
}
 

Absinthe

жожо
сам PHP разрабатывался как язык шаблонов, и закручивать эту идею в новый шаблонизатор, напоминает мне замечательную штучку, smarty
PHP хреновый шаблонизатор по современным меркам.
Именно поэтому появились всякие Smarty и Twig'и.

на самом деле боьлше дело вкуса.
Не согласен.
Вот в соседней теме на незадание attr_accessible в рельсах какашками кидались, на *_escape_string перед запросом - кидались. PHP-шаблонизатор в ту же кучу.
 

Quieteroks

Новичок
Фанат
Вот не поверите, ответили, но суть была не в этом. Я уже до этого про BOM знал и все файлы были без него. Стоило убрать этот момент с внедрением php в шаблон, добавить замену и легкий парсинг для поиска, все проблемы решены.
Реальный пример, который для меня облегчил жизнь. Имею две простые функции: getTpl() и parseTpl(). Первая загружает через file_get-contents шаблон из папки с шаблоном с проверкой на его существование, вторая соответственно берет массив, этот шаблон и совмещает.
В итоге вместо конкатенации и прочих сокращений с вставкой переменных напрямую я пишу просто:

$content = parseTpl(getTpl('index'), array(
'link' => 'main',
'title' => 'Link',
));

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

Я уже много вариантов просмотрел и Ваш был первым, но он мне не подошел.
Я его понял, знаю про все эти шаблонные сокращения для php.

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

Фанат

oncle terrible
Команда форума
В итоге вместо конкатенации и прочих сокращений с вставкой переменных напрямую я пишу просто:
По-моему, ты издеваешься.
Или разговариваешь сам с собой, со своими собственными фантазиями, вообще не понимая, что тебе пишут.
Ты какие-то собственные дикие представления о РНР шаблонах принимаешь за реальность. При этом у себя в глазу бревна не видишь.

Я тебя прошу привести пример реального шаблона страницы, целой страницы - ты мне суёшь свой убогий недошаблон из одной строчки, которых надо будет насовать в реальную страницу штук сто.
Это тебе надо результат рендеринга твоих недошаблонов собирать конкатенацией. Но ты зачем-то упорно рассказываешь про конкатенацию в РНР шаблонах, которой на самом деле там НЕТ. Ты вообще понимаешь значение этого слова?
В твоём случае твои две супер-гениальные функции надо вызывать на каждый недошаблон, а в случае PHP шаблона надо только подготовить данные и вызывать инклюд ровно один раз.
Ты единственный, у кого инклюд добавляет какие-то символы. Сотни тысяч людей пользуются инклюдами, и у них ничего не добавляется. Но при этом собственную криворукость ты записываешь в принципиальные недостатки метода.

Вот тебе пример РНР шаблона. Не самый лучший, но наглядный:
PHP:
<table border="0" cellpadding="2" cellspacing="0" width="600">
<?	foreach ($data as $row): ?> 
  <tr bgcolor="#666699">
    <td align=left><font color="white"><b><?=$row['name']?></b></font></td>
    <td align=right><font color="white"><?=$row['date']?></font></td>
  </tr>
  <tr bgcolor="f0f0f0">
    <td colspan=2><?=$row['body'] ?></td>
  </tr>
<?		if ($row['answer']): ?>
  <tr bgcolor="d3d3d3">
    <td colspan=2 valign="top">
      <table border="0" cellpadding="0" cellspacing="5">
        <tr>
          <td valign="top"><b>Ответ: </b></td>
          <td><?=$row['answer']?></td>
        </tr>
      </table>
    </td>
  </tr>
<?		endif ?>
<?		if($admin): ?>
  <tr>
    <td colspan=2>
      <font size=-1>
<? 			if($row['del']): ?>
      <a href="/gb/?action=undelete&id=<?=$row['id']?>">показать</a>
<? 			else: ?>
      <a href="/gb/?action=delete&id=<?=$row['id']?>">скрыть</a>
<? 			endif ?>
      <a href="/gb/?action=edit&id=<?=$row['id']?>">редактировать</a>
      <a href=/gb/ban.php>бан</a>
      </font>
    </td>
  </tr>
<? 		endif ?>
<?	endforeach ?>
</table>
рендерится он одним инклюдом.
PHP:
include $tpl;
Покажи мне, как такая же страница будет собираться твоими двумя облегчительными функциями.
 

Quieteroks

Новичок
Василий М.
Да жу. Две противоречивые статьи. Каждый все равно для себя решает каким путем идти.
Мне НЕ НУЖЕН скрипт для рисования форм. Я хочу обрабатывать уже нарисованную форму. Если я правильно понял ваш класс.

Фанат
Не спорю, что у многих инклюд не добавляет лишний символ. И его используют отлично.
Данный пример отработает отлично. Если это самостоятельная страница, но это ведь часть страницы. Ее нужно либо записать в буфере в переменную и внедрять вторым инклюдом в основной шаблон. И Ваш один вызов превращается уже не в простой вызов, а использование постоянного ob_get_content (не помню точного написания функции). Или основной шаблон тоже делим на шапку и футер? И уже три инклюда.

Сейчас у меня есть именно несколько недошаблонных функций. Да. Начинаю их изменять для достаточного функционала и облегчения себе жизни. Подчеркну СЕБЕ.
В моем случае Ваш шаблон будет поделен на два. Один для Админа, второй для Пользователя. Согласен недостаток... А может и нет.
Ты вообще понимаешь значение этого слова?
Понимаю, как не странно. У меня часто она встречалась, когда я использовал ваш метод. Вы сейчас привели пример без нее. Но все же я делаю всегда много конкатенаций и прочих ненужных, возможно, вещей.
Свое бревно я вытащил. МНЕ удобнее с моим шаблонизатором. Хочу его переписать и расширить.

Хватит спорить как лучше. Вопрос в другом.
Варианты предложите или их всего три?
1. Вставка php в шаблон. (самый лучший, но не мой вариант).
2. Регулярки.
3. Функции str_replace семейства.

Еще раз повторю вопрос:
Какие есть методы шаблонизации. Кроме регулярок, strtr и php кода в шаблоне (личная несовместимость).
 

Фанат

oncle terrible
Команда форума
В моем случае Ваш шаблон будет поделен на два.
Враньё.
Шаблонов будет гораздо больше.

Я тебя попросил привести код, который отрендерит такой же HTML твоим способом.
Приведи, пожалуйста.

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

Я не то чтобы хочу тебя заставить пользоваться РНР шаблонами. Я хочу, во-первых, чтобы ты хотя бы понял, что это такое (прежде чем хаять и отказываться), а во-вторых - внятно сформулировал свои желания, причём основываясь не на фантазиях и неверных представлениях, а реальности.

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

Фанат

oncle terrible
Команда форума
Пойми, никто не "спорит как лучше".
Тебе просто показывают, что перед тем, как спорить, надо сначала понять - о чём ты споришь.

Вообще, в твоих исканиях ничего плохого нет.
Плохо то, что ты
а) слабо понимаешь, чего хочешь получить в итоге. Не в деталях, а в целом. Ты так и мыслишь в масштабах своего микрошаблона, не ориентируясь на шаблон страницы в целом.
б) вообще не понимаешь технологии, о которых тебе говорят. Зацикливаешься на своих str_replace (зачем-то вынося их в отдельный пункт, хотя пстроить шаблонизатор на одном str_replace невозможно)
 

Quieteroks

Новичок
Absinthe
Написал же, что будет ДВА шаблона. Для Админа и для Пользователя.
Мало? Нужен дублирующий код?
Обертка:
PHP:
<table border="0" cellpadding="2" cellspacing="0" width="600">
   {row}
</table>
Строка таблицы:
PHP:
  <tr bgcolor="#666699">
    <td align=left><font color="white"><b>{name}</b></font></td>
    <td align=right><font color="white">{date}</font></td>
  </tr>
  <tr bgcolor="f0f0f0">
    <td colspan=2>{body}</td>
  </tr>
{answer}
{admin}
Ответ:
PHP:
  <tr bgcolor="d3d3d3">
    <td colspan=2 valign="top">
      <table border="0" cellpadding="0" cellspacing="5">
        <tr>
          <td valign="top"><b>Ответ: </b></td>
          <td>{answer}</td>
        </tr>
      </table>
    </td>
  </tr>
Админ:
PHP:
  <tr>
    <td colspan=2>
      <font size=-1>
      <a href="/gb/?action={action}&id={id}">{title}</a>
      <a href="/gb/?action=edit&id={id}">редактировать</a>
      <a href=/gb/ban.php>бан</a>
      </font>
    </td>
  </tr>
Сейчас я от этого ухожу, ибо неудобно и много файлов.
И начал делить его, чуть больше шаблонов будет чем два, если такую структуру брать. Хотя файл с ответом по идее можно модернизировать и выводить не шаблон с оформленным ответом, а писать что нет ответа допустим.
Строка таблицы с ответом:
PHP:
  <tr bgcolor="#666699">
    <td align=left><font color="white"><b>{name}</b></font></td>
    <td align=right><font color="white">{date}</font></td>
  </tr>
  <tr bgcolor="f0f0f0">
    <td colspan=2>{body}</td>
  </tr>
  <tr bgcolor="d3d3d3">
    <td colspan=2 valign="top">
      <table border="0" cellpadding="0" cellspacing="5">
        <tr>
          <td valign="top"><b>Ответ: </b></td>
          <td>{answer}</td> <!-- Где answer содержит ответ или сообщение о том что он еще не получен -->
        </tr>
      </table>
    </td>
  </tr>
{admin}
Сейчас обработчик допишу...
 

Фанат

oncle terrible
Команда форума
Да, и отвечу на твой вопрос.
Данный пример отработает отлично. Если это самостоятельная страница, но это ведь часть страницы. Ее нужно либо записать в буфере в переменную и внедрять вторым инклюдом в основной шаблон. И Ваш один вызов превращается уже не в простой вызов, а использование постоянного ob_get_content (не помню точного написания функции). Или основной шаблон тоже делим на шапку и футер? И уже три инклюда.
Основной шаблон мы ни на что не делим.
Он представляет собой один файл. Один файл удобно редактировать. поэтому файл у нас один.
Этот файл инклюдится после того, как были получены все необходимые для рендеринга данные.

В том месте основного шаблона, где вставляется изменяемый шаблон конкретной страницы, стоит код, который я привёл выше, include $tpl. Всё.
Что в этой схеме сложного или неудобного?
 

Фанат

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

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

Фанат

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

Фанат

oncle terrible
Команда форума
Еще раз повторю вопрос:
Какие есть методы шаблонизации. Кроме регулярок, strtr и php кода в шаблоне (личная несовместимость).
Ещё один показатель того, что ты не понимаешь, о чем пишешь.
Варианта всего два.
Либо шаблон парсит РНР, либо ты сам. Детали парсинга во втором случае несущественны. Там будут и регулярки, и конкатенации, и замены и куча всего. но это всё незначительные детали, и выносить их в ранг отдельного "способа" - слишком жирно.

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

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

Quieteroks

Новичок
PHP:
$res = sql("SELECT `name`, `date`...");
if($res->num_rows) {
   $tpl['row'] = '';
   $tplrow = getTpl('строка с ответом');
   if($admin) {
      $tpladmin = getTpl('админ');
   }
   while($temp = htmlChars($res->fetch_assoc())) {
       if($admin) {
         $temp['admin'] = parseTpl($tpladmin, array(
            'action' => ($temp['deleted'])?'undelete':'delete',
            'title' => ($temp['deleted'])?'Показать':'Скрыть',
            'id' => $temp['id'],
         ));
      } else {
         $temp['admin'] = '';
      }
      $tpl['row'] .= parseTpl($tplrow, array(
         'name' => $temp['name'],
         'date' => date('d.m.Y', strtotime($temp['name'])),
         'answer' => (!empty($temp['name']))?$temp['name']:'Ответов нет',
         ...
         'admin' => $temp['admin'],
      ));
   }
   $tpl['row'] = parseTpl(getTpl('обертка'), array('row'=>$tpl['row']));
} else {
   $tpl['row'] = 'Нет данных';
}
echo $tpl['row'];
Примерно так. Не все дописал, но смысл понятен. Да, я использую конкатенацию для сбора строк, Вы нет в смоем примере.
Вы вот не поняли чего я спрашиваю и наезжаете. Такая реализация сойдет? Ответил на ваш вопрос?
Да, где то не эффективно. Иду к повышению этой самой эффективности, но своим методом с использованием своего шаблонизатора.

Я хочу, во-первых, чтобы ты хотя бы понял, что это такое (прежде чем хаять и отказываться)
Не подходит мне вариант с php шаблонизацией. Да, она удобнее и не требует лишних затрат. Я не хаю его, если Вы не заметили. Просто у меня с ним возникли проблемы, которые я решил шаблонизацией.
во-вторых - внятно сформулировал свои желания, причём основываясь не на фантазиях и неверных представлениях, а реальности.
Вы считаете что нереально в php найти форму и в ней пройти по атрибутам input'ов? Сравнивая и дописывая другой атрибут?
зачем тебе вообще нужны шаблоны
Это глубоко философский вопрос? Как зачем? Такой ответ нужен, чтоб меня считать дебилом:
"Это же мега круто, все так делают, отделяя логику от шаблона."
Мне это нужно для разделения, которая предоставит возможности перерисовать шаблон в любой момент.

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

Фантазия - отправная точка к реализации.
Да, на одной фантазии далеко не уедешь, свои фантазии я подкрепляю идеями как это можно реализовать.
Сюда все писать? Фантазию и как реализовать? Мне суток не хватит для набора текста...

Сейчас мне не хватает знаний, которые хочу пополнить. Писать регулярки с колбек функциями или есть другие варианты, как DomDocument и тот же библиотеки phpquery.
Поделитесь информацией. Вы же знаете больше меня. Я поставил рамки, без php шапблонизации в шаблоне.
В шаблоне не буду реализовывать ветвления и циклы. Буду искать теги или метки для вставки и анализировать их.
 

Quieteroks

Новичок
Что в этой схеме сложного или неудобного?
Да что ж такого... Сколько еще раз повторить.
Я ОТ ЭТОГО ВАРИАНТА УШЕЛ.
Я им пользовался ранее. Он удобный, мощный, все круто.
Возможно в какой то момент меня сбили какие то статьи. Но это решило мою проблему.

для тебя опять шаблон - это одна строчка таблицы. А то, что потом из этих строчек потом придется колупаться и собирать страницу парой страниц пхп кода - ты почему-то вообще не учитываешь.
А, вот в чем вопрос был. Да. Для меня шаблон это все что я вывел в html файлы. Каюсь. Но это же лучше чем писать шаблон в коде контролера. :)

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

Redjik
К чему эта строчка? Вы мне идею для метода класса шаблонизатора даете?
 
Сверху