За последние 24 часа нас посетили 53849 программистов и 1715 роботов. Сейчас ищут 952 программиста ...

Шаблоны в PHP

Тема в разделе "Прочие вопросы по PHP", создана пользователем Onyx, 5 апр 2007.

  1. Onyx

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

    С нами с:
    5 апр 2007
    Сообщения:
    5
    Симпатии:
    0
    Здравствуйте, вообщем я пишу движок для сайта, предполагается что в дальнейшем двиг будет использоваться и на других сайтах, поэтому встал вопрос о шаблонах, как лучше реализовать такую систему?
    Предполагается наличие парсера, желательный вид например главного шаблона:
    PHP:
    1. <html>
    2. <title><% TITLE %></title>
    3. </head>
    4. <body>
    5. <% CONTENT %>
    6. </body>
    7. </html>
    Т.е. проще говоря должны будут заменяться спец.теги на нужную информацию.
     
  2. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    ! не использовать <% %> - это теги ASP вроде как...

    у меня реализованно криво, но могу подсказать как
    все переменные {tpl:ИМЯ_ПЕРЕМЕННОЙ}
    блоки в виде <!--BEGIN имя_блока--> и <!--END имя_блока-->
    ну и соответственно набор функций для замены.
    их могу выложить и описать работу, но еще раз скажу, что реализация кривая, хотя мои нужды она выполняет.
    *приятного мне аппетита*
     
  3. Onyx

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

    С нами с:
    5 апр 2007
    Сообщения:
    5
    Симпатии:
    0
    Выложи пожалуйста, посмотрю.
     
  4. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Ganzal
    Ты бы ещё посоветовал молотком по монитору постучать :)

    Onyx
    Почитай вот это http://www.massassi.com/php/articles/template_engines/ и многое станет ясно

    Если не знаешь английского почитай топик на этом форуме, длинная тема тут есть про шаблоны...
     
  5. Onyx

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

    С нами с:
    5 апр 2007
    Сообщения:
    5
    Симпатии:
    0
    А эта штука хорошо работает?
     
  6. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    посоветовал бы да не додумался - жрать хотелось :D

    Onyx, если поискать то можно реально много реализаций найти. когда я писал свою систему шаблонов мне просто хотелось чтобы она была понятна мне как мои 5 пальцев. это наверное единственный ее плюс :D
    если очень нада могу и показать...
     
  7. Onyx

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

    С нами с:
    5 апр 2007
    Сообщения:
    5
    Симпатии:
    0
    Ну дык я и её жду )
     
  8. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    "кривой" класс Template
    PHP:
    1. <?
    2. //<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
    3. class Template{
    4.  
    5.     var $s; // исходники
    6.     var $troot; // адрес корня каталога шаблона
    7.     var $wd; // рабоч
    8.     function Template( $templateName )
    9.     {
    10.         global $SITE_ROOT;
    11.         $this->s = array();
    12.         $this->wd = array();
    13.         $this->troot = $SITE_ROOT . "templates/" . $templateName ."/";
    14.         if(! is_dir( $this->troot ) )
    15.         {
    16.             // ошибка - не найден шаблон
    17.         }
    18.    
    19.     }
    20.     function LoadSource( $alias, $fileName )
    21.     {
    22.         $this->s[$alias] = @file_get_contents($this->troot.$fileName);
    23.         if(! $this->s[$alias] ) {}// ошибка - не найден файл шаблона
    24.         else $this->ProcessTPL( $alias );
    25.     }
    26.     function SetVars( $alias, $data=array() )
    27.     {
    28.         if(!isset ($this->wd[$alias]))
    29.         {  
    30.             if(isset($this->s[$alias]) ) $this->wd[$alias] = $this->s[$alias];
    31.             else {}// ошибка - мы еще не загрузили шаблона с таким алиасом
    32.         }
    33.         foreach($data as $var => $val)
    34.         {
    35.        
    36.             if( is_array( $val ) )
    37.             {  
    38.                 $tmp ="";
    39.                 foreach ($val as $ele)
    40.                 {
    41.                     $tmp.= $ele;
    42.                 }
    43.                 $this->wd[$alias] = str_replace("{tpl:".$var."}", $tmp, $this->wd[$alias]);
    44.  
    45.             }else
    46.             {
    47.                 $this->wd[$alias] = str_replace("{tpl:".$var."}", $val, $this->wd[$alias]);
    48.             }              
    49.         }
    50.     }
    51.     function SetBlock ( $alias, $data=array() )
    52.     {
    53.         if(!isset ($this->wd[$alias]))
    54.         {
    55.             if(isset($this->s[$alias]) )
    56.             {
    57.                 $this->wd[$alias] = array();
    58.             }else {}// ошибка - мы еще не загрузили шаблона с таким алиасом
    59.         }
    60.         $i = count($this->wd[$alias]);
    61.         $this->wd[$alias][$i] = $this->s[$alias];
    62.         foreach($data as $var => $val)
    63.         {
    64.             $this->wd[$alias][$i] = str_replace("{tpl:".$var."}",$val,$this->wd[$alias][$i]);      
    65.         }
    66.     }
    67.     function ProcessTPL( $alias )
    68.     {
    69.         $source = $this->s[$alias];
    70.         preg_match_all("<!--BEGIN ([0-9A-Za-z_]+)-->",$source,$output);
    71.         foreach($output[1] as $block)
    72.         {
    73.        
    74.             $pos1 = strpos ($source, "<!--BEGIN $block-->");
    75.             $pos2 = strpos ($source, "<!--END $block-->", $pos1);
    76.            
    77.             $do = substr($source, 0, $pos1);
    78.             $posle = substr($source, $pos2+(11+strlen($block)), strlen($source));
    79.             $newAliasSource = substr($source, $pos1+(13+strlen($block)), $pos2-$pos1-(13+strlen($block)));
    80.             $source = $do . "{tpl:" . $block . "}" . $posle;
    81.             /// create new alias
    82.             $this->s[$block] = $newAliasSource;
    83.             $this->ProcessTPL($block);
    84.         }
    85.         $this->s[$alias] = $source;
    86.     }
    87.     function Show ( $alias = "main")
    88.     {
    89.         if(isset($this->wd[$alias]))
    90.         {
    91.             $this->wd[$alias]=ereg_replace("\{tpl:([0-9A-Za-z_]+)\}","",$this->wd[$alias]);
    92.             print($this->wd[$alias]);
    93.         }
    94.         else {} // ошибка - мы еще не загрузили шаблона с таким алиасом
    95.     }
    96. }
    97. ?>
    как пользуюсь
    1.
    Код (Text):
    1. $tpl = new Template(тема);
    если папка тема есть то работаем дальше иначе - место для ошибки оставлено
    2.
    Код (Text):
    1. $tpl->LoadSource("alias", "filename");
    если найден файл filename с шаблоном, то его содержимое заносится в $tpl->s[alias] и тут же производится аля парсинг на предмет наличия блоков.

    пример файла с темплейтом
    HTML:
    1. <table width="100%" height="100%" bgcolor="{tpl:tablebgcolor}">
    2. <!--BEGIN table-->
    3. <tr><td>{tpl:tablerow}</td></tr>
    4. <!--END table-->
    при парсинге получим следущее
    блок от <!--BEGIN table--> до <!--END table--> будет вырезан в отдельный исодник с алиасом равным имени этого блока (в нашем случае table) а на его месте в исходнике появится место для переменной {tpl:table}
    то есть мы получим $tpl->s['alias']
    HTML:
    1. <table width="100%" height="100%" bgcolor="{tpl:tablebgcolor}">
    2. {tpl:table}
    и $tpl->s['table']
    HTML:
    1. <tr><td>{tpl:tablerow}</td></tr>
    причем если каждый блок распарсивается рекурсивно

    далее при помощи
    Код (Text):
    1. $tpl->SetBlock("table", array("tablerow" => "текст строки таблицы" ));
    мы заполняем шаблон данными
    причем при вызове функции SetBlock первым делом точная копия $tpl->s["table"] скопируется в массив $tpl->wd["table"][] и замена будет происходить именно в нем. соответственно нада передать все данные для блока сразу.

    далее мы заполняем получившимся набором строк блока table нужное место в шаблоне alias
    Код (Text):
    1. $tpl->SetBlock("alias", array("table" => $tpl->wd['table'] ));
    и последним действием выводим данные на экран
    Код (Text):
    1. $tpl->Show()
    ! тут если не передать названия алиаса будет совершена попытка выдать алиас по-умолчанию: main
    при этом мы удалим все лишние {tpl:ПЕРЕМЕННЫЕ}
    то есть на выходе мы получим следующий код
    HTML:
    1. <table width="100%" height="100%" bgcolor="">
    2.  <tr><td>текст строки таблицы</td></tr>
    3.  </table>
    4.  
    обратите внимание что я не передавал значение переменной tablebgcolor и на ее месте ничего нет... (самая моя частая ошибка - верстка летит на раз-два)
    вот... извините за плохое объяснение, но я старался...
     
  9. Onyx

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

    С нами с:
    5 апр 2007
    Сообщения:
    5
    Симпатии:
    0
    Ага спасибо!
     
  10. Битник

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

    С нами с:
    9 фев 2007
    Сообщения:
    103
    Симпатии:
    0
    А я Smarty использую и мне очень нравится :)
     
  11. zodiac

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

    С нами с:
    12 ноя 2006
    Сообщения:
    21
    Симпатии:
    0
    что-то оно не работает. выводит не таблицу, а слово Array
     
  12. zodiac

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

    С нами с:
    12 ноя 2006
    Сообщения:
    21
    Симпатии:
    0
    Написал свой класс Template, в отличии от твоего получилось значительно проще и меньше кода. Все работает :)
     
  13. Psih

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

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
  14. zodiac

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

    С нами с:
    12 ноя 2006
    Сообщения:
    21
    Симпатии:
    0
    Да лана, прост оя сказал о том, что класс предложенный Ganzal у меня не сработал.
     
  15. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    ты не поверишь... я позавчера выяснил что и у меня он хренова работает.... пришлось вносить кучу изменений...
     
  16. zodiac

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

    С нами с:
    12 ноя 2006
    Сообщения:
    21
    Симпатии:
    0
    А как до этого работал?