How to add TinyMCE to a Zend_Form

This post originally appeared on leftcolumn.net. I’ve moved it here because it is much more relevant to this site. Please update your bookmarks to this page. Thanks. J

I struck some annoying issues getting CKEditor to work on a recent project and switched to TinyMCE, which is faster to implement. Here’s how to make TinyMCE integrate with your Zend Forms.

1. Install

Download TinyMCE and put it somewhere the browser can find it. The important thing is that it needs to be accessible to the world, for example: /js/tinymce/, which on your server may be a path like /var/www/html/your_site/js/tinymce/.

2. .htaccess for TinyMCE

The .htaccess that sets up your index.php as the ZF bootstrap will greedily grab all requests ending in .php. It needs to exclude the php files that TinyMCE uses. So if your bootstrap code in .htaccess looks like this:

RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

you’ll need to change it. I typically only rewrite to /index.php if the requested file really doesn’t exist. So .htaccess should be something like this:


RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1

3. Zend_Form Elements

Here’s an example of a textarea element in a Zend_Form:
Important: You must filter out all tags and attributes that you don’t want to explicitly allow. The code below will allow any html permitted by TinyMCE to be uploaded. Use this in conjunction with a quality filtering tool such as HTMLPurifier.


$node_content = new Zend_Form_Element_Textarea('node_content');
$node_content->setLabel('Node Content')
->setRequired(false)
->setAttrib('cols', 40)
->setAttrib('rows', 12)
->addFilter('StringTrim')
->addValidator('NotEmpty')
->addValidator('StringLength', false, array(0,65534));

4. View Script

Let’s assume that you use Layouts, and that you only want to use TinyMCE on a couple of pages on your site. For reasons of economy you don’t want to include the TinyMCE code on every page, so do something like this in the View Script (Note: WordPress is messing with the quote marks in this block, ensure you have single quotes after src= and before the last semicolon. The other quotes should be double quotes.):


$this->custom_head = '<script src="/js/tinymce/tiny_mce.js" type="text/javascript"></script>';
$this->custom_head .= "<script language='javascript' type='text/javascript' src='/js/customs.js'></script>";

5. Layout Script

The scripts we have added in the View Script won’t bubble up to the Layout Script unless it knows about this new variable, so the Layout Script needs to know to refer to $this->custom_head if it is set. Drop the code below inside the section of your layout script:


if ($this->custom_head) {
echo $this->custom_head;
}

6. Start TinyMCE

Create /js/custom.js and put this in it:

tinyMCE.init({
mode : "textareas",
theme : "advanced",
theme_advanced_buttons1_add_before : "separator,insertdate,inserttime,preview,zoom,separator,forecolor,backcolor"
theme_advanced_buttons2_add_before : "bullist,numlist,separator,outdent,indent,separator,undo,redo,separator,link,unlink,anchor,image,cleanup,help,code"
theme_advanced_buttons3_add_before : "hr,removeformat,visualaid,separator,sub,sup,separator,charmap"
});

…You will probably want to customise the toolbar buttons.

7. Last Steps

It is vital that you install and configure HTMLPurifier if you haven’t already. Do not attempt to write your own filter!

No Comments

Be the first to start the conversation.

Leave a Reply

*

Text formatting is available via select HTML.

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>