Rich Text Editor - NSF Custom Plugin Extension

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
	<xp:this.resources>
		<xp:script clientSide="false" type="text/javascript">
			<xp:this.contents>
				<![CDATA[
					// SSJS to calculate path to the current application...
					function getDatabasePath(){
						var value = facesContext.getApplication().getViewHandler().getResourceURL(facesContext, "/");
						value = facesContext.getExternalContext().encodeResourceURL(value);
						if(!value.endsWith("/")){
							value += "/";
						}
						return value;
					}
				]]>
			</xp:this.contents>
		</xp:script>
		<xp:script clientSide="true" type="text/javascript">
			<xp:this.contents>
				<![CDATA[
					// intercept nsf resource requests to stop ?t=timestamp being appended by ckeditor
					// see: http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Editor_Core_URLs_Manipulation
					window.CKEDITOR_GETURL = function(resourceRequest){
						if(null != resourceRequest && resourceRequest.indexOf(".nsf") > -1){
							return resourceRequest;
						}
					}
					XSP.addOnLoad(function(){
						// add the custom extension...
						CKEDITOR.plugins.add("myExtension", { 
							init: function(editor){ 
								editor.addCommand("MyCommandHandler", {
									exec: function(editor) {
										myCommandHandler(editor);
									}
								});
								editor.ui.addButton("MyCommand", {
									label: "Run My Command",
									command: "MyCommandHandler",
									// resource is within the .nsf...
									icon: " ${javascript:getDatabasePath()} ".trim() + "icon.png"
								});                                  
							}
						});
						// define the custom command handler...
						myCommandHandler = function(editor){
							if(null != editor){
								editor.insertHtml(
									"<br><p>CKEditor: Invoked myCommandHandler!</p><br>"
								);
							}
						}
					});
				]]>
			</xp:this.contents>
		</xp:script>
	</xp:this.resources>
	<xp:inputRichText id="inputRichText1">
		<xp:this.dojoAttributes>
			<xp:dojoAttribute name="extraPlugins" value="myExtension">
			</xp:dojoAttribute>
			<xp:dojoAttribute name="toolbar">
				<xp:this.value>
					<![CDATA[#{javascript:
						var customToolbar = "[['Font','FontSize'], \n" +
							"['Bold','Italic','Underline','Strike'], \n" +
								"['MyCommand']]";
						return customToolbar;
					}]]>
				</xp:this.value>
			</xp:dojoAttribute>
		</xp:this.dojoAttributes>
	</xp:inputRichText>
</xp:view>





Example of providing a custom toolbar option c/w custom command handler and icon for the Rich Text Editor control (aka CKEditor) directly from within an NSF.  Therefore avoiding the need to modify the CKEditor sources on the client and/or server file system.

XPages
Tony McGuckin
August 29, 2012 4:47 PM
Rating
174

All code submitted to OpenNTF XSnippets, whether submitted as a "Snippet" or in the body of a Comment, is provided under the Apache License Version 2.0. See Terms of Use for full details.



2 comment(s)Login first to comment...
weihang chen
(at 07:18 on 06.05.2013)
icon: " ${javascript:getDatabasePath()} ".trim() + "icon.png"

the word "icon.png" needs to be part of the getDatabasePath() function as well, else if it is not encoded, sometimes it will add up some strange character after "icon.png" in the URL
weihang chen
(at 05:21 on 16.01.2013)
this snippt works great for a single instance Xpages, but when it is included in a dynamic content controll, it will yield error and the plugin no longer will be registered. the solution I found is to move the client side script to a outputstript control. But to insure that the plugin is not loaded multiple times, following row needs to be added
if (!CKEDITOR.plugins.registered[plugin_name]) {

}


http://stackoverflow.com/questions/8772209/ckeditor-how-to-remove-a-plugin-that-has-been-added