CKSource Helper for CKEditor

This article is also available in the following languages:
By wernerhp
CKEditor is a text editor to be used inside web pages. It's a WYSIWYG editor, which means that the text being edited on it looks as similar as possible to the results users have when publishing it. It brings to the web common editing features found on desktop editing applications like Microsoft Word and OpenOffice.

This helper extends CakePHP's Form core helper. I created the ckeditor function to make it easy to add a CKEditor to any form. I called it CKSource so you can add CKFinder later and have all the CKSource products in one helper. This is still very basic, so feel free to submit changes in the comments.

Update: Added comment for single or double underscore regarding initInputField
Update: Added $this->webroot to base path. This should fix some problems when working in sub-directories.
Please rate and leave comments

Usage


1. Download CKEditor 3.1
2. Extract the archive to the webroot/js directory. i.e. webroot/js/ckeditor
3. Copy the the CKSource Helper (cksource.php) to the helpers directory.

Helper Class:

<?php 
class CksourceHelper extends FormHelper {

    var 
$helpers = array('Html');

    function 
ckeditor($fieldName$options = array()) {
        
//CakePHP 1.2.4.8284
        
$options $this->_initInputField($fieldName$options);
        
//If you have probelms, try adding a second underscore to _initInputField.  I haven't tested this, but some commenters say it works.
        //$options = $this->__initInputField($fieldName, $options);
        
$value null;
        
$config null;
        
$events null;

        if (
array_key_exists('value'$options)) {
            
$value $options['value'];
            if (!
array_key_exists('escape'$options) || $options['escape'] !== false) {
                
$value h($value);
            }
            unset(
$options['value']);
        }
        if (
array_key_exists('config'$options)) {
            
$config $options['config'];
            unset(
$options['config']);
        }
        if (
array_key_exists('events'$options)) {
            
$events $options['events'];
            unset(
$options['events']);
        }

        require_once 
WWW_ROOT.DS.'js'.DS.'ckeditor'.DS.'ckeditor.php';
        
$CKEditor = new CKEditor();
        
$CKEditor->basePath $this->webroot.'js/ckeditor/';

        return 
$CKEditor->editor($options['name'], $value$config$events);
    }
}
?>


4. Include fckeditor.js in each view that will use it, or in your layout if you'll be using it in several views. eg. default.ctp

View Template:


<?php
echo $javascript->link('ckeditor/ckeditor');
?>

5. Include the helper to your view's controller or the AppController. eg. app_controller.ctp

Controller Class:

<?php 
var $helpers = array('Html''Form''Javascript''Cksource');
?>

6. Now all that's left to do is create your form. Now instead of using $form you use $cksource. eg. demo.ctp

View Template:


<?php
echo $cksource->create('CKSource');
echo 
$cksource->ckeditor('example1');

$config['toolbar'] = array(
    array( 
'Source''-''Bold''Italic''Underline''Strike' ),
    array( 
'Image''Link''Unlink''Anchor' )
);
$events['instanceReady'] = 'function (ev) {
          alert("Loaded: " + ev.editor.name);
      }'
;

echo 
$cksource->ckeditor('example2', array('value'=>'It works!''config'=>$config'events'=>$events));
echo 
$cksource->end();
?>

Comments

  • Posted 08/12/11 09:26:27 AM
    Hello, tanks a lot for the Helper.

    I just made a little modification for use language and default setting. Instead user editor function I use replace function with a textarea generate with FromHelper.

    Also I copy php code in app/vendors and delete file we dont need in app/webroot/js/ckeditor such as .asp, .pack files and _samples folder.

    Here the code:
    array('Jquery'));

    /**
    * Sets field defaults for ckeditor: id, config and language.
    *
    * Options
    *
    * - string 'id': To access events, same as $field
    * - array 'config': If not indicate
    * - string 'language': Set the language from cake
    *
    * @param string $field Name of the field to initialize options for.
    * @param array $options Array of options to append options into.
    * @return array Array of options for the input.
    * @access protected
    */
    function _initInputField($field, $options = array()) {

    // It needs id for replace function
    if (!array_key_exists('id', $options)) {
    $options['id'] = $field;
    }

    // CKeditor only works in textarea inputs
    if(!array_key_exists('type', $options)) {
    $options['type'] = 'textarea';
    }


    // Defaults options
    if (!array_key_exists('config', $options))
    {
    $options['config']['toolbar'] = array(
    array( 'Source', '-', 'Bold', 'Italic', 'Underline', 'Strike' ),
    array( 'Image', 'Link', 'Unlink', 'Anchor' ),
    );
    }

    // Config language
    $lang = Configure::read('Config.language');
    if (isset($lang)) {


    // Load language
    $this->Js->buffer('CKEDITOR.config.language = \''.$lang.'\';');
    echo $this->Js->writeBuffer();
    }

    $result = parent::_initInputField($field, $options);


    return $result;
    }

    /**
    *
    * It shows a textarea with CKeditor
    * @param string $fieldName
    * @param array $options
    */
    function ckeditor($fieldName, $options = array()) {

    $options = $this->_initInputField($fieldName, $options);
    $value = null;
    $config = null;
    $events = null;

    if (array_key_exists('value', $options)) {
    $value = $options['value'];
    if (!array_key_exists('escape', $options) || $options['escape'] !== false) {
    $value = h($value);
    }
    unset($options['value']);
    }
    if (array_key_exists('config', $options)) {
    $config = $options['config'];
    unset($options['config']);
    }
    if (array_key_exists('events', $options)) {
    $events = $options['events'];
    unset($options['events']);
    }

    $CKEditor = new CKEditor();
    $CKEditor->basePath = $this->webroot.'js/ckeditor/';

    echo $this->Form->input($fieldName, $options);
    return $CKEditor->replace($options['id'], $config, $events);

    }
    }
    ?>
    • Posted 08/12/11 09:31:04 AM
      [quote] Hello, tanks a lot for the Helper...
      [end quote]
      I'm sorry. The code needs import vendor ckeditor.php and the Helpers Html, Form and Js:

      App::import('Vendor', 'ckeditor/ckeditor');

      class CksourceHelper extends FormHelper {

      var $helpers = array('Html', 'Form', 'Js' => array('Jquery'));
      ...
      }
  • Posted 05/29/11 02:49:34 PM
    The generation of the ckeditor textarea clashes with the security component. To avoid this use the $cksource->replace function and remove the $value var from the options.
    Just add $ckeditor->editor(fieldnamehere) after your textarea and it will replace it and post properly
  • Posted 11/16/10 07:31:13 PM
    whenever i do an edit where it loads a value with html tag the html tags are printed instead of being in the source?
    • Posted 06/24/11 04:10:00 PM
      [quote] whenever i do an edit where it loads a value with html tag the html tags are printed instead of being in the source?
      [end quote]
      I solved the problem by deleting the h() function in line 21 from the controller

      Like this:
      if (!array_key_exists('escape', $options) || $options['escape'] !== false) {
      $value = $value;
      }
    • Posted 04/02/11 03:27:19 PM
      [quote] whenever i do an edit where it loads a value with html tag the html tags are printed instead of being in the source?
      [end quote]
    • Posted 11/16/10 08:45:54 PM
      value from database (i.e. title) is loaded into Data Format on load instead of Source. Have you tried the helper when doing an edit? is there a config for this or what am I missing.

      [quote] whenever i do an edit where it loads a value with html tag the html tags are printed instead of being in the source?
      [end quote]
  • Posted 08/28/10 10:43:19 AM
    Hi everybody,
    first of all: Thank you Werner for the helper and the article.

    TWO OR ONE UNDERSCORES?
    For CakePHP version 1.2.4.8284 the _initInputField() call should stay with a single underscore only. Now that Werner updated his article, it means for you that you have to reverse his change :-)

    CKFINDER INTEGRATION
    Here's a brief how-to for integrating ckFinder. It doesn't cover issues with basic configuration, just Cake-specific stuff.

    Edit Werner's views/helpers/cksource.php and include ckfinder.php. I prefer to store ckfinder within ckeditor directory. Its location affects a lot of the code below.

    Helper Class:

    <?php 
    require_once WWW_ROOT.DS.'js'.DS.'ckeditor'.DS.'ckfinder'.DS.'ckfinder.php';
    ?>

    Then link ckFinder with ckEditor after creating $CKEditor:

    Helper Class:

    <?php 
    $CKFinder 
    = new CKFinder();
    $CKFinder->BasePath '/js/ckeditor/ckfinder/';
    $CKFinder->SetupCKEditorObject($CKEditor);
    ?>

    Edit function CheckAuthentication() in config.php in /js/ckeditor/ckfinder and add code that detects whether your user is authenticated. In my case I not only test whether the user is logged in but also whether he's an administrator.
    session_name("CAKEPHP");
    session_start();

    $isAdmin = false;
    $isLoggedIn = !empty($_SESSION["Auth"]);
    if ($isLoggedIn) {
      $isAdmin = $_SESSION["Auth"]['Member']['is_admin'];
    }

    return $isAdmin;

    In /js/ckeditor/ckfinder/config.php enter $baseUrl relatively to webroot and then replace this code
    $baseDir = resolveUrl($baseUrl); with
    $baseDir = realpath(dirname(__FILE__).'/../../../').$baseUrl; Please note that this particular relative path corresponds to my location of config.php.

    When invoking ckeditor in your code, make sure you call it with 'escape' = false, for example:
    echo $cksource->ckeditor('content', array('escape' => false)); otherwise image tags you insert using the ckFinder will be converted to entities when you edit the record.

    Petr


    Ramsuresh wrote:
    ...Please prefix one more underscore in this function, then it will work fine.
    $options = $this->__initInputField($fieldName, $options);
  • Posted 06/07/10 06:28:32 AM
    Hi Cakephp users,

    I have integrated ckeditor in my project.

    While integrating I am facing some issues. I find that issue and fixed it.

    I hope it will be useful for you guys :-)

    $options = $this->_initInputField($fieldName, $options);

    Please prefix one more underscore in this function, then it will work fine.

    $options = $this->__initInputField($fieldName, $options);

    Happy Coding :-)

    Cheers
    Ramsuresh
    ECGroup Datasoft Pvt Ltd.,
  • Posted 05/25/10 08:13:34 AM
    Hi, thanks for the article, how i can add ckfinder functionality in the above code so it works in cakephp 1.3?

    Thanks,
    Usman

  • Posted 01/31/10 12:49:31 PM
    Instead of including the ckeditor.php file from webroot could you not put it inside vendors folder and use App::import? That would be the proper cake way.
    • Posted 03/14/10 05:24:27 PM
      Instead of including the ckeditor.php file from webroot could you not put it inside vendors folder and use App::import? That would be the proper cake way.
      i could do that, yes. ckeditor.php is in ckeditor directory when you downlaod it from cksource, so to keep implementation of the helper simple, i left it there.

Comments are closed for articles over a year old