Делаем собственный 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х элементов: заголовок и содержание. Нужо просто вывести форму в нужной нам вьюхе.