Вы, вероятно уже поняли, что мой любимый визуальный редактор (Rich Text Editor, по-буржуйски) – это SPAW Editor. Я уже неоднократно писал заметки о SPAW. В частности, о том, как подружить SPAW и WordPress, и как сделать плагин Spaw для Smarty. Сегодня пришло время подружить SPAW с не менее замечательной опенсорсной разработкой – Zend Framework.
Принципы интеграции
В общем-то, можно инстанционировать экземпляр SPAW просто в нужном контроллере действий, и передать его экземпляр скрипту вида, который выведет в нужном месте HTML-код. Но! Во-первых, это очень просто, а мы легких путей не ищем. А – главное – во-вторых, тогда потеряется возможность фильтрации и валидации введенных пользователями данных с помощью механизмов Zend_Form. Можно, конечно, самостоятельно произвести над данными необходимые действия. Но не кошерно это, что ли.
Итак, в этой статье я опишу, как сделать редактор SPAW полноценным элементом Zend_Form.
Для начала, разберем, что собой представляет HTML-вывод SPAW. Элементы ввода (для каждой страницы редактора) – это обычные textarea, которые обрамлены килобайтами трудночитаемого HTML и JS. Это довольно примитивная характеристика, но для понимания сути ее достаточно. Следовательно, нам необходимо всего лишь «завернуть» Zend_Form_Element_Textarea в соответствующую оболочку кода. Примерно так мы и поступим – мы напишем свой Zend_Form_Decorator.
Что необходимо
Так как SPAW может оперировать двумя типами объектов (объект редактора, собственно, и объект страницы), нам понадобится 2 соответствующих декоратора: My_Decorator_Spaw и My_Decorator_SpawPage.
При этом, My_Decorator_SpawPage – это вовсе не декоратор в философии Zend_Form, а лишь механизм, с помощью которого мы будем информировать My_Decorator_Spaw о наличие дополнительных страниц. Конечно это не правильно, но другого выхода я не придумал
. В свою очередь, такая реализация накладывает одно ограничение на использование: все дополнительные страницы редактора должны быть объявлены ДО объявления основной страницы.
Приступим
Для начала приведу код декоратора My_Decorator_SpawPage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/spaw2/spaw.inc.php';
class My_Decorator_SpawPage extends Zend_Form_Decorator_Abstract
{
public function render($content)
{
$element = $this->getElement();
$element->setDisableLoadDefaultDecorators(true);
$page = new SpawEditorPage($element->getName(),
$element->getLabel(),
$element->getValue(),
$element->getAttrib('direction'));
My_Decorator_Spaw::addPage($page);
return NULL;
}
} |
Как видите, он создает объект страницы и передает его статическому методу My_Decorator_Spaw::addPage(). Этот метод сохраняет объект в хранилище My_Decorator_Spaw::$pages. Позже, при рендеринге основной части SPAW, все объекты страниц SpawEditorPage будут изъяты из этого хранилища. Конструктору SpawEditorPage передаюся 4 параметра, которые устанавливаются с помощью соответствующих методов объекта Zend_Form_Element_Textarea. Для понимания этого механизма либо обратитесь к мануалу, либо посмотрите раздел «Пример использования» в этой статье.
Ниже приведен код второго декоратора – My_Decorator_Spaw. Комментарии приведены в самом коде.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| <?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/spaw2/spaw.inc.php';
class My_Decorator_Spaw extends Zend_Form_Decorator_Abstract
{
// объявим статическую переменную $pages - наше хранилище
static $pages = array();
// а это - статический метод для добавление объектов
// страниц редактора в хранилище
static function addPage($page) {
array_push(self::$pages,$page);
}
// метод render() вызывается автоматически в момент генерации
// кода элемента формы. Здесь и происходит перевоплощение обычной
// textarea в полноценный визуальный редактор
public function render($content)
{
// получим объект элемента формы для удобства доступа
// к его свойствам
$element = $this->getElement();
// на всякий случай отключим дефолтные декораторы
// для этого элемента
$element->setDisableLoadDefaultDecorators(true);
// создаем объект SpawEditor. В качестве параметров
// передаются свойства элемента.
$spaw = new SpawEditor($element->getName(),
$element->getValue(),
$element->getAttrib('language'),
$element->getAttrib('toolbarset'),
$element->getAttrib('theme'),
$element->getAttrib('width'),
$element->getAttrib('height'),
$element->getAttrib('stylesheet'),
$element->getLabel());
// А это - небольшая хитрость. Дело в том, что конструктору
// SpawEditor нельзя передать один параметр - направление письма.
// Поэтому мы создадим страницу редактора с тем же именем.
$page = new SpawEditorPage($element->getName(),
$element->getLabel(),
$element->getValue(),
$element->getAttrib('direction'));
$spaw->addPage($page);
// Дальше следует проверка наличия дополнительных свойств,
// и их установка для текущего объекта редактора
if ($element->getAttrib('hideModeStrip')) {
$spaw->hideModeStrip();
}
if ($element->getAttrib('hideStatusBar')) {
$spaw->hideStatusBar();
}
if ($element->getAttrib('setFloatingMode')) {
$spaw->setFloatingMode();
}
if (count($element->getAttrib('setStaticConfigValue')) > 0) {
foreach ($element->getAttrib('setStaticConfigValue') as $name => $value) {
SpawConfig::setStaticConfigValue($name,$value);
}
}
if (count($element->getAttrib('setConfigValue')) > 0) {
foreach ($element->getAttrib('setConfigValue') as $name => $value) {
$spaw->setConfigValue($name,$value);
}
}
if (is_array($element->getAttrib('toolbar'))) {
$toolbars = $element->getAttrib('toolbar');
$element->getAttrib('toolbar');
foreach ($toolbars as $toolbar) {
$spaw->addToolbar($toolbar);
}
}
// Настало время извлечь из хранилища объекты дополнительных
// страниц, и добавить объекту редактора
foreach (self::$pages as $page) {
$spaw->addPage($page);
}
// А дальше следует вывод. Комментарии, надеюсь, излишни.
$separator = $this->getSeparator();
$placement = $this->getPlacement();
$output = $spaw->getHtml();
switch ($placement) {
case (self::PREPEND):
return $output . $separator . $content;
case (self::APPEND):
default:
return $content . $separator . $output;
}
}
} |
Пример использования
Понять принцип использования вам поможет следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| // Создадим собственно объект формы.
$form = new Zend_Form();
// Теперь нужно создать элемент для дополнительной страницы редактора.
// В этом элементе будет содержаться перевод статьи на иврит.
// Создадим новый экземпляр Zend_Form_Element_Textarea,
// в качестве параметра конструктора передадим имя элемента
// формы - 'article_hebrew'
$page = new Zend_Form_Element_Textarea('article_hebrew');
// Установим для этой страницы Label
$page->setLabel('Hebrew translation');
// Следующие 2 строки применяют к элементу созданный нами
// декоратор My_Decorator_SpawPage
$page->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
$page->setDecorators(array('SpawPage'));
// При необходимости - указываем текущее значение элемента
// $page->setValue('Hebrew text');
// А теперь укажем направление текста - справа на лево.
$page->setOptions(array('direction' => 'rtl'));
// Теперь создадим основную страницу редактора с именем 'article'
$element = new Zend_Form_Element_Textarea('article');
// Установим Label
$element->setLabel('English article');
// Следующие 2 строки применяют к элементу декоратор My_Decorator_Spaw
$element->addPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
$element->setDecorators(array('Spaw'));
// При необходимости - указываем текущее значение элемента
// $element->setValue('111');
// Метод setOptions() устанавливает массив параметров для элемента.
// Эти параметры будут использованы для настройки объекта редактора.
// Больше информации об этих параметрах можно найти в документации по SPAW.
$element->setOptions(array('direction' => 'ltr',
'language' => 'ru',
'width' => '600px',
'height' => '400px',
'toolbar' => array('edit','font'),
'theme' => 'spaw2',
'stylesheet' => 'cust.css',
'hideModeStrip' => TRUE,
'setFloatingMode' => FALSE,
'hideStatusBar' => TRUE,
'setStaticConfigValue' => array('default_height' => '200px',
'default_width' => '200px'),
'setConfigValue' => array('default_height' => '500px',
'default_width' => '500px')));
// Вначале добавим в форму все дополнительные страницы редактора
$form->addElement($page);
// И лишь затем - основную страницу. Это связано с тем, что
// рендеринг элементов происходит в порядке их добавления.
$form->addElement($element);
// Теперь можно вывести форму или передать ее в скрипт вида либо на обработку.
echo $form->render(); |
Послесловие
Вероятно, я выбрал не очень «изящный» способ интеграции. Но он наиболее легко реализуем. Если у вас будут другие соображения, как подружить SPAW и Zend Framework, пишите каменты – обсудим!
Автор: Кирилл Павлюков
\\ Метки: PHP, SPAW, Zend Framework, Zend_Form, пример
Свежие комментарии