Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > помогите с шаблонизатором


Автор: VingradFan 19.1.2009, 23:09
Всех приветствую smile

пишу шблонизатор... smile уже предвкушаю гневные отзывы, что PHP - это лучший шаблонизатор и нечего велосипед изобретать....
Но все-таки...


Итак идея: ОЧЕНЬ простой синтаксис; минимальный функционал; возможность инклуда: 
   а. Текста <!--some_text-->
   б. ПХП Скриптов <!!--some_php_file-->

допустим, сначала, для простоты рассуждений, что шаблон формируется в два этапа:
   1. текст заменяется на строки с помощью str_replace
   2. а вот тут встает проблема: как инклудить код?


придумал такой алгоритм:
1. записываем в $template то что получилось после 1-го подхода.
2. ищем все до первого <!!--(что-угодно)-->, выводим это
3. инклудим скрипт из первого <!!--(что-угодно)-->
4. удаляем из $template подстроку, которую уже вывели и первый тег <!!--(что-угодно)-->
5. возвращаемся к шагу 2.



подозреваю, что можно все проще делать....

Жду советов, спасибо!

Автор: ksnk 19.1.2009, 23:59
  Нужно, в принципе, расчитывать на компилируемый шаблонизатор, когда шаблон компилируется в более-менее простой PHP код. Если шаблонизатор некомпилируемый - когда-нибудь настанут тормоза, знаю по своей поделке  smile 

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


Автор: VingradFan 20.1.2009, 00:11
ksnk, спасибо за наводку на компилирующий шаблонизатор...
буду гуглить smile



что-то я совсем забыл про функцию eval();!!!
она ведь решает всю проблему и сводит код к двум строчкам smile

Автор: ksnk 20.1.2009, 00:40
VingradFan, Для тестирования могу предложить  в меру тяжёлую тестовую задачку - "вписать" шаблонный движок в "магазинную страничку ". Магазинная страничка - это:

-- страница вывода товара по категории. Для простоты - слева "деревянный" список категорий (категорий 50-100). Справа - таблица товаров. Снизу еще одна категория товаров (новинки... штуки 3-6). Товар - ассоциативный массив с картинкой, ценой и фиксированным набором атрибутов, некоторые из них удобно выводить выпадающим списком...
-- Список товаров разношаблонный. Для каждого товара (даже и в одной категории) может использоваться разные шаблончики. Впрочем, это на потом smile Для серьезности нагрузки нужно 50-100 товаров на страницу выдавать...
-- Таблица товаров - раскрашена полосками - чёт-нечёт + выделяются цветом некоторые столбцы.

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

В принципе, для конкретики можно в любой e-магазин ткнуться... Оно там везде такое smile

А так - задачка интересная. Разрабатывает логическое мышление.  smile Видимо, это и вся польза, так как, к сожалению, никто кроме тебя, скорее всего, пользоваться таким шаблонизатором не будет. Впрочем, а вдруг...


Автор: VingradFan 20.1.2009, 01:34
ksnk, ну причем тут навороченный магазин smile
я ведь делаю шаблонизатор для конкретной цели: небольшая hand-made CMS...

т.ч. я думаю, eval здесь самое оптимальное решение....


PS я таки осознал, что для большого проекта нужен нативный PHP шаблонизатор smile 

Автор: bars80080 20.1.2009, 10:09
имхо, если есть варианты решения без eval(), даже с полным изменением логики работы, то надо ибегать её

Автор: ksnk 20.1.2009, 11:18
Цитата

я ведь делаю шаблонизатор для конкретной цели: небольшая hand-made CMS...

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

Честно говоря, для небольшого проекта шаблонизатор, как таковой и не нужен. Нужно выделить все классы-функции, ответственные за формирование HTML'я в отдельный файл. обозвать его "шаблонизатором " или view-контролером по вкусу и наслаждаться жизнью...

Автор: VingradFan 20.1.2009, 16:51
bars80080, она типо непроизводительна?


ksnk, ну раньше, когда я не слышал слова шаблонизатор у меня в шаблонах были для текстовых данных echo "somwthing"; а для подключения компонентов include (something);
но потом я прочитал, что так некруто smile и ни один дизайнер не будет писать шаблоны с вставками php...

Автор: ksnk 20.1.2009, 17:21
VingradFan, Нужно уж определиться, это маленький проект, который по определению весь делается одним человеком, или большой проект, для которого специальный верстальщик делает специальные шаблоны.

Обычная, imho, практика работы с шаблонами - приложение формирует ассоциативный массив с данными и передает его шаблонизатору. Шаблонизатор уже сам вставляет нужные параметры в нужные места. Чего-нибудь такое:
Код

...  
class TPL {
   function tplHello($par){
     return '<head><title>'.$par['title'].'</title></head><body>'.$par['data'].'</body>';
  }
...
}

...

echo TPL::tplHello(array('title'=>'Заголовок', 'data'=>'очень много данных...'));




Автор: VingradFan 20.1.2009, 18:37
Цитата

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


пишется пока для себя, но хочется "чтоб все как у взрослых"  smile 




Цитата

приложение формирует ассоциативный массив с данными и передает его шаблонизатору


ну это понятно.... суть темы состоит в том, как передавать шаблонизатору куски кода PHP в виде файлов....

1. вариант - eval();
2. вариант - в первом посте....

пока идею иссякли smile

Автор: ksnk 20.1.2009, 19:00
Цитата

суть темы состоит в том, как передавать шаблонизатору куски кода PHP в виде файлов...

 smile Оно тебе не надо... Мне, вот, не нужно-же ...

приведи пример, где это понадобилось. Всяко можно задачку решить и без eval'а. 

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

Автор: VingradFan 20.1.2009, 22:11
привожу пример шаблона
Код

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 // EN" "http://www.w3.org/TR/REC-html40/<!--doctype-->">
<html>
    <head>
        <title>
            <!--title-->
        </title>
        <link rel="stylesheet" type="text/css" href="css/<!--css_system-->">
        <link rel="stylesheet" type="text/css" href="css/<!--css_color-->">
    </head>
    <body>
        <div id='main' class='shown'>
            <table>
                <tr>
                    <td colspan="2">
                        <h1><!--site_title--></h1>
                    </td>
                </tr>
                <tr>
                    <td class='small'>
                        <p>
                            <!--menu-->
                        </p>
                        <p>
                            <!--login_form-->
                        </p>
                    </td>
                    <td>
                        <!--body-->
                    </td>
                </tr>
            </table>
        </div>
    </body>
</html>
<!--alerts-->




<!--menu-->
<!--login_form-->
<!--body-->

надо заменить на php код, который формирует меню, форму логина, и тело страницы.

Автор: bars80080 20.1.2009, 23:43
причём здесь пхп-код? наверно в браузер ты всё же отправляешь целиком и полностью хтмл-разметку, без единого кусочка кода?
достаточно считать весь файл и заменить куски на соответствующие части:

Код

$fp = fopen('template.html', 'r');
$temp = fread($fp, 9999);
fclose($fp);

$ar = array('<!--site_title-->','<!--menu-->','<!--login_form-->');
$ag = array($title, $menu, $form);
$html = str_replace($ar, $ag, $temp);

echo $html;

где $title, $menu, $form данные из БД или файлов, с генеренные и скомпонованные на пхп в нужном виде

Автор: ksnk 20.1.2009, 23:44
VingradFan, А можно было бы придумать как записать в шаблоне "заголовок" и описать LoginForm, Body и Menu в том-же файле. Это, типа, круто. Все шаблоны маленького приложения в одном файле. Ну в крайнем случае, можно в нескольких файлах, а имя "шаблона" брать из имени файла...

Если свести к моему примеру, все будет примерно так
Код

...
      </div>
    </body>
</html>
<!--alerts-->

<!--begin:LoginForm-->
<form>
<input name='login'>
<input type='password' name='password'>
</form>
<!--end:LoginForm-->


Код

echo TPL::tplHello(array('title'=>'Заголовок', 'LoginForm'=>TPL::tpl('LoginForm',array(...)),'alerts'=>'очень много данных...'));


И куда тут теперь нужно вставить какие-то PHP-шные файлы?

Автор: VingradFan 21.1.2009, 00:42
bars80080, ksnk, спасибо за мысли, буду перечитывать и обдумывать smile



bars80080, например, на место <!--news--> надо подгрузить компонент news.php
Код

<h2>Новости</h2>
<?php
    require (comps.'news/kernel/functions.php');
    if($_GET['read'] > 0){
        form_show();
        new_show ($_GET['read']);
        replys_show($_GET['read']);
    }
    else{
        form_show();
        all_news_show();
    }
?>



Цитата

с генеренные и скомпонованные на пхп в нужном виде

очень просто и логично звучит smile
тоесть надо каким-то образом результат работы этого скрипта записать в текстовую переменную и заменить ею <!--news--> ?
похоже надо будет менять тогда принцип работы компонентов. smile 

Автор: bars80080 21.1.2009, 10:24
Цитата(VingradFan @  20.1.2009,  23:42 Найти цитируемый пост)
похоже надо будет менять тогда принцип работы компонентов

ну, это смотря, что ты подразумеваешь под компонентами. на деле мне кажется это наиболее простой вариант работы. я уже привык делать как: пишу статическую страницу со всеми элементами, css и js (рабочим), а когда всё готово и работает, просто разделяю страницу на блоки, которые могут быть или не быть, или множиться, а все переменные и тексты, что генерируются на странице, выглядят так: {PEREM}. в итоге полнейшее разделение html и php, они вообще никак не пересекаются

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)