Вы, вероятно уже поняли, что мой любимый визуальный редактор (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, пишите каменты – обсудим!

октября 14, 2008 в 0:23
не могли бы помочь – пробую встроить spaw на страницу формы по вашей методике. Но вместо содержимого textarea получаю сообщение:
Zend_Controller_Dispatcher_Exception: Invalid controller specified (spaw2) in E:\DOG\WEBDocs\z2\library\Zend\Controller\Dispatcher\Standard.php on line 249
При этом у меня spaw действительно лежит в подкаталоге приложения spaw2.
октября 15, 2008 в 9:38
dog-64, скорее всего дело в настройках .htaccess.
У меня правила для перезаписи выглядят так:
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1
Так все работает.
февраля 5, 2009 в 15:26
Пробывал интегрировать SPAW в Zend Framework сначала редактор отображается но затем появляется ошибка :
string(1217) «ERROR: Zend_Session::start() – D:\home\ru\library\Zend\Loader.php(Line:83): Error #2 Zend_Loader::include_once() [function.include]: Failed opening ‘SpawConfigItem.php’ for inclusion
не подскажите в чем может быть дело. Предполагаю что в браузер что то передается до начала сессии, но вывод же редактора происходит из вида, а сессия стартует в контроллере.
февраля 10, 2009 в 15:03
fire, столкнулся такой же проблемой, решилось так:
editor.class.php:
строку 618
$js_res .= $objname.’.scid = «‘.$this->config->storeSecureConfig().’»;’;
заменил на:
$js_res .= $objname.’.scid = «‘.session_id().’»;’;
надеюсь кому-нибудь помог ))
марта 9, 2009 в 14:45
Пока втыкаю в коды FCK, но закладочку сделалл, авось пригодится
ноября 9, 2009 в 19:03
визуальный редактор конечно
вещь важная
хочется чтобы был поудобнее
SPAW конечно заслуживает внимания