TTemplate - это класс, который непосредственно генерирует html страницы, используя шаблоны темы. Чтобы понять, как работает TTemplate надо знать, как устроены шаблоны (темы) в блоголёте, а шаблоны в блоголёте устроены очень просто: это самый обычный html, без каких либо особых требований. TTemplate загружает файл шаблона и его обрабатывает, выдавая на выходе уже готовую html страницу. Обработка шаблона сводится к простому действию - текст шаблона принимается как будто это строка (string) в php, таким образом все переменные в строке заменяются их значениями. Приведем пример - это одна строка из каждого файла шаблона блоголёта:


<title>$Template->title</title>

В результате тег title в html странице будет иметь значение свойства title объекта $Template. Дальше начинается самое интересное. В блоголете свойства объектов могут вызывать соответствующие методы, а конкретно для этого случая будет вызван метод Gettitle(). Это простой трюк, чтобы в обычный html текст внедрить вызов php функций при этом никак не нарушая читабельность исходного html, дав тем самым вэбмастеру свободу в создании тем для блоголёта. Не нужно более продираться сквозь нагромождения конструкций вида:


<title><?php echo ?$Template->title; ?></title>

Принятие такой парадигмы шаблонов в блоголёте является реализацией концепции разделения кода и представлений. То есть удалось красиво разделить исполняемый php код и html, сделав их друг от друга независимыми.

Если пойти дальше по цепочке и посмотреть исходный код метода Gettitle, то мы увидим следующее:


public function Gettitle() {
  global $Options;
  $result = '';
  if ($this->DataObject->PropExists('title')) {
   $result = $this->DataObject->title;
  }
  if (empty($result)) {
   $result = $Options->name;
  } else {
   $result = "$result | $Options->name";
  }
  return $result;
}

Мы увидим в этом участке кода использование объекта DataObject - это как раз тот самый объект, который был найден по урлу в классе TUrlmap и передан в TTemplate для генерации html страницы.

Одним из центральных свойств в TTemplate является content. Как правило шаблон устроен достаточно стандартно - html заголовок, меню, контент, сайтбар, подвал. И как правило html страницы отличаются друг от друга контентом - его центральной частью, имея все остальное одинаковое - шапку, меню, сайтбар и подвал. Поэтому одна из основных концепций класса TTemplate является возможность предоставить объекту DataObject генерировать контент, который будет вставлен в получившийся html. Объект DataObject может отдавать контент несколькими способами - посмотрим исходный код метода Getcontent в классе TTemplate:


public function Getcontent() {
  $result = $this->BeforeContent();
  if (empty($result)) $result = '';
  if (method_exists($this->DataObject, 'GetTemplateContent')) {
   $result .= $this->DataObject->GetTemplateContent();
  } elseif ($this->DataObject->PropExists('content')) {
   $result .= $this->DataObject->content;
  }

$result .= $this->AfterContent();
  return $result;
}

Переводя код на человеческий язык - если можно , то вызываем метод GetTemplateContent, иначе пытаемся получить значение свойства content объекта DataObject. На уровне класса TTemplate совсем не важно, как и откуда объект получит контент. В результате мы имеем унифицированный подход к получению контента, например класс THomepage (главная страница) возвращает текст сгенерированный из анонсов записей. Забегая вперед можно раскрыть еще один секрет блоголёта - DataObject для отдачи контента может и использует тот же самый механизм генерации html на основе других файлов шаблона, например записи используют шаблон из файла post.tml текущей темы. Главным файлом шаблона является файл index.tml. Таким образом мы получаем вложенную в друг друга обработку файлов шаблона.

Получается простая иерархия файлов шаблонов: на верхнем уровне файл index.tml, в котором находится макет всей html страницы. На следующем уровне уже идут шаблоны анонса postexcerpt.tml, записи post.tml, страницы меню menuitem.tml. На этом стандартные файлы шаблонов заканчиваются.. Нет никаких проблем, чтобы каждая запись имела свой индивидуальный шаблон.

О виджетах и дополнительных тегах, будет рассказано отдельно.