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
var $helpers = Array('Form', 'Tinymce');
Helper code
app/views/helpers/tinymce.php
<?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
<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 options
<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.








Html->script('/js/tiny_mce/tiny_mce.js', array('inline' => false, 'once' => true));
// Ties the options to the field
$tinyoptions['mode'] = 'exact';
$tinyoptions['elements'] = $this->_name($fieldName);
return $this->Html->scriptBlock('tinyMCE.init(' . $this->Js->object($tinyoptions) . ');', array('inline' => false));
}
/**
* 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);
}
}
?>
- delete/edit you own post
- properly include codeblocks
???
And why is "oldest" and "most recent" in the wrong place here?
Warning (512): Method TinyMceHelper::__name does not exist [CORE/cake/libs/view/helper.php, line 154]Using CakePHP 1.3
I think I've followed the tutorial faithfully, and I'm pretty sure I'm not supposed to edit anything in the libs directory. But that's where it seems to be looking for the TinyMceHelper method. Not sure why. Any help?
Thanks,
Sean
Warning (512): Method TinyMceHelper::__name does not exist [CORE/cake/libs/view/helper.php, line 154]Using CakePHP 1.3
I think I've followed the tutorial faithfully, and I'm pretty sure I'm not supposed to edit anything in the libs directory. But that's where it seems to be looking for the TinyMceHelper method. Not sure why. Any help?
Thanks,
Sean
[end quote] open your TinymceHelper class file in your editor
press Ctrl + F (Find & replace)
find '__name' and replace it with '_name'
The method wich have to be called, have to be named: _name() and not __name().
Sorry for my bad english...
I hope this tipp helps you.
Best regards
I too had the same problem, TinyMCE would work fine with debug set to 1 or higher, UI would not display with cakephp's debug set to 0. No errors in Firebug or Chrome's tools.
After a lot of trial and error, found that I had imagemanager and filemanager in Tiny's plugin list, which didn't exist. After removing these, it worked fine with Debug set to 0. Why CakePHP's debug level affects this, I have no clue.
I have update this to allow multi TinyMCE and add preset if we don't want to write every times the tinyoptions:
Helper Class:
<?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('tiny_mce/tiny_mce.js', false);
}
// Ties the options to the field
$tinyoptions['mode'] = 'exact';
$tinyoptions['elements'] = $this->domId($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(), $preset = null)
{
// If a preset is defined
if(!empty($preset))
{
$preset_options = $this->preset($preset);
// If $preset_options && $tinyoptions are an array
if(is_array($preset_options) && is_array($tinyoptions))
{
$tinyoptions = array_merge($preset_options, $tinyoptions);
}
else
{
$tinyoptions = $preset_options;
}
}
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(), $preset = null)
{
// If a preset is defined
if(!empty($preset))
{
$preset_options = $this->preset($preset);
// If $preset_options && $tinyoptions are an array
if(is_array($preset_options) && is_array($tinyoptions))
{
$tinyoptions = array_merge($preset_options, $tinyoptions);
}
else
{
$tinyoptions = $preset_options;
}
}
$options['type'] = 'textarea';
return $this->Form->input($fieldName, $options) . $this->_build($fieldName, $tinyoptions);
}
/**
* Creates a preset for TinyOptions
*
* @param string $name
* @return array
*/
private function preset($name)
{
// Full Feature
if($name == 'full')
{
return 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' => '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,blockquote,|,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,attribs,|,visualchars,nonbreaking,template,pagebreak',
'theme_advanced_toolbar_location' => 'top',
'theme_advanced_toolbar_align' => 'left',
'theme_advanced_statusbar_location' => 'bottom',
'theme_advanced_resizing' => true,
'theme_advanced_resize_horizontal' => false,
'convert_fonts_to_spans' => true
);
}
// Basic
if($name == 'basic')
{
return array(
'theme' => 'advanced',
'theme_advanced_toolbar_location' => 'top',
'theme_advanced_toolbar_align' => 'left',
'theme_advanced_statusbar_location' => 'bottom',
'theme_advanced_resizing' => true,
'theme_advanced_resize_horizontal' => false,
'convert_fonts_to_spans' => true
);
}
// BBCode
if($name == 'bbcode')
{
return array(
'theme' => 'advanced',
'plugins' => 'bbcode',
'theme_advanced_buttons1' => 'bold,italic,underline,undo,redo,link,unlink,image,forecolor,styleselect,removeformat,cleanup,code',
'theme_advanced_buttons2' => '',
'theme_advanced_buttons3' => '',
'theme_advanced_toolbar_location' => 'top',
'theme_advanced_toolbar_align' => 'left',
'theme_advanced_styles' => 'Code=codeStyle;Quote=quoteStyle',
'theme_advanced_statusbar_location' => 'bottom',
'theme_advanced_resizing' => true,
'theme_advanced_resize_horizontal' => false,
'entity_encoding' => 'raw',
'add_unload_trigger' => false,
'remove_linebreaks' => false,
'inline_styles' => false
);
}
return null;
}
}
?>
Sorry for my english =D
<?php echo $scripts_for_layout; ?>
in my view...just in case anyone else new to cake is wondering.
Taff
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 :-)
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 :)
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?
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?
I need for multiple language editing.
Thanks
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
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.
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>
Comments are closed for articles over a year old