За последние 24 часа нас посетили 8780 программистов и 488 роботов. Сейчас ищут 297 программистов ...

шаблонизатор [нужен алгоритм]

Тема в разделе "Решения, алгоритмы", создана пользователем Koc, 16 май 2009.

  1. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.154
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Понакрутили, понавертели! Я вот юзаю простенький шаблонизатор и доволен.

    Всего 2 метода:
    PHP:
    1. <?php
    2. $TPL->block('pm/inbox_body.tpl', 'pm_inbox', $pm_inbox);
    3.  
    4. $TPL->parse('link.tpl', 1, array('href' => HTTP.DOMAIN.PATH.SCRIPT_FILENAME.'?m=users&a=profile&id='.$row['sender'].SID, 'value' => htmlspecialchars($row['user_login'])))
    5.  
    Всё =) Все циклы и прочая хрень делается на чистом пэхапэ.

    // приведённые методы - это лишь вершина айсберга, многое делается автоматом внутри класса, да и у этих методов несколько режимов работы =)
    // Весь шаблонизатор - 118 строк кода, масюсенький такой.
    // и не наезжать на меня!!! не хочу тут с вами спорить =)
     
  2. Mr.M.I.T.

    Mr.M.I.T. Активный пользователь

    С нами с:
    28 янв 2008
    Сообщения:
    4.584
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    это ты неудачно зашёл ;)
    без циклов фигово
     
  3. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.154
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Показываю цикл:
    PHP:
    1. <?php
    2. while($row = $DB->fetch_assoc($result))
    3.         {
    4.             $pm_inbox[] = array('create_date' => ***_date('j.n.Y G:i:s', $row['create_date']),
    5.                                 'sender' => (!$row['user_delete'])? $TPL->parse('link.tpl', 1, array('href' => HTTP.DOMAIN.PATH.SCRIPT_FILENAME.'?m=users&a=profile&id='.$row['sender'].SID, 'value' => htmlspecialchars($row['user_login']))) : $LANG['pm_sender_deleted'],
    6.                                 'read' => ($row['read'])? $TPL->parse('pm/img.tpl', 1, array('src' => HTTP.DOMAIN.PATH.'templates/'.TEMPLATE.'/pic/pm/old.png', 'alt' => $LANG['pm_inbox_old_message_alt'], 'title' => $LANG['pm_inbox_old_message_title'])) : $TPL->parse('pm/img.tpl', 1, array('src' => HTTP.DOMAIN.PATH.'templates/'.TEMPLATE.'/pic/pm/new.png', 'alt' => $LANG['pm_inbox_new_message_alt'], 'title' => $LANG['pm_inbox_new_message_title'])),
    7.                                 'subject' => htmlspecialchars($row['subject']),
    8.                                 'url_pm' => HTTP.DOMAIN.PATH.SCRIPT_FILENAME.'?m=pm&a=inbox_item&id='.$row['id'].SID,
    9.                                 'url_delete' => HTTP.DOMAIN.PATH.SCRIPT_FILENAME.'?m=pm&a=inbox_delete&id='.$row['id'].SID,
    10.                                 'lang_pm_action_delete' => $LANG['pm_action_delete']);
    11.         }
    12.  
    13.         $TPL->block('pm/inbox_body.tpl', 'pm_inbox', $pm_inbox);
    14.  
     
  4. Mr.M.I.T.

    Mr.M.I.T. Активный пользователь

    С нами с:
    28 янв 2008
    Сообщения:
    4.584
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    Hight
    яб на такое пошёл только ради хайлоада =)

    для нормал нет смысла
     
  5. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.154
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    Mr.M.I.T.
    Зато всё железно.
     
  6. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    5
    Адрес:
    Рига, Латвия
    Mr.M.I.T.
    А чё такого в таком подходе? У меня точно такой-же, только выглядет это не так страшно, ну и я ссылки делаю относительные :) + у меня нету доступа к шаблонам в циклах, за исключением 1-2 мест, где это просто необходимо.
    PHP:
    1.  
    2. <?php
    3. class Guestbook extends ModuleCore
    4. {
    5.  
    6.     /**
    7.      * Show guestbook to it's owner with moderation functional
    8.      *
    9.      * @return string
    10.      */
    11.     public function show()
    12.     {
    13.         $profiles = Core::getInstance('profiles', true);
    14.         /* @var $profiles Profiles */
    15.         $page = $this->utils->getPage($this->core->getArgs(2));
    16.         $usr_id = $this->session['auth']['id'];
    17.         $sql = 'SELECT gsb_usr_id_from, gsb_subject,
    18.                         gsb_id, gsb_msg, DATE_FORMAT(gsb_added, "'.DATE_FORMAT_SQL.'") AS added,
    19.                         DATEDIFF(CURDATE(), gsb_added) AS when_added
    20.                 FROM guestbook
    21.                 WHERE gsb_usr_id_to = '.$usr_id.
    22.                 ' ORDER BY gsb_id DESC'.$this->db->limit($page, $this->per_page);
    23.         $r = $this->db->query($sql);
    24.         if ($r && $r->num_rows) {
    25.             $ids = $rows = array();
    26.             while ($row = $r->fetch_assoc()) {
    27.                 $ids[] = $row['gsb_usr_id_from'];
    28.                 $rows[] = $row;
    29.             }
    30.             $profiles->preFetch($ids);
    31.  
    32.             foreach ($rows as &$v) {
    33.                 $v['gsb_id'] = $this->utils->encode($v['gsb_id']);
    34.                 $v['user'] = $profiles->getUser($v['gsb_usr_id_from']);
    35.                 list($v['added'], $v['when_added']) = $this->utils->getAdded($v['added'], $v['when_added']);
    36.                 $v['gsb_msg'] = nl2br($this->utils->wrap($this->utils->htmlsc($v['gsb_msg'])));
    37.                 $v['gsb_subject'] = $this->utils->wrap($this->utils->htmlsc($v['gsb_subject']));
    38.             }
    39.             unset($v);
    40.             $sql = 'SELECT COUNT(*) FROM guestbook WHERE gsb_usr_id_to = '.$usr_id;
    41.             list($total) = $this->db->query($sql)->fetch_row();
    42.             $this->parser->set('pager', $this->utils->pager($this->core->joinArgs(1), $total, $page, $this->per_page));
    43.             $this->parser->append('guestbook', $rows);
    44.         }
    45.         return ($this->box(_("My guestbook"), $this->template('list.htm')));
    46.     }
    47. }
    48. ?>
    PHP:
    1.  
    2. <form id="postform" method="post">
    3.     <?php if (is_set('guestbook')):?>
    4.         <table id="guestbook" class="tables thumbnails" cellspacing="0">
    5.             <?php foreach (get('guestbook') as $val):?>
    6.             <tr class="row">
    7.                 <td class="from"><?php echo $val['user']?></td>
    8.                 <td class="message">
    9.                     <span class="time-block"><span class="subject"><?php echo $val['gsb_subject']?></span> <?php echo $val['added']?></span>
    10.                     <div class="msg"><?php echo $val['gsb_msg']?></div>
    11.                 </td>
    12.             </tr>
    13.             <?php endforeach;?>
    14.         </table>
    15.     <?php else:?>
    16.         <div class="hint"><?php echo _("No messages")?></div>
    17.     <?php endif;?>
    18. </form>
    19.  
     
  7. kostyl

    kostyl Guest

    а может хранить уже в html, что бы не тратить кучу времени на преобразование?
     
  8. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    5
    Адрес:
    Рига, Латвия
    kostyl
    С динамическим контентом не пойдёт.
     
  9. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    короче я сдался. Не могу распарсить вложенные циклы.

    Смотрел код h2o (можно сказать, что идеал для меня. Те же теги, что и в питоновском Джанго). Так там все как-то разнесено по классам. Такое впечатление, что теги не зависят друг от друга. А у меня гавно какое-то получается.
     
  10. sorteros

    sorteros Активный пользователь

    С нами с:
    28 авг 2009
    Сообщения:
    54
    Симпатии:
    0
    Koc, дело конечно хозяйское, но считаю, что вложенные циклы - это уже перебор. Трудно представить ситуацию, где без них нельзя обойтись. Кроме того, при громоздких шаблонах и больших количествах циклов, такой шаблонизатор даст тебе просраться по полной, поверь.
     
  11. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    вложенные циклы могут использоваться в такой ситуации: прорисовка какой-то таблички, у которой динамическое количество столбцов. Цикл 1 рисует строки, цикл 2 - столбцы. Эта табличка может в админке использоваться например. Первое, что в голову пришло.

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

    Да и вообще: будет контроль вложенности
     
  12. sorteros

    sorteros Активный пользователь

    С нами с:
    28 авг 2009
    Сообщения:
    54
    Симпатии:
    0
    Так уж и один раз? Кеш может сбрасываться часто, ежеминутно. А делать поверх пхп ещё один интерпретируемый язык - это не слишком хорошо, на хайлоаде всё узнаете.
     
  13. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    а зачем мне каждую минуту сбрасывать кеш шаблонов? я их меняю может быть 1 раз в месяц.
     
  14. sorteros

    sorteros Активный пользователь

    С нами с:
    28 авг 2009
    Сообщения:
    54
    Симпатии:
    0
    1 месяц - вопросов нет. А столнётесь с ситуацией, когда придётся его чистить постоянно?
     
  15. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    но ведь можно сбрасывать не весь кеш а по тегу (ключу):

    добавился новый комментарий к описанию отеля (hotel_id=12)
    $this->cache->removeByPattern('tourust.hotels/comments/12');

    изменилась структура страниц
    $this->cache->removeByPattern('content.menu/:any');
     
  16. sorteros

    sorteros Активный пользователь

    С нами с:
    28 авг 2009
    Сообщения:
    54
    Симпатии:
    0
    Весь кеш конечно сбрасывать не обязательно, это вовсе самоубийство. Но надо выбирать меньшее из двух зол. В погоне за удобством и изящностью своих конструций, люди часто забывают об ограничениях языка. Можно много чего накрутить в шаблонизатор - вложенные циклы, рекурсия, всевозможные операторы и т.д. В общем, создать ещё одного монстра, который рано или поздно обязательно подведёт.
     
  17. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    другой пример того, когда нужны вложенные циклы. Отели, комментарии к отелю. В комментарии может быть список фотографий (пользователь загрузил фотки, когда писал коммент). 1 цикл - вывод комментариев. Условие - есть фотки к комменту или нет. Цикл 2 - вывод этих фоток внутри коммента.

    Я не буду сильно шаблонизатор нагружать функционалом. Подстановка переменных, циклы, ветвления, наследование, подгрузка шаблонов, комментарии
     
  18. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    5
    Адрес:
    Рига, Латвия
    Вложенные циклы это нормально, бывает что и они нужны.
    Но, ИМХО, городить очередной Smarty - оно того не стоит. Лучше придумать удобный и лёгкий API для Native шаблонов.
     
  19. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.449
    Симпатии:
    581
    Кто-как думает, стоит ли кешировать результат работы нейтив-шаблонов?
     
  20. kostyl

    kostyl Guest

    [vs]
    я кеширую... ибо иногда без этого никак, и пофиг какой шаблонизатор.
     
  21. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.449
    Симпатии:
    581
    Например?
     
  22. kostyl

    kostyl Guest

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

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    так это уже резалт парсинга страницы/ее части
     
  24. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.449
    Симпатии:
    581
    Аа ну тогда да.
    Хотя по-мойму проще транслировать бб-коды в хтмл при записи в БД, а расцветку задавать стилями.
     
  25. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    и, да, я форкаю twig. Еще правда не решил: это будет старый или новый twig.

    Вчера весь вечер переписывал OOTemplate, так а он без кеша оказался.