За последние 24 часа нас посетил 44251 программист и 3101 робот. Сейчас ищут 995 программистов ...

Простейший шаблонизатор с использованием самого пхп

Тема в разделе "Решения, алгоритмы", создана пользователем Gromo, 1 ноя 2010.

  1. Gromo

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

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    Предисловие:
    Сам я использую простой шаблонизатор, основанный на регулярках, который просто ищет плейсхолдеры в шаблоне и заменяет их на хтмл блоки. И пока задачи являлись лёгкими, структура - простейшей, а кода было не так много, всё было шикарно. Контент блоков формировался внутри пхп фукнций.

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

    Задача: как совместить простоту пхп, выделить шаблоны в отдельные файлы и чтобы не было необходимости разучивать новый синтаксис шаблонизатора?


    Возможное решение:

    index.php
    PHP:
    1. <?php
    2.  
    3. function templater($template_path, $vars){
    4.   extract($vars, EXTR_OVERWRITE);
    5.   ob_start();
    6.   include($template_path);
    7.   $content = ob_get_contents();
    8.   return $content;
    9. }
    10.  
    11. $vars = array();
    12. $vars['array'] = array('abc', 'cde', 'efg', 'hij');
    13. $content = templater('template.html', $vars);
    14.  
    15. ?>
    16. <html>
    17. <head>
    18. <title>Simple templater</title>
    19. </head>
    20. <body>
    21. <?php echo $content; ?>
    22. </body>
    23. </html>
    template.html
    HTML:
    1.  
    2. <?php foreach($array as $value){ ?>
    3.   <tr><td><?php echo $value; ?></td></tr>
    4. <?php } ?>
    5.  
    Конструктивные комментарии приветствуются.
     
  2. Padaboo

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

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    а как вот такой вариант?
    http://www.php.ru/forum/viewtopic.php?p=211516#211516
    сам пользуюсь таким типом
    PHP:
    1. <?php
    2. foreach ($this->vars as $var => $val){
    3.     $content = str_replace('{' . $var . '}', $val, $content);
    4.  
    5. }
    пожалел, думаю в следующий раз что нибудь потяжелее взять, либо, попробовать то что по ссылке выше
     
  3. Psih

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

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Базовое решение любого нативного шаблонизатора. Основа основ :)

    Только я бы посоветовал синтаксис в шаблоне юзать альтернативный:
    PHP:
    1.  
    2. <table>
    3. <?php foreach($array as $value):?>
    4.    <tr>
    5.       <td><?php echo $value;?></td>
    6.    </tr>
    7. <?php endforeach;?>
    8. </table>
    9.  
    Для любителей копнуть поглубже phpsavant.org
     
  4. Padaboo

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

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    Psih
    а если куча подшаблонов нужна? будет нагромаждение...
     
  5. Apple

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

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Мне Twig нра
     
  6. Padaboo

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

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    Apple
    вот его наверное и попробую в следующий раз
     
  7. Gromo

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

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    Padaboo
    просматривая тему, не добрался до 13 страницы :)
    мой велосипед по сути тот же самый, только кода меньше.

    это как?
     
  8. Gromo

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

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    Apple
    Почитал немного. Twig почти полная компия шаблонизатора, используемого в Django =/
     
  9. Padaboo

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

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
  10. Gromo

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

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    есть какие-либо условия или противопоказания использования ob_ функций?
    влияет ли это на вывод, использование памяти или время генерации?
     
  11. Padaboo

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

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    Gromo
    ускоряет работу скрипта
    память вроде как после того как скрипт отработает освобождается, мне кажется разницы нету в этом плане
    Apple надо спросить, он всегда такие вещи знает )
     
  12. Psih

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

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Padaboo
    А не делайте так, что бы куча подшаблонов была. Слишком мелкое деление тоже плохо и у вас будет дырка в производительности из-за слишком большого кол-ва I/O.
     
  13. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Psih
    Странный совет. Наоборот, надо структурировать свои шаблоны как можно детальнее (но не чрезмерно, конечно).
    Если в двух шаблонах повторяется одна и та же верстка - это основание для выноса повторяющегося фрагмента в отдельный шаблон. Как в программировании: копипаста=плохо.

    Ну а если вас от такой стратегии удерживают соображения типа "слишком много I/O" - значит ваш шаблонизатор плохой, возьмите нормальный. Который не требует большого количества "I/O" для работы.
     
  14. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
  15. Gromo

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

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    Vladson
    угу, осознал, что это велосипед по ссылке от Padaboo.

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

    просто я не нашёл среди тем форума данной реализации (а точнее не хватило терпения
    дойти до 13 страницы темы Шаблонизатора), но всё же я дошёл до этого решения сам.

    расту потихоньку :)

    не я первый, не я последний изобретатель велосипеда
     
  16. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    heredoc прекрасный шаблонизатор
     
  17. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
  18. Gromo

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

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    [vs]
    нее, там ещё тема идёт о [loop]-ах и прочих, а не о нативном пхп
     
  19. pohapecoder

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

    С нами с:
    16 окт 2010
    Сообщения:
    63
    Симпатии:
    0
    фуууу, это наследие perl - жесть из жести
     
  20. pohapecoder

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

    С нами с:
    16 окт 2010
    Сообщения:
    63
    Симпатии:
    0
    >function templater($template_path, $vars){

    был тоже подобный велосипед.
    но еще там добавлена была поддержка функций-снипетов - т.е. шаблонов реализованых не в виде файла, а в виде функции имя которой состоит из названия шаблона и префикса (например block1_snippet). примерно такая:

    Код (Text):
    1.  
    2. function block1_snippet($vars){ extract($vars, EXTR_OVERWRITE);?>
    3.  
    4.   <!-- template code -->
    5.  
    6. <?}
    тоесть проверяется название шаблона - если такая функция есть - вызывается она если нет то подключается файл.
    таким образом и структурирование будет и накладные расходы на подключение файлов значительно снизятся.
    получается некий аналог подключаемых хелперов для вьювсов.
     
  21. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    PHP:
    1. <?
    2. include('topmenu.php');
    3. $topmenu = ob_get_contents();
    4.  
    5. include('headmenu.php');
    6. $headmenu = ob_get_contents();
    7.  
    8. ////// requested page have to be the last one!
    9. include($file);
    10. $main .= ob_get_contents();
    11.  
    12.  
    PHP:
    1. <?
    2.  
    3. //RENDER PAGE!
    4. echo <<<HEREDOC
    5. $hat
    6. <head>
    7.   <title>$title</title>
    8. $head
    9. </head>
    10. <body>
    11.   <div class="main">
    12.     <div id="header">
    13.      
    14.     </div>
    15.     <div id="topmenu">
    16. $topmenu
    17. <div id="topmenu-preloader-hover"></div>
    18. <div id="topmenu-preloader-active"></div>
    19. <div id="topmenu-preloader-active-hover"></div>
    20.     </div>
    21.     <div id="headmenu" class="corner5">
    22.       $headmenu
    23.     </div>
    24.     <!--content -->
    25.     <div id="content">
    26.       $main
    27.     </div>
    28.   </div>
     
    Dimon2x нравится это.
  22. sDevAlex

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

    С нами с:
    28 окт 2010
    Сообщения:
    53
    Симпатии:
    0
    Из Yii...CBaseController.php
    Код (Text):
    1.     public function renderInternal($_viewFile_,$_data_=null,$_return_=false)
    2.     {
    3.         // we use special variable names here to avoid conflict when extracting data
    4.         if(is_array($_data_))
    5.             extract($_data_,EXTR_PREFIX_SAME,'data');
    6.         else
    7.             $data=$_data_;
    8.         if($_return_)
    9.         {
    10.             ob_start();
    11.             ob_implicit_flush(false);
    12.             require($_viewFile_);
    13.             return ob_get_clean();
    14.         }
    15.         else
    16.             require($_viewFile_);
    17.     }
     
  23. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    ob_get_clean()
     
  24. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Ужоснах ваши "шаблонизаторы", ребята, честное слово.
    Чем такими костылями, лучше уж действительно на нативном похапэ писать. Так же громоздко и неудобно верстать, как и у ваших вариантов, но хотя бы работает быстро и надежно. Без обид.
     
  25. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    По порядку постов:
    1. (Шаблонизатор от Gromo). Почему половина верстки в пхп-коде, половина в шаблоне?
    2. (Шаблонизатор от Padaboo). Глючить же будет (нельзя подставлять значения циклом str_replace'ов), и неужели один strtr не будет быстрее и надежнее?
    3. (Шаблонизатор от Psih). А экранизация данных где? Каждый раз будем писать htmlspecialchars() или будем писать шаблоны, уязвимые к XSS?
    Ко всем троим вопрос: как планируете вызывать вспомогательные шаблоны? Неужели ни разу не сталкивались? Как быстро будут работать такие вызовы, если вспомогательных шаблонов на странице штук 20?