template, how

Name

Новичок
template, how

Пытаюсь сделать для себе несложный template engine.

Как Просто подставлять значение вместо {name} ясно.

Бывает что то и посложнее
Ну вот например в том же guestbooke
если заполнено поле email

Без шаблонов пишем, например
if($email)
echo <a href="mailto:">$name</a>
else
echo $name

И как такго добиться чтоб в самом шаблоне ни строчки кода
а в коде никаких <a href....

Может кто делал подобное. Any ideas.
 

ForJest

- свежая кровь
А есть еще такое понятие как блоки. Если переменная в блоке установлена, то он парсится. Если не установлена, то не парсится.
 

su1d

Старожил PHPClubа
зачем делать engine, когда всё уже сделано? =)
 

EkyT

Guest
чтобы реализовать такую конструкцию уже нужен не простенький парсер

в темплейте должно быть что то вроде
{if EMAIL} <a href="mailto:{EMAIL}">{NAME}</a>{endif EMAIL}
{ifnot EMAIL}{NAME}{endif EMAIL}

а в коде парсера соответственно вылавливать такие условия примерно как
preg_match("/\{if (\w+)\}/", $line, $matches);
if ($matches)
{
$m=$matches[1];
preg_match("/\{if $m\}(\s*)(.*?)(\s*)\{endif $m\}/Ss", $line, $matches1);
// а тут долгая и нудная разборка содержимого, потому что условия могут быть вложенными да и чорт знает что вообще
}
 

.des.

Поставил пиво кому надо ;-)
su1d было бы неплохо если бы ты еще и (подмигивая) как обещал документацию расширил - практическими примерами.. ;)
вот set_global приведи примеры использования...
просто многое не интуитивно понятно.. я например пытался понять изменяет ли iterate путь или нет.. так как долго не спал .. то у меня на это ушло времени :(
русского не надо онли english
я сейчас очень радуюсь что заставил твой движок работать с Zend Studio :)
 

su1d

Старожил PHPClubа
su1d было бы неплохо если бы ты еще и (подмигивая) как обещал документацию расширил - практическими примерами
сдЭлаем..
на этих выходных - вряд ли.. может на следующих..
 

jeka!

Просто Member
Я конечно немного не в тему хочу спросить...
Можно ли загонять код типа:
PHP:
   $tpl    = new template;
   $tpl   -> load_file('file', '../../design/news/news.htm');
   $tpl   -> register('file', 'meta_t,meta_d,meta_k,title,images,news,id');
   $tpl   -> parse('file');
   $output = $tpl -> return_file('file');
в функцию?

В общем у меня всё прекрасно работает, но, когда я загоняю это дело в функцию, то переменные не обрабатываются, вернее они подменяются нулевым значением...
Смотрел всякие примеры, типа форум phpBB но там ничего подоюбного не нашел, это реально?
 

.des.

Поставил пиво кому надо ;-)
jeka! не совсем тебя понял.. но кажется тебе стоит почитать о Variables scope
Приведенный выше твой код в принципе должен работать и в функции.
покажи свой реальный пример. Что у тебя не работает?
вот если ты создашь объект вне функции то в функции он виден не будет. и наоборот кстати тоже.
ну вообщем пройди по ссылке - в мануале все доходчиво описано.
 

jeka!

Просто Member
Хорошо, вот что именно я хотел поместить в функцию, чтоб потом вставлять её в разные части скрипта, а не копировать всё тело несколько раз:
Эта фича создайт хтмл страницы новостей.
PHP:
<?php
 ...
   /* --- Шаблон --- */
   $meta_t = title($row[5]);            # Мета тег - TITLE
   $meta_d = description($row[4]);      # Мета тег - DESCRIPTION
   $meta_k = keywords($row[5].$row[4]); # Мета тег - KEYWORDS
   $title  = $row[5];                   # Заголовок новости
   $id     = $row[0];                   # Идентификатор новости
   $news   = $row[4];                   # Текст новости
   $tpl    = new template;
   $tpl   -> load_file('file', '../../design/news/news.htm');
   $tpl   -> register('file', 'meta_t,meta_d,meta_k,title,images,news,id');
   $tpl   -> parse('file');
   $output = $tpl -> return_file('file');
   /* --- Шаблон --- */
   // Создать страницу
   $fp = fopen($c_dir."/".$row[0].".html","w+");
   fputs($fp, $output, strlen($output));
   fclose($fp);
   $fo = fopen($c_dir."/".$row[0]."_c.htm","w+");
   fputs($fo, "");
   fclose($fo);
 ...
?>
Эту часть можно было бы поместить в функцию.
Может в Global надо чего помещать?
 

.des.

Поставил пиво кому надо ;-)
мда.. :( когда я просил пример - не имелось ввиду столько кода. Вообщем так - запомни в функции ничего не известно про переменные объявленные и инициализированные в других частях программы, в частности $db (,..etc) в твоем примере
то есть если ты хочешь что то сделать в функции, тебе надо передать необходимые ей для работы в качестве параметров.
Или же обращаться к ним через $GLOBALS (но параметры лучше).
Далее если функция оперирует с данными и они тебе модифицированные нужны впоследствии, ты должен эти данные возвращать при помощи return или же передавать в параметрах по ссылке. по ситуации.
Обо всем об этом написано в мануале (ссылку я тебе привел). Захочешь прочтешь.
 

jeka!

Просто Member
Да, спасибо, читаю, но это на долго, надо всё потестить...
Просто я с классами раньше не работал, и собственно сталкнулся с такой вот проблемой.
Попробую...
 

.des.

Поставил пиво кому надо ;-)
Да не в классах дело. Variables scope переводится как область видимости ПЕРЕМЕННЫХ.
Простой пример:
PHP:
$a=1
function foo()
{
   echo $a;
}
Что выведет?
правильно ничего. - Undefined variable
Потому что в функции ничего не известно о глобальной переменной $a
чтобы получить к ней доступ можно поступить следующим образом
PHP:
$a=1
function foo()
{
   echo $GLOBALS["a"];
}

// Или так
$a=1
function foo()
{
    global $a;   
    echo $a;
}
// или так
 

jeka!

Просто Member
Я понял, и прекрасно это знаю... ты просто наверное не правильно меня понял...
С переменными, это одно дело, а из за чего не работает класс я не знаю, пример:
Я беру вот этот кусок, из файла выше:
PHP:
function template($images, $c_dir, $row и т.д.) {
   $meta_t = title($row[5]);            # Мета тег - TITLE 
   $meta_d = description($row[4]);      # Мета тег - DESCRIPTION 
   $meta_k = keywords($row[5].$row[4]); # Мета тег - KEYWORDS 
   $title  = $row[5];                   # Заголовок новости 
   $id     = $row[0];                   # Идентификатор новости 
   $news   = $row[4];                   # Текст новости 
   $tpl    = new template; 
   $tpl   -> load_file('file', '../../design/news/news.htm'); 
   $tpl   -> register('file', 'meta_t,meta_d,meta_k,title,images,news,id'); 
   $tpl   -> parse('file'); 
   $output = $tpl -> return_file('file'); 
   /* --- Шаблон --- */ 
   // Создать страницу 
   $fp = fopen($c_dir."/".$row[0].".html","w+"); 
   fputs($fp, $output, strlen($output)); 
   fclose($fp); 
   $fo = fopen($c_dir."/".$row[0]."_c.htm","w+"); 
   fputs($fo, "");
   fclose($fo);
return 1;
}
# на а том месте, от куда я это вытащил, веставляю:
template($images, $c_dir, $row и т.д.);
Естественно, что все переменные функции теперь известны, но прекращает работать класс!!!
Умерает именно
PHP:
$tpl   -> register('file', 'meta_t,meta_d,meta_k,title,images,news,id');
,
а всё остальное работает, страница создаётся, но пустая...
Вот и проблема вся в том, что я не знаю из за чего???
Я же не могу в глобале указать типа Global new template,$tpl;

Вернее конкретно, работает всё, кроме register, выходит страница с дизайном, но без данных.
 

.des.

Поставил пиво кому надо ;-)
хм.. покажи-ка мне метод register этого класса .. я кажется догадываюсь в чем дело.
$tpl -> register
 

jeka!

Просто Member
Прости, сами классы пока ещё не понимаю, по этому приведу его почти полностью, всё не относящиеся к делу вырезал...
PHP:
class template {
 ...

function traverse_array($file_id, $array){
    while(list(,$value) = each($array)){
            if(is_array($value)) $this -> traverse_array($file_id, $value);
            else $this -> var_names[$file_id][] = $value;
            }
}
function register($file_id, $var_name){
     if(is_array($var_name)){
     $this -> traverse_array($file_id, $var_name);
     }elseif($var_name != ''){
                 if(is_long(strpos($var_name, ',')) == TRUE){
                 $var_name = explode(',', $var_name);
                 for(reset($var_name); 
                 $current = current($var_name);
                 next($var_name)) $this -> var_names[$file_id][] = trim($current);
                }else{
                $this -> var_names[$file_id][] = $var_name;
                }
     }
}
function parse($file_id){
 ...
 for($i=0; $i < sizeof($this -> var_names[$file_id]); $i++){
     $temp_var = $this -> var_names[$file_id][$i];
     global $$temp_var;
 ...
      }
 }
 ...
}
 

.des.

Поставил пиво кому надо ;-)
хех... видно ты решил не мелочиться и запостить весь класс...
спасибо ты мне очень облегчил задачу..
ошибка вот в этих строках.
$temp_var = $this -> var_names[$file_id][$i];
global $$temp_var;
Переменные в функции не являются глобальными..
как ее решать ну можешь попробовать так
PHP:
$GLOBALS["meta_t"] = title($row[5]);            # Мета тег - TITLE 
   $GLOBALS["meta_d"] = description($row[4]);      # Мета тег - DESCRIPTION 
   $GLOBALS["meta_k"] = keywords($row[5].$row[4]); # Мета тег - KEYWORDS 
   $GLOBALS["title"]  = $row[5];                   # Заголовок новости 
   $GLOBALS["id"]     = $row[0];                   # Идентификатор новости 
   $GLOBALS["news"]   = $row[4];
То есть все переменные регистрируемые в классе должны быть глобальными.
вообще идея очень странная... но раз выбрал этот класс вот и придется так решать трудности.
 
Сверху