Перейти к содержимому

Визуальный редактор - панель, сниппеты, чистка вставленного кода

Даём контент-менеджеру привычный редактор: подключение к своему полю, тип содержимого, готовые блоки и чистка вставленной из документа разметки.

Что нужно знать заранее

Редактор хранит рядом со значением ещё и тип содержимого. Одно поле держит текст, второе - признак «текст или HTML», и без второго поля вывод на витрине будет неверным.

Панель кнопок зависит от прав сотрудника. Вставка кода на языке платформы доступна только тем, у кого есть отдельная операция на правку такого кода.

Вставка из офисного документа тянет за собой чужие стили и служебные теги. Это главный источник сломанной вёрстки на страницах, которые ведёт менеджер, а не разработчик.

Шаги

  1. Решить, где менеджеру действительно нужен редактор, а где хватит текста.
  2. Подключить редактор к своему полю и завести поле для типа содержимого.
  3. Сохранять значение вместе с типом и учитывать тип при выводе на витрине.
  4. Собрать сниппеты для повторяющихся блоков вместо ручной вёрстки в редакторе.
  5. Чистить вставленную разметку на сохранении и проверять результат на витрине.

Решение

Подключаем редактор к своему полю:

\CModule::IncludeModule('fileman');
\CFileMan::AddHTMLEditorFrame(
'UF_TEXT', // имя поля формы
$text, // текущее содержимое поля
'UF_TEXT_TYPE', // имя поля с типом содержимого
$type, // text или html
['height' => 400, 'width' => '100%'] // размеры окна редактора
);
// модуль подключают до вывода формы, иначе редактор не отрисуется вовсе

Редактор рисует и поле ввода, и переключатель типа содержимого. Оба имени полей приходят в запрос вместе, и обрабатывать их тоже надо вместе.

Сохраняем значение вместе с типом:

$fields['UF_TEXT'] = $request['UF_TEXT'];
$fields['UF_TEXT_TYPE'] = $request['UF_TEXT_TYPE'] === 'html' ? 'html' : 'text';
// потерянный тип превращает вёрстку в текст с видимыми тегами на витрине

Тип содержимого теряют чаще самого текста. Симптом узнаваемый: на странице появляются теги в открытом виде, хотя в редакторе всё выглядело правильно.

Даём менеджеру готовые блоки:

<!-- /bitrix/snippets/s1/callout.html - файл появляется во вкладке сниппетов -->
<div class="callout callout--warning">
<p>Текст предупреждения</p>
</div>
<!-- имя файла становится названием блока в списке редактора -->

Сниппет появляется в отдельной вкладке редактора и вставляется одной кнопкой. Это дешевле любых инструкций: менеджер собирает страницу из готовых блоков и не пишет разметку руками.

Чистим вставленную разметку на сохранении:

$html = preg_replace('/\s(style|class|lang)="[^"]*"/iu', '', $html);
$html = preg_replace('/<\/?(o:p|span)[^>]*>/iu', '', $html); // мусор из документа
$html = preg_replace('/<!--\[if[\s\S]*?<!\[endif\]-->/iu', '', $html);
$fields['UF_TEXT'] = trim($html);

Чистка на сохранении надёжнее просьб «вставлять без форматирования». Список тегов и атрибутов подбирают под свой проект, а результат обязательно смотрят на самой витрине.

Проверяем права на код в редакторе:

printf("правка кода: %s\n", $USER->CanDoOperation('edit_php') ? 'есть' : 'нет');
printf("группы: %s\n", implode(',', $USER->GetUserGroupArray()));
// без этого права вставленный код платформы молча вырезается при сохранении

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

На витрине видны теги вместо оформленного текста.

Поле с типом содержимого не сохранено вместе со значением поля. Тип и значение приходят в запрос парой и обрабатываются тоже парой.

После вставки из документа поехала вёрстка страницы.

Вместе с текстом приехали чужие стили и служебные теги офисного пакета. Разметку чистят обработчиком на сохранении, а не просьбами к менеджеру.

Вставленный в редактор код платформы пропадает.

У сотрудника нет отдельной операции на правку такого кода. Право выдают явно и только тем, кто понимает последствия правки.

Редактор не открывается и поле остаётся пустым.

В консоли браузера видна ошибка скрипта редактора или его расширений. Чаще всего мешает свой код в шаблоне админки или устаревший кэш браузера.

Менеджеры каждый раз верстают блок заново и по-разному.

Повторяющиеся блоки не вынесены в сниппеты редактора. Готовый блок вставляется кнопкой и выглядит одинаково на всех страницах.

Частые вопросы

Где хранится тип содержимого поля?

В отдельном поле рядом со значением, обычно с тем же именем и признаком типа. У описания элемента инфоблока это штатное поле, у своего поля его заводят сами.

Можно ли убрать лишние кнопки с панели?

Да, состав панели задаётся настройками модуля и правами сотрудника. Менеджеру обычно оставляют текст, ссылки, картинки и сниппеты.

Как запретить вставку кода платформы?

Не выдавать сотруднику операцию на правку такого кода. Тогда вставленные вызовы вырезаются при сохранении и на витрину не попадают.

Чем сниппет отличается от включаемой области?

Сниппет вставляет разметку прямо в текст, а включаемая область живёт отдельным файлом. Общий блок для многих страниц делают областью, а не сниппетом.

Стоит ли давать редактор в каждом поле?

Нет, для коротких значений он только мешает и плодит лишнюю разметку. Редактор оправдан там, где менеджер собирает страницу целиком.

Смежное

Первоисточник