Программное создание плагина WYSIWYG в Drupal 7

NovaInfo 9, скачать PDF
Опубликовано
Раздел: Технические науки
Просмотров за месяц: 1

Аннотация

В статье рассказывается о программном создании фильтров для форматирования текста на примере модуля Emoticon. Данный модуль позволяет добавлять в содержимое сайта изображения в виде смайликов. Реализован фильтр, который заменяет акронимы смайликов на соответствующие изображения.

Ключевые слова

DRUPAL 7, CKEDITOR, HOOK_WYSIWYG_PLUGIN, WYSIWYG, ПЛАГИН, HOOK_WYSIWYG_INCLUDE_DIRECTORY, DRUPAL_ADD_JS, PAGEBREAK

Текст научной работы

Взаимодействие с пользователем играет решающую роль при работе с пользователем. Именно для решения этой задачи разработаны визуальные редакторы. В этой статье будет рассказываться о самом популярном из них — редакторе CKEditor. По-моему мнению этот визуальный редактор обеспечивает максимум возможностей по сравнению с другими редакторами. Если таких возможностей на данный момент не существует, то их не трудно разработать. В своей статье я расскажу как это реализовать.

Для взаимодействия визуальных редакторов и Drupal существует модуль WYSIWIG. Он позволяет добавить для форм ввода текста функциональность визуальных редакторов. Также он позволяет сторонним разработчикам, таким как мы с вами, добавлять свои плагины для расширения существующих возможностей. Покажу два метода как это можно реализовать.

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

hook_wysiwyg_plugin

Добавим в файл emoticon.module функцию emoticon_wysiwyg_plugin для перехвата hook_wysiwyg_plugin:

/** * hook_wysiwyg_plugin(). */function emoticon_wysiwyg_plugin($editor, $version) {  if ($editor == 'ckeditor') {    return array(      'emoticon' => array(        'path' => drupal_get_path('module', 'emoticon') . '/plugins',        'filename' => 'emoticon_ckeditor.js',        'buttons' => array(          'emoticon' => t('Смайлики'),        ),        'load' => TRUE,      ),    );  }}

Этот хук вызывается когда модуль WYSIWIG формирует список доступных плагинов. Выбираем визуальный редактор. Как ранее уже сообщал, мы будем работать с CKEditor. Поэтому в функции выбираем наш редактор и возвращаем результат. Результатом выполнения функции должен быть массив параметров. Нужно указать где располагается наш плагин. Создадим в подкаталоге модуля Emoticon директорию plugins. Здесь будет находиться наш плагин.

Плагином CKEditor является javascript функция, которую мы расположим в отдельном файле. Создадим файл emoticon_ckeditor.js и добавим в неё следующий код:

(function($) {  CKEDITOR.plugins.add('emoticon', {    init: function(editor) {      editor.addCommand('emoticon', new CKEDITOR.dialogCommand('emoticonDialog'));      editor.ui.addButton('emoticon',  {        label: Drupal.t('Смайлики'),        command: 'emoticon',        icon: this.path + 'icon.png'      });    }      });  CKEDITOR.dialog.add('emoticonDialog', function(editor) {    var g;    function grid(){      var icons = Drupal.settings.emoticon.icons, table = '', row;      do {        row = icons.splice(0,icons.length>10?10:icons.length);        table += '<tr><td>' + row.join('</td><td>') + '</td></tr>';      } while (icons.length > 0)      return '<table>' + table + '</table>';    }    return {      title: 'Выберите смайлик',      minWidth: 400,      minHeight: 400,       contents:      [        {          id: 'general',          label: 'Settings',          elements:          [            {              type: 'html',              html: grid(),              onLoad:function(o){                g=o.sender;              },              onClick:function(e){                var                  elem=e.data.getTarget(),                  name=elem.getName();                  if(name=='td')                    elem=elem.getChild(0);                  else if(name!='img')                    return;                var                  src=elem.getAttribute('src'),                  title=elem.getAttribute('title'),                  t=editor.document.createElement('img', {attributes:{                    src:src,                    title:title,                    alt:title,                    width:elem.$.width,                    height:elem.$.height                  }});                  editor.insertElement(t);                  g.hide();                  e.data.preventDefault();              },            },          ]        },      ],      buttons:[CKEDITOR.dialog.cancelButton]    };  });})(jQuery);

CKEDITOR.plugins.add

Метод CKEDITOR.plugins.add позволяет нам добавить плагин для визуального редактора CKEditor. Мы должны зарегистрировать диалоговое окно, о котором речь пойдет ниже. Затем добавляем саму кнопку. Метод Drupal.t позволяет нам использовать несколько языков. Применяется в javascript и является аналогом php функции t. Также указываем изображение для нашей кнопки. Файл изображения располагается в директории plugins, которую мы создали выше.

CKEDITOR.dialog.add

Метод CKEDITOR.dialog.add позволяет использовать диалоговое окно при нажатии на кнопку нашего плагина. В начале создаём функцию grid, которая формирует таблицу с нашими смайликами. Данные о смайликах мы получаем из Drupal. Как это реализовать мы поговорим немного позже.

Затем возвращаем результат в виде массива параметров. Указывает тип html-код. Сам код мы реализовали ранее. Указываем его также в параметрах. При клике мыши на диалоговом окне определяем какое изображение смайлика было выбрано. Получаем параметры этого смайлика и вставляем его в текст содержимого. Для этого предназначен метод editor.insertElement.

В завершение закрываем диалоговое окно.

Передача данных в javascript c помощью drupal_add_js

При формировании страницы в Drupal нам необходимо передать данные о смайликах в javascript. Для этого в файл emoticon.module добавим функцию emoticon_preprocess_html:

/** * hook_preprocess_html(). */function emoticon_preprocess_html(&$vars) {  $emoticon = new emoticon();  $package = variable_get('emoticon_package');  $values = $emoticon->getValues($package);  $icons = array();  foreach ($values[1] as $key => $value) {    $acronym = explode(",", $values[0][$key]);    $acronym = $acronym[0];    $icons[] = '<img src="' . $value . '" title="' . $acronym . '" />';  }  drupal_add_js(array('emoticon' => array('icons' => $icons)), 'setting');}

Данный метод использует хук hook_preprocess_html, который предназначен для перехвата действий при формировании страницы. Функция drupal_add_js позволяет передать параметры в javascript. Перед этим получаем данные о используемом пакете смайликов и считываем его.

Это был первый метод, который позволяет реализовать поставленную перед нами задучу. Напомню, что он основан на применении hook_wysiwyg_plugin.

hook_wysiwyg_include_directory

Второй метод использует хук hook_wysiwyg_include_directory, который позволяет указать для WISYWIG дополнительную директорию с плагином. В качестве примера создадим плагин CKEditor, который позволит добавлять в текст содержимого разделители страницы. В файл demo.module добавим функцию demo_wysiwyg_include_directory:

/** * hook_wysiwyg_include_directory(). */function demo_wysiwyg_include_directory($type) {  return $type;}

Далее создадим саму директорию. Для этого в подкаталоге нашего модуля создадим следующую структуру директорий и файлов:

— plugins
—— wysiwyg
——— demo_pagebreak
———— images
————— pagebreak.gif
———— demo_pagebreak.js
———— demo_pagebreak.css
——— demo_pagebreak.inc

Нужно использовать именно такую структуру для правильной работы плагина. Файл demo_pagebreak.inc использует hook_wysiwyg_plugin для того, чтобы добавить его к нашему визуальному редактору. Добавим в этот файл функцию demo_demo_pagebreak_plugin:

function demo_demo_pagebreak_plugin() {  $plugins['demo_pagebreak'] = array(    'title' => t('Page break'),    'icon file' => 'pagebreak.gif',    'icon title' => t('Добавить разрыв страницы'),    'settings' => array(),  );  return $plugins;}

Об этом хуке мы разговаривали ранее. Отличие в том, что здесь нужно вместо wysiwyg указать название нашего плагина demo_pagebreak.

Drupal.wysiwyg.plugins

В javascript файле необходимо добавить методы для нашего нового плагина следующим образом:

(function ($) {Drupal.wysiwyg.plugins['demo_pagebreak'] = {  // Описание методов})(jQuery);

Теперь нужно описать необходимые методы, которые будет использовать Drupal. В отличие от предыдущего метода, в этом можно форматировать текст средствами редактора. Мы можем в визуальном редакторе отображать html комментарий <!--pagebreak--> в виде блока, для которого применим css свойства из файла demo_pagebreak.css:

.pagebreak{  display:block;  border:0;  border-top:3px dotted #ccc;  margin:1em 0;  width:100%;}

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

Метод определения визуального отображения в виде форматированного блока:

  /**   * Определяет визуальное отображение   */  isNode: function(node) {    return ($(node).is('div.pagebreak'));  },

Метод для вставки в текст содержимого визуального отображения, либо самого комментария, в зависимости от вида редактора:

  /**   * Добавляет визуальное отображение, либо    */  invoke: function(data, settings, instanceId) {    if (data.format == 'html') {      var content = '<!--pagebreak-->';    }    if (typeof content != 'undefined') {      Drupal.wysiwyg.instances[instanceId].insert(content);    }  },

Метод, который будет выполнять замену <!--pagebreak--> на визуальное отображении при загрузке визуального редактора:

  /**   * Заменяет <!--pagebreak--> на визуальное отображение   */  attach: function(content, settings, instanceId) {    var pagebreak = '<!--pagebreak-->';    var placeholder = '<div></div>';    var pattern = new RegExp(pagebreak, 'ig');    content = content.replace(pattern, placeholder);    return content;  },

Метод, который будет выполнять обратную замену при выключении визуального редактора:

  /**   * Заменяет визуальное отображение на <!--pagebreak-->   */  detach: function(content, settings, instanceId) {    var pagebreak = '<!--pagebreak-->';    newContent = newContent.replace(/<div><\/div>/ig, pagebreak);    return newContent;  }

На практике оба метода имеют свои плюсы и минусы. Вы должны сами решить какой метод использовать вам.

Читайте также

Цитировать

Долганов, А.А. Программное создание плагина WYSIWYG в Drupal 7 / А.А. Долганов. — Текст : электронный // NovaInfo, 2012. — № 9. — URL: https://novainfo.ru/article/1487 (дата обращения: 11.06.2023).

Поделиться