Добавляем кнопку в Markdown-редактор OctoberCMS

Вообще, у OctoberCMS есть плагин Wysiwig Editors. С этим плагином можно из коробки получить для блог-постов поддержку TinyMCE, CKEditor и даже Froala. Но я все это попробовал и пришел к выводу, что мне встроенный Markdown-редактор как-то ближе — то ли ввиду чистоты HTML на выходе, то ли еще почему. Решил пока на нем остановиться.

Но есть у этого редактора недостаток: чтобы понять, как его расширить, надо покопаться в коде. Код чистенький, понятный, но покопаться надо. В общем, я покопался, теперь рассказываю, как добавить в Markdown-редактор новую кнопку на примере своего старого js-типографа.

TL;DR: рассматриваемый далее код можно опробовать в действии в составе плагина BlogArchive.

Чтобы внедрить скрипт, добавляющий кнопку редактор, воспользуемся документированным способом расширения форм через события в методе boot() плагина. Заодно и скрипт типографа сразу добавим:


public function boot() {
  Event::listen('backend.form.extendFields', function (Form $widget) {
    // добавляем скрипты только если у формы контроллер Posts
    if (!($widget->getController() instanceof \RainLab\Blog\Controllers\Posts)) {
      return ;
    }
    $widget->addJs('/plugins/graker/blogarchive/assets/js/typofilter.js');
    $widget->addJs('/plugins/graker/blogarchive/assets/js/typofilter-markdown-extend.js');
  });
}

Теперь сам скрипт добавления кнопки:

+function ($) {
  $(document).ready(function () {
    // ищем на странице редактор
    var editor = $('[data-control="markdowneditor"]').data('oc.markdownEditor');
    // создаем кнопку
    var button = {
      // Название кнопки:
      label: 'Typofilter',
      // иконка
      icon: 'magic',
      // после какой кнопки вставить
      insertAfter: 'formatting',
      // какой метод редактора выполнить по нажатию
      action: 'runTypofilter',
      // темплейт для замены
      template: '$1'
    };
    // определяем метод, который будет вызван по нажатию на кнопку
    editor.runTypofilter = function (template) {
      var editor = this.editor,
        pos = this.editor.getCursorPosition(),
        text = editor.session.getTextRange(editor.selection.getRange()).trim();
      if (!text.length) {
        // если выделение пустое, выделим весь текст
        editor.selection.selectAll();
        text = editor.session.getTextRange(editor.selection.getRange()).trim();
      }
      text = Typographus.process(text);
      // вставляем обработанный текст в редактор
      editor.insert(template.replace('$1', text));
      editor.moveCursorToPosition(pos);
      if (template.indexOf('$1') != -1) {
        editor.navigateRight(template.indexOf('$1'))
      }
      editor.focus();
    };
    // добавляем кнопку в редактор
    editor.addToolbarButton('typofilter', button);
  });
}(window.jQuery);
Тут нужно заметить, что если не использовать insertAfter (или insertBefore) в описании структуры кнопки, кнопка не добавится на основной тулбар. Это, видимо, баг, но пока вот так. Про работу с selection и range можно почитать здесь, а про набор иконок для кнопок — вот тут.

Вот и всё, кнопка типографа добавлена. Кстати, сам типограф, слегка подправленный, теперь живет на Гитхабе.

Комментарии