Tutorial – Extending the IBM Connections Rich Text Editor

connections_logo.thumbnailThe editing experience in IBM Connections is pretty good. IBM has incorporated the open source CKEditor across many products – Connections, XPages applications, Quickr, and more. But a little known and not-so-incredibly documented aspect of the editor is that it’s extensible. That’s right, CKEditor accepts plugins to enhance the editing experience in many ways.

Some of these are quite individual such as new buttons that bring open dialogs. Some take advantage of external resources like spell checkers. Others are analytic like word and character counters. And custom plugins, where some of the real value lies, can do things as cool as word and link replacement, application embedding, and custom pattern recognition. We’ve used this bit of trivia to create a suite of plugins called SnappLinks™, adding social linking and embedding to the editing experience.

In this tutorial I will explain how to do one of the more simple customizations, adding a plugin that gives the user a choice of content templates. It’s a nice example because of the obvious business ROI…and should open your eyes to the possibilities for editor extensions. In fact, you may want to use some of the ones already created by others…

Step 1: Familiarize yourself with CKEditor plugins

The first step to customizing the CKEditor is to familiarize yourself with the plugin architecture and the kinds of things developers are doing with CKEditor. The best way to start is by examining other plugins at http://ckeditor.com/addons/plugins/all . While it’s tempting to get carried away downloading and trying to apply these, note that given the way Connections editor is set up, they won’t all work, and the instructions will not make any sense!

Step 2: Download the “templates” plugin

The smiley plugin is available here http://ckeditor.com/addon/templates  – just download and unzip, it will be self-contained in a folder. For the most part, all plugins have the same folder structure. Inside the main folder which will be named after the plugin, there will be the plugin definition file plugin.js. Some plugins also have other files like a readme.txt or readme.md, licenses for the more complex ones, maybe some source control or scratch files, etc. Four folders that are common to most plugins are lang (language files), images, icons (for the toolbar) and dialogs. The dialogs folder contains the main logic files for the plugin, in this case JavaScript.

A typical plugin folder structure

A typical plugin folder structure – yours may vary from this one.

Step 3: Create a path in Connections for the plugin(s)
In Connections, the path to resources can be quite confusing, since most of the files are already deployed as jars (zip files). And since by default there aren’t any customizations, figuring out where one goes can be a chore. A good start is in the Connections 4.0 or 4.5 API documentation, where an article on extending JavaScript has some clues. Most of the JavaScript used by IBM Connections is located inside one of the web resources JAR files inside the provisioning directory (typically CONNECTIONS_HOME/data/shared/provision/webresources), or inside the Common.ear file.

In our case, we are going to create a nice long directory path of:

CONNECTIONS_HOME/data/shared/customization/javascript/com/ibm/oneui/ckeditor/editor/plugins

Where CONNECTIONS_HOME is the directory where Connections code is installed — not the WebSphere app. In my case, it’s /opt/IBM/Connections.

Once this folder is created, we’re almost done right? Nope.

Step 4: Define the extra plugin

If you’ve spent some time with the CKEditor plugin documentation, and let’s face it, who hasn’t, you know to look for config.js. Not so in Connections, where we have a different method of defining plugins and consuming them, using similar syntax but not the same file naming structure. To discover where the CKEditor definition files are, we need to inspect the right jar file in CONNECTIONS_HOME/data/shared/provision/webresources (or Common.ear, but we can find it here).

For the sake of this exercise we are going to modify just the editor in Connections Wikis. It’s the hardest one to figure out, since there are additional plugins already there, and it has its own style of editor.

So first step, get a copy of CONNECTIONS_HOME/data/shared/provision/webresources/com.ibm.lconn.wikis.web.resources<version>.jar and unzip it locally. We need two files from this folder: resources/ckeditor.js and resources/scenes/CKEditor.js. Copy those to their own folder, keeping the scenes folder under the resources folder.

Next, we need to let the editor know we want to declare an extra plugin. Open the resources/scenes/CKEditor.js file and locate the following lines:

extraPlugins: dojo.getObject(“lconn.share0.config.displayMacrosGUI”) ?
‘wikilinking,quicklink,wikimacros,autogrow’ :
‘wikilinking,quicklink,autogrow’,

On both sides of the colon, add your plugin name:

extraPlugins: dojo.getObject(“lconn.share0.config.displayMacrosGUI”) ?
‘wikilinking,quicklink,wikimacros,autogrow,templates‘ :
‘wikilinking,quicklink,autogrow,templates‘,

Save the file.

Step 5: Modify a bit of code

As I mentioned, you shouldn’t expect the plugins to work straight away in Connections. Mostly, they’re being used by developers, so are very generic in nature and coding style. Connections adds a bit of mystery by combining configuration and definition files, then in some cases – as with wikis – having multiple files like ckeditor.js so that features can be injected into the editor. Blogs are the opposite, everything is in one file over there.

That said, I’m going to list out some code changes in the plugin.js file. It’s only a couple lines.

In the init function, you’ll see this:

editor.ui.addButton && editor.ui.addButton( ‘Templates’, {
label: editor.lang.templates.button,
command: ‘templates’,
toolbar: ‘doctools,10’
});

Well Connections wikis don’t like being told (from this file) what toolbar to use, and it really likes to be told the icon to use within this command. So we’ll change this to:

editor.ui.addButton && editor.ui.addButton( ‘Templates’, {
label: editor.lang.templates.button,
command: ‘templates’,
icon: this.path + “icons/templates.png”,
//toolbar: ‘doctools’
});

Next, go near the bottom of the file and find this (we’re not going to change it, just explain it):

CKEDITOR.config.templates_files = [
CKEDITOR.getUrl( ‘plugins/templates/templates/default.js’ )
];

All of the CKEditor stuff has configurations, and individual plugins can contribute to that configuration. But since we’re setting that configuration up in another place, we’re going to leave this here and rewrite it in the second ckeditor.js file. For the meantime, copy this bit to an empty document for reference.

In the case of this plugin, we lucked out and don’t have to modify the language file. I’ve found that most of them need a tweak to work with Connections, specifically adding another layer to the function. So we’ll skip that.

Now to the configuration file. That’s right, the “other” ckeditor.js (you can tell them apart in your editor because the names are case sensitive). Open ckeditor.js that you have right under resources, and find the section that starts with “dojo.mixin(CKEDITOR.config” which essentially means

Yo, Dojo, find the config bits of CKEDITOR and mix in this other stuff I’m about to throw at you!

You’ll see several lines in the toolbar_Wiki array with names and items. Choose a reasonable place on the toolbar like, say, “insert” and append (,’Templates’) to the end of the line. That’s a comma, and those are single quotes.

Now, we revisit our bit of config that we copied to a scratch document and insert it into this “mixin” using different syntax. Add the following after the toolbar_Wiki array. First, add a comma after the closing square bracket of the toolbar_Wiki array. Then, add:

templates_files : [
CKEDITOR.getUrl( ‘plugins/templates/templates/default.js’ )
]

See what I did there? I took the original CKEDITOR.config.templates_files “directive” in one place and reformatted it for the dojo.mixin syntax in another.

Note the lack of a comma at the end — JavaScript wants it this way, no comma after the last element before closing.

Step 6: Upload the modifications to the server

First, copy your lower-case ckeditor.js file to the server. Where, you might ask? Here:

CONNECTIONS_HOME/data/shared/customizations/javascript/lconn/wikis

Copy your CKEditor.js file to the server. Where, you might ask again? Here:

CONNECTIONS_HOME/data/shared/customizations/javascript/lconn/wikis/scenes

You can almost start to see the connection between the jar file and the ensuing folder structure for customization. Almost.

Last but not least, copy the entire “templates” folder, including your modified plugin.js, to the plugins folder you created in Step 3.

Step 7: Restart Connections and Test

Yeah, I know. Some tutorials say you can be an admin and restart just one or two servers from the WAS ISC, but I don’t buy it. 90% of the time for me, that doesn’t work, so I just restart. Your mileage may vary.

After restarting, armed with Firebug or Chrome Developer Tools, after dropping your browser cache, give it a go. Go to Connections Wikis, enter a wiki and create a new page. You should see a new icon to the right of the “Smiley” icon on the second row. Click it, and you will be presented with the following dialog if all goes well:

Content Templates let you insert pre-formatted HTML into the Connections rich text editor, and you can create your own templates!

Content Templates let you insert pre-formatted HTML into the Connections rich text editor, and you can create your own templates!

If all did not go well, retrace your steps. The most likely scenario is a missing or extra comma or semicolon. If it is working, check it out. You choose one of the templates, which organizes the content of the editor by pushing in HTML for you. The practical business uses are numerous – standardized templates for documents are kind of a no-brainer. Product sheets, resumes, you name it and someone, somewhere has a format for it.

So we’re ready for production, right? Well, sort of but not quite. It’s all working fine, but the customization “override” directory we’ve been using (CONNECTIONS_HOME/data/shared/customizations) is only supposed to be a temporary home for customizations during development. Technically, what we should do now is to wrap up our code, including replacements and additions, into an OSGi bundle (a JAR file with a special MANIFEST.MF file and some directories) and deploy the bundle into Connections.

But honestly, that’s another article. Or consulting. Whatever.

Next steps

Now that you have a template-aware editor, you probably want to add….templates! Well you can have a look at the code for this, it’s in the plugins subfolder templates\default.js (as we referenced in Step 5 above). My suggestion would be to create a new file, and reference it in the configuration by adding a new reference to it in the array (back when we messed with the dojo.mixin stuff…Step 5 also). You can create HTML templates to your heart’s content that way.

Enjoy!

19 thoughts on “Tutorial – Extending the IBM Connections Rich Text Editor

  1. Carl Radino

    Rob –

    Great and timely article. One thing though, these Plugins seem to be CKEditor version specific to V4.0 or v4.1. I don’t believe these will work with the current Connections CKEditor version of v3.5.3. Have you tested these with the CKEditor version in Connections today?

    Thanks

    Reply
    1. Rob Novak Post author

      Hi Carl,

      Actually this one (Templates) also says 4.0/4.1 but I installed it on a Connections 4.0 environment, which is CKEditor 3.5.x also. I’ve tried and had mixed success with some of the other published ones, and kept to a formula for our SnappLinks that works with 3.5.x.

      I got one of the code editors and ACE to work here too, but haven’t put much time into it yet.

      I think most of them could be tweaked to work with 3.5.x…but as you can tell the specifics and documentation on the CKeditor side are sparse as well.

      -Rob

      Reply
      1. Carl Radino

        Thanks for the quick reply. On the CodeEditor Plugins – which one have you had success with? I have a customer who needs this add-on capability for their implementation. Running IC4 – Cr2 in this case.

        Many thanks again..

        Reply
        1. Rob Novak Post author

          Sure Carl,
          I tried codemirror, but then the one I got to working was PBCKcode, which implements the ACE editor. I abandoned it in favor of the Templates plugin for the article due to the more general appeal of the Templates one and because the PBCKcode editor was only for the editing pane and not the result set in the text…which needs more work than I could explain in a five minute read!
          -Rob

          Reply
          1. Carl Radino

            Rob –

            I wanted to enlist you for some additional help if I may. I have decided to do the PBCKcode add-in for this particular IC4 installation. So where I am stuck is on Step 5. What I did was add the new entry on the Wiki Toolbar in the ‘Insert” section. I appended the entry ,’PBCKcode’ after the ‘Smiley’ entry. So where I am stuck is the “configuring” PBCKcode within the ‘ckeditor.js’ so it t can get called. The configuration part.

            My question is: “How did you approach this for the PBCKcode add-in for this step?” There isn’t an obvious point (at least to me) to copy and extract the call to add after toolbar_Wiki array section. Also, one other question – “would it make more sense to add this under Tools area of the Editor UI vs. in the Insert section?”

            Thanks – any help would be greatly appreciated.

            Carl

          2. Rob Novak Post author

            Sure Carl,

            Tricky wiki. You need to get the extra CKEditor.js file from inside the scenes folder, and add pbckcode to the extraPlugins…

            As far as where you put it, I think I remember that one needing its own toolbarGroup, but could be wrong.

            I can have a look at mine and see if I saved it…I’ll email you.

            -Rob

  2. Chitra Thambirajan

    Hi Rob,

    Thank you for this post.It is really a cool feature 🙂
    I need your advice in the following, we are trying to add Web Spell Checker into CKEditor to implement spell checker facility in Wiki editor.
    Downloaded the latest Web Spell Checker(wsc) plugin from this http://ckeditor.com/addon/wsc page.

    Followed the same procedure which you have given.This plugin folder also having the same folder structure except template folder which contains default.js
    Once I made the required changes and restarted Connections,am not able to see the toolbar itself in Wiki editing area.
    If I go for editing a wiki am getting an empty page under Rich Text tab.
    Please advice me to implement this Spell checker facility.

    Thanks
    Chitra

    Reply
    1. Rob Novak Post author

      Hi Chitra,
      I’ve tried the web spell checker a couple times with no luck so far but haven’t put in a concerted (e.g. customer needs it) effort — some of the plugins available on the CKEditor site aren’t readily “plugged in” to Connections, Quickr or XPages.

      A blank wiki page means something isn’t loading right. My typical steps are to use Chrome Developer Tools or Firebug (Chrome is more helpful for this), identify what is not loading properly, and compare to a working plugin for syntax. Connections has some odd syntax compared to a standard HTML, PHP, etc. implementation.

      Reply
  3. Pingback: Activate and customize “Table of contents” macro in IBM Connections Wiki | Stoeps

  4. Klaus

    Looks like life is easier with Connections 4.5 CR1, just add Plugin to plugins folder and add it to toolbar_Wiki array in ckeditor.js, that’s it. Just tested it with the Maximize plugin & works like a charm.

    Reply
        1. Rohit Rusia

          Hi Rob, Hope you have installed CR1 by now as I have got some issues in that. 🙂

          I have got Connections 4.5 CR1 and I have tried Template plugins for most of the application in Connections like blogs, wikis, calendar, forum etc but approximately for all the applications its different way of configuration but in some cases like Community Forums(opened from Forum widget) and Community Description editor and activities application it is not working after doing the necessary configuration. please suggest if you have got any success.
          And Did you try SCAYT or WSC for spell check as both of them are not working in 4.5 with CR1. I can see some really weird errors in firebug.

          Thanks,
          Rohit

          Reply
  5. Pingback: Customize the IBM Connections Richtext Editor | kbild's Blog

    1. Rob Novak Post author

      I’m afraid not, I haven’t played with that one in read mode. IBM has let me know that persistence between edit and read is quite difficult.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *