Создание плугина "Cut" для CKEditor 4

В этом туторе я расскажу, как сделать простенький плугин для CKE 4, который будет:

  1. Иметь кнопку на панели редактора.
  2. По нажатию на кнопку вставлять кусочек HTML-кода.
  3. Иметь своё CSS-оформление внутри редактора.

 

Сначала немного предыстории. В своём блоге я решил сделать так называемый "Кат". Это, если кто не знает, такая метка, которая вставляется в пост и по которой потом пост "режется": то, что над "катом" (обычно начальная короткая часть, содержащая в себе краткую суть всего поста) используется в виде "короткой версии" поста и попадает, например, на главную страницу или на индекс категории.

Я у себя использую CKEditor, и в нём даже есть уже кнопка "Вставить разрыв страницы для печати", которую я и хотел использовать для этой цели. Однако всё же решил сделать всё по-человечески: чтоб и кнопочка была, и выглядело по-цивильному, да и HTML-код свой.

Итак, задача:

Написать плугин для CKEditor, который делает кнопку на панели инструментов, по нажатию на которую в текущую позицию курсора вставляется следующее:

<div class="pagecut" contenteditable="false" ><!-- CUT --></div>

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

Задача поставлена, давайте её выполнять! Перво-наперво, я набрёл в Сети на этот замечательный (официальный, между прочим) туториал, который рассказывает, как сделать простейший плугин, вставляющий в позицию курсора текущую дату и время. То есть, по идее, перекроить его под мои нужды (вместо даты и времени вставлять свой HTML-код) было не очень сложно, и я уже решил, что переведу его потом на русский язык, но этому помешали две вещи:

  1. Тот тутор был под старую версию CKE 3.x, которая, по заверениям авторов, скоро отбросит коньки. С некоторыми оговорками почти тот же код работает и с CKE 4.х, но всё же зачем переводить заведомо устаревшую информацию?
  2. Перекроить под мои нужды только казалось несложным, на самом же деле мне пришлось поискать некоторую информацию, которую я собираюсь изложить здесь.

В итоге было принято решение написать свой собственный туториал. Итак, начнём!

Создание файлов для плугина

Для начала сделайте папку с названием плугина в папке plugins CKEditor'а. Наш плугин будет называться "Pagecut", поэтому папку я назвал "pagecut" (обратите внимание, с маленькой буквы!). Название папки должно соответствовать названию вашего плугина.

Теперь создайте в ней файлик plugin.js. Этот файл должен быть назван так и только так. В итоге должно получиться:

Минимальный исходный код

Теперь открываем plugin.js и внутри пишем:

CKEDITOR.plugins.add( 'pagecut',
{
    init: function( editor )
    {
        
    }
} );

Все плугины создаются при помощи функции CKEDITOR.plugins.add, которая должна получать название плугина и объект, свойство которого init должно представлять из себя функцию, которая вызывается при инициализации плугина.

Создание команды редактора

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

Для этой цели мы воспользуемся функцией addCommand. С её помощью мы опишем команду insertPagecut, которая, собственно, и будет вставлять наш код в позицию курсора.

            editor.addCommand( 'insertPagecut',
            {
                exec: function( editor )
                {                                    
                                    editor.insertHtml( 'Это произвольный текст' );
                }
            });

Описывается она в виде объекта, у которого пока только один метод, exec. Он содержит в себе функцию, которая будет исполнена при выполнении нашей команды insertPagecut.

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

Создание кнопки

Но как же мы используем наш плугин в редакторе, если у него нет кнопки? Надо её сделать. Для начала нам нужна иконочка. Она должна быть размером 16х16. Я сделал вот такую: . На ней изображена небольшая пила-ножовка и написано "cut". Уж не знаю, насколько достоверно, художником я себя никогда не считал. Почему пила, а не ножницы? Потому что они твёрдо ассоциируются с "cut" в смысле "в буфер обмена", а у нас тут совершенно иное.

Итак, иконка готова, давайте положим её в папку плугина. Чтоб был порядок, внутри папки плугина я создал ещё папочку images, куда положил иконку, названную icon.png. Теперь файловая структура у нас такая:

Вернёмся к коду. Для добавления кнопки используется метод addButton свойства ui инстанса редактора. Первый аргумент — название кнопки. Оно будет использоваться в дальнейшем для добавления её на панель инструментов. Второй аргумент - объект с такими свойствами: label - всплывающая подсказочка, command - команда, которую будет вызывать данная кнопка. В данном случае это insertPagecut, которую мы сделали выше. И icon — иконочка. Обратите внимание, что при помощи this.path можно получить текущее расположение папки с плугином.

            editor.ui.addButton( 'Pagecut',
            {
                label: 'Вставить кат',
                command: 'insertPagecut',
                icon: this.path + 'images/icon.png'
            } );

Подключение

Настала пора использовать наш плугин! Для этого нужно сделать две вещи в то месте, где у вас вызывается CKEditor.

Первая: В параметрах передать название нашего плугина через config.extraPlugins, чтобы CKEditor был в курсе, что его надо звгрузить.

В данном случае это делается так:

config.extraPlugins = 'pagecut',

Вторая: Разместить кнопочку на панельке. 

А именно куда-нибудь в конфиг панели инструментов пихаем наш 'Pagecut'.

Вот так выглядит мой config.js после всех манипуляций:

 

CKEDITOR.editorConfig = function( config ) {
    config.uiColor = '#9A9A9A',

    config.height=500,
    config.extraPlugins = 'pagecut',
    toolbar_Custom=
    [
        { name: 'clipboard',   items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
        { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ] },
        '/',
        { name: 'paragraph',   items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','BidiLtr','BidiRtl' ] },
        { name: 'links',       items : [ 'Link','Unlink','Anchor' ] },
        { name: 'insert',      items : [ 'Image', 'Table','HorizontalRule','Smiley','SpecialChar','PageBreak' ] },
        '/',
        { name: 'styles',      items : [ 'Styles','Format','Font','FontSize' ] },
        { name: 'colors',      items : [ 'TextColor','BGColor' ] },
        { name: 'tools',       items : [ 'Maximize', 'ShowBlocks','-' ] },
        { name: 'custom',       items : [ 'Pagecut' ] }
    ]

        
};

Если всё сделано верно, то, перезагрузив страницу, вы увидите нашу кнопочку, по нажатию на которую в позицию курсора вставляется "Это произвольный текст".

Хорошо, плугин работает. Но мы же хотим, чтобы он вставлял нам не текст, а HTML-код. Ок, давайте менять.

Вместо editor.insertHtml( 'Это произвольный текст' ); пишем editor.insertHtml( '<div class="abtocut" contenteditable="false" ><!-- CUT --></div>' );

Пробуем. Вот те раз! Вставляется только <!-- CUT -->. Что такое? Давайте что-нибудь другое попробуем.

editor.insertHtml( '<b>Ололо</b>' );

А получается почему-то <strong>Ололо</strong>.

В-общем, CKE бесцеремонно цензурирует то, что мы передаём в editor.insertHtml! Порывшись в документации, я обнаружил, что у этого метода есть второй аргумент, mode, который, по идее, указывает, нужна ли дополнительная корректировка. Но мне не удалось с его помощью заставить вставлять как надо. Всё равно переделывает и всё тут.

Покопавшись, я нашёл другое решение:

                    var element = CKEDITOR.dom.element.createFromHtml( '<div class="pagecut" contenteditable="false" ><!-- CUT --></div>' );
                    editor.insertElement( element );

Тут вначале создаётся DOM-элемент, который затем вставляется при помощи уже insertElement. Это позволяет предотвратить самодеятельность со стороны CKE. Проверяем:

 

Ага, вставляет то, что заказывали! Вот только жаль в самом редакторе это не видно. Да и на фронте — только через view source. Исправим положение.

CSS для собственных элементов в редакторе.

CSS вставляется при помощи CKEDITOR.addCss. Обратите внимание, что это метод на инстанса, а глобальный CKEDITOR. Вот такой я придумал css:

CKEDITOR.addCss("div.pagecut {background: no-repeat center url('"+this.path+"images/large.png');height: 75px;width: 150px;border: #000 3px dashed;}");

Простенько и со вкусом. Иконочка пилы в качестве фона:

А вот как оно выглядит в редакторе:

 

Ну, пожалуй, последнее. Внимательный читатель заметил атрибут contenteditable="false", который есть у вставляемого нами дива. Зачем он? А чтобы в редакторе ничего нельзя было написать внутрь его. Нам это совершенно ни к чему.

Вот и всё. Вы научились делать простейший плугин для CKEditor. В завершение, прилагаю архив с самим плугином.

До новых встреч!


You can leave a comment with "Facebook":
Не забывайте оставлять комментарии при помощи "ВКонтакте":
Яндекс.Метрика