Модераторы: Illuminaty
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> PHP шаблоны 
:(
    Опции темы
Master
  Дата 18.2.2004, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1530
Регистрация: 13.5.2003
Где: Mother Russia

Репутация: нет
Всего: 10



Вот написал свой первый парсер шаблонов на PHP!
Зацените:
есть 3 типа данных
1) HTML текст
2) PHP сценарий
3) Обычный текст

Код
<?php

$cap = '<FONT style="font-size:20px;">Шапка страницы</FONT><BR><BR>';
$menu = 'echo "Менюшка<BR><BR>";';
$content = 'Содержимое страницы содержимое страницы содержимое страницы содержимое страницы содержимое страницы
содержимое страницы содержимое страницы содержимое страницы содержимое страницы содержимое страницы
содержимое страницы содержимое страницы содержимое страницы содержимое страницы содержимое страницы
содержимое страницы содержимое страницы содержимое страницы содержимое страницы содержимое страницы
содержимое страницы содержимое страницы содержимое страницы содержимое страницы содержимое страницы
содержимое страницы содержимое страницы содержимое страницы содержимое страницы содержимое страницы
содержимое страницы содержимое страницы содержимое страницы содержимое страницы содержимое страницы
содержимое страницы содержимое страницы содержимое страницы содержимое страницы содержимое страницы';



class shablone_mod {
var $shablone = '';
var $page = '';

function shablone_load($source) {
 $s_file = fopen($source,"r");

 if ($s_file) {
  while (!feof($s_file)) {
   $this->shablone .= fgets($s_file,1024);
  }
 }
}

function shablone_replace() {

 $this->page = preg_replace_callback(
  "%{([^:]*):([^}]*)}%",
  create_function (
   '$results',
   '
    if ($results["1"]=="html_result") {
     global ${$results["2"]};
     return ${$results["2"]};
    }
    if ($results["1"]=="php_result") {
     global ${$results["2"]};
     ob_start();
     eval(${$results["2"]});
     $php_result = ob_get_contents();
     ob_end_clean();
     return $php_result;
    }
    if ($results["1"]=="txt_result") {
     global ${$results["2"]};
     return nl2br(htmlspecialchars(${$results["2"]}));
    }
   '
  ),
  $this->shablone
 );

 return $this->page;
}

}

$shablone_mod = new shablone_mod;
$shablone_mod->shablone_load("shablones/shablone.txt");
$shablone_mod->shablone_replace();
echo $shablone_mod->page;

?>


Код
<HTML>
<HEAD>
 <TITLE></TITLE>
</HEAD>

<BODY>
{html_result:cap}
{php_result:menu}
{txt_result:content}
</BODY>
</HTML>


Есть предложения по улутшению?


--------------------
Вавилон, Вавилон
Что ты построил, что разрушил?
Вавилон, Вавилон
Плавятся души дьявольским огнем.
PM WWW ICQ   Вверх
Master
Дата 20.2.2004, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1530
Регистрация: 13.5.2003
Где: Mother Russia

Репутация: нет
Всего: 10



Изменил регулярное выражение.

Код
%(?=[^\\\]){([^:]*):([^}]*[^\\\])}%

теперь есть возможность ставить не интерпритируемые символы {} предворяя их слешем.


--------------------
Вавилон, Вавилон
Что ты построил, что разрушил?
Вавилон, Вавилон
Плавятся души дьявольским огнем.
PM WWW ICQ   Вверх
mr.DUDA
Дата 25.2.2004, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: нет
Всего: 232



Master, а что насчёт включения (inclusion) одного шаблона другим ?


--------------------
user posted image
PM MAIL WWW   Вверх
Master
Дата 1.3.2004, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1530
Регистрация: 13.5.2003
Где: Mother Russia

Репутация: нет
Всего: 10



Добавил обработку включения подшаблонов.
Для их вызова используется синтаксис: {include:путь_к_файлу}

Версия Master'S^E 1.1 выглядит так:

Код
class shablone_mod {
var $shablone = '';
var $page = '';

function shablone_load($source) {
 $s_file = fopen($source,"r");

 if ($s_file) {
  $str = '';
  while (!feof($s_file)) {
   $str .= fgets($s_file,1024);
  }
  $this->shablone = $str;
 }

 #print_r($this->shablone);
}

function shablone_replace() {


 $this->page = preg_replace_callback(
  "%(?=[^\\\]){([^:]*):([^}]*[^\\\])}%",
  create_function (
   '$results',
   '
    if ($results["1"]=="html_result") {
     global ${$results["2"]};
     return ${$results["2"]};
    } elseif ($results["1"]=="php_result") {
     global ${$results["2"]};
     ob_start();
     eval(${$results["2"]});
     $php_result = ob_get_contents();
     ob_end_clean();
     return $php_result;
    } elseif ($results["1"]=="txt_result") {
     global ${$results["2"]};
     return nl2br(htmlspecialchars(${$results["2"]}));
    } elseif ($results["1"]=="include") {
     global $shablone_mod;
     $shablone_mod->shablone_load($results["2"]);
     return $shablone_mod->shablone_replace();
    }
   '
  ),
  $this->shablone
 );

 $this->page = str_replace("\{","{",$this->page);
 $this->page = str_replace("\}","}",$this->page);

 return $this->page;
}

}


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

Хотя например построение менюшки в виде:


Код
<TABLE>
<TR>
 {foreach:ключ, значение as массив} {
  <TD><A href="?{ключ}">{значение}</A></TD>
 }
</TD>
</TABLE>


выглядит довольно симпатично и мы отделяем PHP от HTML практически полностью...


--------------------
Вавилон, Вавилон
Что ты построил, что разрушил?
Вавилон, Вавилон
Плавятся души дьявольским огнем.
PM WWW ICQ   Вверх
IZ@TOP
Дата 1.3.2004, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: нет
Всего: 73



Даешь циклы в TPL!


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
Vaulter
Дата 1.3.2004, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1724
Регистрация: 30.12.2002
Где: бункер

Репутация: нет
Всего: 22



Iz@top
Master
даешь ((PHP в HTML) в PHP) и все это в HTML!!!!


--------------------
PM MAIL WWW ICQ   Вверх
Master
Дата 3.3.2004, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1530
Регистрация: 13.5.2003
Где: Mother Russia

Репутация: нет
Всего: 10



Цитата
даешь ((PHP в HTML) в PHP) и все это в HTML!!!!

чего чего?

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


--------------------
Вавилон, Вавилон
Что ты построил, что разрушил?
Вавилон, Вавилон
Плавятся души дьявольским огнем.
PM WWW ICQ   Вверх
Master
Дата 3.3.2004, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1530
Регистрация: 13.5.2003
Где: Mother Russia

Репутация: нет
Всего: 10



Теперь класс может обрабатывать включение исполняемого шаблона:

Код
class shablone_mod {
var $shablone = '';
var $page = '';

function shablone_load($source) {
 $s_file = fopen($source,"r");
 if ($s_file) {
  $str = '';
  while (!feof($s_file)) {
   $str .= fgets($s_file,1024);
  }
  $this->shablone = $str;
 }
}

function shablone_load_eval($source) {
 $s_file = fopen($source,"r");
 if ($s_file) {
  $str = '';
  while (!feof($s_file)) {
   $str .= fgets($s_file,1024);
  }
  $str = "?>".$str;
  ob_start();
  eval($str);
  $php_result = ob_get_contents();
  ob_end_clean();
  $this->shablone = $php_result;
 }
}

function shablone_replace() {


 $this->page = preg_replace_callback(
  "%(?=[^\\\]){([^:]*):([^}]*[^\\\])}%",
  create_function (
   '$results',
   '
    if ($results["1"]=="html_result") {
     global ${$results["2"]};
     return ${$results["2"]};
    } elseif ($results["1"]=="php_result") {
     global ${$results["2"]};
     ob_start();
     eval(${$results["2"]});
     $php_result = ob_get_contents();
     ob_end_clean();
     return $php_result;
    } elseif ($results["1"]=="txt_result") {
     global ${$results["2"]};
     return nl2br(htmlspecialchars(${$results["2"]}));
    } elseif ($results["1"]=="include") {
     global $shablone_mod;
     $shablone_mod->shablone_load($results["2"]);
     return $shablone_mod->shablone_replace();
    } elseif ($results["1"]=="include_eval") {
     global $shablone_mod;
     $shablone_mod->shablone_load_eval($results["2"]);
     return $shablone_mod->shablone_replace();
    }
   '
  ),
  $this->shablone
 );

 $this->page = str_replace("\{","{",$this->page);
 $this->page = str_replace("\}","}",$this->page);

 return $this->page;
}

}



--------------------
Вавилон, Вавилон
Что ты построил, что разрушил?
Вавилон, Вавилон
Плавятся души дьявольским огнем.
PM WWW ICQ   Вверх
Master
Дата 23.3.2004, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1530
Регистрация: 13.5.2003
Где: Mother Russia

Репутация: нет
Всего: 10



Усовершенствованая версия шаблона:
Много всяких фишок добавил. Все в коментариях перед функциями.
Сейчас перехожу на использование register_globals off т.к. своими глазами обнаружил проблему.
Данные из $_GET['var'] читаются из класса нормально в то время как $var даже при включенов рг не читаются из класса без импорта во внутренний объект.

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

Оценивайте сами:

Код
class template_mod {

# Массив с переменными для шаблона
var $content = Array();
# Массив Шаблона
var $templates = Array();

# Готовое содержимое страницы
var $page = '';

# Переменая управления ошибками.
     # Если on, при обнаружении ошибки выполнение прерывается и выдается сообщение об ошибке.
     # В противном случае ошибки игнорируются.
var $template_error_rep = 'on';

# Массив описания ошибок.
var $template_errors = Array(
 '1' => 'Undefined variable', # Переменная не определена
 '2' => 'File not exists', # Файл не найден
 '3' => 'Undefined method', # Метод не определен
);


# Приватная функция обработки ошибок в шаблонах
function pm_template_error($source,$err_num) {
 if ($this->template_error_rep=="on") {
   echo '<B>template_mod error:</B> "<U>'.$source.'</U>" '.$this->template_errors[$err_num];
   exit;
 }
}

# Функция загрузки массива из переменных для содержимого шаблона и интерпритация их как шаблонов
function template_load_content($content) {
 $this->content = $content;
 foreach ($this->content as $key=>$value) {
  $this->pm_template_var_parse($key);
 }
}

# Функция загрузки шаблона и интерпретация его как текст
# Функция проверяет был ли загружен текущий шаблон или нет
# Функция проверяет существует ли указанный файл. Возвращает false если файл не найден.
function template_load($source) {
 if (isset($this->templates[$source])) {
  return true;
 } else {
  if (file_exists($source)) {
   $s_file = fopen($source,"r");
   if ($s_file) {
    $str = '';
    while (!feof($s_file)) {
     $str .= fgets($s_file,1024);
    }
    $this->templates[$source] = $str;
   }
   return true;
  } else {
   $this->pm_template_error($source,2);
   return false;
  }
 }
}

# Функция загрузки шаблона и интерпретация его как PHP код
# Функция проверяет был ли загружен и выполнен как PHP код текущий шаблон или нет
# Функция проверяет существует ли указанный файл. Возвращает false если файл не найден.
function template_load_eval($source) {
 if (isset($this->templates[$source])) {
  return true;
 } else {
  if (file_exists($source)) {
   $s_file = fopen($source,"r");
   if ($s_file) {
    $str = '';
    while (!feof($s_file)) {
     $str .= fgets($s_file,1024);
    }
    $str = "?>".$str;
    ob_start();
    eval($str);
    $php_result = ob_get_contents();
    ob_end_clean();
    $this->templates[$source] = $php_result;
   }

   return true;
  } else {
   $this->pm_template_error($source,2);
   return false;
  }
 }
}

# Приватная функция замены интерпретаторов на результаты их обработки
function pm_template_replace($results) {
 switch ($results['1']) {
  case 'html_result': # Вставка переменной в виде HTML текста
   if (isset($this->content[$results['2']])) {
    return $this->content[$results['2']];
   } else {
    $this->pm_template_error($results['2'],1);
   }
  case 'php_result': # Вставка переменной в виде исполняемого PHP кода
   if (isset($this->content[$results['2']])) {
    ob_start();
    eval($this->content[$results['2']]);
    $php_result = ob_get_contents();
    ob_end_clean();
    return $php_result;
   } else {
    $this->pm_template_error($results['2'],1);
   }
  case 'txt_result': # Вставка переменной в виде простого текста с преобразованиями HTML кода в визуальное представление
   if (isset($this->content[$results['2']])) {
    return nl2br(htmlspecialchars($this->content[$results['2']]));
   } else {
    $this->pm_template_error($results['2'],1);
   }
  case 'include':  # Загрузка шаблона
   if (file_exists($results['2'])) {
    $this->template_load($results['2']);
    return $this->template_parse($results['2']);
   } else {
    $this->pm_template_error($results['2'],2);
   }
  case 'include_eval': # Загрузка и исполнение шаблона PHP интерпретатором
   if (file_exists($results['2'])) {
    $this->template_load_eval($results['2']);
    return $this->template_parse($results['2']);
   } else {
    $this->pm_template_error($results['2'],2);
   }
  default:   # Определение неопознанного метода и вызов ошибки
    $this->pm_template_error($results['1'],3);
  }
 }

# Функция парсинга указанного файла шаблона на поиск интерпретаторов.
# Если шаблон не был загружен функция пытается его загрузить 1 раз.
function template_parse($source) {
 if (isset($this->templates[$source])) {
  $this->page = preg_replace_callback(
   "%(?=[^\\\]){([^:]*):([^}]*[^\\\])}%",
   array($this,'pm_template_replace'),
   $this->templates[$source]
  );

  $this->page = str_replace("\{","{",$this->page);
  $this->page = str_replace("\}","}",$this->page);

  return $this->page;
 } else {
  if ($this->template_load($source)) {
   $this->template_parse($source);
  }
 }
}

# Приватная функция парсинга переменной из загруженного массива content на поиск интерпретаторов.
function pm_template_var_parse($key) {
 $this->content[$key] = preg_replace_callback(
  "%(?=[^\\\]){([^:]*):([^}]*[^\\\])}%",
  array($this,'pm_template_replace'),
  $this->content[$key]
 );

 $this->content[$key] = str_replace("\{","{",$this->content[$key]);
 $this->content[$key] = str_replace("\}","}",$this->content[$key]);

 return true;
}

}



--------------------
Вавилон, Вавилон
Что ты построил, что разрушил?
Вавилон, Вавилон
Плавятся души дьявольским огнем.
PM WWW ICQ   Вверх
Master
Дата 23.3.2004, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1530
Регистрация: 13.5.2003
Где: Mother Russia

Репутация: нет
Всего: 10



Сейчас вот столкнулся с проблемой... если парсится шаблон и в нем есть {text-decoration:none} (описание стиля), то интерпритатор вызывает ошибку не найдя метод text-decoration...

и сейчас либо:
1) пофиксить баг указав иной синтаксис шаблона... например {%mt:value%}
2) расчитывать на сообразительность кодера... в том, что он вынетет стили за пределы шаблона.


--------------------
Вавилон, Вавилон
Что ты построил, что разрушил?
Вавилон, Вавилон
Плавятся души дьявольским огнем.
PM WWW ICQ   Вверх
IZ@TOP
Дата 23.3.2004, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: нет
Всего: 73



Master, предлагаю использовать изменяемый синтаксис шаблона. например в моем классе для обработки шаблонов есть такие вот переменные - $this->stag = "<%"; и $this->etag = "%>";. Очень удобно. А для циклов иные - $this->loop_stag = "<#";, и $this->loop_etag = "#>";.

Цитата
2) расчитывать на сообразительность кодера... в том, что он вынетет стили за пределы шаблона.
Нет, на это лучше не пологаться biggrin.gif Знаем мы этих кодеров tounge.gif

Добавлено @ 23:39
Вообще ни чего классик получился, но что то мне вот не нравится preg_replace_callback sad.gif Хотя может в нем и ни чего плохого и нет...
Мастер, ждем когда добавишь возможность обработки циклов. Я например в своих проектах в шаблонах очень часто их использую, очень полезно при построении прайс-листа, новостей и т.п.

PS Если интересно, могу кинуть сюда свой класс для парсинга шаблонов smile.gif Если кому не лень будет замерить производительность (не сомневаюсь что у Мастера она выше, но все же), то прошу smile.gif


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
Master
Дата 24.3.2004, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1530
Регистрация: 13.5.2003
Где: Mother Russia

Репутация: нет
Всего: 10



Iz@top
я сейчас не особо тороплюсь делать циклы... может позже.
сейчас у меня трабл с парсингом... потом я хочу сделать сохранение ошибок в массив и выводить в самом конце например и ещё сохранять в лог и ещё определять строку шаблона в которой написан не корректный интерпритатор. потом думаю организовать выборку шаблонов из БД.
Добавлено @ 09:05
а идея с $this->tag мне пондравилась.


--------------------
Вавилон, Вавилон
Что ты построил, что разрушил?
Вавилон, Вавилон
Плавятся души дьявольским огнем.
PM WWW ICQ   Вверх
Master
Дата 24.3.2004, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1530
Регистрация: 13.5.2003
Где: Mother Russia

Репутация: нет
Всего: 10



Iz@top про скорость скриптов очень хорошая статья есть:
http://php.spb.ru/php/speed.html


--------------------
Вавилон, Вавилон
Что ты построил, что разрушил?
Вавилон, Вавилон
Плавятся души дьявольским огнем.
PM WWW ICQ   Вверх
IZ@TOP
Дата 24.3.2004, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Панда-бир!
****


Профиль
Группа: Участник
Сообщений: 4795
Регистрация: 3.2.2003
Где: Бамбуковый лес

Репутация: нет
Всего: 73



Master, сенкс. Я много нового узнал... полез переделывать свой движок для парсинга шаблонов hmmm.gif

Добавлено @ 22:15
И еще, я тут прикалывался, точнее не совсем прикалывался, я делал отлов в шаблоне неотпарсенных %констант%, и заменял на предупреждение при выставлении соответствующей функции в true.


--------------------
Один из розовых плюшевых-всадников апокалипсиса... очень злой...

Семь кругов ада для новых элементов языка
Мои разрозненные мысли
PM MAIL WWW ICQ Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Веб-разработка, идеи, проектирование"
Illuminaty
dr.ZmeY

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

2. В этом разделе проводится обсуждение дизайна готовых сайтов, рабочих web-проектов, web-макетов, а также сами идеи и перспективы ресурсов.

3. Обсуждение отдельных элементов (логотипов, баннеров, анимации и т.п.) проводится здесь

4. В разделе запрещается

   а) предлагать на обсуждение форумы, чаты, гостевые книги, имеющие стандартный движок без собственного дизайнерского оформления;

   б) рекламировать какой-либо проект;

   в) предлагать купить web-проект, работу, модераторство, зарегистрироваться в разделах web-ресурса;

   г) спрашивать о возможной стоимости проекта.

Указанные сообщения будут удаляться без предупреждения(!)

5. При создании новой темы (обсуждение конкретного ресурса) необходимо указать: в названии темы - название вашего проекта, в описании темы - адрес, в топике - вопрос и ссылку

6. Все сообщения, касаемые критики сайта, не содержащие какие-либо собственные предложения будут удаляться!


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Illuminaty, dr.ZmeY.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Стартапы, проекты, идеи | Следующая тема »


 




[ Время генерации скрипта: 0.1127 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.