Локализация экстраполей в Cotonti (пример: статус товара)

Локализация экстраполей в Cotonti: подробная инструкция на конкретном примере для начинающих разработчиков

Введение (обзор проблемы и цели инструкции)

Возьмём конкретный пример: экстраполе с именем "product_status" (статус товара) для модуля "pages" (страницы, но представим, что это страницы товаров в вашем сайте-магазине). Это поле типа "select" (выпадающий список) с вариантами значений: "available" (в наличии), "out_of_stock" (нет в наличии), "running_low" (заканчивается), "on_order" (под заказ).

Почему именно "pages"? Потому что в Cotonti это одна из базовых сущностей, и пример из исходного кода был оттуда. Если у вас другой модуль (например, "market" или кастомный), принципы идентичны — просто замените 'pages' на имя вашей таблицы (например, 'market').

Что мы сделаем в этой инструкции:

  • Добавим экстраполе в базу данных.
  • Создадим локализацию для заголовка поля и для каждого значения варианта.
  • Покажем, как использовать в PHP-коде модуля.
  • Покажем вывод в шаблонах (TPL).
  • Обработаем типичные ошибки.
  • Дадим полный цикл тестирования.
  • Всё с копируемыми примерами кода.

Теперь по шагам.

Шаг 1: Подготовка расширения и языкового файла

1.1. Создайте структуру плагина

Если у вас нет плагина — создайте папку plugins/my_shop/. Внутри:

  • my_shop.php (основной файл плагина).
  • my_shop.setup.php (для установки, включая добавление экстраполей).
  • Папка lang/ с my_shop.ru.lang.php.

Почему плагин? Экстраполи можно добавлять в плагине или модуле — для новичков плагин проще, так как не требует полной структуры модуля.

1.2. Создайте языковой файл

Файл: plugins/my_shop/lang/my_shop.ru.lang.php

Содержимое (копируйте целиком):

<?php
// Защита от прямого доступа — обязательно, иначе хакеры могут вызвать файл напрямую.
defined('COT_CODE') or die('Wrong URL.');
// ── Заголовок поля: префикс 'page_' + имя поля 'product_status' + '_title' ──
// Это для функции cot_extrafield_title(). Без префикса может быть конфликт с другими полями.
$L['page_product_status_title'] = 'Статус товара';
// ── Локализация значений вариантов: имя поля 'product_status' + '_' + значение ──
// Значения — это ключи из вариантов в cot_extrafield_add() (см. шаг 2).
// Без префикса 'page_', потому что cot_build_extrafields_data() ищет именно так: $L['field_name' . '_' . $value].
// Если добавить 'page_' — локализация не сработает, выведет сырое значение (например, 'available' вместо 'В наличии').
$L['product_status_available'] = 'В наличии';
$L['product_status_out_of_stock'] = 'Нет в наличии';
$L['product_status_running_low'] = 'Заканчивается';
$L['product_status_on_order'] = 'Под заказ';
// ── Опционально: подсказка или хинт для админки/формы. Используйте в коде вручную.
$L['page_product_status_hint'] = 'Выберите статус товара: в наличии, нет и т.д.';
// ── Если нужно склонения (для чисел, но здесь не нужно) — используйте $Ls, но для статуса не актуально.

Пояснение по именам:

  • Заголовок: 'page_product_status_title' — префикс 'page_' обязателен, чтобы функция cot_extrafield_title() нашла его по приоритету (см. исходный код функции: сначала с префиксом, потом с location, потом без).
  • Значения: 'product_status_available' — без 'page_', потому что в функции cot_build_extrafields_data() для типов select/radio/checklistbox код такой: (!empty($L[$extrafield['field_name'] . '_' . $value])) ? $L[$extrafield['field_name'] . '_' . $value] : $value;. То есть, field_name = 'product_status', value = 'available' → ищет 'product_status_available'.
  • Если вы ошибётесь и напишете 'page_product_status_available' — функция не найдёт, и выведет 'available' (сырое значение из БД).
  • Значения должны быть на латинице в ключах (available, out_of_stock), потому что в БД хранятся ключи, а не переводы. Переводы — только для вывода.

Типичная ошибка: Забыть defined('COT_CODE') — файл уязвим. Или использовать кириллицу в ключах — Cotonti не поймёт.

1.3. Установите плагин в админке

Зайдите в админ-панель Cotonti: /admin/extensions → Установить 'my_shop'. Это подключит lang-файл автоматически.

Шаг 2: Добавление экстраполя в setup-файл

Файл: plugins/my_shop/my_shop.setup.php

Содержимое (копируйте):

PHP
<?php
// Защита
defined('COT_CODE') or die('Wrong URL.');
// Добавляем экстраполе только если его нет (проверяется внутри функции).
// Параметры: location = 'pages' (таблица cot_pages), name = 'product_status' (имя колонки в БД: page_product_status).
// Тип 'select' — для выпадающего списка.
// Варианты: строка с ключами через запятую — 'available,out_of_stock,running_low,on_order'.
// Эти ключи будут храниться в БД (короткие, латиница, без пробелов).
// Default = 'available' — по умолчанию "в наличии".
cot_extrafield_add(
 'pages', // Локация: таблица без 'cot_' (pages → cot_pages).
 'product_status', // Имя поля: только a-z0-9_ (без '-', пробелов, кириллицы).
 'select', // Тип: select для списка.
 '', // HTML: оставьте пустым, Cotonti сам сгенерирует <select>.
 'available,out_of_stock,running_low,on_order', // Варианты: ключи, которые будут в value опций.
 'available', // Default: один из вариантов.
 false, // Required: false — не обязательно.
 'HTML', // Parse: HTML — парсинг как HTML (не актуально для select).
 'Статус товара для страниц-магазина', // Description: для админки, видно в /admin/extrafields.
 '', // Params: для select — пусто.
 1, // Enabled: 1 — включено.
 false, // Noalter: false — ALTER таблицу, добавит колонку page_product_status VARCHAR(255).
 '' // Customtype: пусто, по умолчанию VARCHAR для select.
);
// Если нужно обновить позже — используйте cot_extrafield_update(), но для нового — add.

Пояснение:

  • Функция добавит запись в cot_extra_fields и ALTER'ит cot_pages, добавив колонку 'page_product_status' типа VARCHAR(255) DEFAULT ''.
  • Варианты: 'available,out_of_stock...' — это ключи. В форме админки Cotonti покажет их как опции, но если есть локализация — в выводе (не в форме!) покажет переводы.
  • В форме добавления страницы (админка) опции будут сырыми: "available", "out_of_stock" — потому что формы не локализуют варианты автоматически. Чтобы локализовать опции в форме, нужно кастомизировать форму (не в этой инструкции, но возможно через хуки).
  • Почему VARCHAR? Смотрите исходный код cot_extrafield_add(): для select — "VARCHAR(255) DEFAULT ''".
  • Ошибка: Если имя не alphanumeric — функция вернёт false (проверяет cot_import($name, 'D', 'ALP')).
  • После выполнения: Очистите кэш в админке (/admin/cache) или кодом Cot::$cache->db->remove('cot_extrafields', 'system');.

Что если ошибка: Если "field already exists" — удалите вручную из cot_extra_fields и ALTER DROP COLUMN page_product_status.

Шаг 3: Использование в PHP-коде модуля (обработка данных)

Предполагаем, вы модифицируете модуль "pages" (или свой). В файле modules/pages/inc/pages.main.php (или в вашем плагине через хук 'pages.page.loop') добавьте цикл для экстраполей.

Код (добавьте в место, где формируется $temp_array для шаблона):

// Проверяем, есть ли экстраполи для pages.
if (!empty(Cot::$extrafields[Cot::$db->pages])) {
 // Цикл по всем экстраполям (Cot::$extrafields['cot_pages'] — глобальный кэш полей).
 foreach (Cot::$extrafields[Cot::$db->pages] as $exfld) {
 // Тег для шаблона: uppercase имени поля (PRODUCT_STATUS).
 $tag = mb_strtoupper($exfld['field_name']); // 'PRODUCT_STATUS'
 // Префикс для заголовка — 'page_' (соответствует location).
 $prefix = 'page_';
 // Локализованный заголовок: cot_extrafield_title() ищет $L['page_product_status_title'].
 // Если не найдёт — fallback на description или имя поля.
 $exfld_title = cot_extrafield_title($exfld, $prefix);
 $temp_array[$tag . '_TITLE'] = $exfld_title; // PAGE_PRODUCT_STATUS_TITLE = 'Статус товара'
 // Значение из данных страницы: $page_data — массив из БД (предполагаем, он есть).
 // Ключ в БД: 'page_product_status'.
 $temp_value = isset($page_data['page_' . $exfld['field_name']]) ? $page_data['page_' . $exfld['field_name']] : null; // Например, 'running_low'
 // Локализованное значение: cot_build_extrafields_data() для select ищет $L['product_status_running_low'] = 'Заканчивается'.
 // Если не найдёт — вернёт 'running_low'.
 // 'page' — имя сущности (не таблица), $page_data['page_parser'] — парсер страницы (обычно 'HTML').
 $temp_array[$tag] = cot_build_extrafields_data('page', $exfld, $temp_value, $page_data['page_parser']);
 // Сырое значение (опционально, для условий в шаблоне).
 $temp_array[$tag . '_VALUE'] = $temp_value; // 'running_low'
 }
}
// Присваиваем в шаблон (предполагаем, $t — объект шаблонизатора).
$t->assign($temp_array);

Пояснение:

  • Cot::$extrafields[Cot::$db->pages] — массив всех экстраполей для pages (кэшируется).
  • cot_extrafield_title($exfld, 'page_') — приоритет: $L['page_product_status_title'].
  • cot_build_extrafields_data('page', ...): 'page' — это код сущности (в функциях Cotonti для pages — 'page', для users — 'user').
  • Для select: если value = 'available' → ищет $L['product_status_available'] → 'В наличии'.
  • Ошибка: Если префикс не 'page_' — может не найти заголовок.
  • В реальном коде: Добавьте это в цикл по страницам (если список) или в single-страницу.

Шаг 4: Вывод в шаблонах (TPL)

Файл: themes/ваша_тема/page.tpl (или кастомный).

Добавьте

<!-- Блок статуса товара -->
<div class="product-status">
 <strong>{PAGE_PRODUCT_STATUS_TITLE}:</strong> {PAGE_PRODUCT_STATUS}
 <!-- Вывод: Статус товара: Заканчивается -->
 <!-- Если сырое: {PAGE_PRODUCT_STATUS_VALUE} = running_low (для CSS-классов, например class="status-{PAGE_PRODUCT_STATUS_VALUE}") -->
</div>
<!-- Если в списке страниц (pages.list.tpl) -->
{PHP.L.page_product_status_title}: {LIST_ROW_PRODUCT_STATUS}

Пояснение:

  • Теги uppercase: {PAGE_PRODUCT_STATUS_TITLE} — из $temp_array.
  • В админке: При редактировании страницы (/pages/edit/ид) поле появится автоматически с заголовком 'Статус товара' (из $L), опции — сырые ключи.
  • Чтобы локализовать опции в форме: Нужно переопределить форму через хук 'pages.edit.tags', но это продвинутый уровень.

Шаг 5: Локализация в административной панели и формах

  • В админке (/admin/extrafields?type=pages): Поле видно с description 'Статус товара для страниц-магазина'.
  • В форме добавления/редактирования страницы: Заголовок — из cot_extrafield_title(), то есть 'Статус товара'.
  • Опции: Cotonti генерирует <select> с value="available" и текстом "available" (сырым). Чтобы перевести опции в форме:
    • В lang.php добавьте $L['product_status_available_option'] = 'В наличии'; (кастом ключ).
    • В хуке pages.edit.tags модифицируйте HTML поля: используйте cot_default_html_construction('select') и замените тексты на $L['product_status_xxx_option'].
    • Но для базовой инструкции — оставим сырые, так как фокус на выводе.

Шаг 6: Полный цикл тестирования

  1. Установите плагин: /admin/extensions → my_shop → Установить.
  2. Проверьте БД: В phpmyadmin посмотрите cot_pages — есть колонка page_product_status.
  3. Добавьте страницу: /pages/add → Заполните поле 'Статус товара' — выберите 'running_low'.
  4. Посмотрите страницу: /pages/ид — должно быть 'Статус товара: Заканчивается'.
  5. Если 'running_low' вместо перевода — проверьте ключ в lang: $L['product_status_running_low'].
  6. Смените язык на en (если есть en.lang.php) — создайте аналогичный файл с английскими переводами.
  7. Очистите кэш после изменений.

Типичные проблемы и решения:

  • Нет поля в форме: Не очистили кэш.
  • Сырое значение: Ошибка в ключе $L (проверьте опечатку, например 'product_status_runnig_low' вместо 'running_low').
  • Конфликт ключей: Если другой плагин имеет $L['product_status_available'] — добавьте уникальный префикс, но для значений это редко.
  • ALTER не сработал: Проверьте права БД, или установите noalter=true и добавьте колонку вручную SQL: ALTER TABLE cot_pages ADD page_product_status VARCHAR(255) DEFAULT ''.

Шаг 7: Расширенные советы (для полноты)

  • Для checklistbox: Тип 'checklistbox', варианты те же, но значение в БД — 'available,out_of_stock' (через запятую). В выводе: cot_build_extrafields_data() локализует каждый и соединит через $extrafield['field_params'] (по умолчанию ', ').
  • Обновление: cot_extrafield_update('pages', 'old_name', 'product_status', ... ) — изменит имя колонки в БД.
  • Удаление: Нет встроенной, вручную: DELETE FROM cot_extra_fields WHERE field_name='product_status' AND field_location='pages'; ALTER TABLE cot_pages DROP page_product_status;
  • Многоязычность: Создайте my_shop.en.lang.php с $L['page_product_status_title'] = 'Product Status';
  • Интеграция с поиском: В запросах SQL используйте page_product_status для фильтров.
  • Если для structure: location='structure', prefix='structure_', tag='CAT_PRODUCT_STATUS'.
8 minutes read Sodium Carbonate

Comments (0)

No comments yet
Only registered users can post new comments

Content author

webitproff

Online

Sodium Carbonate

Last logged: 2026-09-03 16:47

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: 2026-03-01 08:36
  • Last update: 2026-04-24 06:19

Similar pages

Локализация экстраполей в Cotonti Пошаговая инструкция на примере поля "статус товара"
1 Экстраполя в Cotonti: полное руководство по созданию и локализации значенийВведениеCotonti — мощная и гибкая CMS с
Локализация экстраполей в Cotonti
2 Локализация экстраполей в Cotonti: полное пошаговое руководство для начинающих разработчиковЭкстраполя — это мощный
Локализация экстраполей в Cotonti Общий обзор
3 Локализация экстраполей в CotontiПолное практическое руководство для разработчиков: от механики движка до вывода в
Локализация значений экстраполей в TPL-шаблоне
4 Если вы уже начали знакомиться с API Cotonti Siena, то наверняка успели заметить,что вывод значений экстраполей с типом
API экстраполей в Cotonti (Extrafields API)
5 API экстраполей (Extrafields API)Экстраполя служат для дополнения определенными данными какие-либо сущности на сайте.