i18n - устанавливаем локаль перевода только по селектору

Модификация плагина i18n для Cotonti – корректная работа селектора языка при добавлении и редактировании переводов. Устанавливаем язык перевода статьи из доступных в выпадающем списке.

0 Опубликована Опубликовано в: Cotonti Siena CMF > Авторские плагины для Cotonti

Статья: Модификация плагина i18n для Cotonti – корректная работа селектора языка при добавлении и редактировании переводов


1. Введение (Часть 1 общее)

Плагин i18n (интернационализация) является стандартным инструментом Cotonti для управления переводами страниц. Он позволяет создавать локализованные версии страниц на разных языках. Однако в процессе эксплуатации были выявлены серьёзные недостатки, связанные с определением языка при добавлении и редактировании переводов, что приводило к путанице и ошибкам. В данной статье описан процесс диагностики, внесённые изменения и итоговый функционал модифицированной версии плагина.


2. Исходная проблема

При работе с плагином наблюдались следующие проблемы:

  • При добавлении перевода язык определялся не из селектора в форме, а из глобальной локали (определяемой по URL, кукам или настройкам пользователя). В результате, даже если пользователь выбирал в форме другой язык, перевод сохранялся для текущего языка сайта (например, при выборе польского – сохранялось в английский).
  • Форма добавления могла не отображаться, если для текущей глобальной локали уже существовал перевод – плагин считал, что перевод уже есть, и перенаправлял на редактирование.
  • При редактировании перевода отсутствовала возможность сменить язык: локаль была жёстко привязана к той, с которой открыли форму. Если требовалось изменить язык перевода, приходилось удалять старый и создавать новый.
  • В шаблоне присутствовали два одинаковых поля name="locale" (одно для десктопа, другое для мобильных). При отправке браузер передавал оба значения, и PHP использовал последнее (мобильное), которое часто оставалось со значением по умолчанию.
  • При ошибках валидации (например, пустой заголовок) происходил редирект на ту же форму, но все введённые данные терялись, что было неудобно.

Таким образом, плагин в оригинале не позволял полноценно управлять переводами: селектор языка был декоративным, а реальная локаль бралась извне.


3. Поставленные задачи

На основе выявленных проблем были сформулированы следующие задачи:

  1. При добавлении перевода локаль должна браться исключительно из POST-поля locale (выбор пользователя), игнорируя все остальные источники.
  2. Гарантировать отображение формы добавления всегда, независимо от наличия перевода для глобальной локали.
  3. Добавить проверку на уникальность – не позволять создавать дубликаты для одного языка.
  4. Включить возможность смены языка при редактировании перевода, с соответствующей проверкой на существование целевой локали.
  5. Устранить дублирование селектора в шаблоне, оставив один элемент select с именем locale.
  6. Сохранять введённые данные при ошибках валидации, не сбрасывая поля формы.
  7. После успешного сохранения редиректить на страницу с той локалью, которую выбрал пользователь.

4. Реализованные изменения

4.1. Изоляция логики добавления (файл i18n.page.php)

В оригинале перед отображением формы всегда выполнялся запрос к таблице переводов с глобальной локалью. Мы изменили это:

if($a=='add'){
 $pag_i18n=[];
}else{
 $stmt=Cot::$db->query(...);// для edit/delete
}

Теперь при a=add массив $pag_i18n пуст, что гарантирует показ формы, даже если для текущей глобальной локали уже есть перевод.

4.2. Обработка POST при добавлении

  • Локаль получаем через cot_import('locale', 'P', 'ALP') – только из POST.
  • Добавлена проверка на существование перевода для выбранной локали (чтобы избежать дубля).
  • При ошибках (неверная локаль, пустой заголовок) редирект не выполняется – просто продолжаем выполнение, и форма отображается снова с заполненными данными (массив $pag_i18n хранит введённые значения).
  • При успехе – вставка записи в БД и редирект на страницу с выбранной локалью.

4.3. Обработка POST при редактировании

  • Добавлена обработка поля locale из POST: $new_locale = cot_import('locale', 'P', 'ALP');.
  • Проверка допустимости новой локали.
  • Если локаль изменилась, выполняется проверка на существование перевода для $new_locale.
  • Обновление записи в БД с условием по старой локали ($i18n_locale), а в массив данных включается новое значение ipage_locale.
  • При ошибках – форма отображается с заполненными полями (значения из POST), селектор сохраняет выбранное.
  • При успехе – редирект на страницу с новой локалью.
  •  

4.4. Формирование списка локалей для редактирования

$lc_list=$i18n_locales;
unset($lc_list[Cot::$cfg['defaultlang']]);// исключаем язык оригинала
$existing=cot_i18n_list_page_locales($id);
foreach($existingas$lc){
 if($lc!=$i18n_locale){
 unset($lc_list[$lc]);// убираем занятые, кроме текущей
 }
}

Это позволяет выбрать любую свободную локаль, а текущая остаётся доступной (чтобы можно было не менять язык).

4.5. Шаблон i18n.page.tpl

  • Удалён мобильный дубликат селектора (тот, что внутри правой колонки).
  • В верхнем блоке (где раньше был селектор только для десктопа) убраны классы d-none d-md-block, теперь он видим на всех устройствах.
  • В результате остался один элемент <select name="locale">, что исключает путаницу при отправке формы.
  • Добавлена подпись для селектора с использованием языковой константы {PHP.L.i18n_locale_selection} (при необходимости её можно добавить в языковые файлы).

4.6. Обработка ошибок без потери данных

При ошибках валидации редиректы заменены на повторное отображение формы. Для этого:

  • В блоке добавления: массив $pag_i18n заполняется из POST.
  • В блоке редактирования: значения полей берутся из POST через cot_import() внутри отрисовки.
  • Селектор сохраняет выбранное значение через переменные $selected_in_selector (для добавления) и $selected_in_selector = ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($new_locale)) ? $new_locale : $i18n_locale; (для редактирования).

5. Итоговый функционал

После внесённых изменений плагин работает следующим образом:

  • Добавление перевода:
    • Форма отображается всегда, независимо от наличия перевода для текущего языка.
    • Язык перевода выбирается строго через селектор.
    • Проверка на уникальность предотвращает создание дубликатов.
    • При ошибках все введённые данные сохраняются.
    • После успешного добавления пользователь переходит на страницу с выбранным языком.
  • Редактирование перевода:
    • В форме присутствует селектор языка, где отображаются все доступные для выбора локали (исключая уже занятые, кроме текущей).
    • Можно изменить язык перевода – запись будет обновлена для новой локали (с проверкой на уникальность).
    • При ошибках данные не теряются.
    • После успешного обновления – переход на страницу с новой локалью.
  • Удаление перевода: без изменений.
  • Обработка ошибок: все сообщения об ошибках выводятся через стандартный механизм cot_display_messages(), поля формы заполнены ранее введёнными значениями.
  • Совместимость: все хуки сохранены, плагин остаётся расширяемым.

6. Инструкция по обновлению

  1. Скопируйте модифицированные файлы:
    • plugins/i18n/inc/i18n.page.php
    • themes/ваша_тема/i18n.page.tpl (или plugins/i18n/i18n.page.tpl, если используется стандартный шаблон)
  2. Очистите кэш Cotonti:
    • Удалите содержимое папки datas/cache/.
    • Или через админ-панель: Администрирование → Очистка кэша.
  3. При необходимости добавьте языковые константы (в файлы lang/ru/lang.php, lang/en/lang.php и т.д.):

    $L['i18n_locale_selection']='Выберите язык';
    $L['i18n_translation_exists']='Перевод для этого языка уже существует';
  4. Проверьте работу согласно сценариям тестирования (см. раздел 7).

7. Тестирование изменений

Рекомендуется проверить следующие сценарии:

  • Добавление перевода:
    • Перейти на страницу добавления для страницы без переводов. Выбрать язык, заполнить поля, отправить – перевод создаётся для выбранного языка.
    • Попытаться добавить перевод для языка, который уже есть – должна появиться ошибка.
    • Отправить форму с пустым заголовком – поля не сбрасываются, ошибка отображается.
    • После успешного добавления проверить URL – он должен содержать выбранный язык (?l=xx).
  • Редактирование перевода:
    • Открыть существующий перевод на редактирование. В селекторе должен быть выбран текущий язык.
    • Изменить текст и выбрать другой язык (если он свободен) – после сохранения перевод должен отображаться для нового языка, старый исчезнуть.
    • Попытаться изменить язык на уже занятый – ошибка.
    • Отправить форму с ошибкой (пустой заголовок) – поля заполнены введённым текстом, селектор сохраняет выбранное значение.
    • После успешного редактирования редирект на страницу с новым языком.
  • Удаление перевода: проверить, что удаление работает корректно.

8. Заключение

Модифицированная версия плагина i18n полностью решает описанные проблемы. Теперь селектор языка выполняет свою прямую функцию – определяет локаль перевода при добавлении и позволяет изменять её при редактировании. Все внешние источники локали игнорируются, что исключает ошибки и неоднозначности. Улучшена также обработка ошибок – пользователь не теряет данные при неудачной отправке формы.

Данные изменения могут быть внедрены в любой проект на Cotonti, использующий стандартный плагин i18n, без потери совместимости с другими расширениями.

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

Оффлайн

Последняя авторизация: 17.10.2026 16:52

Обо мне кратко
Поддержка и разработка веб-проектов на CMF Cotonti: приватные мессенджеры через сайт, открытые и закрытые небольшие социальные сети, торговые площадки и маркетплейсы, портал биржи фриланса и услуг, каталоги товаров оптовых поставщиков, дропшиппинг-платформы, интернет-магазины и многое другое.
Смотреть разработки и скачать
Публичное портфолио моих работ и разработок
Телеграм для сообщений
@webitproff
Телеграм-канал
@s/aBuyFILE
Публичный профиль
  • Дата размещения 08.03.2026 14:56
  • Обновлено 08.03.2026 17:45

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

Интеграция Extrafields в плагин I18n в Cotonti CMF
1 Полное руководство по интеграции Extrafields в плагин I18n для Cotonti CMFВведениеШтатный плагин I18n (Content
Язык интерфейса пользователя и плагин i18n modified в Cotonti: полное руководство
2 Переменная $usr['lang'] в Cotonti и плагин i18n modified: полное справочное