Abr@X@bra.ru
Добавляем кнопку кода в визуальный редактор битрикса
Добавляем кнопку кода в визуальный редактор битрикса

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

15.02.2017
649

Разберем как поставить кнопку оформления кода в редакторе битрикса и прикрутим нормальную подсветку.

Как известно, в визуальном редакторе битрикса, который открывается при редактировании инфоблоков, нет кнопки вставки кода. Давайте устраним эту несправедливость

Для начала нам нужно подключить свои js скрипты в момент загрузки скриптов визуального редактора(ВР) битрикса.

И для этого нам надо зацепиться за событие OnBeforeHTMLEditorScriptRuns модуля fileman.

Сделать это можно 2 способами.

1 - это глобально зарегистрировать обработчик в БД.

$ev = \Bitrix\Main\EventManager::getInstance();
$ev->registerEventHandlerCompatible('fileman','OnBeforeHTMLEditorScriptRuns', 'ab.tools', '\AB\Tools\EventHandlers', 'onIncludeHTMLEditorScript');


2 - через файл /php_interface/init.php

$EventManager = \Bitrix\Main\EventManager::getInstance();
$EventManager->addEventHandlerCompatible('fileman','OnBeforeHTMLEditorScriptRuns', ['\AB\Tools\EventHandlers', 'onIncludeHTMLEditorScript']);

В обоих примерах у меня есть класс AB\Tools\EventHandlers а в нем метод onIncludeHTMLEditorScript и его код

    /**
	 * @method onIncludeHTMLEditorScript
	 */
	public static function onIncludeHTMLEditorScript()
	{
		$path = '/local/modules/ab.tools/asset';
		\CJSCore::RegisterExt('ab_html_edit', [
			'js' => [
				$path.'/js/shim/es6-shim.min.js',
				$path.'/js/shim/es6-sham.min.js',
				$path.'/js/react/react-with-addons.min.js',
				$path.'/js/react/react-dom.min.js',
				$path.'/js/htmlEditor/lib/prism.js',
				$path.'/js/htmlEditor/build/ab.htmlEditor.js',
			],
			'css' => [
				$path.'/js/htmlEditor/lib/prism.css',
				$path.'/css/ab_html_edit.css'
			]
		]);
		\CJSCore::Init(array('jquery','ab_html_edit'));
	}

Здесь CJSCore::RegisterExt регистратор своих расширений. Которые потом можно подключать через CJSCore::Init(). И теперь указанные скрипты и стили будут подключаться всякий раз, когда загружается ВР.

Наш основной файл - ab.htmlEditor.js, в нем нужно зацепиться за событие начала формирования редактора и добавить кнопку.

BX.addCustomEvent('OnEditorInitedBefore', function (editor) {
	this.AddButton({
		iconClassName: 'ab_html_edit_code',
		id: 'ab_html_edit_code_btn',
		name: 'test',
		handler: function (ev) {
			alert('жмакнули на кнопку');
		}
	});
});

addCustomEvent - обработка битриксовых кастомных событий. 

this.AddButton - метод добавления кнопки, принимает:
  • iconClassName - класс, который будет висеть на иконке
  • id - ид тега иконки
  • name - всплывашка при наведении на кнопку
  • handler - функция - обработчик клика на кнопку, с ним и будем работать.

Но просто вывести код - это легко. А вот хорошо бы еще и выбор языка прикрутить.

Я подумал, что самым оптимальным будет, при нажатии на кнопку кода, всплывающее окно, в нем выбор языка, текстарея для вставки кода, и по сохранению, все что было в текстарии должно завернуться в теги pre и code с нужными классами, и встать в редактор на то место, где стоит курсор.

Дополним обработчик события:

BX.addCustomEvent('OnEditorInitedBefore', function (editor) {
    // соберем объект стандартного диалогового окна для админки
	const codeDialog = new BX.CDialog({
		title: 'Вставка кода',
		content: "< div id="ab_code_editor">< /div>",
		min_width: 960,
		min_height: 600,
	});
	
	this.AddButton({
		iconClassName: 'ab_html_edit_code',
		id: 'ab_html_edit_code_btn',
		name: 'test',
		handler: function (ev) {
			codeDialog.SetSize({width: 960, height: 600}); // установим размер по дефолту
			codeDialog.Show(); // покажем окно
		}
	});
});

Далее все манипуляции будем проводить с помощью reactjs.

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

Остановлюсь на одном методе, для вставки кода в редактор.

let lang = '';
// вытащим выбранный язык
if (typeof this.state.selectedLang == 'object') {
	lang = 'language-' + this.state.selectedLang[0].value;
}
// установим класс для нумерации строк
let classPre = className(lang, {'line-numbers': this.state.showLineNum});

// соберем строку с кодом для вставки в редактор
let htmlCode = '<pre class="' + classPre + '"><code class="' + lang + '">';
htmlCode += this.state.codeText;
htmlCode += '</code></pre>';

// вставим код, в то место - this.BXEditor.selection.GetRange() - где сейчас курсор
this.BXEditor.InsertHtml(htmlCode, this.BXEditor.selection.GetRange());

// закрываем окно
dialog.Close();
setTimeout(() => {
	// обновляем контент редактора
	this.BXEditor.SetContent(this.BXEditor.GetContent());

	// и переинициализируем фрейм, чтоб стили раскраски кода применить
	this.BXEditor.ReInitIframe();
}, 50);

Здесь this.BXEditor = editor из BX.addCustomEvent('OnEditorInitedBefore', function (editor). Т. е. это объект редактора.

Для подсветки кода использовался плагин prism. Теперь в шаблоне сайта или компонента остается только подключить css и js этого плагина. И будет нормальная подсветка кода.



React.js, Javascript, Bitrix
Читайте также:
Как настроить каталог товаров Битрикс

Как настроить каталог товаров Битрикс

Иногда для размещения на сайте каталога товаров не подходит использование комплексного компонента Каталог и тр...
Читать
Как настроить вложенные ЧПУ Битрикс

Как настроить вложенные ЧПУ Битрикс

Начиная с версии 12.5 в продукте добавлена поддержка вложенных ЧПУ, т.е. при просмотре элемента каталога формируется абс...
Читать
Как настроить информационный блок для модуля поиск Битрикс

Как настроить информационный блок для модуля поиск Битрикс

При создании нового инфоблока важно, чтобы в его настройках были указаны правильные пути к просмотру элемента инфоблока...

Читать