Выводим товар где угодно с любым шаблоном по ID товара
Инструкция, как конкретный товар по его ID, вывести в любом месте и в любом шаблоне сайта на CMF Cotonti, без дополнительных плагинов. Готовое решение из коробки модуля Market
Как вывести конкретный товар модуля Market в любом месте сайта, зная только его ID. В качестве примера — вывод в page.tpl (страница полной статьи). Всё, что описано, работает и в index.tpl, и в шаблонах других модулей, и в шаблонах плагинов.
Часть 1. Что вам нужно знать перед началом
ID товара. Число, под которым товар записан в базе. Его видно в адресной строке, когда открываешь карточку товара в админке или на сайте: .../market/29-название-товара — где 29 и есть ID. Пусть в примере это будет 29.
Шаблон товара. Файл с расширением .tpl, который описывает внешний вид блока с товаром. Вы создаёте его сами, кладёте в папку своей темы. Сколько угодно разных шаблонов — под разные места сайта.
Функция вывода. Одна PHP-функция cot_market_get_by_id_owner_tpl(), уже присутствующая в модуле Market PRO. Её задача: принять имя шаблона и ID, найти данные товара в базе, подставить их в ваш TPL и вернуть готовый HTML.
Часть 2. Пошаговый пример: вывести товар 29 внутри статьи
Шаг 1. Создайте папку для шаблонов Market в своей теме
Откройте папку своей темы:
themes/имя_вашей_темы/
Если внутри ещё нет подпапки modules, создайте её. Внутри modules создайте market. Должно получиться:
themes/имя_вашей_темы/modules/market/
Это стандартная папка, в которой Cotonti ищет шаблоны модуля Market.
Шаг 2. Создайте файл шаблона
Внутри themes/имя_вашей_темы/modules/market/ создайте текстовый файл с именем:
market.getbyid.tpl
Имя состоит из трёх частей:
market — префикс модуля,
getbyid — произвольное имя, которое вы сами придумываете,
.tpl — расширение.
Через getbyid вы потом будете ссылаться на этот шаблон из вызова функции.
Шаг 3. Заполните файл содержимым
Откройте market.getbyid.tpl и напишите:
<!-- BEGIN: MAIN -->
<!-- IF {MARKET_CHECK_29_ID} -->
<div class="alert alert-info mt-4">
<a href="{MARKET_CHECK_29_URL}">{MARKET_CHECK_29_TITLE}</a>
</div>
<!-- ENDIF -->
<!-- END: MAIN -->
Разбор построчно:
<!-- BEGIN: MAIN --> и <!-- END: MAIN --> — обязательная обёртка. Внешний блок всегда называется MAIN. Без него функция не найдёт, что рендерить, и вернёт пустую строку.
<!-- IF {MARKET_CHECK_29_ID} --> — проверка: если для товара 29 в базе нет данных (не найден или не опубликован), весь блок не выведется вообще. Ничего не сломается.
{MARKET_CHECK_29_URL} — ссылка на карточку товара. Подставит функция.
{MARKET_CHECK_29_TITLE} — название товара. Подставит функция.
{MARKET_CHECK_29_ID} — сам ID (пригодится, если хотите вывести его на экран). Подставит функция.
Шаг 4. Откройте шаблон статьи
Найдите файл:
themes/имя_вашей_темы/page.tpl
Шаг 5. Вставьте вызов в нужное место
Внутри page.tpl найдите место, где по логике должен появиться блок с товаром. Например, после текста статьи. Вставьте туда:
<!-- IF {PHP|cot_market_get_by_id_owner_tpl('getbyid', 29)} --> — сначала вызываем функцию прямо в условии. Если товар найден и опубликован, она вернёт непустой HTML, условие истинно, блок покажется. Если товара нет, функция вернёт пустую строку, условие ложно — и весь блок вместе с <div> исчезнет, пустого места с отступами не останется;
{PHP|cot_market_get_by_id_owner_tpl('getbyid', 29)} — второй вызов, уже внутри блока, выводит сам HTML.
Про саму строку вызова:
PHP| — конструкция CoTemplate, которая говорит «вызови PHP-функцию и вставь её результат сюда»;
cot_market_get_by_id_owner_tpl — имя функции;
'getbyid' — имя вашего шаблона (без префикса market. и без .tpl);
29 — ID товара.
Шаг 6. Сохраните и откройте страницу
Обновите любую статью на сайте. Под её текстом появится блок со ссылкой на товар 29.
Часть 3. Как это работает внутри — без воды
Когда Cotonti доходит до строки {PHP|cot_market_get_by_id_owner_tpl('getbyid', 29)}:
Вызывается функция. Ей приходят имя шаблона 'getbyid' и ID 29.
Функция идёт в базу. Одним запросом тянет строку товара с ID = 29 и проверяет, что fieldmrkt_state = 0 (товар опубликован).
Формируются теги. Для товара 29 собираются три тега: MARKET_CHECK_29_ID, MARKET_CHECK_29_URL, MARKET_CHECK_29_TITLE.
Ищется файл шаблона. Функция смотрит в вашу тему в таком порядке: сначала market.getbyid.29.tpl (если вы его создали), потом market.getbyid.tpl (тот, что вы создали в шаге 2).
Шаблон рендерится. Cotonti берёт найденный .tpl, подставляет в него теги, обрабатывает IF, возвращает готовый HTML.
HTML вставляется в page.tpl. Результат появляется ровно там, где стояла ваша строка.
Если товар не найден или не опубликован — внешняя проверка <!-- IF {PHP|cot_market_get_by_id_owner_tpl('getbyid', 29)} --> не сработает, и на странице ничего не появится. Ни ошибок, ни пустых мест.
Часть 4. Отдельный шаблон для конкретного ID
Если для товара 29 вы хотите особый вид, отличный от всех остальных, создайте в той же папке ещё один файл:
market.getbyid.29.tpl
Функция ищет его раньше общего market.getbyid.tpl. Достаточно его создать — и он автоматически перекроет общий для товара 29. Для остальных ID по-прежнему будет использоваться market.getbyid.tpl.
Такой приём удобен, когда у вас есть 2–3 «VIP-товара», которым нужен нестандартный блок (например, с картинкой или особой вёрсткой), а для всего остального хватает одного общего шаблона.
Часть 5. Несколько товаров одним вызовом
Если нужно вывести сразу три товара — 29, 71 и 105 — в одном блоке, действуйте так.
Шаблон market.getbyid.tpl
<!-- BEGIN: MAIN -->
<div class="row">
<!-- IF {MARKET_CHECK_29_ID} -->
<div class="col-md-4">
<a href="{MARKET_CHECK_29_URL}">{MARKET_CHECK_29_TITLE}</a>
</div>
<!-- ENDIF -->
<!-- IF {MARKET_CHECK_71_ID} -->
<div class="col-md-4">
<a href="{MARKET_CHECK_71_URL}">{MARKET_CHECK_71_TITLE}</a>
</div>
<!-- ENDIF -->
<!-- IF {MARKET_CHECK_105_ID} -->
<div class="col-md-4">
<a href="{MARKET_CHECK_105_URL}">{MARKET_CHECK_105_TITLE}</a>
</div>
<!-- ENDIF -->
</div>
<!-- END: MAIN -->
Обратите внимание: ID перечисляются через запятую, и вся строка берётся в кавычки. Разделять можно также пробелами: '29 71 105'.
Когда ID несколько, функция ищет только общий файл market.getbyid.tpl — персональные типа market.getbyid.29.tpl в этом режиме не используются, потому что под один файл подставлять сразу три блока смысла нет.
Часть 6. Свой префикс тегов
Если на одной странице вы выводите несколько независимых блоков товаров, теги могут конфликтовать. Решение — задать третьим аргументом свой префикс.
Теперь в шаблоне market.alsobuy.tpl теги будут не MARKET_CHECK_29_*, а RECO_29_*:
<!-- BEGIN: MAIN -->
<!-- IF {RECO_29_ID} -->
<div class="also-buy">
<span>{PHP.L.market_also_buy}:</span>
<a href="{RECO_29_URL}">{RECO_29_TITLE}</a>
</div>
<!-- ENDIF -->
<!-- END: MAIN -->
Правило простое: какой префикс указали в вызове — такие теги пишете в шаблоне.
Если префикс не указан, работает значение по умолчанию — MARKET_CHECK_. Для 99% случаев этого достаточно, третий аргумент нужен только в нетипичных сценариях.
Часть 7. Что НЕ работает из шаблона
CoTemplate — не PHP, у него свои ограничения на форму записи аргументов. При передаче ID из шаблона page.tpl работают только эти варианты:
29
'29'
'29,71,105'
'29 71 105'
Не работают из шаблона:
массив [29, 71, 105] — в CoTemplate нет литералов массива;
строка с вертикальной чертой '29|71|105' — символ | режется парсером до того, как попадёт в функцию.
Из PHP (если вызываете не из шаблона, а из кода модуля или плагина) работают все формы, включая массив и |. Это ограничение касается только вызовов из .tpl.
Часть 8. Шпаргалка
Что нужно
Файл шаблона
Строка вызова в шаблоне сайта
Один товар, общий вид
market.getbyid.tpl
<!-- IF {PHP|cot_market_get_by_id_owner_tpl('getbyid', 29)} --><div class="mb-5">{PHP|cot_market_get_by_id_owner_tpl('getbyid', 29)}</div><!-- ENDIF -->
Один товар, особый вид
market.getbyid.29.tpl
<!-- IF {PHP|cot_market_get_by_id_owner_tpl('getbyid', 29)} --><div class="mb-5">{PHP|cot_market_get_by_id_owner_tpl('getbyid', 29)}</div><!-- ENDIF -->
Три товара
market.getbyid.tpl
<!-- IF {PHP|cot_market_get_by_id_owner_tpl('getbyid', '29,71,105')} --><div class="mb-5">{PHP|cot_market_get_by_id_owner_tpl('getbyid', '29,71,105')}</div><!-- ENDIF -->
<!-- IF {PHP|cot_market_get_by_id_owner_tpl('recommend', '29,71')} --><div class="mb-5">{PHP|cot_market_get_by_id_owner_tpl('recommend', '29,71')}</div><!-- ENDIF -->
Часть 9. Частые проблемы и что делать
Блок не появился вообще. Откройте page.tpl, убедитесь, что строка вызова вставлена внутрь блока MAIN и не спрятана внутри какого-нибудь <!-- IF -->, который не срабатывает.
Блок появился как текст {PHP|cot_market_get_by_id_owner_tpl(...)}. Функция не найдена. Убедитесь, что модуль Market активен и файл modules/market/inc/market.functions.php подключён (обычно подключается автоматически при активном модуле).
Ничего не выводится, хотя товар существует. Проверьте, что товар опубликован (fieldmrkt_state = 0), а не находится в черновиках или на модерации.
Выводится не то, что ожидалось. Проверьте имя шаблона в вызове — оно должно совпадать с именем файла. 'getbyid' соответствует market.getbyid.tpl; 'recommend' — market.recommend.tpl, и так далее.
Хотите другой вид только для одного товара. Создайте файл market.<имя>.<ID>.tpl. Функция подхватит его автоматически.
Итог
Три вещи, которые нужно сделать, чтобы вывести любой товар в любом месте сайта по его ID:
Создать файл шаблона в themes/ваша_тема/modules/market/ с блоком MAIN и тегами {MARKET_CHECK_<ID>_URL} / {MARKET_CHECK_<ID>_TITLE}.
В нужном шаблоне сайта вставить вызов, обёрнутый в проверку:
Обёртка <!-- IF ... --> гарантирует, что при отсутствии товара (не найден, не опубликован) на странице не останется ни самого блока, ни пустого контейнера с отступами.
Больше ничего делать не нужно — ни SQL, ни правок PHP, ни плагинов под каждый случай.
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.