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


Автор: alexey009 28.7.2008, 23:57
Что требуется:
1. Для каждой функции свой шаблон, пример:
index.tpl
Код

<html>
<head>
<title>@TITLE@</title>
</head>
<body>
<table border="0" width="100%" cellspacing="0" cellpadding="0">
<tr>
<td width="100%">@name@</td>
</tr>
</table>
<table border="0" width="100%" cellspacing="0" cellpadding="0">
@text@
</table>
</body>
</html>

news.tpl
Код

<tr>
<td width="100%">@name01@</td><td width="100%">@name02@</td>
</tr>


Теперь пояснения:
1. замена обычных переменных: title, name
2. замена блоков text в index.tpl: заменяется на файл news.tpl, который собственно выполняется N-е кол-во раз, т.е. результат может быть:
Код

<tr>
<td width="100%">@name01-@</td><td width="100%">@name02-@</td>
</tr><tr>
<td width="100%">@name01--@</td><td width="100%">@name02--@</td>
</tr>


Ваши предложения по реализацииsmile
Готовые решения не подходят(сильно огромные)
Вариант (который щас у меня стоит) не подходит по разным причинам:
Код

<html>
<head>
<title>@TITLE@</title>
</head>
<body>
<table border="0" width="100%" cellspacing="0" cellpadding="0">
<tr>
<td width="100%">@name@</td>
</tr>
</table>
<table border="0" width="100%" cellspacing="0" cellpadding="0">
<!-- BEGIN news -->
<tr>
<td width="100%">@news.name1@</td><td width="100%">@news.name2@</td>
</tr>
<!-- END news -->
</table>
</body>
</html>

Автор: americanets 29.7.2008, 09:37
http://forum.vingrad.ru/forum/topic-54581.html почитай

Автор: alexey009 29.7.2008, 12:39
americanets, уже прочитал. ничего нового для себя не узнал...
Там нет намеков на решение моей проблемы.
мне надо в один файл(шаблон) подключать другие шаблоны. а не разбивать 1 сраницу на несколько последовательных файлов, типа
Код

$template->pparse('overall_header');
$template->pparse('left_body');
$template->pparse('index_body');
$template->pparse('overall_footer');


Добавлено через 4 минуты и 44 секунды
По сути мне требуется "загонять" шаблон в переменную. smile 

Автор: americanets 29.7.2008, 12:44
Цитата(alexey009 @  29.7.2008,  13:39 Найти цитируемый пост)
уже прочитал. ничего нового для себя не узнал...


ну и зря, смотри все шаблоны это что-то заменить на данные, ну вот 

Код

$Data = тут твои данные, др щаблоны и прочее;

/*
* Обрабатываешь все что нужно
*
*/
$Html = str_replace('TYT_BYDYT_DANNIE',$Data,$AllHtmlTpl);


echo $Html;


мысль ясна ?


Автор: alexey009 29.7.2008, 13:00
Ага. спасибо. И ещё вопрос, как лучше подключить и обработать файл шаблона, чтобы была минимальная нагрузка на сервер?

Автор: americanets 29.7.2008, 13:04
Код

file_get_contents() 


получать содержимое файла

Код

str_***
preg_*** 


обрабатывать , str - работают быстрее


Цитата(alexey009 @  29.7.2008,  14:00 Найти цитируемый пост)
подключить и обработать файл шаблона, чтобы была минимальная нагрузка на сервер? 


кэшируй

Автор: alexey009 29.7.2008, 13:31
Вот, но почемуто не работает цикл. заменят только 1 раз.  smile  :
Код

function news($news){
    $html_n = $news;
    for($i = 0; $i<5; $i++){
        $name = 'ИМЯ_НОВОСТИ';
        $text = 'ТЕКСТ_НОВОСТИ';
        $html_n = str_replace('@name@', $name, $html_n);
        $html_n = str_replace('@text@', $text, $html_n);
    }
    return $html_n;
}

$start = file_get_contents('index.tpl');
$news = file_get_contents('news.tpl');

$title = 'ЗАГЛАВИЕ';
$text = 'ТЕКСТ_ЗАГЛАВИЕ';
$new = news($news);

$html = str_replace('@news@', $new, $start);
$html = str_replace('@title@', $title, $html);
$html = str_replace('@text@', $text, $html);

echo $html;

index.tpl
Код

<html>

<head>
  <title></title>
</head>

<body>
@title@<br>
@text@<br>
@news@

</body>

</html>

news.tpl
Код

@name@<br>
@text@<br>
--------

Автор: americanets 29.7.2008, 14:02
Цитата(alexey009 @  29.7.2008,  14:31 Найти цитируемый пост)
1 раз


видимо последний, а как ты думал smile ты передешь ему кусок кода, он в нем все заменяет, потом так еще 4 раза перетирает его


как пример 

Код

$Html = 'la la la ';

$Html = 'Test';

echo $Html;

/////////////////////

$Html = 'la la la';
$Html .='Test';

echo $Html;

Автор: alexey009 29.7.2008, 16:09
И что же менять?
Пробывал сам, не получилось...

Автор: americanets 29.7.2008, 16:20
Код

function news($news){

    $html_n = '';

    for ($i = 0; $i<5; $i++) {
         $name = 'ИМЯ_НОВОСТИ';
         $text = 'ТЕКСТ_НОВОСТИ';
         $html_n .= str_replace(
                                 array('@name@' , '@text@'), 
                                 array($name,$text), 
                           $news);
    }
    return $html_n;
}


как то так

Автор: alexey009 29.7.2008, 20:23
Все понятноsmile
Теперь, я думаю, надо шаблонизатор загнать в класс...
Вот только что в нем должно быть?
Мне кажется должны быть минимум 2 функции:
1. Замена
2. определение шаблона
Что ещё?

 smile P.S. в php уже более 3х лет, а в классах ничего не понимаю, посоветуйте документацию плиз

Автор: klyxa 29.7.2008, 21:02
Код

<?php
    class Template
    {
        var $tplname;
        var $tpl;
        var $path;
        var $tplfile;

        function Template($tpl, $module)
        {
            $this->tplname = $tpl.".php";
            $this->path = $this->set_path($module);

            if (!$tpl) $this->kill_class("Error: Empty template name!");
            if (!$this->path) $this->kill_class("Error: Unknown template module!");

            $this->tplfile = $this->path . $this->tplname;

            if (!$this->tpl_exists()) $this->kill_class("Error: Template file $this->tplfile doesn't exist!");
        }
        
        function set_path($module)
        {
            switch($module)
            {
                case "IBlock": $dir = TPL_DIR."infoblocks/"; break;
                default: $dir = ""; break;
            }

            return $dir;
        }

        function kill_class($error)
        {
            print $error."<BR>";
        }

        function tpl_exists()
        {
            if (file_exists($this->tplfile)) return true;
            else return false;
        }

        function Load_Template()
        {
            $cnt = file_get_contents($this->tplfile);
            return $cnt;
        }

    };
?>

м?

Автор: alexey009 29.7.2008, 21:21
klyxa, опа smile а какая функция что делает?  smile 

Автор: americanets 30.7.2008, 12:48
alexey009, это не совсем - то что ты хочеш сделать, а книжка вот http://www.ozon.ru/context/detail/id/3600968/

Автор: alexey009 31.7.2008, 00:24
americanets, спасибо, почитал...

Как разумно организовать шаблонизатор?
может вообще не создавать никаких функций и классов?
Просто ограничится
Код

str_replace(array(), array(), file)

Но все-таки хотелось организовать что-то вроде:
определение шаблонов(в функции должен задаваться "истинный" путь к файлам шаблонов(типа engine/templates/new_temp)):
Код
set_filenames(array(
    'index' => 'index.tpl',
    )
);


замены(функция должна возвращать получившееся, чтобы вставлять в след. замены шаблонов):
Код
assign_vars(array(
    '@name@' => $name,
    '@text@' => $text
    ), $file
);


ну и далее вывод(в переменной $index должен лежать результирующий шаблон)
Код

pparse($index);


И вопрос, как это все можно организовать без глюков и тормозов?

Автор: alexey009 1.8.2008, 00:56
Вот, написал класс шаблонизатора
Код

class temp{

    var $_tpldata = array();

    var $files = array();

    function set_filenames($filename_array)
    {
        reset ($filename_array);
        while(list($handle, $filename) = each($filename_array))
        {
            $this->files[$handle] = $this->make_filename($filename);
        }

        return $this->files;
    }

    function make_filename($filename)
    {
        global $root_path, $root_engine, $site;
        // Check if it's an absolute or relative path.
        if (substr($filename, 0, 1) != '/')
        {
            $filename = $root_path . $root_engine .'templates/' . $site['template'] . '/' . $filename;
        }

        if (!file_exists($filename))
        {
            die("Template->make_filename(): Error - file $filename does not exist");
        }

        return $filename;
    }

    function assign_vars($vararray)
    {
        reset ($vararray);
        while (list($key, $val) = each($vararray))
        {
            $this->_tpldata[$key] = $val;
        }

        return $this->_tpldata;
    }

    function assign_replace($vararray, $file)
    {
        reset ($vararray);
        $rrr = str_replace(array_keys($vararray), array_values($vararray), $file);

        return $rrr;
    }

}


Плиз, оцените и скажите что можно улучшить?smile


Да и ещё, нужна функция для циклов:
Код

@BeginNews@
название  - @name@<br>
содержание  - @text@<br>
@EndNews@

Т.е. то что между Begin и End выполнялось "по циклу". Как лучше организовать? 
Есть такие мысли:
1. использовать функцию strstr() но как тогда искать конец( может preg_match()) ?
2. полностью положиться на preg_match()
Знатоки, помогите с выбором ну и реализацией по возможностиsmile

Автор: alexey009 1.8.2008, 01:48
Появилась ещё одна задача:
В шаблоне index.tpl написано:
Код

<img src="images/logo.gif" alt="" border="0">

Шаблон лежит в /engine/templates/new/main/index.tpl
картинка лежит в /engine/templates/new/images/logo.gif

Вопросы:
1. Как в адрес картинки дописать недостоющее "/engine/templates/new/"
2. Сильная ли будет нагрузка на сервер такими заменами(картинок то много)
3. Или лучше сразу в шаблоне писать полный адрес до картинки?

Автор: americanets 1.8.2008, 10:14
Цитата(alexey009 @  1.8.2008,  02:48 Найти цитируемый пост)
Вопросы:


1 введи константы IMAGE_PATCH и т д
2 терпимая smile 
3 смотря какой случай, если периодически нужно перемещать папки с файлами в другие директории то нет, константы, а так пиши как удобнее


Автор: Kefir 1.8.2008, 11:16
Вообще, думается мне, что лучше всего покопаться в сырцах смарти (я бы предложил его и использовать, но как было сказано - не подходит). В итоге в шаблонизаторе необходимы следующие фичи/ф-ции (без которых обойтись можно, но очень сложно).
1. $templater->assign // назначение переменной в шаблоне
2. $templater->fetch // получение заполненного темплейта в переменную
3. $templater->display // вывод заполненного темплейта на экран
4. шаблонизатор просто обязан "компилировать" себя в чистый ПХП код. без этого нагрузка будет большой. например шаблон "<p>@text@</p>" должен переводится в чистый ПХП - "<p><?php echo $templater->vars['text']; ?></p>". Также, соответственно, необходимо следить за изменениями в шаблоне и по необходимости копилировать заново. получается, что всесто того чтобы каждый раз парсить шаблон заново надо будет всего лишь запустить имеющийся скрипт.
5. кэширование - ещё одна фича, позволяющая снизить нагрузку.
6. вызов встроенных пхп функций из шаблона и возможность создания дополнительных функций. второе, в общем, необязательно, но вызов встроенных ф-ций необходим 100%. в шаблонах нередко необходимо посчитать чего-нибудь (к примеру {if count($image_thumbs) > 0}<img src={$image_thumbs[0]}>{else}<p>No images{/if}).

В общем сильно рекоммендую посмотреть что и как делает смарти - ребята сделали всё грамотно.

Автор: alexey009 1.8.2008, 13:19
Kefir, смарти здоровый и не понятны. я дня два сидел и въежал как его использовать, но ничерта не понял(не умею я в чужолм коде разбираться).
А так я же написал класс шаблонизатора!
Цитата

Плиз, оцените и скажите что и как можно улучшить?

Автор: skyboy 1.8.2008, 13:45
alexey009, зачем тебе было "разбираться в коде смарти" - не понятно. для построения шаблонов вполне достаточно списка разных конструкций(типа {if}, {foreach} и т.д.). для инициации достаточно двух методов: assign и display.
впрочем, не хочешь - не надо.
Цитата(alexey009 @  31.7.2008,  23:56 Найти цитируемый пост)
Плиз, оцените и скажите что можно улучшить?

разве то, что написал Kefir уже есть? где кеширование? каждый раз заново заменяешь текст?
где циклы в шаблоне? где условные конструкции? как сделать перебор массива? как включить один шаблон в другой? как сделать счетчик или итератор(например, чтоб на уровне шаблона сделать чередование цвета строк таблицы)? где это все?
Цитата(alexey009 @  1.8.2008,  00:48 Найти цитируемый пост)
. Как в адрес картинки дописать недостоющее "/engine/templates/new/"

а зачем, интересно? чтоб браузер корректно отобразил картинку, она должна иметь не абсолютный путь на диске относительно папки с шаблоном, а относительный/абсолютный путь основываясь на доменном имени(с точки зрения сервера - это DOCUMENT_ROOT)

Автор: Kefir 1.8.2008, 14:12
alexey009, да ну и чёрт с ним с кодом - поюзай его маленько - сразу поймёшь чего тебе не хватает. полистай мануал, где его фичи описаны. но опять же - я перечислил те вещи, которые обязаны быть в шаблонизаторе, иначе же это не тянет на таковой - максимум "улучшенный str_replace" В) Смарти я посоветовал как раз как источник многих полезных фич. А разобраться как его использовать - три минуты (читай, залил на сервер, подрубил инклюд и сделал экземпляр смарти, всё).

Автор: alexey009 1.8.2008, 14:26
ну впринципе можно и смарти использовать, но вот проблемы
Цитата(skyboy @  1.8.2008,  13:45 Найти цитируемый пост)
alexey009, зачем тебе было "разбираться в коде смарти" - не понятно. для построения шаблонов вполне достаточно списка разных конструкций(типа {if}, {foreach} и т.д.). для инициации достаточно двух методов: assign и display.

не могу понять как задать циклы и как один шаблон пихать в другой, если они в разных папках (например index.tpl лежит в папке engine/tempaltes/new/main, news.tpl  лежит в папке engine/tempaltes/new/news)
главный файл лежит в корневой директории( / ).
Нужно в index.tpl подключить news.tpl и news.tpl загнать в цикл(вывести список новостей)
подскажите как?

Цитата(skyboy @  1.8.2008,  13:45 Найти цитируемый пост)
а зачем, интересно? чтоб браузер корректно отобразил картинку, она должна иметь не абсолютный путь на диске относительно папки с шаблоном, а относительный/абсолютный путь основываясь на доменном имени(с точки зрения сервера - это DOCUMENT_ROOT)


просто так надо...
не хочется каждый раз писать /engine/templates/new/images/******.gif
а просто писать images/*****.gif
Потому что шаблонов может быть несколько(все лежат в папке templates) и чтобы адреса картинок не менялись.. удобнеее тому кто будет делать шаблоны..smile

Автор: skyboy 1.8.2008, 15:08
Цитата(alexey009 @  1.8.2008,  13:26 Найти цитируемый пост)
не могу понять как задать циклы

preg_replace c модификатором "е"
Цитата(alexey009 @  1.8.2008,  13:26 Найти цитируемый пост)
и как один шаблон пихать в другой

preg_replace c модификатором "е"
или же strstr и подобное.

Добавлено через 1 минуту и 26 секунд
Цитата(alexey009 @  1.8.2008,  13:26 Найти цитируемый пост)
и как один шаблон пихать в другой, если они в разных папках 

очевидно, надо указывать полный путь. не знаю, что ты рассчитывал найти в исходнике Смарти. он тоже не телепатирует, а:
а) смотрит в папке, указанной как "корневая папка шаблонов"
б) смотри по полному пути
все. поиск по всему диску на предмет файлов с заданным названием никто не проводит.

Автор: Kefir 1.8.2008, 15:39
news.tpl
Цитата

{foreach from=$newsArray item=news}
<p>{$news->Content}</p>
{/foreach}

index.tpl
Цитата

<html>
...
{$newsBlock}
...
</html>



Код

// создаём смарти
$smarty = new Smarty();
$smarty->template_dir = 'engine/templates';
$smarty->compile_dir = '...';
$smarty->cache_dir = '...';
$smarty->config_dir = '...';

// работаем
$smarty->assign("newsArray", $newsManager->getNews());
$smarty->assign("newsBlock", $smarty->fetch("new/news/news.tpl");
$smarty->display("new/main/index.tpl");

извини, но для каждой отдельной новости мучать news.tpl - это мазохизм  smile . поэтому мы просто даём в news.tpl массив с новостями и там его весь выводим. потом говорим смарти, чтобы он в переменную $newsBlock положил то что получилось с news.tpl (то биш уже готовый блок новостей) и выводим index.tpl. Вуаля.

Добавлено через 2 минуты и 17 секунд
то есть по сути тебе надо делать так - создавать конструкцию цикла для шаблона и передавать туда массив. потом загонять то что получилось в переменную и её уже вставлять в индекс. вот и всё. по крайней мере такая система в смарти.

Автор: alexey009 1.8.2008, 16:30
Цитата(Kefir @  1.8.2008,  15:39 Найти цитируемый пост)
извини, но для каждой отдельной новости мучать news.tpl - это мазохизм

разве?
вообще-то будет как-то так:
news.tpl
Код

<table border="0" cellspacing="0" cellpadding="6">
    <tr>
        <td width="100%" valign="top">{news_error.TEXT}</td>
    </tr>
</table>
<!-- BEGIN news_block -->
<table border="0" width="400" cellspacing="0" cellpadding="0" background="engine/images/news_fon.gif">
    <tr>
        <td width="100%" valign="top">
        <table border="0" width="100%" cellspacing="5" cellpadding="5">
            <tr>
                <td>
                <table border="0" width="100%" cellspacing="0" cellpadding="0">
                    <tr>
                        <td width="100%" align="left">&nbsp;&nbsp;<font size="3" color="#FFFFFF"><b>{news_block.NAME}</b> ({news_block.DATE})</font></td>
                    </tr>
                    <tr>
                        <td width="100%" align="left"><font size="3" color="#FFFFFF">{news_block.TEXT}</font></td>
                    </tr>
                </table>
                </td>
            </tr>
        </table>
        </td>
    </tr>
</table>
<!-- END news_block -->


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

Автор: americanets 1.8.2008, 16:36
alexey009, видимо Kefir имел ввиду не дергать кждый раз файл а загнать его в переменную и ее юзать smile 

Автор: alexey009 1.8.2008, 17:12
americanets, как бы я так и хотел и описывал эту задачу в требованиях в шаблонизатору... smile 

И ещё вопрос... вот идет компиляция..
если задать
Код

$smarty->compile_dir = 'engine/templates/new/compile';

Верно? И как далее правильно компилировать и извлекать?

Автор: Kefir 1.8.2008, 18:01
alexey009, ну как, делаешь парсер. я ж писал уже. к примеру
somthing.tpl:
Цитата

{if $myImage != ""}<img src="{$myImage}">{else}<p>No image specified</p>{/if}

должно перевестись в:
something.tpl.php:
Код

<?php if($templater->vars['myImage'] != "") { ?><img src="<?php echo $templater->vars['myImage']; ?>"><?php } else { ?><p>No image specified</p><?php } ?>

то есть парсер должен переводить язык шаблона в язык ПХП. потом, к примеру, делаешь в классе шаблонизатора:
Код

funciton fetch( $path ) {
  if(!Templater::compiled( $path ) || Templater::needsRecompile( $path )) {
    Templater::compile( $path );
  }
  include( Templater::getCompiledVersion( $path );
}


Добавлено через 17 секунд
ну эт всё условно. но логика именно такая.

Автор: alexey009 1.8.2008, 20:55
Я вот все-равно никак понять не могу, как делать ЦИКЛЫ
файл index.php
Код

$smarty = new Smarty();
$smarty->template_dir = 'engine/templates';
$sql = "SELECT `id`, `name`, SUBSTRING_INDEX(`text`, ' ', 20) AS `text`, `site`, `date`, `img`, `visible` FROM `".NEWS_TABLE."` where `visible`='on' ORDER BY id desc";
$result = mysql_query ($sql);
while($row=mysql_fetch_assoc($result)) {
    $row['name'];
    $row['text'];
    $row['date'];
}

файл news.tpl
Код

<table border="0" width="100%" cellspacing="0" cellpadding="0">
    <tr>
        <td width="100%" align="left">{NAME} ({DATE})</td>
    </tr>
    <tr>
        <td width="100%" align="left">{TEXT}</td>
    </tr>
</table>

Так вот то что в news.tpl надо загнать в цикл. 
foreach НЕ ПОЙДЕТ, т.к. он по жизни тормознутый.
если делать типа
Код

{while ($row=mysql_fetch_assoc($result))}
<table border="0" width="100%" cellspacing="0" cellpadding="0">
    <tr>
        <td width="100%" align="left">{NAME} ({DATE})</td>
    </tr>
    <tr>
        <td width="100%" align="left">{TEXT}</td>
    </tr>
</table>
{/while}

то вот это уже возникает вопрос, а в чем собвственно заключается шаблонизатор? половина кода в php файле, а другая половина уже в самом шаблоне.
где плюсы? 
Отсюда - может мне ввобще нафиг шаблнизатор и html коды пихать в php файлы и все?
Знатоки, что посоветуете?

Автор: Fortop 1.8.2008, 21:42
Цитата(alexey009 @  1.8.2008,  20:55 Найти цитируемый пост)
foreach НЕ ПОЙДЕТ, т.к. он по жизни тормознутый.

мда...

Без обид, но ты мерял? Или просто слышал?
Сделай рабочий сайт и профайлинг ему.... результаты тебя удивят.


Цитата(alexey009 @  1.8.2008,  20:55 Найти цитируемый пост)
Отсюда - может мне ввобще нафиг шаблнизатор и html коды пихать в php файлы и все?
Знатоки, что посоветуете? 

Почитай другие темы про разделение логики и представления. Про архитектуру MVC.

Шаблоны/Представления должны быть отдельно от логики... но лучше всего если они будут из себя представлять обычные phtml файлы. Тогда и циклы и условия все будет у тебя легко и просто.

Автор: alexey009 1.8.2008, 22:06
Цитата(Fortop @  1.8.2008,  21:42 Найти цитируемый пост)
Без обид, но ты мерял? Или просто слышал?Сделай рабочий сайт и профайлинг ему.... результаты тебя удивят.

читал и сам проверял..  работет медлено..

Цитата(Fortop @  1.8.2008,  21:42 Найти цитируемый пост)
Шаблоны/Представления должны быть отдельно от логики... но лучше всего если они будут из себя представлять обычные phtml файлы. Тогда и циклы и условия все будет у тебя легко и просто.

я вообще-то про это и говорю, что это и есть шаблонизатор, а в смарти(если его все-таки использовать) как циклы выводить "без заноса" логики в шаблон!(см. предыдущий пост) smile 

Автор: Fortop 1.8.2008, 22:18
Цитата(alexey009 @  1.8.2008,  22:06 Найти цитируемый пост)
читал и сам проверял..  работет медлено..

Позволь усомниться... 
Как проверял?

Если не затруднит, скриншот из http://sourceforge.net/projects/wincachegrind smile

Цитата(alexey009 @  1.8.2008,  22:06 Найти цитируемый пост)
я вообще-то про это и говорю, что это и есть шаблонизатор,

Кто мешает использовать простой include?

Автор: alexey009 1.8.2008, 22:45
Цитата(Fortop @  1.8.2008,  22:18 Найти цитируемый пост)
Кто мешает использовать простой include?

Читал предыдущие посты?
Цель - весь шаблон страницы должен лежать в одном файле(index.tpl), а не разбивать его на header, body, footer;
а далее body разбивать на left_menu, right_menu, main.
а их уже разбивать на более мелкие детали... ну не маразм? smile 

Вообщем пока у меня один вариант виден: дописывать собственный шаблон.
Кстати, про компиляцию, как организовать и нужло ли это вообще?

Автор: Kefir 1.8.2008, 23:03
alexey009, постой-постой, ты разделяй код, занимающимся доставкой и обработкой данный от логики представления, так сказать. суть шаблонизатора как раз их и разделить.
задача: вывести новости на экран. делим на две части - достать новости из БД и отобразить их. ты, соответственно, достаёшь новости и получает, по сути, массив обьектов. так выполнена первая задача - бизнес логика. вторая задача - отобразить их. эту задачу и решает шаблонизатор. в бизнес логике ты вообще не думаешь о том как и где эти данные будут отображаться, ты просто говоришь шаблонизатору - "вот тебе новости, покажи мне их на экране!". и уже в шаблонизаторе эти новости превращаются в пхп-код.

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

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

Автор: alexey009 1.8.2008, 23:12
Kefir, есть мой пост в конце 2 странице - http://forum.vingrad.ru/index.php?showtopic=222402&view=findpost&p=1598812

Соответственно ответы на него не уведил.. smile 

Автор: Fortop 1.8.2008, 23:24
Цитата(alexey009 @  1.8.2008,  22:45 Найти цитируемый пост)
Цель - весь шаблон страницы должен лежать в одном файле(index.tpl), а не разбивать его на header, body, footer;
а далее body разбивать на left_menu, right_menu, main.
а их уже разбивать на более мелкие детали... ну не маразм?
\
Нет не маразм. Страница у тебя собирается из деталей того уровня, который тебе нужен. Не нужна более мелкая детализация - не делай ее

Но я бы предпочел такой, index.phtml
Код

include 'header.phtml';
include 'body.phtml';
include 'footer.phtml;


Если тебе нужна более продвинутая манипуляция, то рекомендую...
Посмотри, как организованы http://framework.zend.com/manual/en/zend.view.html + http://framework.zend.com/manual/en/zend.layout.html  в Zend Framework

Цитата(alexey009 @  1.8.2008,  23:12 Найти цитируемый пост)
Kefir, есть мой пост в конце 2 странице - http://forum.vingrad.ru/index.php?showtopi...t&p=1598812
Соответственно ответы на него не уведил..

Кхм, а где ответ про foreach?

Автор: alexey009 1.8.2008, 23:30
Цитата(Fortop @  1.8.2008,  23:24 Найти цитируемый пост)
Кхм, а где ответ про foreach?

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

Автор: Kefir 1.8.2008, 23:33
ну раз тебе надо поцитатно  smile 
Цитата(alexey009 @  1.8.2008,  20:55 Найти цитируемый пост)
foreach НЕ ПОЙДЕТ, т.к. он по жизни тормознутый.

очень хорошая конструкция. зря ты так. даже ЕСЛИ (не будем мерится циклами) твой код будет выполняться на 0.001 секунду дольше - ничего страшного.

Цитата(alexey009 @  1.8.2008,  20:55 Найти цитируемый пост)
а в чем собвственно заключается шаблонизатор?

коротко - в разделении логики и представления.

Цитата(alexey009 @  1.8.2008,  20:55 Найти цитируемый пост)
половина кода в php файле, а другая половина уже в самом шаблоне.
где плюсы? 

опять приходится повторяться - есть логика которая бизнес, а есть логика представления. первая отвечает за то, чтобы достать и обработать данные (к примеру, сделать запросы в БД, отсортировать и/или отфильтровать полученные данные). вторая - за то как данные будут отображены. к примеру, надо чтобы у новости с пометкой Important был красный фон. к бизнес логике это не относится - сам понимаешь, то есть в класс News приделать поле BackgroundColor это всё равно что водителей трамваев в трамваям гвоздями прибивать. а раз это относится к логике представления - это должно быть реализовано в самом шаблоне. понял?

Цитата(alexey009 @  1.8.2008,  20:55 Найти цитируемый пост)
может мне ввобще нафиг шаблнизатор и html коды пихать в php файлы и все?

ну скажем так - главное чтобы тебе это нравилось В))) а по хорошему - ни в коем случае.


ЗЫ всё то же самое я писал и в предыдущем посте, но, к сожалению, ты почему-то не увидел этих ответов.

Добавлено через 1 минуту и 19 секунд
alexey009, а что органихация циклов то? чем цикл от ифа отличается? вот и подумай smile

Автор: alexey009 2.8.2008, 00:10
Kefir,  smile 
может я конечно полный нуб, но попробую ещё раз получить ответ, не сердитесь плиз. smile 
Значит,
файл index.tpl
Код

/// шапка
NEWS
/// все что ниже

файл news.tpl
Код

!!!НОВОСТИ!!!
начало
<table border="0" width="100%" cellspacing="0" cellpadding="0">
    <tr>
        <td width="100%" align="left">{NAME} ({DATE})</td>
    </tr>
    <tr>
        <td width="100%" align="left">{TEXT}</td>
    </tr>
</table>
конец

файл index.php
Код

$sql = "SELECT * FROM `".NEWS_TABLE."` where `visible`='on' ORDER BY id desc";
$result = mysql_query ($sql);
if( !$result){
    message_die(GENERAL_ERROR, 'Could not query categories list', '', __LINE__, __FILE__, $sql);
}
while($row=mysql_fetch_assoc($result)) {
    $row['text'];
    $row['name'];
    $row['date'];
}


папка с шаблоном index.tpl engine\templates\new\main
папка с шаблоном news.tpl engine\templates\new\news
смарти лежит в папке engine\smarty
файл index.php лежит в корневой директории.

внимание вопрос как в index.tpl NEWS заменить на файл news.tpl и отоброзить полученные новости из базы, при этом шаблон отображения новостей расположен между "начало" и "конец". НА ПРИМЕРЕ SMARTY

Автор: skyboy 2.8.2008, 00:19
Цитата(Kefir @  1.8.2008,  22:33 Найти цитируемый пост)
в разделении логики и представления.

бееее... сам же говорил, что в представлении тоже логика есть. и вполне себе имеет право быть. так что тогда уже "модели и представления". точне - "операций по формированию модели и представления"  smile 

Автор: Fortop 2.8.2008, 03:03
Цитата(alexey009 @  2.8.2008,  00:10 Найти цитируемый пост)
внимание вопрос как в index.tpl NEWS заменить на файл news.tpl и отоброзить полученные новости из базы, при этом шаблон отображения новостей расположен между "начало" и "конец".

Только цикл.

Ну или его эмуляция подобный конструкциями

Код

NEWS{150} //повторить 150 раз


P.S. В Smarty есть оператор для цикла

Автор: alexey009 4.8.2008, 16:49
Fortop, как задать цикл. этот вопрос задавался не раз, никто тольком не ответил smile 

Автор: Kefir 4.8.2008, 17:07
alexey009
index.tpl:
Код

{$newsBlock}

news.tpl (замечаем, что тут, внутри, есть цикл  smile ):
Код

!!!НОВОСТИ!!!
начало
{foreach from=$newsArray item=news} // ВОТ ЭТО ТУТ ЦИИИИКЛ! В))
<table border="0" width="100%" cellspacing="0" cellpadding="0">
    <tr>
        <td width="100%" align="left">{$news->NAME} ({$news->DATE})</td>
    </tr>
    <tr>
        <td width="100%" align="left">{$news->TEXT}</td>
    </tr>
</table>
{/foreach} // ЗАКАНЧИВАЕТСЯ ЦИКЛ
конец

index.php:
Код

$sql = "SELECT * FROM `".NEWS_TABLE."` where `visible`='on' ORDER BY id desc";
$result = mysql_query ($sql);
if( !$result){
    message_die(GENERAL_ERROR, 'Could not query categories list', '', __LINE__, __FILE__, $sql);
}
$newsArray = array();
while($row=mysql_fetch_assoc($result)) {
    $newsArray[] = $row;
}
$smarty->template_dir = "engine/templates/new";
...
$smarty->assign("newsArray", $newsArray);
$smarty->assign("newsBlock", $smarty->fetch("news/news.tpl"));
$smarty->display("main/index.tpl");




Цитата(skyboy @  2.8.2008,  00:19 Найти цитируемый пост)
бееее... сам же говорил, что в представлении тоже логика есть. и вполне себе имеет право быть. так что тогда уже "модели и представления". точне - "операций по формированию модели и представления"  smile  

вот надо тебе к словам попридираться. ведь и так понял, что я имею в виду.  smile 

Автор: BaNaNaS 4.8.2008, 17:25
Я бы сделал так:
Код
!!!НОВОСТИ!!!
<table border="0" width="100%" cellspacing="0" cellpadding="0">
[NEWS_FETCH_ROWS]
    <tr>
        <td width="100%" align="left">{NAME} ({DATE})</td>
    </tr>
    <tr>
        <td width="100%" align="left">{TEXT}</td>
    </tr>
[/NEWS_FETCH_ROWS]
</table>

Код

function ShowNews($tpl)
{
  $RESULT = "SELECT * FROM news";
  $outTpl = "";
  While($ROW = mysql_fetch_object($RESULT))
   {
      $outTpl .= $tpl;
      $outTpl = str_replace("{NAME}", $ROW->NAME, $outTpl);
      $outTpl = str_replace("{DATE}", $ROW->DATE, $outTpl);
      $outTpl = str_replace("{TEXT}", $ROW->TEXT, $outTpl);
   }
  return $outTpl;
}

$tpl = file_get_contents("news.tpl");
$tpl = preg_replace("#\[NEWS_FETCH_ROWS\](.+?)\[/NEWS_FETCH_ROWS\]#ies","ShowNews('\\1')", $tpl);


З.Ы. Мог и на мудрить не проверял.

Автор: alexey009 4.8.2008, 18:11
BaNaNaS, сообщения внимательно читал?
Цитата(alexey009 @  2.8.2008,  00:10 Найти цитируемый пост)
НА ПРИМЕРЕ SMARTY


Автор: alexey009 7.8.2008, 15:41
Вообщем понял, что смарти фуфлоsmile
И теперь соответственно вопрос!
Как задать цикл?
Код

@StartBlock@
//содержание
@EndBlock@

Все что между @Start@ и @End@ надо загнать в цикл. можно и в переменную..
 smile 

Автор: lisishe 23.8.2008, 22:07
Код

class parse_class
    {
    var $vars     = array();
    var $template;

    function get_tpl($tpl_name)
      {
      if(empty($tpl_name) || !file_exists($tpl_name))
        {
        return false;
        }
      else
        {
        $this->template  = file_get_contents($tpl_name);
        }
      }
    function set_tpl($key,$var)
      {
      $this->vars[$key] = $var;
      }
    function tpl_parse()
      {
      foreach($this->vars as $find => $replace)
             {
             $this->template = str_replace($find, $replace, $this->template);
             }
      }
    }
$parse = new parse_class;
$parse->get_tpl('tpl/file2compile.tpl'); //Файл который мы будем парсить 
$parse->set_tpl('{NRAMKA}',$uramka);
$parse->set_tpl('{KRAMKA}',$dramka);
$parse->set_tpl('{BLOKS}',$bloks);
$parse->set_tpl('{TITLE}','Супер сайт'); //Установка переменной {TITLE}
$parse->set_tpl('{BGCOLOR}','#F2F2F2'); //Установка переменной { BGCOLOR }
$parse->set_tpl('{SOMETPLTAGS}','<font color=red>Это тэстовый сайт</font>'); //Установка переменной {SOMETPLTAGS}

$parse->tpl_parse(); //Парсим

print $parse->template; //Выводим нашу страничку


шаблон

Код

<html>
<head>
<title>{TITLE}</title>
</head>
<body bgcolor={BGCOLOR}>
<div align="center">
<br/>
{SOMETPLTAGS}
<br/>
{NRAMKA}
{SOMETPLTAGS}
{KRAMKA}
<br/>
{NRAMKA}
<br/><br/>
{BLOKS}
<br/><br/>
{KRAMKA}
<br/><br/>
{BLOKS}
</div>
</body>
</html>


Можно ещё проще 
Ну а переменные можно формировать отдельно при чём через этот же класс

Автор: ktulh 3.9.2008, 19:04
Ну а почему бы не использовать нативный шаблон?
А если нужны повторяющиеся блоки, то просто их загонять в перменную а ее подключать в нужном месте основного шаблона.

Автор: ktulh 3.9.2008, 21:59
Тут подумал... есть ли способ сделать шаблоны пр помощи heredoc?

Автор: ktulh 4.9.2008, 11:23
index.tpl
Код

<html>
<title>$title</title>
<body>
$news
</body>
</html>

index.php
Код

$title="title";
$news="news message";
$tmpl=file_get_contents("./index.tpl");
$html= "echo <<<out\n".$tmpl."\nout;\n";
print eval($html);

НА выходе 
Код

<html>
<title>gsfd</title>
<body>
news message
</body>
</html>

загрузку шаблона можно по идее обернуть в функцию. а переменные передавать в качестве аргументов.
Хотя это и не обязательно. Они всреано продставляются из общего пространства.
Этот способ позволяет и подгражть какие-то внутренние шаблоны элементов.
Ток вот пока не думал на счет управляющих конструкции внутри шаблона.(а нужны ли они там, вет все можно сделать в скрипте.)

Автор: americanets 4.9.2008, 12:18
это не есть шаблонновсть 



M
MoLeX
Модератор: мат!!!!

Автор: ktulh 7.9.2008, 18:26
Привиде тогда пример шаблонизатора с использованием heredoc

Автор: americanets 8.9.2008, 08:29


Molex, чет не подумал сразу о том что на мат похоже , сори . 

Просто в eval , не очень правильно  пихать все

Автор: ktulh 9.9.2008, 21:48
И всеже жду предложения с использованием этого синтаксиса.

Автор: americanets 10.9.2008, 08:32
ktulh

на примере твоего синтаксиса есть вариант , он php называется smile 

file.tpl

Код

<br/>
echo $mainText;
<br/>



index.php

Код

$mainText = 'Text Text';
include 'file.tpl';

Автор: ktulh 10.9.2008, 20:51
ну с инклюдами или заменои это понятно.. мне то интересен именно способ реализации через heredoc  или его впринципе без использования евал нет?!

Автор: gta4kv 10.9.2008, 21:10
ktulh, а зачем вообще такая кривая реализация? Зачем шаблон выводить через eval!? И использовать для всего этого heredoc.. не понятно..

Автор: ktulh 11.9.2008, 13:54
Ну допустим так сказать зацикл небольшои.. просто инетресен увидеть именно этим способом... и впринципе не особо важно целесообразность его использования.. просто сам принцип...

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