Категории форума

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


webitproff
webitproff • 30.04.2026 06:53 #1

в файл 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 - именно для страницы товара в этой категории... пользуемся и донатим

 

 

 

 

 

Отредактировано: webitproff (13.05.2026 12:18, 2 месяца назад)
🗿

🧙‍♂️ Радуйся, странниче добрый и честный! Не понапрасну привела тя стезя в земли сии. Зде бо мужи мудры и искусники дела писменнаго и численнаго, что куют словеса и плетут узоры кода, тайны разгадывают и знанием делятся, летописи множа и ремесло цифровое творя.
⬅️ Аще налево пойдеши — обрящеши грамоты древния, писания старинныя и свитки учения. ⬆️ Аще прямо — слово мудрое и совет от мужей разумеющих, что в деле кодописном искусны, получиши. ➡️ Аще направо — сам в писцы и летописцы внидеши, и в ремесло цифровое, где строки и знаки в дело живое обращаются, слово свое в память веков вложиши.
📝 Не медли же — нареки имя свое, и вниди в чин наш, и стань с нами в братстве, где код есть магия, а строки — заклятия живыя, числом и буквою слово едины суть.
🏰 Не тайно есть собрание сие, и не инициации в нем, но многое сокрыто от пришлых и ступалого, понеже не всякому открывается знание, но токмо ищущим и пребывающим в деле сем.