Wednesday, October 17, 2012

Customized CKEditor ToolBars Based on User Roles

So let's say you've built a really cool content management system (CMS) using ckeditor which has you feeling all "rock star-like" when you suddenly realize that you can't have everyone hitting the SOURCE button on the toolbar (things can get pretty ugly...)

Here's how to display a different toolbar set based on user roles.

So I have two roles within my CMS - a super editor and a basic editor. The super editor sees the advance toolbar and the basic, sees the basic.

In my config.js files, I define my toolbars:

Here is my basic tool bar (Basic Editor Access):

config.toolbar_Basic =
[
    ['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink','-','About']
];

};


Here is my FULL tool bar (Super Editor Access):

   config.toolbar_Full =
[
    { name: 'document', items : [ 'Source','-','Save','NewPage','DocProps','Preview','Print','-','Templates' ] },
    { name: 'clipboard', items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
    { name: 'editing', items : [ 'Find','Replace','-','SelectAll','-','SpellChecker', 'Scayt' ] },
    //{ name: 'forms', items : [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton',
    //    'HiddenField' ] },
    '/',
    { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ] },
    { name: 'paragraph', items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv',
    '-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','BidiLtr','BidiRtl' ] },
    { name: 'links', items : [ 'Link','Unlink','Anchor' ] },
    //{ name: 'insert', items : [ 'Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe' ] },
    '/',
    { name: 'styles', items : [ 'Styles','Format','Font','FontSize' ] },
    { name: 'colors', items : [ 'TextColor','BGColor' ] },
    { name: 'tools', items : [ 'Maximize', 'ShowBlocks','-','About' ] }
];



Ok so here is my editor reference on the CFM page:

My textarea field

 <textarea id="englishText" class="ckeditor" name="englishText">#englishText#</textarea>





Code to show the different toolbars:

 <cfif session.user.roleID EQ 1>
    <script type="text/javascript"> // <![CDATA[
    CKEDITOR.replace( 'englishText', { toolbar : 'Full' });
    // ]]>
    </script>
<cfelse>
    <script type="text/javascript"> // <![CDATA[
    CKEDITOR.replace( 'englishText', { toolbar : 'Basic' });
    // ]]>
    </script>
</cfif>



I want to make a few notes about this code:

1. Notice I did not add the toolbar attribute to the textarea field
2. Notice I added the code UNDER the textarea field. For some reason that I don't know about and had to learn the HARD WAY (GRRRR....) the code has to go after the textarea.


Enjoy! :)

Tuesday, October 16, 2012

What to use instead of the evaluate function

I have seen on MANY occasions where it is highly advised to not use the ColdFusion evaluate function. Word on the street is, the function slows down processing of the code.

Well that's fine and dandy but if you do a search on this NO ONE gives you an alternative!!! (AUGH!!)

Well I have been using one - I can't credit it because I forgot where I found it.

Here goes:

Instead of this:    
<cfset response= evaluate("form.#VarName#")>

Use this:
<cfset response=form["#VarName#"]>


Enjoy!


More examples: 01.13.16


Instead of this: #Evaluate( "#session.languagePreference#SUBSECTION" )#

Use this: <cfset SUBSECTION = content["#session.languagePreference#SUBSECTION"]>


Monday, October 8, 2012

How to protect your Coldfusion tags in CkEditors

It too me soooo long to figure this one out. I dug through TONS of Google links to finally come up with a solution.  Enjoy!

First, lets walk through the steps of installing CKEditor

Step 1: Download the files here: http://ckeditor.com/download

Step 2: Follow the installation Instructions here: http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Installation

Step 3: Go to the SAMPLE files (see installation Instructions) and recreate one of the samples as your actual editing form. Make sure the following files are included on your editing form:


    <script type="text/javascript" src="ckeditor/ckeditor.js"></script>
    <script src="ckeditor/_samples/sample.js" type="text/javascript"></script>
    <link href="ckeditor/_samples/sample.css" rel="stylesheet" type="text/css" />

AND this is how to create the actual editor:

<textarea class="ckeditor" toolbar="Basic"  name="englishText"></textarea>

Step 4: Here is where the config.js file comes in. You'll want to open the config.js file (it's in the ckeditor root folder)  and add the following lines:

   
    config.protectedSource.push( /<\?[\s\S]*?\?>/g );
    config.protectedSource.push(/[^<]*(<h1>([^<]+)<\/h1>)/g);
    config.protectedSource.push( /<cfscript[\s\S]*?\/cfscript>/g );
    config.protectedSource.push( /<br[\s\S]*?\/>/g );   // BR Tags
    config.protectedSource.push( /<img[\s\S]*?\/>/g );   // IMG Tags
    config.protectedSource.push( /{exp:[\s\S]*?{\/exp:[^\}]+}/g );    // Expression Engine style server side code
    config.protectedSource.push( /{.*?}/g);
    config.protectedSource.push( /<tex[\s\S]*?\/tex>/g);
    config.protectedSource.push( /<object[\s|\S]+?<\/object>/g); // Protects <OBJECT> tags
    config.protectedSource.push( /<style[\s\S]*?\/style>/g); // Protects <STYLE> tags
    config.protectedSource.push( /<cfoutput[\s\S]*?\/cfoutput>/g); // Protects <CFOUTPUT> tags
    config.protectedSource.push( /<pre[\s\S]*?\/pre>/g);
    config.protectedSource.push( /<code[\s\S]*?\/code>/g);
    config.protectedSource.push( /<cfinclude[\s\S]*?\/cfinclude>/g);
    config.protectedSource.push( /<cfloop[\s\S]*?\/cfloop>/g);   
    config.protectedSource.push( /<cfset[\s\S]*?\/cfset/g);
   
   
config.protectedSource.push( /<cf[\s\S]*?>/gi ) ; // ColdFusion cf tags - OPEN.
config.protectedSource.push( /<\/cf[\s\S]*?>/gi ) ; // ColdFusion cf tags - CLOSE.

   
    config.ProtectedTags = 'cfquery|cfif|cfoutput|cfloop' ;



CKEDITOR.on( 'instanceReady', function( ev )
   {
     ev.editor.dataProcessor.writer.setRules( 'cfoutput',
         {
            indent : false,
            breakBeforeOpen : false,
            breakAfterOpen : false,
            breakBeforeClose : false,
            breakAfterClose : false
         });
       
          ev.editor.dataProcessor.writer.setRules( 'cfinvoke',
         {
            indent : false,
            breakBeforeOpen : false,
            breakAfterOpen : false,
            breakBeforeClose : false,
            breakAfterClose : false
         });
       
       
          ev.editor.dataProcessor.writer.setRules( 'cfloop',
         {
            indent : false,
            breakBeforeOpen : false,
            breakAfterOpen : false,
            breakBeforeClose : false,
            breakAfterClose : false
         });
       
           ev.editor.dataProcessor.writer.setRules( 'cfinclude',
         {
            indent : false,
            breakBeforeOpen : false,
            breakAfterOpen : false,
            breakBeforeClose : false,
            breakAfterClose : false
         });
       
           ev.editor.dataProcessor.writer.setRules( 'p',
         {
            indent : false,
            breakBeforeOpen : false,
            breakAfterOpen : false,
            breakBeforeClose : false,
            breakAfterClose : false
         }
         );
       
         /*// Output self closing tags the HTML4 and HTML5 way
ev.editor.dataProcessor.writer.selfClosingEnd = '>';*/
       
   }
   


Now, so far all of my CF tags are protected and it is working fine. If you see that I am missing something, let me know. Also let me know how this works for you.