Метод parse() в Cotonti
отвечает за разбор (парсинг) блока в шаблоне, его подблоков и динамическую обработку данных, а также за отладочную информацию в случае активированного режима отладки
Описание работы метода parse()
Метод parse() отвечает за разбор (парсинг) блока в шаблоне, его подблоков и динамическую обработку данных, а также за отладочную информацию в случае активированного режима отладки. Давайте разберемся поэтапно, что происходит в этом методе.
1. Получение пути блока
$path = isset($this->index[$block]) ? $this->index[$block] : null;
- Переменная
$pathполучает путь блока, если блок существует в индексе ($this->index[$block]). Путь в данном случае — это массив, который указывает на конкретное место блока в структуре шаблона. - Если блок не найден в индексе,
$pathостается равнымnull.
2. Проверка существования пути
if ($path) {
- Если путь к блоку существует, то начинается обработка этого блока. В противном случае метод завершится без изменений.
3. Обработка первого уровня блока
$blockIndex = array_shift($path);
$blk = isset($this->blocks[$blockIndex]) ? $this->blocks[$blockIndex] : null;
- Из массива пути извлекается первый элемент с помощью
array_shift($path). Этот элемент представляет собой индекс блока в массиве$this->blocks. - С помощью этого индекса находится сам блок, который сохраняется в переменную
$blk. Если блока нет, переменная остается пустой (null).
4. Проверка наличия блока и обработка подблоков
if (!empty($blk)) {
foreach ($path as $node) {
if (is_array($blk)) {
$blk = $blk[$node];
} else {
$blk = $blk->blocks[$node];
}
}
$blk->parse($this);
}
- Если блок существует (
!empty($blk)), то начинается цикл, который проходит по оставшемуся пути$path. Каждый элемент пути представляет собой один из подблоков. - Для каждого элемента пути:
- Если текущий блок является массивом, происходит переход в следующий подблок через индекс
$node:$blk = $blk[$node]. - Если блок не является массивом (предположительно объект), переход в подблок происходит через свойство
blocks:$blk = $blk->blocks[$node].
- Если текущий блок является массивом, происходит переход в следующий подблок через индекс
- После того как все подблоки обработаны, вызывается метод
parse()для текущего блока, что означает рекурсивную обработку этого подблока.
5. Отладка
if (self::$debugMode) {
if (!in_array($block, $this->displayed_blocks)) {
$file = basename($this->filename);
$tags = $this->vars;
ksort($tags);
foreach ($tags as $key => $val) {
if (is_array($val)) {
foreach ($val as $key2 => $val2) {
if (is_string($val2) && mb_strlen($val2) > 60) {
$val2 = mb_substr($val2, 0, 60) . '...';
}
self::$debugData[$file][$block][$key . '.' . $key2] = $val2;
}
} else {
if (is_string($val) && mb_strlen($val) > 60) {
$val = mb_substr($val, 0, 60) . '...';
}
self::$debugData[$file][$block][$key] = $val;
}
}
unset($tags);
$this->displayed_blocks[] = $block;
}
}
- Если включен режим отладки (
self::$debugMode), проверяется, был ли уже выведен текущий блок (через массив$this->displayed_blocks). - Если блок ещё не был выведен, происходит сбор информации о переменных шаблона (
$this->vars). Переменные сортируются по ключам с помощьюksort($tags). - Для каждой переменной проверяется, является ли она массивом:
- Если переменная — это массив, то рекурсивно обрабатываются его элементы, и они сохраняются в отладочных данных.
- Если значение переменной — строка, и её длина больше 60 символов, то строка обрезается и добавляется многоточие (
...).
- Все собранные данные сохраняются в глобальный массив
self::$debugData. - Далее текущий блок добавляется в список выведенных блоков (
$this->displayed_blocks[] = $block), чтобы избежать повторного вывода в дальнейшем.
6. Возврат объекта для цепочки вызовов
return $this;
- В конце метод возвращает текущий объект (
$this), что позволяет продолжить цепочку вызовов, если нужно.
Пример работы метода
Предположим, что в шаблоне существует блок MAIN, который имеет несколько подблоков, например:
<!-- BEGIN: MAIN -->
<!-- BEGIN: BLOCK_1 -->
Content for block 1
<!-- END: BLOCK_1 -->
<!-- BEGIN: BLOCK_2 -->
Content for block 2
<!-- END: BLOCK_2 -->
<!-- END: MAIN -->
Когда вызывается метод parse('MAIN'), выполняется следующее:
- Ищется путь к блоку
MAINв индексе ($this->index['MAIN']). - Извлекается первый элемент пути (индекс блока
MAIN). - На основе этого индекса находится сам блок из массива
$this->blocks. - Далее выполняется разбор подблоков
BLOCK_1иBLOCK_2. Каждый подблок также передается в методparse()для дальнейшей обработки. - Если включен режим отладки, выводятся переменные и их значения для каждого блока, а также обеспечивается правильный вывод отладочной информации.
Итог
Метод parse() выполняет важную функцию — он обрабатывает блоки и подблоки шаблона, динамически подставляя соответствующие данные в нужные места. Также в этом методе реализована система отладки, которая помогает разработчикам отслеживать состояние переменных и данных в процессе работы шаблонов.
Конечно! Вот подробные комментарии к каждому шагу кода:
/**
* Parses a block
*
* @param string $block Block name
* @return XTemplate $this object for call chaining
*/
public function parse($block = 'MAIN') // Объявляется метод parse с параметром $block, по умолчанию равным 'MAIN'.
{
$path = isset($this->index[$block]) ? $this->index[$block] : null; // Проверяется наличие блока в индексе. Если есть, то получаем путь к блоку, иначе присваиваем null.
if ($path) { // Если путь найден, продолжаем выполнение.
$blockIndex = array_shift($path); // Извлекаем первый элемент пути, который представляет собой индекс блока.
$blk = isset($this->blocks[$blockIndex]) ? $this->blocks[$blockIndex] : null; // Ищем сам блок в массиве $this->blocks, используя индекс из пути.
if (!empty($blk)) { // Если блок существует (не пуст), начинаем обработку подблоков.
foreach ($path as $node) { // Для каждого элемента оставшегося пути (подблока) выполняем следующие действия.
if (is_array($blk)) { // Если текущий блок является массивом, обрабатываем его как массив.
$blk = $blk[$node]; // Переходим к следующему подблоку по индексу $node.
} else { // Если блок является объектом.
$blk = $blk->blocks[$node]; // Переходим к следующему подблоку через свойство blocks объекта.
}
}
$blk->parse($this); // Вызываем метод parse для текущего блока, что позволяет обработать этот подблок рекурсивно.
}
}
// В случае если путь не найден, выбрасывается исключение (закомментировано в коде).
//else throw new Exception("Block $block is not found in " . $this->filename);
if (self::$debugMode) { // Если включен режим отладки, то собираем информацию о текущем блоке.
if (!in_array($block, $this->displayed_blocks)) { // Если текущий блок ещё не был выведен.
$file = basename($this->filename); // Извлекаем имя файла, в котором используется текущий блок.
$tags = $this->vars; // Получаем все переменные текущего шаблона.
ksort($tags); // Сортируем переменные по ключу.
foreach ($tags as $key => $val) { // Для каждой переменной:
if (is_array($val)) { // Если переменная является массивом:
foreach ($val as $key2 => $val2) { // Проходим по элементам массива.
if (is_string($val2) && mb_strlen($val2) > 60) { // Если элемент — строка и её длина больше 60 символов.
$val2 = mb_substr($val2, 0, 60) . '...'; // Обрезаем строку до 60 символов и добавляем многоточие.
}
self::$debugData[$file][$block][$key . '.' . $key2] = $val2; // Сохраняем отладочную информацию в глобальном массиве.
}
} else { // Если переменная не является массивом:
if (is_string($val) && mb_strlen($val) > 60) { // Если переменная — строка и её длина больше 60 символов.
$val = mb_substr($val, 0, 60) . '...'; // Обрезаем строку до 60 символов и добавляем многоточие.
}
self::$debugData[$file][$block][$key] = $val; // Сохраняем отладочную информацию.
}
}
unset($tags); // Очищаем переменные после использования.
$this->displayed_blocks[] = $block; // Добавляем текущий блок в список отображённых блоков.
}
}
return $this; // Возвращаем текущий объект, что позволяет продолжить цепочку вызовов методов.
}
Описание процесса:
-
Получение пути к блоку: Метод ищет путь для блока в индексе
$this->index. Если блок существует, то возвращается путь к этому блоку. Путь представляет собой массив индексов, который поможет найти точное местоположение блока в структуре шаблона. -
Обработка блоков и подблоков: После получения пути, метод начинает обработку каждого элемента этого пути. Для каждого подблока извлекается нужный блок из массива
$this->blocks, после чего продолжается рекурсивный поиск, пока не будет найден нужный блок. В конце вызывается методparse()для каждого найденного блока, что позволяет обработать данные в этих блоках. -
Отладка: Если активирован режим отладки (
self::$debugMode), то метод собирает информацию о переменных шаблона. В процессе сбора данных все переменные сортируются, и если они являются строками длиннее 60 символов, они обрезаются. Эта информация сохраняется в глобальный массив отладочных данных, чтобы потом можно было проанализировать, какие переменные были использованы в каждом блоке. -
Возврат текущего объекта: Метод возвращает объект самого себя (
$this), что позволяет использовать цепочку вызовов (method chaining).
В Cotonti, расширения (или плагины) могут использовать систему шаблонов и блоков для отображения информации на страницах сайта. Приведенные ниже примеры объясняют, как можно использовать логику шаблонов и блоков в расширениях Cotonti для создания динамических страниц и интерфейсов.
Пример 1: Использование блоков для отображения данных в расширении
Допустим, вы пишете расширение для отображения списка последних новостей на сайте. В расширении вам нужно использовать блоки шаблона для отображения этих новостей.
Шаг 1: Создание PHP-кода для обработки блока
В PHP-коде вы можете реализовать логику, которая будет передавать данные в блок шаблона:
// Функция, которая обрабатывает блок новостей
function display_news($block = 'MAIN') {
// Получаем последние 5 новостей из базы данных
$news = get_recent_news(5);
// Устанавливаем данные в шаблон
$xtpl = new XTemplate('news_template.tpl'); // Загружаем шаблон news_template.tpl
foreach ($news as $item) {
// Добавляем данные о каждой новости в шаблон
$xtpl->assign('NEWS_TITLE', $item['title']);
$xtpl->assign('NEWS_EXCERPT', $item['excerpt']);
$xtpl->assign('NEWS_DATE', date('d M Y', strtotime($item['date'])));
$xtpl->parse('MAIN.NEWS');
}
// Выводим обработанный шаблон с данными
$xtpl->parse($block);
$xtpl->out($block);
}
// Пример функции получения новостей
function get_recent_news($limit) {
// Пример данных (обычно это будет запрос к базе данных)
return [
['title' => 'Новости 1', 'excerpt' => 'Краткое описание новости 1', 'date' => '2025-02-28'],
['title' => 'Новости 2', 'excerpt' => 'Краткое описание новости 2', 'date' => '2025-02-27'],
// добавьте другие новости
];
}
Шаг 2: Создание шаблона для отображения блоков
В шаблоне news_template.tpl вы определяете блок NEWS, который будет заполняться данными, переданными из PHP-кода:
<!-- BEGIN: MAIN -->
<h2>Последние новости</h2>
<!-- BEGIN: NEWS -->
<div class="news-item">
<h3>{NEWS_TITLE}</h3>
<p>{NEWS_EXCERPT}</p>
<span class="news-date">{NEWS_DATE}</span>
</div>
<!-- END: NEWS -->
<!-- END: MAIN -->
В этом примере блоки BEGIN: NEWS и END: NEWS заключают код, который будет повторяться для каждой новости. PHP-код будет передавать заголовок, описание и дату для каждой новости, и шаблон их отобразит в блоке.
Пример 2: Расширение для управления пользователями с использованием блоков
Предположим, что вы хотите создать расширение для отображения информации о пользователях, включая их аватары, имена и информацию о регистрации.
Шаг 1: Создание PHP-кода для получения данных пользователя
function display_user_info($block = 'MAIN') {
// Получаем информацию о пользователе (например, из базы данных)
$user = get_user_info(1); // Получаем информацию о пользователе с ID 1
// Инициализируем шаблон
$xtpl = new XTemplate('user_info_template.tpl');
// Передаем данные пользователя в шаблон
$xtpl->assign('USER_NAME', $user['name']);
$xtpl->assign('USER_AVATAR', $user['avatar']);
$xtpl->assign('USER_REGISTRATION_DATE', date('d M Y', strtotime($user['registration_date'])));
// Парсим и выводим блок
$xtpl->parse($block);
$xtpl->out($block);
}
// Пример функции для получения информации о пользователе
function get_user_info($user_id) {
// Пример данных пользователя (обычно это запрос к базе данных)
return [
'name' => 'Иван Иванов',
'avatar' => 'path/to/avatar.jpg',
'registration_date' => '2020-01-15',
];
}
Шаг 2: Шаблон для отображения данных о пользователе
<!-- BEGIN: MAIN -->
<h2>Информация о пользователе</h2>
<div class="user-info">
<img src="{USER_AVATAR}" alt="Аватар пользователя">
<p><strong>Имя:</strong> {USER_NAME}</p>
<p><strong>Дата регистрации:</strong> {USER_REGISTRATION_DATE}</p>
</div>
<!-- END: MAIN -->
Пример 3: Использование parse() для вложенных блоков в расширении
В некоторых случаях вам нужно обрабатывать вложенные блоки. Например, вы хотите показать комментарии к статье, которые будут отображаться внутри основного блока статьи.
Шаг 1: Код для обработки статьи и комментариев
function display_article_with_comments($block = 'MAIN') {
// Получаем статью и комментарии
$article = get_article(1); // Статья с ID 1
$comments = get_comments_for_article(1);
// Инициализируем шаблон
$xtpl = new XTemplate('article_with_comments_template.tpl');
// Передаем данные статьи в шаблон
$xtpl->assign('ARTICLE_TITLE', $article['title']);
$xtpl->assign('ARTICLE_CONTENT', $article['content']);
$xtpl->assign('ARTICLE_DATE', date('d M Y', strtotime($article['date'])));
// Парсим блок статьи
$xtpl->parse('MAIN.ARTICLE');
// Для каждого комментария создаем подблок
foreach ($comments as $comment) {
$xtpl->assign('COMMENT_AUTHOR', $comment['author']);
$xtpl->assign('COMMENT_TEXT', $comment['text']);
$xtpl->parse('MAIN.ARTICLE.COMMENT');
}
// Парсим и выводим итоговый шаблон
$xtpl->parse($block);
$xtpl->out($block);
}
// Пример функции для получения статьи
function get_article($article_id) {
return [
'title' => 'Заголовок статьи',
'content' => 'Текст статьи...',
'date' => '2025-02-20',
];
}
// Пример функции для получения комментариев к статье
function get_comments_for_article($article_id) {
return [
['author' => 'Петр Петров', 'text' => 'Отличная статья!'],
['author' => 'Ирина Ирина', 'text' => 'Очень полезно, спасибо!'],
];
}
Шаг 2: Шаблон с вложенными блоками
<!-- BEGIN: MAIN -->
<h2>{ARTICLE_TITLE}</h2>
<p>{ARTICLE_CONTENT}</p>
<span>{ARTICLE_DATE}</span>
<!-- BEGIN: ARTICLE -->
<div class="comments">
<h3>Комментарии</h3>
<!-- BEGIN: COMMENT -->
<div class="comment">
<p><strong>{COMMENT_AUTHOR}:</strong> {COMMENT_TEXT}</p>
</div>
<!-- END: COMMENT -->
</div>
<!-- END: ARTICLE -->
<!-- END: MAIN -->
Заключение
В этих примерах показаны типичные случаи использования блоков и шаблонов в расширениях Cotonti. Ключевые моменты включают:
- Использование блоков в шаблонах для динамического вывода информации.
- Использование метода
parse()для обработки и отображения вложенных блоков. - Передача данных из PHP-кода в шаблон через методы
assign()иparse().
Эти техники позволяют создавать динамичные, многоуровневые страницы и интерфейсы с использованием системы шаблонов Cotonti.
Комментарии (0)
Автор контента
Онлайн
Sodium Carbonate
Последняя авторизация: 19.07.2026 00:02
- Страница размещена: 28.02.2025 20:18
- Последнее обновление: 08.03.2025 13:43