Делаем собственный Zend_Form_Decorator для MarkItUp
На кого расчитана эта статья
В первую очередь на новичков в Zend Framework, по своему опыту знаю, что сначала возникает много вопросов. Надеюсь кому-нибудь будет полезно.
Что мы получим в итоге
Мы напишем декоратор для Zend_Form_Element, который будет активировать плагин markItUp для текстареи. Так же добавим пару своих кнопок: для отображения редактора на полный экран и вызов файлового менеджера.
Почему MarkItUp
На мой взгляд это очень хороший инструмент для создания форматированного текста. Я его использую в своем собственном проекте, который сейчас разрабатываю на Zend Framework. Не похдодит правда для обычных пользователей. Для моих задач подходит идеально.
Поехали
Первым делом нужно добавить нашу собственную библиотеку в Zend_Loader. Просто в application.ini добавим наш namespace(в данном случае это «CC», аббревеатура моего будущего проекта):
autoloadernamespaces[] = CC
Структуру и именование можно прочитать в документации к Zend Framework.
Итак создаем класс CC_Form_Decorator_Element_MarkItUp. Файл должен лежать в директории /library/CC/Form/Decorator/Element
class CC_Form_Decorator_Element_Markitup extends Zend_Form_Decorator_Abstract { public $helper = 'FormMarkitup'; public function render($content) { $element = $this->getElement(); $attribs = $element->getAttribs(); $options = $this->getOptions(); $view = $element->getView(); $helper = $this->helper; $view->$helper($attribs, $options); return $content; } }
В этом коде мы вызываем хелпер FormMarkItUp
Далее создаем хелпер CC_View_Helper_FormMarkitup в директории /library/CC/View/Helper
class Cave_View_Helper_FormMarkitup extends Zend_View_Helper_Abstract { protected $options = array( ); public function getOptions() { return $this->options; } public function FormMarkitup($attribs, $options = null) { if ($options AND is_array($options)) { $this->setOPtions($options); } $view = $this->view; //Включаем jQuery хелпер, для этого должно быть активирована библиотека ZendX $view->jQuery()->enable() ->setVersion('1.5'); //Подключаем нужные нам стили и JavaScript файлы $view->jQuery()->addJavascriptFile($view->baseUrl('scripts/markitup/jquery.markitup.js')) ->addJavascriptFile($view->baseUrl('scripts/markitup/sets/default/set.js')) ->addStylesheet($view->baseUrl('scripts/markitup/skins/simple/style.css')) ->addStylesheet($view->baseUrl('scripts/markitup/sets/default/style.css')); $id = $attribs['id']; $js = 'jQuery("#'.$id.'").markItUp(mySettings)'; $this->view->jQuery()->addOnLoad($js); } }
Кратко о том что происходит. Просто добавляем в head подключение плагина markItUp к нужной нам текстареи. Исполуется переменная mySettings которая определяет набор кнопок для markItUp. У меня она находится в файле scripts/markitup/sets/default/set.js
mySettings = { onShiftEnter: {keepDefault:false, replaceWith:' \n'}, onCtrlEnter: {keepDefault:false, openWith:'\n<p>', closeWith:'</p>\n'}, onTab: {keepDefault:false, openWith:' '}, markupSet: [ {name:'Heading 1', key:'1', openWith:'<h1(!( class="[![Class]!]")!)>', closeWith:'</h1>', placeHolder:'Your title here...' }, {name:'Heading 2', key:'2', openWith:'<h2(!( class="[![Class]!]")!)>', closeWith:'</h2>', placeHolder:'Your title here...' }, {name:'Heading 3', key:'3', openWith:'<h3(!( class="[![Class]!]")!)>', closeWith:'</h3>', placeHolder:'Your title here...' }, {name:'Heading 4', key:'4', openWith:'<h4(!( class="[![Class]!]")!)>', closeWith:'</h4>', placeHolder:'Your title here...' }, {name:'Heading 5', key:'5', openWith:'<h5(!( class="[![Class]!]")!)>', closeWith:'</h5>', placeHolder:'Your title here...' }, {name:'Heading 6', key:'6', openWith:'<h6(!( class="[![Class]!]")!)>', closeWith:'</h6>', placeHolder:'Your title here...' }, {name:'Paragraph', key: 'P', openWith:'<p(!( class="[![Class]!]")!)>', closeWith:'</p>' }, {separator:'---------------' }, {name:'Bold', key:'B', openWith:'(!(<strong>|!|<b>)!)', closeWith:'(!(</strong>|!|</b>)!)' }, {name:'Italic', key:'I', openWith:'(!(<em>|!|<i>)!)', closeWith:'(!(</em>|!|</i>)!)' }, {name:'Stroke through', key:'S', openWith:'<del>', closeWith:'</del>' }, {separator:'---------------' }, {name:'Ul', key: 'U', openWith:'<ul>\n', closeWith:'</ul>\n' }, {name:'Ol', key: 'O', openWith:'<ol>\n', closeWith:'</ol>\n' }, {name:'Li', key: 'L', openWith:'<li>', closeWith:'</li>', placeholder: 'list item..' }, {separator:'---------------' }, {name:'Picture', replaceWith:'<img src="[![Source:!:http://]!]" alt="[![Alternative text]!]" >' }, {name:'Link', openWith:'<a href="[![Link:!:http://]!]"(!( title="[![Title]!]")!)>', closeWith:'</a>', placeHolder:'Your text to link...' }, {separator:'---------------' }, {name: 'FileManager', key: 'F', className: 'fileManager', call: 'openFileManager'}, {name:'Clean', className:'clean', replaceWith:function(markitup) { return markitup.selection.replace(/<(.*?)>/g, "") } }, {separator:'---------------' }, {name:'Fullscreen', className:'fullscreen', call:'fullscreen' }, {name:'Preview', className:'preview', call:'preview' } ] }
Подробнее про наборы можно прочитать в документации. Для нас тут интересны только кнопки FileManager и Fullscreen. По клику на FileManager вызывается функция openFileManager, которая и открывает сам менеджер, например ElFinder. В котором нужно прописать callback на выбор файла для вставки кода в наш редактор.
jQuery.markItUp({replaceWith:'<img src="http://'+path+'" alt="[![Alternative text]!]"/>'});
Где path это путь до изображения. Так же будет предложено ввести альтернативный текст.
А кнопка Fullscreen будет просто вызывать функцию fullscreen, главной задачей которой, это переключение класса fullscreen для контейнера редактора. Код будет что-то вроде:
function fullscreen() { var container = jQuery('.markItUp'); container.toggleClass('fullscreen'); }
Код для css приводить не буду.
Итак, самый важный момент для нас. Создание самой формы с Zend_Form_Element_Textarea и нашим декоратором.
class Admin_Form_News extends Zend_Form { public function init() { parent::init(); $this->addPrefixPath('CC_Form_Decorator_Element','Cave/Form/Decorator/Element',Zend_Form::DECORATOR); $this->addElement('text','title',array( 'label' => 'Заголовок', ))->addElement('textarea','content',array( 'label' => 'Текст новости', 'rows' => '3', 'cols' => '80', )); $this->getElement('content')->addDecorator('Markitup'); } }
Пример простой формы для новости из 2х элементов: заголовок и содержание. Нужо просто вывести форму в нужной нам вьюхе.