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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> UD-Template classes - шаблонизатор. оцените работу скрипта. 
:(
    Опции темы
IZ@TOP
Дата 3.8.2004, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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

Возможности.
1) Обработка и замена строк.
2) Обработка циклов в шаблоне (вложенные циклы не поддерживаются).
3) Обработка условий в шаблонах (вложенные условия не поддерживаются).


Настройка, написания шаблонов и использование:
  • Служебные заголовки в шаблонах.
    В классе существует несколько настроечных параметров которые определяют необходимо ли обработать тот или иной тип блоков в шаблоне. По умолчанию этим настройкам присвоены следующие значения:
    $ParseVariable = 1 // Выполнять поиск и замену строковых констант в шаблоне.
    $ParseCondition = 0 // Выполнять поиск и замену условий в шаблонах.
    $ParseLoop = 0 // Выполнять поиск и замену циклов в шаблоне.

    Для того чтобы каждый раз не изменять код PHP для изменения данных параметров, предусмотрены заголовки в шаблонах, в которых можно устанавливать настроки класса по обработке блоков. Использование заголовков:
    Цитата
    <!--ud:header option = value-->

    Где option это имя настроечного параметра. Например
    Цитата
    <!--ud:header ParseLoop = 1-->
    Разрешит обработку циклов в шаблоне.
    Примечание: так же можно настройки изменять внутри РНР скрипта.
    Например:
    Цитата
    $TemplateClass->ParseLoop = 1;



  • Инициализация класса шаблонов.
    Цитата
    <?php
    include('library/template.class.php'); // Подключение файла с классом шаблонов.
    $Template = implode('', file('templates/template.htm')); // Чтение файла с шаблоном.
    $TemplateClass = new UD_TemplateDocument($Template); // Инициализация класса шаблонов и загрузка документа.
    // ...
    ?>



  • Использование констант под замену в шаблонах.
    Определение констант под замену оформляется следующим методом:
    Цитата
    --- template.htm
    <p>Привет %session_user_name%, Вы были у нас последний раз %session_user_last_visit%</p>

    При этом чтобы назначить замену констант, необходим следующий код:
    Цитата
    $TemplateClass->Assign('session_user_name', $_SESSION['user_name']);
    $TemplateClass->Assign('session_user_last_visit', $_SESSION['last_visit']);

    Есть еще один вариант назначения замены для шаблонных констант, который в некоторой степени упрощает определение большого количества переменных:
    Цитата
    $TemplateClass->Assign(
        array(
            'session_user_name',
            'session_user_last_visit',
        ),
        array(
            $_SESSION['name'],
            $_SESSION['last_visit'],
        )
    );



  • Использование условий в шаблонах.
    Синтаксис шаблонных условий:
    Цитата
    --- template.htm
    {if %variable == %variable2} какой то текст {endif}
    <!-- Есть еще один вариант такого блока: -->
    {if %variable == 12} какой то текст {elseif} ошибка. {endif}

    Так же можно включать в условия циклы и константы.
    Для обработки и сравнения переменных в условиях используются значение и имена переменных из таблицы констант. То есть чтобы сравнить variable и variable2 необходимо добавить их в таблицу констант:
    Цитата
    $TemplateClass->Assign('variable', 12);



  • Циклы в шаблонах.
    Синтаксис:
    Цитата
    ---- template.htm
    <!-- вариант 1: индексно-цифровой массив -->
    <table>
    {loop loop_name}
    <tr><td>key: @index</td><td>value: @loop_name</td></tr>
    {endloop}
    </table>
    Для объявления этого цикла необходимо добавить все необходимые атрибуты в таблицу циклов:
    Цитата
    $TemplateClass->AssignLoop('loop_name', array('a','b','c','d'), 'NUM');
    Первый аргумент функции принимает имя цикла. Второй - массив. Третий определяет тип индексов массива: существует два типа которые можно передать, это NUM и ASSOC. первый тип определен по умолчанию.
    Цитата

    <!-- вариант 2: индексно-цифровой массив многомерный -->
    <table>
    {loop loop_name}
    <tr><td>key: @index</td><td>value: @loop_name[0], @loop_name[1] ... etc</td></tr>
    {endloop}
    </table>

    Собственно второй вариант ни чем не отличается от первого, как по синтаксису так и по занесению в таблиццу циклов, за исключением добавление индексов к квадратных скобках. Скрипт сам определяет многомерность массива.
    Цитата
    <!-- вариант 3: индексно-ассоциативный массив -->
    <table>
    {loop loop_name}
    <tr><td>key: @index</td><td>value: @loop_name</td></tr>
    {endloop}
    </table>

    Вариант похож на первый, но разница в том что в качестве массива для обработки в таблицу циклов передается ассоциативный массив:
    Цитата
    $TemplateClass->AssignLoop('loop_name', array('a'=>1, 'b'=>2, 'c'=>3), 'ASSOC');

    Цитата
    <!-- вариант 4: индексно-ассоциативный многомерный массив -->
    <table>
    {loop loop_name}
    <tr><td>key: @index</td><td>value: @loop_name[key1], @loop_name[key2] ... etc</td></tr>
    {endloop}
    </table>

    Думаю комментарии излишни.


  • Компиляция шаблона.
    Компиляция шаблона производится с помощью класса UD_TemplateCompiler:
    Цитата
    $TemplateCompiler = new UD_TemplateCompiler($TemplateClass);
    После чего скомпилированный шаблон содержиться в перменной класса В_TemplateDocument Document:
    Цитата
    echo $TemplateClass->Document;




Файл класса шаблона:
Цитата
---- template.class.php
<?php
/* --------------------------------------------- */
// UD-TemplateDocument v1.2
// Класс для определения шаблонов.
// © 2004 Beer Artur (izatop at mail.ru)
// [#FileVersion 1.0]
/* --------------------------------------------- */

class UD_TemplateDocument {

var $Document   = '';     // Текст шаблона.

var $VarValues   = array();    // Значения шаблонных переменных.
var $VarKeys   = array();    // Ключи шаблонных переменных.
var $Variables   = array();    // Дублируемые шаблонные перемнные для обработки условий.
var $LoopTable   = array();    // Таблица шаблонных циклов.
var $LoopMatches  = array();    // Таблица циклов шаблона.
var $ConditionMatches = array();    // Таблица условий шаблона.

var $Headers   = array();    // Заголовки шаблона.
var $Options   = array(    // Опции компиляции шаблона.
        'Debug'    => 0,
        'ParseVariable'  => 1,
        'ParseCondition' => 0,
        'ParseLoop'   => 0,
       );
             // Конструктор.
function UD_TemplateDocument($Document = '') {
  $this->Document = $Document;
             // Чтение заголовков и определение опций компиляции.
  $this->SetParseOptions($this->GetDocumentHeaders());
}

function GetDocumentHeaders() {     // Обработка заголовков шаблона.
             // Регулярное выражение для поиска заголовков в шаблоне.
  $Preg = "|<!--\s?ud:header\s?([a-zA-Z0-9_]*)\s?=\s?([a-zA-Z0-9_]*)\s?-->|s";
             // Регулярное выражение для удаления служебных заголовков из шаблона.
  $PregR = "|\s?<!--\s?ud:header\s?([a-zA-Z0-9_]*)\s?=\s?([a-zA-Z0-9_]*)\s?-->\s?|s";
             // Найти все заголовки и поместить в массив Headers.
  preg_match_all($Preg, $this->Document, $this->Headers);
             // Удалить все заголовки из шаблона.
  $this->Document = preg_replace($PregR, '', $this->Document);
  return true;
}

function SetParseOptions() {     // Установить значения опций компиляции из шаблона заменив ими опции по умочанию.
  for($i = 0; $i < sizeof($this->Headers[1]); $i++) {
   $this->Options[$this->Headers[1][$i]] = $this->Headers[2][$i];
  }
}

function Assign($Key, $Value) {     // Инициализация переменных шаблона.
  if(is_array($Key)) {      // Может принимать как отдельные значения, так и массивы.
   for($i = 0; $i < sizeof($Key); $i++) {
    $this->VarValues[]   = $Value[$i];
    $this->VarKeys[]   = '%'.$Key[$i].'%';
    $this->Variables[$Key[$i]] = $Value;
   }
  } else {
   $this->VarValues[]  = $Value;
   $this->VarKeys[]  = '%'.$Key.'%';
   $this->Variables[$Key] = $Value;
  }
  return true;
}

             // Инициализация циклов шаблона.
function AssignLoop($Name, $Loop, $Mode = 'NUM') {
             // Принимает три аргумента:
             // имя шаблона, массив который нужно обработать и вставить в цикл шаблона
             // и режим обработки массива - как индексно числовой (NUM) или как индексно ассоциативный (ASSOC).
  $this->LoopTable[] = array(
   'Name' => $Name,
   'Loop' => $Loop,
   'Mode' => $Mode
  );
  return true;
}

function FindLoop() {       // Поиск шаблонных циклов.
             // регулярное выражение для поиска вхождений циклов в шаблоне.
  $Preg = "|{loop \s?([a-zA-Z0-9_]*)}(.*?){endloop}|s";
  preg_match_all($Preg, $this->Document, $Matches);
  if(isset($Matches[0][0])) {     // Преобразование полученных результатов для дальнейшей обработки в компиляторе.
   for($i = 0; $i < sizeof($Matches[0]); $i++) {
    $this->LoopMatches[$Matches[1][$i]][0] = $Matches[2][$i];
    $this->LoopMatches[$Matches[1][$i]][1] = $Matches[1][$i];
    $this->LoopMatches[$Matches[1][$i]][2] = $Matches[0][$i];
   }
   return true;       // Вернуть логическое "да" из функции при удачной обработке.
  } else {         // Если вхождений не найдено, функция возращает логическое нет.
   return false;
  }
}

function FindCondition() {      // Поиск шаблонных условий.
             // Регулярное выражение для поиска условий в шаблоне.
  $Preg = "|{if\s+?([a-zA-Z0-1_%]*)\s+?([=!<>]*)\s+?([a-zA-Z0-1_%]*)}(.*){endif}|s";
             // При нахождении консрукций шаблонных условий они заносятся в массив ConditionMatches.
  preg_match_all($Preg, $this->Document, $this->ConditionMatches);
  return true;
}
}

/* --------------------------------------------- */
// UD-TemplateCompiler v1.1
// Класс для компиляции объектов шаблонов.
// © 2004 Beer Artur (izatop at mail.ru)
// [#FileVersion 1.0]
/* --------------------------------------------- */

class UD_TemplateCompiler {

function UD_TemplateCompiler(&$Template) {  // Конструктор класса.
  $this->Compile($Template);
}

function Compile(&$Template) {     // Компилятор шаблонов.
  if($Template->Options['ParseCondition']) { // Если опция компиляции условий включена:
   $Template->FindCondition();    // найти все вхождения конструкций шаблонных условий.
   for($i = 0; $i < sizeof($Template->ConditionMatches[0]); $i++) {
             // Если в условных блоках шаблона не встречаются блоки "или":
    if(!strpos($Template->ConditionMatches[4][$i], '{else}')) {
             // Разбор условий на составляющии и их обработка.
     $l = str_replace('%', '', trim($Template->ConditionMatches[1][$i]));
     $c = trim($Template->ConditionMatches[2][$i]);
     $r = str_replace('%', '',trim($Template->ConditionMatches[3][$i]));
     if(!is_numeric($l)) @$l = $Template->Variables[$l];
     if(!is_numeric($r)) @$r = $Template->Variables[$r];
     switch($c) {
      case '==': {
       if($l == $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $Template->ConditionMatches[4][$i], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], '', $Template->Document);
       }
      }
      case '>': {
       if($l > $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $Template->ConditionMatches[4][$i], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], '', $Template->Document);
       }
      }
      case '<': {
       if($l < $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $Template->ConditionMatches[4][$i], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], '', $Template->Document);
       }
      }
      case '<=': {
       if($l <= $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $Template->ConditionMatches[4][$i], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], '', $Template->Document);
       }
      }
      case '>=': {
       if($l >= $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $Template->ConditionMatches[4][$i], $Template->Document);
       } else {
          $Template->Document = str_replace($Template->ConditionMatches[0][$i], '', $Template->Document);
       }
      }
      case '===': {
       if($l === $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $Template->ConditionMatches[4][$i], $Template->Document);
       } else {
          $Template->Document = str_replace($Template->ConditionMatches[0][$i], '', $Template->Document);
       }
      }
      case '!=': {
       if($l != $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $Template->ConditionMatches[4][$i], $Template->Document);
       } else {
          $Template->Document = str_replace($Template->ConditionMatches[0][$i], '', $Template->Document);
       }
      }
     }
    } else {       // Если в условных блоках шаблона встречаются блоки "или":
             // Разбор условий на составляющии и их обработка.
     $l = str_replace('%', '', trim($Template->ConditionMatches[1][$i]));
     $c = trim($Template->ConditionMatches[2][$i]);
     $r = str_replace('%', '',trim($Template->ConditionMatches[3][$i]));
     if(!is_numeric($l)) @$l = $Template->Variables[$l];
     if(!is_numeric($r)) @$r = $Template->Variables[$r];
     switch($c) {
      case '==': {
       if($l == $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       }
      }
      case '>': {
       if($l > $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       }
      }
      case '<': {
       if($l < $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       }
      }
      case '<=': {
       if($l <= $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       }
      }
      case '>=': {
       if($l >= $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       }
      }
      case '===': {
       if($l === $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       }
      }
      case '!=': {
       if($l != $r) {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       } else {
        $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
       }
      }
     }
    }
   }
  }
 
             // Компиляция шаблонных переменных:
  if($Template->Options['ParseVariable']) { // Если опции компиляции переменных включена.
             // Замена шаблонных перменных на значения.
   $Template->Document = str_replace($Template->VarKeys, $Template->VarValues, $Template->Document);
  } 
             // Компиляция шаблонных циклов:
  if($Template->Options['ParseLoop']) {  // Если опции компиляции циклов включены.
   if($Template->FindLoop()) {    // Поиск шаблонных циклов. Если функция вернула логическое "да" - обработать.
    for($i = 0; $i < sizeof($Template->LoopTable); $i++) {
             // Если режим обработки массива цикла равен ASSO:
     switch($Template->LoopTable[$i]['Mode']) {
      case 'ASSOC': {    // Обработать как индексно ассоциативный массив.
       $Key = key($Template->LoopTable[$i]['Loop']);
       if(is_array($Template->LoopTable[$i]['Loop'][$Key])) {
        foreach($Template->LoopTable[$i]['Loop'][$Key] as $key => $v) {
          $Fields[] = '@'.$Template->LoopTable[$i]['Name'].'['.$key.']';
        }
        foreach($Template->LoopTable[$i]['Loop'] as $Index => $Value) {
          $Temp[] = @str_replace('@index', $Index,
            str_replace($Fields, $Value,
              $Template->LoopMatches[$Template->LoopTable[$i]['Name']][0]));
        }
       } else {
        foreach($Template->LoopTable[$i]['Loop'] as $Index => $Value) {
          $Temp[] = @str_replace('@index', $Index,
            str_replace('@'.$Template->LoopTable[$i]['Name'], $Value,
              $Template->LoopMatches[$Template->LoopTable[$i]['Name']][0]));
        }
       }
       $Template->Document     = str_replace($Template->LoopMatches[$Template->LoopTable[$i]['Name']][2], implode('', $Temp), $Template->Document);
       break;
      } default: {    // Если возвращается любое противоположенное значению ASSOC (например NUM),
             // обработать как индексно числовой.
       if(is_array($Template->LoopTable[$i]['Loop'][0])) {
        $Size = sizeof($Template->LoopTable[$i]['Loop'][0]);
        for($i = 0; $j < $Size; $j++) {
         $Fileds[] = '@'.$Template->LoopTable[$j]['Name'].'['.$j.']';
        }
        for($j = 0; $j < sizeof($Template->LoopTable[$i]['Loop']); $j++) {
         $Temp[] = str_replace('@index', $j,
          str_replace($Fields, $Template->LoopTable[$i]['Loop'][$j],
           $Template->LoopMatches[$Template->LoopTable[$i]['Name']][0]));
        }
       } else {
        for($j = 0; $j < sizeof($Template->LoopTable[$i]['Loop']); $j++) {
         $Temp[] = str_replace('@index', $j,
          str_replace('@'.$Template->LoopTable[$i]['Name'], $Template->LoopTable[$i]['Loop'][$j],
           $Template->LoopMatches[$Template->LoopTable[$i]['Name']][0]));
        }
       }
             // Замена в шаблоне конструкций циклов на обработанные данные.
       $Template->Document = str_replace($Template->LoopMatches[$Template->LoopTable[$i]['Name']][2], implode('', $Temp), $Template->Document);
       break;
      }
     }
     unset($Temp);     // Удаление временной таблицы с обработанными данными.
    }
   }
  }
}
}
?>



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

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


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

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



IZ@TOP, а прикладные задачи у него какие? ИМХО, есть sablotron & xslt. Или я чего-то недопонял?



--------------------
Теперь при чем :P
PM   Вверх
IZ@TOP
Дата 3.8.2004, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Ignat
Это самый простой шаблонизатор с поддержкой циклов и условий. Задачи можно решать разные. Например построение каталога или вообще использование как шаблонного движка для сайта. Все зависит от целей.


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

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


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

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



//offtop (навеяло)
IZ@TOP, у меня есть идея "нарисовать" движок сайта на php для xml/xslt-шаблонами и CMS-ку. Ничего подобного не замышлял?



--------------------
Теперь при чем :P
PM   Вверх
IZ@TOP
Дата 3.8.2004, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Ignat
Замышлял. Но, почему именно на xml/xslt? Просто я считаю что это не всем доступно, а смена HTML шаблонов немножко проще будет. Хотя конечно можно подумать над этой идеей.


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

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


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

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



xml/xslt - это перспектива, если пользоваться трансформом на сервере, то к клиенту придет тот же HTML, но как и задумывали разработчики в данном случае информация отделена от представления. В будущем можно безболезненно перейти на клиентский трансформ - IE с версии 5.5 поддерживает, а мозилла ни фига.


--------------------
Теперь при чем :P
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Веб-разработка, идеи, проектирование"
Illuminaty
dr.ZmeY

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

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

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

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

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

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

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

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

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

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

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


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

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


 




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


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

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