TinyMCE helper
This is a basic helper to make it really easy to use TinyMCE inside CakePHP.
Notes
To specify any TinyMCE options, provide the extra $tinyoptions array with the information. It'll be converted to JavaScript and used when creating the editor.Tiny MCE
Go and grab TinyMCE from its website http://tinymce.moxiecode.com/download.php and copy the /tinymce/jscripts/tiny_mce folder to the /app/webroot/jsController
Download code
var $helpers = Array('Form', 'Tinymce');
Helper code
app/views/helpers/tinymce.phpDownload code
<?php
class TinyMceHelper extends AppHelper {
// Take advantage of other helpers
var $helpers = array('Javascript', 'Form');
// Check if the tiny_mce.js file has been added or not
var $_script = false;
/**
* Adds the tiny_mce.js file and constructs the options
*
* @param string $fieldName Name of a field, like this "Modelname.fieldname", "Modelname/fieldname" is deprecated
* @param array $tinyoptions Array of TinyMCE attributes for this textarea
* @return string JavaScript code to initialise the TinyMCE area
*/
function _build($fieldName, $tinyoptions = array()) {
if (!$this->_script) {
// We don't want to add this every time, it's only needed once
$this->_script = true;
$this->Javascript->link('/js/tiny_mce/tiny_mce.js', false);
}
// Ties the options to the field
$tinyoptions['mode'] = 'exact';
$tinyoptions['elements'] = $this->__name($fieldName);
return $this->Javascript->codeBlock('tinyMCE.init(' . $this->Javascript->object($tinyoptions) . ');');
}
/**
* Creates a TinyMCE textarea.
*
* @param string $fieldName Name of a field, like this "Modelname.fieldname", "Modelname/fieldname" is deprecated
* @param array $options Array of HTML attributes.
* @param array $tinyoptions Array of TinyMCE attributes for this textarea
* @return string An HTML textarea element with TinyMCE
*/
function textarea($fieldName, $options = array(), $tinyoptions = array()) {
return $this->Form->textarea($fieldName, $options) . $this->_build($fieldName, $tinyoptions);
}
/**
* Creates a TinyMCE textarea.
*
* @param string $fieldName Name of a field, like this "Modelname.fieldname", "Modelname/fieldname" is deprecated
* @param array $options Array of HTML attributes.
* @param array $tinyoptions Array of TinyMCE attributes for this textarea
* @return string An HTML textarea element with TinyMCE
*/
function input($fieldName, $options = array(), $tinyoptions = array()) {
$options['type'] = 'textarea';
return $this->Form->input($fieldName, $options) . $this->_build($fieldName, $tinyoptions);
}
}
?>
View example
Download code
<div class="form-container">
<?php echo $form->create('Page'); ?>
<fieldset>
<legend>Page</legend>
<?php
echo $form->input('title');
echo $tinymce->input('content');
?>
</fieldset>
<?php echo $form->end('Save'); ?>
</div>
Here's an example supplying some extra tinyMCE configuration optionsDownload code
<div class="form-container">
<?php echo $form->create('Page'); ?>
<fieldset>
<legend>Page</legend>
<?php
echo $form->input('title');
echo $tinymce->input('content', null, array(
'theme' => 'advanced',
'theme_advanced_toolbar_location' => 'top',
'theme_advanced_toolbar_align' => 'left',
'theme_advanced_statusbar_location' => 'bottom',
));
?>
</fieldset>
<?php echo $form->end('Save'); ?>
</div>
Suggestions
Everyone should know that letting users submit HTML can be a bit risky when it comes to displaying it, unless you trust them of couse (like an admin user). If you want more general users taking advantage of something like this, I'd suggest looking into something like http://htmlpurifier.org/. This parses the HTML and can remove anything you don't want submitted.
Comments
Question
1 TinyMCE attributes for the textarea
Actually I need a configuration like the following one:
tinyMCE.init({
mode : "textareas",
theme : "advanced",
plugins : "inlinepopups,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras",
theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,|,visualchars,nonbreaking",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_statusbar_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]"
});
Thank you very much for you help.
Comment
2 TinyMCE attributes example
You basically pass the helper a third parameter that is a php array similar to the JavaScript object that TinyMCE usually gets.
Note that you shouldn't supply a "mode" since the helper will create that bit for you and tie it to the textarea automatically.
Hope that explains things,
Dave
Comment
3 solve the tinyMcc issue
View Template:
<div>
<?php echo $form->create('Page'); ?>
<?php
echo $tinymce->input('content', null, array(
'theme' => 'advanced',
"plugins" => "safari,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",
"theme_advanced_buttons1" => "newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,formatselect,fontselect,fontsizeselect",
"theme_advanced_buttons2"=> "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,image,code,|,insertdate,inserttime,preview,|,forecolor,backcolor,advhr,|,print,|fullscreen",
"theme_advanced_buttons3" => "",
//theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak",
"theme_advanced_toolbar_location" => "top",
"theme_advanced_toolbar_align" => "left",
"theme_advanced_statusbar_location" => "bottom",
"theme_advanced_resizing" => true,
));
?>
<?php echo $form->end('Save'); ?>
</div>
Comment
4 Multiple Instances in Same page
I need for multiple language editing.
Thanks
Comment
5 great helper
Comment
6 Multiple Instances
View Template:
echo $form->label('description', 'Description:');
echo $tinymce->input('description', array('label' => false, 'rows' => 20, 'cols' => 50));
echo $form->label('tech_description', 'Technical Description:');
echo $tinymce->input('tech_description', array('label' => false, 'rows' => 20, 'cols' => 50));
However this does not create two instances, the first one works fine, but the second one just creates a normal textarea box. Any suggestions?
Comment
7 Reply to: Multiple Instances
First you have to choose between a way:
If it's easier to convert all textareas to TinyMce-Editors (and optionally exclude some of them by CSS-class):
<?php
function _build($fieldName, $tinyoptions = array()) {
[...]
// Converts all textareas to TinyMCE-Editors, excluding textareas having the CSS-Class 'mceNoEditor'
$tinyoptions['mode'] = 'textareas';
$tinyoptions['editor_deselector'] = 'mceNoEditor';
[...]
}
?>
If you want have only editors on textareas having a certain CSS-class.
<?php
function _build($fieldName, $tinyoptions = array()) {
[...]
// converts only these textareas to TinyMCE-Editors having the CSS-Class 'mceEditor'
$tinyoptions['mode'] = 'specific_textareas';
$tinyoptions['editor_selector'] = 'mceEditor';
[...]
}
?>
For the second option you can modify to code of the input/textarea function to always insert the class. So if you use $tinymce->input the area will automatically turned into tinymce fields but fields created by $forms->textarea won't.
To achieve that you have to insert:
<?php
function textarea($fieldName, $options = array(), $tinyoptions = array()) {
if(isset($options['class'])){
$options['class'] = $options['class'].' mceEditor';
}else{
$options['class'] = 'mceEditor';
}
return $this->Form->textarea($fieldName, $options) . $this->__build($fieldName, $tinyoptions);
}
?>
(Do the same with function input.)
Hope that helps, Stevie :)
Comment
8 Suggestion to extension
Really cool, though I found one problem: One of my entries in the tinyMCE.init is not a variable, but a function:
When using $this->Javascript->object, it assumes that all values in the array are to be quoted, but this function is not.setup : function(ed) {
ed.onDblClick.add(function(ed, e) {
var attribute = ed.dom.getAttrib(e.target,'class');
// make sure it is the MathML span tag which has been doubleclicked
if(e.target.nodeName=="IMG" && attribute=="InteractiveGraph"){
var id = ed.dom.getAttrib(e.target,'id');
ed.execCommand("mceinteractivegraphs",false,id);
}
});
},
Hence, I came up with this extension:
Helper Class:
<?php
function _build($fieldName, $tinyoptions = array()) {
if (!$this->_script) {
// We don't want to add this every time, it's only needed once
$this->_script = true;
$this->Javascript->link('/js/tiny_mce/tiny_mce.js', false);
}
// Ties the options to the field
$tinyoptions['mode'] = 'exact';
$tinyoptions['elements'] = $this->domId($fieldName);
$manual_json = $tinyoptions['manual_json'];
unset($tinyoptions['manual_json']);
$json = $this->Javascript->object($tinyoptions);
$json = substr($json,0,strlen($json)-1).',';
if (!empty($manual_json)) {
foreach ($manual_json as $k => $v) {
$json .= '"'.$k.'":'.$v;
}
}
$json .= "}";
return $this->Javascript->codeBlock('tinyMCE.init(' . $json . ');',array('inline'=>false));
}
?>
I furthermore changed $this_>__name() to $this->domId(), because the 'elements' should be passed the id of the textarea, not the name.
My textarea element looks like this:
View Template:
<?php print $tinymce->textarea('Lesson.source',array(),array(
"theme" => "advanced",
"cleanup" => "true",
"manual_json" => array(
"setup" => str_replace("\n","",str_replace("\t","","function(ed) {
ed.onDblClick.add(function(ed, e) {
var attribute = ed.dom.getAttrib(e.target,'class');
if(e.target.nodeName=='IMG' && attribute=='InteractiveGraph') {
var id = ed.dom.getAttrib(e.target,'id');
ed.execCommand('mceinteractivegraphs',false,id);
}
});
}"))
),
));?>
I hope that is is of some help to others using advanced tinymce techniques!
Best regards,
Jesper :-)
Comment
9 More? :)
Stevie any chance you can give a little more explanation? I tried what you did, and when I save my data is getting lost somewhere... it's not showing up in $this->data. Do you have any idea what the issue may be?
Question
10 problem when running under debug 0