Метод 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 minutes read Sodium Carbonate

Comments (0)

No comments yet
Only registered users can post new comments

Content author

webitproff

Offline

Sodium Carbonate

Last logged: 2026-09-01 22:41

About me briefly
Support and development of web projects on the CMF Cotonti: private messengers via the website, open and closed small social networks, trading platforms and marketplaces, freelance and services exchange portal, catalogs of goods from wholesale suppliers, dropshipping platforms, online stores, and much more.
View developments and download
Public portfolio of my works and developments
Telegram for messages
@webitproff
Telegram channel
@s/aBuyFILE
  • Page published: 2025-02-28 20:18
  • Last update: 2025-03-08 13:43

Similar pages

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