Метод 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'), выполняется следующее:

  1. Ищется путь к блоку MAIN в индексе ($this->index['MAIN']).
  2. Извлекается первый элемент пути (индекс блока MAIN).
  3. На основе этого индекса находится сам блок из массива $this->blocks.
  4. Далее выполняется разбор подблоков BLOCK_1 и BLOCK_2. Каждый подблок также передается в метод parse() для дальнейшей обработки.
  5. Если включен режим отладки, выводятся переменные и их значения для каждого блока, а также обеспечивается правильный вывод отладочной информации.

Итог

Метод 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;  // Возвращаем текущий объект, что позволяет продолжить цепочку вызовов методов.
}

Описание процесса:

  1. Получение пути к блоку: Метод ищет путь для блока в индексе $this->index. Если блок существует, то возвращается путь к этому блоку. Путь представляет собой массив индексов, который поможет найти точное местоположение блока в структуре шаблона.

  2. Обработка блоков и подблоков: После получения пути, метод начинает обработку каждого элемента этого пути. Для каждого подблока извлекается нужный блок из массива $this->blocks, после чего продолжается рекурсивный поиск, пока не будет найден нужный блок. В конце вызывается метод parse() для каждого найденного блока, что позволяет обработать данные в этих блоках.

  3. Отладка: Если активирован режим отладки (self::$debugMode), то метод собирает информацию о переменных шаблона. В процессе сбора данных все переменные сортируются, и если они являются строками длиннее 60 символов, они обрезаются. Эта информация сохраняется в глобальный массив отладочных данных, чтобы потом можно было проанализировать, какие переменные были использованы в каждом блоке.

  4. Возврат текущего объекта: Метод возвращает объект самого себя ($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.

10 минут чтения Sodium Carbonate

Комментарии (0)

Комментарии отсутствуют
Добавление комментариев доступно только зарегистрированным пользователям

Автор контента

webitproff

Онлайн

Sodium Carbonate

Последняя авторизация: 19.07.2026 00:02

  • Страница размещена: 28.02.2025 20:18
  • Последнее обновление: 08.03.2025 13:43

Похожие страницы

Метод out() в Cotonti
1 Метод out() отвечает за вывод обработанного блока шаблона и отладочной информации, если она включена. В начале метода
XTemplate. Функции (методы) parse(), text() и out() в Cotonti Siena
2 Техническое руководство по функциям парсера шаблонов, в частности функциям parse() и out(), а также основам работы с
Cotonti Siena CMF • 22.02.2026 20:11 webitproff
Руководство по методам parse(), text() и out() в XTemplate Cotonti Siena
3 Руководство для новичков: методы assign(), parse(), text() и out() в XTemplate (CoTemplate) Cotonti Siena
Cotonti Siena CMF • 22.02.2026 20:28 webitproff