Text Editor Integration

Can anyone suggest any tutorial or guide to integrate textEditor (cKEditor or tinyMCE)?

Thanks in advance.

I don’t use existing extensions for TinyMCE. Instead I have a very lightweight widget:

extensions/tiny_mce/TinyMCE.php:




class TinyMCE extends CInputWidget

{

    public $editorOptions = array();

    

    public function run()

    {

        list($name, $id) = $this->resolveNameID();

        

        // Publishing assets.

        $dir = dirname(__FILE__);

        $assets = Yii::app()->getAssetManager()->publish($dir.DIRECTORY_SEPARATOR.'assets');

        $this->editorOptions['script_url'] = $assets.'/tiny_mce.js';

        

	// Registering javascript.

        $cs = Yii::app()->getClientScript();

	$cs->registerCoreScript('jquery');

        $cs->registerScriptFile($assets.'/jquery.tinymce.js');

        

        $cs->registerScript(

            'Yii.'.get_class($this).'#'.$id,

            '$(function(){$("#'.$id.'").tinymce('.CJavaScript::encode($this->editorOptions).');});'

        );

        

	$this->htmlOptions['id'] = $id;

        

        if($this->hasModel())

	    $html = CHtml::activeTextArea($this->model, $this->attribute, $this->htmlOptions);

	else

	    $html = CHtml::textArea($name, $this->value, $this->htmlOptions);

            

        echo $html;

    }

}



To don’t specify all parameters everytime I have some classes for different kinds of editors. Here is an example of a simple editor without any advanced buttons:

extensions/tiny_mce/TinyMCE_Simple.php:




require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'TinyMCE.php';


class TinyMCE_Simple extends TinyMCE

{    

    public $editorOptions = array(

        'language'=>'ru',


        'plugins'=>'paste,safari,inlinepopups',

        

        'theme'=>'advanced',

        'theme_advanced_buttons1'=>'pasteword, separator, bold, italic, underline, separator, undo, redo, separator, code',

        'theme_advanced_buttons2'=>'',

        'theme_advanced_buttons3'=>'',

        'theme_advanced_buttons4'=>'',

        'theme_advanced_toolbar_location'=>'top',

        'theme_advanced_toolbar_align'=>'center',

        'theme_advanced_statusbar_location'=>'bottom',

        'theme_advanced_path'=>false,

        'theme_advanced_resizing'=>false,

        'theme_advanced_path_location'=>'none',

        

	'force_br_newlines'=>true,

	'force_p_newlines'=>false,

        'forced_root_block'=>'',

    );

}



All options correspond to the TinyMCE built-in options.

All you need now is to download TinyMCE jQuery package and put it into extensions/tiny_mce/assets directory.

To use this widget with CActiveForm, write the following code:




	<div class="row">

        <?php

        $this->widget('application.extensions.tiny_mce.TinyMCE_Simple', array(

            'model'=>$model,

            'attribute'=>'attribute_name',

            'htmlOptions'=>array('style'=>'width: 100%; height: 350px;'),

        )); ?>

	</div>



Hope, it will work for you :)

Beside andy_s suggestion, maybe this will help you.

I also don’t use an extension from Yii website, instead i created mine, having in mind the idea of driver based editors(too much said at this moment), so i have an extension called “editor” structured like:




---extensions/

-----extensions/editor/

----------------------views/

----------------------views/ckeditor/

----------------------views/ckeditor/assets/

----------------------views/ckeditor/render.php

----------------------textEditorWidget.php




For now i only use ckeditor, therefore a single "driver", but tiny_mce can easily be added.

So, in views/ckeditor/assets i keep all the ckeditor files (ckeditor.js etc)

In the render.php file, near assets folder, i keep the logic for generating the editor

The textEditorWidget.php is the widget that renders the editor.




// textEditorWidget.php


<?php

/**

* Driver based loading of editors.

* This is just a starting point in this moment.

**/

class TextEditorWidget extends CWidget{


    private $editor='ckeditor';

    public $models;

    public $clientOptions=array();

    

    public function init()

    {

        $this->setScriptUrl();

    }

    

    

    public function run()

    {

        if(!is_array($this->models))

            throw new CHttpException(500,Yii::t('app',"Please provide an array of models")) ;

        

        $models=array();

        

        foreach($this->models AS $model)

        {

            if(!array_key_exists('instance',$model)||!array_key_exists('attributes',$model))

                throw new CHttpException(500,Yii::t('app',"The model params are not correct")) ;  

            

            $attributes=array();

            foreach($model['attributes'] AS $attributeName=>$attributeOptions)

            {

                $fieldName=CHtml::getActiveId($model['instance'], $attributeName);

                if(is_array($attributeOptions))

                    $options=$this->parseOptions($this->setOptions($attributeOptions));

                else

                    $options=$this->parseOptions($this->setOptions(array()));

                

                $models[]=array(

                    'fieldName'=>$fieldName,

                    'options'=>$options,

                );

            }

        }

        $this->render($this->editor.'/render',array(

            'models'=>$models,

        ));

    }

    

    /**

    * Just this for now.

    **/

    private function setOptions($options)

    {

        $defaults=array(

            'height'=>400,

            'width'=>'100%',

            'toolbar'=>'Basic',

            'resize_enabled'=>false,

        );

        return array_merge($defaults, $options, $this->getFileManager());

    }

    

    private function parseOptions($options)

    {

        $output=array();

        foreach($options AS $key=>$value)

        {

            $out=$key.':';

            if(is_bool($value))

                $out.=$value?'true':'false';

            elseif(is_numeric($value))

                $out.=$value;

            else

                $out.='"'.$value.'"';

            $output[]=$out;

        }

        return implode(",\n",$output);

    }

    

    private function setScriptUrl()

    {

        $publish=Yii::app()->assetManager->publish(Yii::getPathOfAlias('ext.editor').'/views/'.$this->editor.'/assets/',false,-1);

        Yii::app()->clientScript->registerScriptFile($publish.'/'.$this->editor.'.js');

    }

    

    private function getFileManager()

    {

        return array(

            'filebrowserBrowseUrl'=>Yii::app()->createUrl('elfinder/default/index'),

            'filebrowserWindowWidth'=>900,

            'filebrowserWindowHeight'=>600

        );

    }

    

    

}







// the render.php file


<script>

<?php foreach($models AS $model):?>

    CKEDITOR.replace('<?php echo $model['fieldName'];?>',{

        <?php echo $model['options'];?>

        ,enterMode : CKEDITOR.ENTER_BR // avoid the FF BUG

    });    

<?php endforeach;?>




function getTextareaContent(textareaId){

    if(typeof(CKEDITOR.instances[textareaId])!=='object'){

        return ;

    }

    return CKEDITOR.instances[textareaId].getData();

}


</script>




And i call the widget like:




<?php $this->widget('ext.editor.textEditorWidget',array(

    'models'=>array(

        array(

            'instance'=>$model,

            'attributes'=>array(

                'prize'=>array('width'=>700, 'height'=>200),

                'how_to_enter'=>array('width'=>700,'height'=>200),

                'extra_info'=>array('width'=>700,'height'=>80),

            ),

        ),

    ),

));?>



The above call will create 3 editors for prize/how_to_enter/extra_info fields of the $model.

You can pass as many models as you need and as many fields as you need in a single widget instance(that’s the huge advantage, many extensions will need a widget call for each editor instance).

Also, the render.php file, gives you a javascript function (getTextareaContent) to get the editor content in case you are doing ajax submissions.

This can be a good starting point for you. Anyway, once this extension is done in my own CMS i will share it with everybody…but it will take some time.

It did the same way as you have mentioned. But shows error:

The asset "E:\xampp\htdocs\myProject\protected\extensions\tiny_mce\assets" to be published does not exist.

I have too downloaded the tinyMCE. Where shall I have to keep this folder?

I also tired this but displays error:

The asset "/views/ckeditor/assets/" to be published does not exist.

I slightly modified in view part during calling widgets :

instead of ext.editor.textEditorWidget I modified with application.extensions.editor.textEditorWidget. Similarly in textEditorWidget.php in line no.83

extensions\tiny_mce\assets directory should containt TinyMCE (jQuery version) files:

  • langs

  • plugins

  • themes

  • … etc

andy_s, it displays just a text box with out editor. It also shows the following error:

$("#Ad_body").tinymce is not a function

Make sure all assets are published. On my local (slow) machine sometimes it takes over 30 seconds (what is more than the default max execution time) :huh: Also remove ‘language’=>‘ru’ from TinyMCE_Simple.php, because if you don’t have this language, a textbox won’t be displayed.

Publish You mean generation of related files & directory inside assets?? If so then the Yii has automatically done it. All the files and directories are resided in assets/e412b135/

I have also changed the ‘language’=‘en’

Still same error :




Application Log[15:21:48.446][trace][system.db.CDbCommand] Querying SQL: SHOW COLUMNS FROM `tbl_ad`in E:\xampp\htdocs\socialsite\protected\modules\ads\controllers\AdsController.php (65)

in E:\xampp\htdocs\socialsite\index.php (13)

[15:21:48.450][trace][system.db.CDbCommand] Querying SQL: SHOW CREATE TABLE `tbl_ad`in E:\xampp\htdocs\socialsite\protected\modules\ads\controllers\AdsController.php (65)

in E:\xampp\htdocs\socialsite\index.php (13)

[url=""]index..../create (line 154)[/url]


$("#Ad_body").tinymce is not a function 		[url=""]anonymous[/url]()index..../create (line 144)

[url=""]anonymous[/url] ()jquery.js 			(line 282)[url=""]anonymous[/url]()jquery.js (line 199)

[url=""]anonymous[/url] ()jquery.js			(line 25)

[url=""]anonymous[/url] ()index..../create 		(line 144)

[url=""]anonymous[/url] ()jquery.js 			(line 447)

[url=""]anonymous[/url] ()jquery.js 			(line 875)

[img]chrome://firebug/content/blank.gif[/img][url=""]$(function(){$("#Ad_body").tinymce({'l...te/assets/e412b135/tiny_mce.js'});});[/url]

[url=""]index..../create (line 144)[/url]




Yes, I mean files under (in your case) assets/e412b135/ directory. Make sure there is jquery.tinymce.js file. Or you can better try to replace all directory files with original (from the downloaded archive) manually. Also check, how it works in other browsers…

[font=arial, sans-serif][size="3"]Спасибо, очень много.[/size][/font] andy_s

You are welcome, but better speak english (translators are not very smart) :D