Integrating HTML editing with FCKEditor

HTML Editing Overview

Many applications can benefit from HTML supplied by users. For example, an Announcements channel or Classifieds channel is much more functional if users can supply links and images in their descriptions.

A number of open source editors are available to convert HTML textareas into HTML editors. One of the most popular is the FCKEditor. FCKEditor supplies all the normal editing and styling functions (bold, color, justification, etc.) but also include the ability to insert images, links and other objects.

The one downside to these editors is that they depend on the browser support content-editing. Both IE and Mozilla browsers like Firefox fit into this category, but until May 2005, Safari and other KHTML browsers did not. Version 1.3 of Safari just announced content editing although FCKEditor has not yet had time to develop a KHTML version. Hopefully within the next year, FCKEditor will be functional on almost all platforms.

Installing the Basic FCKEditor

You can download FCKEditor (Currently 2.0 FC) from the above FCKEditor site. It is essentially a directory full of Javascript, CSS and image resources to implement the editor. To install in the portal, unzip the downloaded copy and move to your portal installation in the main directory. For example, on Tomcat, this might be in webapps/uPortal/fckeditor. I would keep a copy of this whole directory structure in a different area, but you can remove all directories that begin with an underscore.

I recommend that you make a copy of the fckconfig.js file and put it in the same directory (in the examples below I use myconfig.js). This files lets you set base directories, menu options and a variety of other options to customize the editor for different applications.

Finally, create a textarea out of HTML as you normally would, making sure that you give it a name for both the ID and name attributes of the text area. Immediately after this, include Javascript like the following:

Javascript to call FCKEditor

<textarea id="myeditor" name="myeditor" cols="80" rows="24" wrap="virtual/>

<script type="text/javascript">
    var name = 'myeditor';
    var base_url = window.location.href;
    base_url = base_url.substring(0,base_url.indexOf('/tag.'));
    var editor = new FCKeditor(name,'100%','400','Default') ;
    editor.BasePath= base_url + '/fckeditor/';
    editor.Width = '400px';
    editor.Height = 400px';
    editor.Config['CustomConfigurationsPath'] = editor.BasePath + 'myconfig.js';
    editor.ReplaceTextarea() ;
</script>

Note that there are a number of configuration parameters that can be set globally in your myconfig.js or locally for each editor as shown here.

Customizations to the Basic Editor

FCKEditor provides for a large number of customizations. For example, in myconfig.js you can control the menu options that appear:

Changing Menu Options
FCKConfig.ToolbarSets["Default"] = [
	['Source','DocProps','-','Save','NewPage','Preview','-','Templates'],
	['Cut','Copy','Paste','PasteText','PasteWord','-','Print','SpellCheck'],
	['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
	['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],
	['OrderedList','UnorderedList','-','Outdent','Indent'],
	['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
	['Link','Unlink','Anchor'],
	['Image','Table','Rule','Smiley','SpecialChar','UniversalKey','Comment'/*,'Placeholder'*/],
	//['Form','Checkbox','Radio','TextField','Textarea','Select','Button','ImageButton','HiddenField'],
	['TextColor','BGColor'],
	['About'],
	'/',
	['Style','FontFormat','FontName','FontSize']
] ;

FCKConfig.ToolbarSets["Basic"] = [
	['Bold','Italic','-','OrderedList','UnorderedList','-','Link','Unlink','-','About']
] ;

A simple and fully-loaded toolbar set are defined above. I have commented out the form options because my users don't need them for building simple HTML. However, you can choose whichever icons you desire by editing the above lists. Each array is a collection of tools that are grouped together. The dash give some space between them. You specify the toolbar in the new FCKEditor function (see previous Javascript example). You can change the background color of the toolbar by editing
fckeditor/editor/skins/default/fck_editor.css.

Initial fonts, pulldown items and colors can all be specified in this file.

Image and Link Browsing

The FCKEditor Image and Link tools include file browsers to browse files in directories on the portal. Follow these steps to configure your channel to supply these browsing functions:

  • Use the following Javascript in your HTML code:
    Javascript to implement file browsing
    <textarea id="myeditor" name="myeditor" cols="80" rows="24" wrap="virtual/>
    
    <script type="text/javascript">
        var name = 'myeditor';
        var base_url = window.location.href;
        base_url = base_url.substring(0,base_url.indexOf('/tag.'));
        var editor = new FCKeditor(name,'100%','400','Default') ;
        editor.BasePath= base_url + '/fckeditor/';
        var worker_url = '<xsl:value-of select="$baseWorkerURL"/>';
        editor.Width = '400px';
        editor.Height = 400px';
        editor.Config['BaseHref'] = base_url + '/' + worker_url;
        editor.Config['CustomConfigurationsPath'] = editor.BasePath + 'myconfig.js';
        var link_url = worker_url + '&amp;ServerPath=';
        var image_url = link_url + '&amp;Type=Image';
        // hack to convert to ampersands due to xslt processing
        image_url = image_url.replace(/amp;/gi,'');
        link_url = link_url.replace(/amp;/gi,'');
        editor.Config['ImageBrowserURL'] = editor.BasePath +     
            'editor/filemanager/browser/default/browser.html?Connector=../../../../../' + image_url;
        editor.Config['LinkBrowserURL'] = editor.BasePath +     
            'editor/filemanager/browser/default/browser.html?Connector=../../../../../' + link_url;
        editor.ReplaceTextarea() ;
    </script>
    

You will need to supply the baseWorkerURL to your XSLT and configure your channel to support IMimeResponse or IMultithreadedMimeResponse (see the attach CThemes.java). When the Link or Image browser button in the FCKEditor is clicked the ImageBrowserURL or LinkBrowserURL will be called. This will display the editor/filemanager/browser/default/browser.html. In turn, a command will be sent using the value specified by the Connector in the url above. The parameters sent back to your channel via the BaseWorkerURL may include

  • Command (GetFolder,GetFolderAndFiles,CreateFolder,FileUpload)
  • Type (Image etc.)
  • ServerPath (possible subdirectory to work from)
  • CurrentFolder (current folder selected when file browsing)
  • 'NewFolderName'

In CThemes, a ThemeState object (see attached ThemeState.java) is created for each user and this object is accessed in most of the channel's methods. In CThemes.setRuntimeData, ThemeState.setNextState is called to process the query parameters, which then calls ThemeState.connector. A DownloadWorker object is created (see attached DownloadWorker.java) to supply the necessary data. The actual data is provided to the browser when the portal framework calls CThemes.getInputStream.

Caution

This code will not run unmodified because file environments are different (this code is based on Hypercontent1.3 and special OpenAFS code). If you already have DownloadWorker code, you can replace these calls with your own.

In most cases, this code will return an XML file as response. The formats are explained on the FCKEditor site.

Displaying FileSystem Files in Editor

To display images and other files from the filesystem in the editor, the BaseHref must be set (see above example). Because BaseHref cannot include parameters, I have set the BaseHref to just the baseWorkerURL. The browser will append the relative URL filenames to this URL. The appended URL will then be sent to the channel. To capture this request, I have made the Channel privileged and inspect the URL in setPortalControlStructures. If BaseWorker is called with no query parameters, I strip off the filename and set the downloadfile field in ThemeState. When ThemeState.setNextState is subsequently called, I set up a DownloadWorker for the requested file.

Adding Plugins

Adding plugins isn't well documented but I have created a Comment plugin to demonstrate the process of creating plugins. You can insert a note and comment and it will appear when the mouse passes over the stickpin. It is still a work in progress (editing of existing comments has not been implemented and deleting is a bit problematic.)

To install, unzip the attached comment.zip file and put in the fckeditor/editor/plugins directory. Put the following line in your myconfig.js file after FcKConfig.PluginsPath:

FCKConfig.Plugins.Add( 'Comment', 'en,it') ;

In ToolbarSets, add the tool "Comment" to one of the arrays.

When the comment tool is clicked, the fck_comment.html will be displayed and prompts for the comment. The fckplugin.js file creates the FCKComment object and processes the comment when it is submitted. The appropriate HTML is then inserted into the HTML the user is entering.