CKEditor and Mustache become friends
In the beginning there was WordStar and CSV. The possibility of (then printed) personalized mass-communication had arrived in the form of mail-merge. For Notes eMails that is still a challenge (the latest version of OpenOffice now seems to have a reasonable eMail-Merge, but that's off topic here) since creating the template message with variables to be filled is kind of fuzzy (a.k.a usually out of the reach of mere mortal users).
XPages, Mustache and CKEditor to the rescue! The CKEditor shipping with XPages can be easily customized, so adding a dropdown that inserts Mustache markup shouldn't be too hard. To allow easy reuse of the code, I created a bean than contains all needed components. Add it to a page and simply call the bean functions. The first sample, using only uses static therefore is quite simple:
The variable
While it seems a little overkill to move the JavaScript into a Java function, we will see that the bean, once completed, is quite useful and keeps what we need in one place.The code so far:
Next stop: generate the list of variables from a form or a document (or supply a collection)
XPages, Mustache and CKEditor to the rescue! The CKEditor shipping with XPages can be easily customized, so adding a dropdown that inserts Mustache markup shouldn't be too hard. To allow easy reuse of the code, I created a bean than contains all needed components. Add it to a page and simply call the bean functions. The first sample, using only uses static therefore is quite simple:
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:scriptBlock id="scriptBlock1" value="#{mustache.sampleData}">
</xp:scriptBlock>
<h1>Mustache and CKEdit demo</h1>
<xp:inputRichText id="inputRichText1">
<xp:this.dojoAttributes>
<xp:dojoAttribute name="extraPlugins" value="mustache">
</xp:dojoAttribute>
</xp:this.dojoAttributes>
</xp:inputRichText>
</xp:view>
The variable
mustache
is configured as a managed bean in faces-config.xml
:
<managed-bean>
<managed-bean-name>mustache</managed-bean-name>
<managed-bean-class>com.notessensei.xpages.MustacheWrapper</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
While it seems a little overkill to move the JavaScript into a Java function, we will see that the bean, once completed, is quite useful and keeps what we need in one place.The code so far:
package com.notessensei.xpages;
import java.io.Serializable;
/**
* @author Stephan H. Wissel
*/
public class MustacheWrapper implements Serializable {
private static final long serialVersionUID = 1L;
private final String preText;
private final String postText;
public MustacheWrapper() {
this.preText = this.populatePreText();
this.postText = this.populatePostText();
}
public String getSampleData() {
StringBuilder sample = new StringBuilder();
sample.append(this.preText);
sample.append("this.add('{{Subject}}','Subject','Subject');\n");
sample.append("this.add('{{From}}','From','From');\n");
sample.append("this.add('{{To}}','To','To');\n");
sample.append("this.add('{{Date}}','Date','Date');\n");
sample.append("this.add('{{Form}}','Form','Form');\n");
sample.append(this.postText);
return sample.toString();
}
/**
* Client JavaScript code before the actual values
*
* @return
*/
private String populatePreText() {
StringBuilder result = new StringBuilder();
result.append("CKEDITOR.plugins.add( 'mustache',\n");
result.append(" { requires : ['richcombo'],\n");
result.append(" init : function( editor ) {\n");
result.append(" var config = editor.config\n");
result.append(" var lang = editor.lang.format\n");
result.append(" editor.ui.addRichCombo( 'mustache',\n");
result.append(" { label : \"Variables\",\n");
result.append(" title : \"Variables\",\n");
result.append(" voiceLabel : \"Variables\",\n");
result.append(" className : 'cke_format',\n");
result.append(" multiSelect : false,\n");
result.append(" panel : {\n");
result.append(" css : [ config.contentsCss, CKEDITOR.getUrl( editor.skinPath + 'editor.css' ) ],\n");
result.append(" voiceLabel : lang.panelVoiceLabel },\n");
result.append(" init : function() {\n");
result.append(" this.startGroup(\"Variables\");\n");
// The rest is in the PostText
return result.toString();
}
/**
* Client JavaScript code AFTER the actual values
*
* @return
*/
private String populatePostText() {
StringBuilder result = new StringBuilder();
result.append(" },\n"); // End of the init function!
result.append(" onClick : function( value ) {\n");
result.append(" editor.focus();\n");
result.append(" editor.fire('saveSnapshot');\n");
result.append(" editor.insertHtml(value);\n");
result.append(" editor.fire('saveSnapshot');\n");
result.append(" } });\n");
result.append(" var toolbarName = config.toolbar;\n");
result.append(" config[\"toolbar_\"+toolbarName].push(");
result.append("{\"name\" : \"mustache\", \"items\" : [\"mustache\"] });\n");
result.append(" }});\n");
return result.toString();
}
}
Next stop: generate the list of variables from a form or a document (or supply a collection)
Posted by Stephan H Wissel on 09 April 2014 | Comments (2) | categories: XPages