Using TinyMCE with CakePHP

By Jean-Baptiste Tréglos (jtreglos)
TinyMCE is a nice WYSIWYG web editor by Moxiecode, giving your users a very convenient way to edit HTML content. And guess what, its very easy to use it in your Cake apps !

What is TinyMCE ?


TinyMCE is a WYSIWYG editor by Moxiecode that you can find here : http://tinymce.moxiecode.com

Its very fast to load (much faster than FCKEditor last time i've tried, which is quite a long time ago now, I must admit...), easy to setup and configure. It isn't as powerful as FCKEditor (http://www.fckeditor.net/) in terms of text processing, but if all you need is a small WYSIWYG editor to get clean (X)HTML, TinyMCE is your boy.

Installation


First step, of course, is to download TinyMCE. You can do this here : http://tinymce.moxiecode.com/download.php. At the time of writing, latest version is 2.0.6.1, and has been for a few months. 2.0.6.1 is very stable. Once downloaded, unpack TinyMCE, and copy just the tinymce/jscripts/tiny_mce folder in /webroot/js. You don't need the rest of the archive (documentation, examples, etc.) on your webserver.

Configuration


Next step is to implement it in Cake. Its very easy. First, we need to add this to the layout(s) that will be used on the page(s) that will have the editor. Of course, you need to add the javascript helper to your $helpers array in your controller(s) :

PHP Snippet:

Download code <?php 
if(isset($javascript)):
    ...
    echo 
$javascript->link('tiny_mce/tiny_mce.js');
    ...
endif;
?>


Then, for each page that will have a TinyMCE editor, you'll have to add to the top of the view file :

HTML:

Download code
<script type="text/javascript">
    tinyMCE.init({
        theme : "simple",
        mode : "textareas",
        convert_urls : false
    });
</script>


By default, there are 2 themes with TinyMCE : 'simple' and 'advanced'. You specify the one you want to use on your page with the theme parameter. You can create your own themes or modify the existing ones in the webroot/js/tiny_mce/themes folder. The mode parameter is set here to 'textareas', meaning that all textareas of the page will be replaced by TinyMCE editors of the same size. If this behaviour doesn't satisfy you, check the documentation (http://tinymce.moxiecode.com/tinymce/docs/option_mode.html). The last parameter, convert_urls, is set to false so that TinyMCE doesn't try to process URLs for images or links.

There are loads of other parameters (All documented here : http://tinymce.moxiecode.com/tinymce/docs/index.html) to customize the way the editor will work. For example, the file_browser_callback allows you to give a js callback function or method to call a custom file browser for the image insertion popup dialog.

If you want to change the way the text in the editor appears, each theme has a css/editor_content.css file that you can modify to match your site's styles.

 

Comments 60

CakePHP Team Comments Author Comments
 

Question

1 Is it really that simple

Jean,

Should we add TinyMCE to the bakery?
Posted Sep 25, 2006 by gwoo
 

Comment

2 Preventing duplicate code

If you like the DRY principle (Don't Repeat YOurself) as much as I do, you will probably want to put those 7 javascript lines in a seperate .js file that you can then "call" with for example the javascript helper.

Or even better: what i did is put those lines in an element, so that you can pass arguments to it if you want to call tinyMCE with some options (like theme, mode,...)
Posted Sep 25, 2006 by Dieter Plaetinck
 

Question

3 Can you give me some example

If you like the DRY principle (Don't Repeat YOurself) as much as I do, you will probably want to put those 7 javascript lines in a seperate .js file that you can then "call" with for example the javascript helper.

Or even better: what i did is put those lines in an element, so that you can pass arguments to it if you want to call tinyMCE with some options (like theme, mode,...)


Can you show me an (or some) example(s)?
Posted Oct 6, 2006 by Fendy Limanto
 

Comment

4 example of using elements for DRY approach

here's an excerpt of some code i once wrote:
app/views/elements/tinymce.thtml:

View Template:


<?php echo($javascript->link("tinymce/jscripts/tiny_mce/tiny_mce.js"));
?>
<script language="javascript" type="text/javascript">
<?php if($preset "basic")
{
    
$options '
    mode : "textareas",
    theme : "advanced",
    theme_advanced_buttons1 : "bold,italic,underline,separator,justifyleft,justifycenter,justifyright, justifyfull,bullist,numlist,undo,redo,link,unlink",
    theme_advanced_buttons2 : "",
    theme_advanced_buttons3 : "",
    theme_advanced_toolbar_location : "top",
    theme_advanced_toolbar_align : "left",
    theme_advanced_path_location : "bottom",
    extended_valid_elements : "a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]",
    content_css : "/css/'
.$this->layout.'.css"    
    '
;
}
?>

tinyMCE.init({<?php echo($options); ?>});
</script>


then, whereever i need it in a view, i just call it like this

View Template:


<?php echo $this->renderElement('tinymce',array('preset' => 'basic')); ?>


the 'basic' preset if one i created myself, change or expand to your likings :)
Posted Oct 8, 2006 by Dieter Plaetinck
 

Comment

5 This is a good idea

This is an excellent idea ! Putting those few js lines in an element would avoid repetition of this code, and be evolutive enough to allow for params for specific instanciations.

I guess I'm not DRY enough ;)
Posted Oct 8, 2006 by Jean-Baptiste Tréglos
 

Comment

6 Its your call

I'd rather use a WYSIWYG editor like TinyMCE when the editing has to be done by non-techy type of people. I guess (hope !) that people writing to the Bakery are technically savvy enough not to need such a tool...

Because even if WYSIWYG editors are great tools for the layman, its main drawback is that the generated HTML is most of the time VERY bad code, likely to break a carefully planned CSS layout, and prevent the page from validating correctly.
Posted Oct 8, 2006 by Jean-Baptiste Tréglos
 

Comment

7 Simplify

Because even if WYSIWYG editors are great tools for the layman, its main drawback is that the generated HTML is most of the time VERY bad code, likely to break a carefully planned CSS layout, and prevent the page from validating correctly.

if you create an additional theme, you should be able to take out editting features you don't want your clients to use. in a lot of cases all you'll really need is inserting urls, paragraphs, headings, bulletted lists. if you don't want your client to break your css, don't allow any font sizing or coloring.
Posted Oct 12, 2006 by mike karthauser
 

Question

8 Tiny and AJAX

After submiting by ajax request a form, where textarea is handling by tinyMCE, this form (textarea elements) doesn't contain tiny again.

Was made follow this tutorial.

Why? Maybe anyone know ?
Posted Nov 3, 2006 by Tomek Ceszke
 

Comment

9 It is all in how Tiny works

After submiting by ajax request a form, where textarea is handling by tinyMCE, this form (textarea elements) doesn't contain tiny again.

I've found the same problem. Basically Tiny replaces the textareas with iframes. Upon Submit, it uses javascript to pull the values from the iframe and populates your original field before the form gets submitted.


This causes all sorts of errors when used with Ajax.


I am still working out the details, but the answer lies in passing a command in your ajax call to load tiny again. Once I've got it worked out, I'll post a tutorial.

Posted Nov 3, 2006 by Tom OReilly
 

Comment

10 About Tiny and AJAX

In response to Tomek's comment #8:

There is a solution. I posted a new tutorial(http://bakery.cakephp.org/articles/view/140) that covers TinyMCE and AJAX.

Hope it helps.
Posted Nov 8, 2006 by Tom OReilly
 

Comment

11 Correction to example code

Please note a small typo in the excerpt of Dieter's code: the line
<?php if($preset = "basic")
should be
<?php if($preset == "basic")
A small, but important difference.

here's an excerpt of some code i once wrote:
app/views/elements/tinymce.thtml:

View Template:


<script language="javascript" type="text/javascript">
<?php if($preset == "basic")
{
    
$options 
    ... and 
so on...

Posted Dec 15, 2006 by Alexander Dolinin
 

Question

12 TinyMCE for beginners

As I have titled this comment, I am a beginner with cakePHP, and in general with MVC approach.
I succeded in testing the blog tutorial, but not the use of the tiny MCE editor. Would you please help me?

1- According to the DRY advice, I created a file, 'tinymce.thml' in 'app/views/elements'
2- Then added the suggested links to the javascripts within the default layout i.e 'app/views/layouts/default.thml'; e.g
echo $javascript->link('tiny_mce/tiny_mce');
3- Finally, added the following line
<?php echo $this->renderElement('tinymce',array('preset' => 'basic')); ?> within my 'add' view i.e 'app/views/posts/add.thml'

But: it does not work properly
I have a message like this 'Error rendering Element: tinymce'
Posted Jan 4, 2007 by Raymond
 

Comment

13 Forget WYSIWYG... Use WYSIWYM

As said before, WYSIWYG editors generate most of the time a very ugly html code...

Everyone should better use a WYSIWYM (what you see is what you MEANT) editor such as WYMeditor, that can be found here : http://www.wymeditor.org/. It's a powerfull tool that generates a beautiful code ;o)

Unfortunately, it supports only IE and gecko-based browsers, so if you're using Opera...
Posted Jan 14, 2007 by Adrien
 

Comment

14 Use TinyMCE to build a WYSIWYM

I like WYMeditor, but its not ready for production use just yet. Instead I use tinyMCE and modify the settings to replicate the same environment. I even used a stylesheet with similar styles to the WYMeditors to display the type of content the user is typing. At present the code is perfect and the users are very happy.
Posted Mar 27, 2007 by Mark Kirby
 

Comment

15 DRY element with added spell check and GZ compression and Jquery

Here is my reusable element, its basically the same as Alexander Dolinin's except i've added a little functionality on top an included the spellcheck plugin and php compression, and it ties it all together using jquery :)

View Template:


<?php 
/* SVN FILE: $Id$ */

/**
 * Reusable element for creating an compressed tinyMCE editor, with jquery. 
 *
 * This element expects 2 varables, $preset which determins the 
 * layout and features of the editor and an array $textareas which is
 * list of the ID's to which the editor should be applied.
 * 
 * Also the code uses the GZip compression to increase speed and the
 * curl based google spell checker plugin.
 * 
 * code taken from : 
 * http://wiki.moxiecode.com/index.php/TinyMCE:Compressor/PHP
 * http://dev.jquery.com/wiki/Plugins/tinyMCE
 * http://bakery.cakephp.org/articles/view/using-tinymce-with-cakephp
 *
 * PHP versions 5
 *
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright        Copyright 2006-2008, Alex McFadyen
 * @link                http://www.acmconsulting.eu acmConsulting
 *
 * @package        app
 * @subpackage    views.elements 
 *
 * @version            $Revision$
 * @modifiedby        $LastChangedBy$
 * @lastmodified    $Date$
 *
 * @license            http://www.opensource.org/licenses/mit-license.php The MIT License
 */

echo($javascript->link("tiny_mce/tiny_mce_gzip.js"));
?>
<script type="text/javascript">
tinyMCE_GZ.init({
    plugins : 'style,layer,table,save,advhr,advimage,advlink,emotions,iespell,'
                    +'insertdatetime,preview,media,searchreplace,print,contextmenu,'
                    +'paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,'
                    +'xhtmlxtras,spellchecker',
    themes : 'advanced',
    languages : 'en',
    disk_cache : true,
    debug : false
});
</script>
<script defer language="javascript" type="text/javascript">
<?php 
switch ($preset) {
    case 
'basic':
        
$options '
        mode : "none",
        theme : "advanced",
         plugins : "advhr,advlink,spellchecker,",
        theme_advanced_buttons1 : "bold,italic,underline,separator,justifyleft,justifycenter,justifyright, justifyfull,bullist,numlist,undo,redo,link,unlink,spellchecker,",
        theme_advanced_buttons2 : "",
        theme_advanced_buttons3 : "",
        theme_advanced_toolbar_location : "top",
        theme_advanced_toolbar_align : "center",
        extended_valid_elements : "a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]",
        content_css : "/css/'
.$this->layout.'.css"    
        '
;
    break;
    
    default:
        
$options '
         mode : "none",
       theme : "advanced",
       plugins : "advhr,advlink,spellchecker,",
       theme_advanced_layout_manager : "SimpleLayout",
       theme_advanced_disable: "hr,",
       theme_advanced_buttons1: "pasteword,justifyleft,justifycenter,justifyright,justifyfull,separator,removeformat,separator,charmap,advhr,",
       theme_advanced_buttons2: "styleselect,bold,italic,underline,separator,link,separator,bullist,numlist,outdent,indent,spellchecker,",
       theme_advanced_buttons3: "",
       theme_advanced_toolbar_location : "top",
       theme_advanced_toolbar_align : "left",
       content_css : "/css/'
.$this->layout.'.css"
         '
;
    break;
}

?>

    $(document).ready(function(){
<?php 
    
foreach($textareas as $id)
        echo(
"\t\t$('#$id').tinymce();");
?>
    });
    $.fn.tinymce = function(options){
        return this.each(function(){
            // I don't think the style declaration is not really used in this sense, but I left it anyway
            preString = "<div class='jqHTML_frame' style='width:"+$(this).css("width")+"px;height:" + ($(this).css("height")+20) + "px;'>";
            postString = "</div>";
            $(this).wrap(preString + postString);
            // this comes last to avoid IE7 bug
            tinyMCE.addMCEControl(document.getElementById(this.id), this.id);
        });
    }
    function initMCE()
    {
        tinyMCE.init({ <?php echo($options); ?>});
    }
    // initialize tiny mce
    initMCE();
</script>
Posted Jun 25, 2007 by Alex McFadyen
 

Comment

16 TinyMCE integration

I'm not new to PHP, but really new to Cake (started today with Cake). How can i add the Javascripts Helper to the $helpers array?
Posted Nov 18, 2007 by Christoph Hochstrasser
 

Comment

17 helpers

I'm not new to PHP, but really new to Cake (started today with Cake). How can i add the Javascripts Helper to the $helpers array?

Hi there welcome and enjoy the magic..
i have started this several months ago ...

so if you have some questions, please do ask, i know the frustrations of the lack of good documentations

your question's answer :

in the controller use this

Class TestController extends AppController {
var $name = 'Test';
var $helpers = array('Html','Form','Javascript');

function index() {
... something ...
}

}


hope this helps abit
Posted Dec 28, 2007 by joren
 

Comment

18 error javascript

Hi, I'm really new with cakephp.
using this code :

<?php
if(isset($javascript)):
...
echo $javascript->link('tiny_mce/tiny_mce.js');
...
endif;
?>

for include javascript, but I got error from my browser. the tinyMCE not present, cause my FireBug report error with this file (tiny_mce.js)

can I using javascripts with another way ?
thank's
sorry for my language
Posted Jan 13, 2008 by topan