Локализация экстраполей в 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 минут чтения Sodium Carbonate

Комментарии (0)

Комментарии отсутствуют
Добавление комментариев доступно только зарегистрированным пользователям

Автор контента

webitproff

Оффлайн

Sodium Carbonate

Последняя авторизация: 20.07.2026 04:22

  • Страница размещена: 01.03.2026 08:36
  • Последнее обновление: 24.04.2026 06:19

Похожие страницы

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