Forum categories

Дифференциация пользовательских шаблонов header.tpl

webitproff
webitproff • 2026-04-30 06:53 #547

в файл modules/market/inc/market.functions.php 

 добавить:  

/**
* Функция проверяет существование общего файла шаблона заголовка для категории маркета.
* Имя файла формируется как header.market.{код_категории}.tpl в папке текущей темы.
*
* @param string $catCode Код категории
* @return bool true, если файл существует, иначе false.
*/
function market_cat_has_header_tpl(string $catCode): bool
{
   /**
    * Если код категории пустой, шаблон не может существовать — возвращаем false.
    */
   if (empty($catCode)) return false;
   /**
    * Формируем полный путь к файлу шаблона: каталог темы + имя файла header.market.{cat}.tpl.
    */
   $tplFile = Cot::$cfg['themes_dir'] . '/' . Cot::$cfg['defaulttheme']
            . '/header.market.' . $catCode . '.tpl';
   /**
    * Проверяем наличие файла в файловой системе и возвращаем результат.
    */
   return file_exists($tplFile);
}
/**
* Функция проверяет существование специализированного шаблона заголовка для страницы товара.
* Имя файла: header.market.{код_категории}.pagehasid.tpl
*
* @param string $catCode Код категории
* @return bool true, если файл существует, иначе false.
*/
function market_cat_has_header_tpl_pageid(string $catCode): bool
{
   /**
    * Если код категории пустой, возвращаем false.
    */
   if (empty($catCode)) return false;
   /**
    * Формируем путь к файлу: директория темы + 'header.market.' + код категории + '.pagehasid.tpl'.
    */
   $tplFile = Cot::$cfg['themes_dir'] . '/' . Cot::$cfg['defaulttheme']
            . '/header.market.' . $catCode . '.pagehasid.tpl';
   /**
    * Возвращаем true, если файл существует.
    */
   return file_exists($tplFile);
}

 

создать файл market.header.first.php в modules/market/

закинуть 

<?php
/* ====================
[BEGIN_COT_EXT]
Hooks=header.first
[END_COT_EXT]
==================== */
/**
* Проверяем, что константа COT_CODE определена — стандартная защита от прямого вызова файла.
* Если скрипт запущен не в составе Cotonti, die прерывает выполнение с сообщением об ошибке.
*/
defined('COT_CODE') or die('Wrong URL.');
/**
* Если текущее расширение (модуль) не является 'market', то наш хук не должен выполняться.
* Таким образом, все последующие проверки и подмены заголовка работают только для страниц модуля маркета.
*/
if (Cot::$env['ext'] !== 'market') return;
/**
* Подключаем главный файл модуля market, чтобы получить доступ к его функциям, в том числе
* к тем, которые мы добавили для проверки существования шаблонов заголовков (market_cat_has_header_tpl и др.).
*/
require_once cot_incfile('market', 'module');

// Дефолтная локация для корня модуля (header.market.tpl)
Cot::$env['location'] = 'market';


// 1. ID-товара (числовой)
/**
* Проверяем, передан ли в GET-запросе параметр 'id'. Если он присутствует и не пуст,
* значит пользователь просматривает конкретный товар по его числовому идентификатору.
*/
if (!empty($_GET['id'])) {
   /**
    * Приводим значение параметра 'id' к целому числу, чтобы избежать SQL-инъекций.
    * Если после приведения получился 0, значит параметр был некорректным — игнорируем.
    */
   $id = (int)$_GET['id'];
   if ($id > 0) {
       /**
        * Выполняем запрос к таблице маркета для получения кода категории (fieldmrkt_cat) товара по его ID.
        * Используем подготовленный запрос с плейсхолдером ? для безопасной подстановки значения.
        * fetchColumn() возвращает значение первого столбца первой строки результата.
        */
       $cat = Cot::$db->query(
           "SELECT fieldmrkt_cat FROM " . Cot::$db->market . " WHERE fieldmrkt_id = ? LIMIT 1",
           [$id]
       )->fetchColumn();
       /**
        * Если запрос вернул не пустое значение категории, продолжаем проверку шаблонов.
        * Если код категории пуст или не найден, переходим к следующим способам определения.
        */
       if ($cat) {
           /**
            * Сначала ищем специализированный шаблон для страницы товара с суффиксом '.pagehasid'.
            * Функция market_cat_has_header_tpl_pageid проверяет существование файла header.market.{cat}.pagehasid.tpl.
            */
           if (market_cat_has_header_tpl_pageid($cat)) {
               /**
                * Если такой шаблон существует, подменяем переменную location на 'market.{cat}.pagehasid'.
                * Это заставит Cotonti искать шаблон заголовка с соответствующим именем.
                */
               Cot::$env['location'] = 'market.' . $cat . '.pagehasid';
               /**
                * Немедленно выходим из хука, так как нужный location уже установлен.
                */
               return;
           }
           /**
            * Если специализированный шаблон для страницы товара не найден, проверяем общий шаблон категории.
            * Функция market_cat_has_header_tpl ищет файл header.market.{cat}.tpl.
            */
           if (market_cat_has_header_tpl($cat)) {
               /**
                * Устанавливаем location в 'market.{cat}' для использования общего шаблона заголовка категории.
                */
               Cot::$env['location'] = 'market.' . $cat;
               return;
           }
       }
   }
}
// 2. alias-товара (ЧПУ)
/**
* В Cotonti при использовании ЧПУ товары могут открываться по параметру 'al' (алиас).
* Проверяем, есть ли такой параметр в GET-запросе.
*/
if (!empty($_GET['al'])) {
   /**
    * Безопасно получаем значение алиаса через функцию cot_import, которая фильтрует входные данные.
    * Режим 'G' — GET, 'TXT' — текст.
    */
   $al = cot_import('al', 'G', 'TXT');
   /**
    * Если после фильтрации алиас не пустой, выполняем запрос к базе данных.
    */
   if ($al) {
       /**
        * Ищем категорию товара по его алиасу в таблице маркета.
        * Аналогично числовому ID, получаем код категории через fetchColumn().
        */
       $cat = Cot::$db->query(
           "SELECT fieldmrkt_cat FROM " . Cot::$db->market . " WHERE fieldmrkt_alias = ? LIMIT 1",
           [$al]
       )->fetchColumn();
       /**
        * Если категория найдена, пытаемся применить шаблоны.
        */
       if ($cat) {
           /**
            * Проверяем наличие шаблона страницы товара с .pagehasid для найденной категории.
            */
           if (market_cat_has_header_tpl_pageid($cat)) {
               /**
                * Устанавливаем location для специализированного шаблона.
                */
               Cot::$env['location'] = 'market.' . $cat . '.pagehasid';
               return;
           }
           /**
            * Если специальный шаблон отсутствует, проверяем общий шаблон категории.
            */
           if (market_cat_has_header_tpl($cat)) {
               /**
                * Устанавливаем location для общего шаблона категории.
                */
               Cot::$env['location'] = 'market.' . $cat;
               return;
           }
       }
   }
}
// 3. Списки категорий (URL-парсинг, только если нет товара)
/**
* Чтобы не перебивать ранее определённый location для товара, проверяем, что ни 'id', ни 'al' не заданы.
* Только в этом случае парсим URL для определения категории в режиме списка товаров.
*/
if (empty($_GET['id']) && empty($_GET['al'])) {
   /**
    * Получаем текущий URI запроса, убираем начальный и конечный слеши.
    * Если $_SERVER['REQUEST_URI'] не установлен, используем пустую строку.
    */
   $uri = trim($_SERVER['REQUEST_URI'] ?? '', '/');
   /**
    * Разбиваем URI на части по слешу. Например, "ru/market/portable-energy" станет массивом ['ru', 'market', 'portable-energy'].
    */
   $segments = explode('/', $uri);
   /**
    * Если первый сегмент существует, состоит из 2 букв и является алфавитным, считаем его языковым кодом.
    * Удаляем его из массива, чтобы не мешал дальнейшему анализу.
    */
   if (isset($segments[0]) && strlen($segments[0]) == 2 && ctype_alpha($segments[0])) {
       array_shift($segments);
   }
   /**
    * Проверяем, что после удаления языка первый оставшийся сегмент — 'market'.
    * Это подтверждает, что мы находимся на странице модуля маркет.
    */
   if (!empty($segments[0]) && $segments[0] === 'market') {
       /**
        * Перебираем все последующие сегменты URL, потому что категория может быть вложенной.
        * Начинаем с индекса 1 (после 'market') и до конца массива.
        */
       for ($i = 1; $i < count($segments); $i++) {
           /**
            * Текущий сегмент рассматривается как возможный код категории.
            */
           $possibleCat = $segments[$i];
           /**
            * Для каждого возможного кода категории проверяем существование общего шаблона заголовка.
            * Как только находим совпадение, устанавливаем location и выходим.
            */
           if (market_cat_has_header_tpl($possibleCat)) {
               /**
                * Устанавливаем location для найденной категории списка товаров.
                */
               Cot::$env['location'] = 'market.' . $possibleCat;
               return;
           }
       }
   }
}
// 4. Старый ?c=
/**
* Для обратной совместимости поддерживаем старый способ указания категории через параметр 'c' в GET.
*/
if (!empty($_GET['c'])) {
   /**
    * Безопасно получаем значение 'c' с помощью cot_import.
    */
   $c = cot_import('c', 'G', 'TXT');
   /**
    * Если значение не пустое и для него есть шаблон заголовка, применяем его.
    */
   if ($c && market_cat_has_header_tpl($c)) {
       /**
        * Устанавливаем location для категории, переданной через параметр 'c'.
        */
       Cot::$env['location'] = 'market.' . $c;
   }
}

 

в админке обновить модуль.

в папку с шаблоном закинуть 

header.market.notebooks.tpl - шаблон шапки сайта для категории товаров с "notebooks" в поле `fieldmrkt_cat`

header.market.notebooks.pagehasid.tpl - именно для страницы товара в этой категории... пользуемся и донатим

 

 

 

 

 

This post was edited by webitproff (2026-05-13 12:18, 2 months ago)
🗿

🧙‍♂️ Well met, good traveler! Fate has guided your steps to our humble realm. Here, wise sages and masters of the coding craft ⚒️📜 gather to unravel the mysteries of the code ✨⚙️, share their knowledge, and add new chapters to our chronicles.
⬅️ To the left lie ancient scrolls 📚 filled with forgotten wisdom. ⬆️ Straight ahead, friendly folk offer counsel 💬 to those in need. ➡️ To the right, you may become a chronicler ✍️ yourself, sharing your craft and leaving words of wisdom for those yet to come.
📝 Delay no longer—tell us the name by which you are known, complete the rite of registration 🛡️, and join our fellowship!
🏰 Our brotherhood holds no secret initiation, yet many halls remain closed to wandering guests, for some knowledge 💎 is reserved for those who choose to walk this path beside us.