Взаимодействие с пользователем играет решающую роль при работе с пользователем. Именно для решения этой задачи разработаны визуальные редакторы. В этой статье будет рассказываться о самом популярном из них — редакторе 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;
}
На практике оба метода имеют свои плюсы и минусы. Вы должны сами решить какой метод использовать вам.