Article: Advanced Domino TinyMCE integration »
FERDY CHRISTANT - DEC 22, 2006 (07:29:20 AM)
Introduction
This article will explain how to integrate TinyMCE, a web-based rich text editor, into Domino. Ultimate goal is to have it working reliably in all modern browsers, and well integrated into your Domino backend. This exercise has been performed by Jake before, but needs a little updating:
- The demo database of Jake's article contains a 2 year old version of TinyMCE thats has some bugs that make it hard to get it to play nicely with the modern browsers.
- This article adds instructions on how to integrate images stored in Domino into the image selection panel of TinyMCE.
- This article will focus on an optimized integration path where you we will configure TinyMCE to include exactly the functionality we want, and where we only use the files of the TinyMCE package that we truly need.
Before I start, let me state that this article would not be possible without the help of Ben Poole. You can consider this article as our combined service to the community.
For the sake of inspiration, here is a little teaser of what an integrated TinyMCE editor looks like:
Getting started
There are two ways to integrate TinyMCE into your Domino application. One way is to store the TinyMCE source files on your server, in the domino\html directory. From then on, you can refer to these files from multiple applications. The other way is to integrate the TinyMCE source files into your database design. This article will focus on integrating the source files into the database design. The main advantage of this method is that your application will be modular and deployable to any server. The major drawback of course is that if any TinyMCE upgrades are released, you may have to apply them to multiple applications manually.
Throughout the rest of this article I will refer to my Blogo application. Blogo 1.50 has TinyMCE integrated exactly the way described in the rest of this article. So, go ahead, download Blogo 1.50, and open it in Designer.
The source files
TinyMCE consists of a lot of html, js and css files. In the Blogo design, these are stored as File design elements. Not every file of TinyMCE is included, only the ones we need to use TinyMCE's advanced theme. Two extra remarks apply:
Firefox does not recognize the css File design elements as true css files. Therefore, these File design elements have their mime type explicitly set to "text/css". This is done on the second tab of the File Resource properties box.
To enable the integration of images stored in Notes documents in the TinyMCE editor, the file "editor/themes/advanced/editor_template.js" has to be modified. The line containing "image.htm?src=" has to be replaced with "image.htm?open&src=".
This is already done in the Blogo File design elements, so if you are integrating TinyMCE in your own design, you can simply copy all these File design elements to your own design. It will save you a lot of work.
Text areas
TinyMCE basically transforms your html textarea elements into a TinyMCE editor. There are different modes to select which textarea should be turned into a TinyMCE editor. The one demonstrated appears to me as the most flexible and modular way. It tags text area elements with a HTML attribute, to indicate that it needs to be a rich text editor.
If you open up the subform "Page Edit Form" in the Blogo design, somewhere around the bottom the following line demonstrates the attribute:
<textarea rows="20" cols="70" wrap="virtual" name="pgContent" id="pgContent" class="mceEditor" style="width:100%;"></textarea>
Three elements are crucial in this line of code. First, the rows, cols, and width attributes indicate the size of the TinyMCE editor. The name attribute will link it to a rich text field with the same name. This creates the connection between the editor and the field to store the rich text content in. The class="mceEditor" part indicates that this is a TinyMCE textarea. By simply setting an attribute on a textarea we can loosely couple the TinyMCE init script, for maximum flexibility.
Note that in Blogo, the html coming from the TinyMCE editor is stored in a text field (in the Page Fields subform), not a rich text field. The reason is that Blogo does not do Notes client-based rich text editing, only web-based rich text editing. Your own implementation may vary, but integration is still straightforward if you consider the html required for the textarea, as explained above. Jake's original artice contains an agent that tranforms the TinyMCE html content into a rich text field.
The init script
The TinyMCE init script is the most important aspect of the integration process. It loads the TinyMCE editor for the selected text areas, and configues the features available in the editor. In Blogo, the initiation script is decoupled from any form you apply it to. In essence, this means that to enable the TinyMCE editor on your form, two simple steps apply:
- Mark the text areas on your form that need to be a TinyMCE editor using the class attribute
- Insert the "Rich Text Editor" subform at the top of your form.
Easy, right? Let's have a deep look at the initation script in the "Rich Text Editor" subform:
01. <script type="text/javascript" src="editor/tiny_mce.js"></script>
02. <script language="javascript" type="text/javascript">
03. tinyMCE.init({
04. mode : "specific_textareas",
05. editor_selector : "mceEditor",
06. theme : "advanced",
07. plugins : "table",
08. apply_source_formatting : "true",
09. theme_advanced_container_toolbar1_align : "left",
10. theme_advanced_container_toolbar2_align : "left",
11. theme_advanced_layout_manager : "RowLayout",
12. theme_advanced_containers : "toolbar1,toolbar2,mceEditor",
13. theme_advanced_container_toolbar1 :
14. "bold,italic,underline,strikethrough,charmap,separator,"+
15. "justifyleft,justifycenter,justifyright,justifyfull,"+
16. "separator,bullist,numlist,indent,outdent,separator,"+
17. "link,unlink,anchor,hr",
18. theme_advanced_container_toolbar2 :
19. "tablecontrols,separator,image,removeformat,code",
20. theme_advanced_path : "false",
21. remove_script_host : "true",
22. document_base_url : "<Computed Value>",
23. relative_urls : "true",
24. external_image_list_url : "/<Computed Value>/pagRTEImages.js"
25. })
26. </script>
Since this script is so crucial for a proper integration, let's go over it line by line:
L01: Include the main TinyMCE javascript library. In Blogo, I make use of the base href tag to make use of relative paths throughout the entire design. The value of the base href tag is set to "http://server/dbpath/". If you do not use a base href tag, you should make sure that the path to the tiny_mce.js File design element is correct, whether it is absolute or relative.
L02: Start a javascript that must be executed as soon as it is loaded.
L03: Initiate the TinyMCE init call. This will only work if the path defined in line 1 is correct.
L04: This line is to indicate which text areas should be transformed to rich text editors. We do not want this for all text areas on our form, only the ones we marked as such.
L05: Indicate that all textarea elements with the attribute class="mceEditor" should be transformed to rich text editors.
L06: TinyMCE has a number of modes. The advanced mode is the one where we have maximum control over the features, so we will use that one.
L07: TinyMCE has a set of plugins to extend the functionality of the basic editor. The table features is not part of the basic functionality, therefore we load it as a plugin.
L08: TinyMCE allows you to switch to html editing mode. This setting will make sure that the HTML code is nicely formatted, making it more readable and easier to edit.
L09-L10: We will defined two rows of buttons in the editor, these two lines make sure that buttons are aligned to the left. By default, they are centered.
L11: This line puts TinyMCE in a mode where we have maximum control over the rows, buttons, order of buttons, etc.
L12: Here we specify that we have three rows: a button row, a second button row, and the TinyMCE editor pane. By naming the rows, we have control over them in the subsequent lines.
L13-L19: These lines define exactly what buttons to insert into which row of the editor. The order of buttons specified here will be respected in the end result. As you can see, you can also insert seperators to group related buttons. You may want different buttons in your own implementation. If so, please refer to the TinyMCE button/controls list.
L20: By default, TinyMCE insert a path element below the editor. The path element displays the hierarchy of html elements based on your cursor position in the editor. I wish not to bother non-technical users with this, so I disabled it.
L21: This parameter makes sure that TinyMCE does not automatically insert the server name into your relative URLs.
L22: The document base URL parameter is crucial to make your paths work. In Blogo it is set to a computed value with the following formula:
tmpProtocol:= "http" + @If(HTTPS="ON"; "s"; "");
tmpProtocol + "://" + Server_Name + "/" + @WebDBName + "/"
You would assume that the base href tag accomplishes the same effect. The reason to still do this is that we want our TinyMCE editor to work when we create a new document and when we edit an existing document. As you can imagine the URL hierarchy in both scenarios is different:
server/dbpath/myform?openform
versus:
server/dbpath/view/docid?editdocument
Notice the extra level in the second URL. This is why we need to set the document base URL of TinyMCE.
L23: Set TinyMCE to use relative URLs. together with the two previous lines, this gives us the control over our paths that we want.
L24: By default, TinyMCE will assume that when you try to insert an image in your editor, it must pick them from the web server's file system. Since we want the list to be populated by Notes image attachments, we will set the image picklist to a Page design element, which is explained in the next section. Note that the computed value in this line is set to @WebDbName.
L25-26: End of init call and script.
Domino image integration.
As stated before, we would like TinyMCE to be able to insert images that are stored as attachments inside documents. How you implement this can be specific to your situation, but it should be easy after I explain how this is done in Blogo.
First, as stated in line 24 of the init script, we direct the source of our images to a Page called "pagRTEImages.js". The purpose of this page is to produce a javascript array of images that TinyMCE will use in the insert image dialog box. The content type of the page is set to html. When you open it, you can see that a javascript array is setup with two elements: an embedded view and a default value (---). The format that TinyMCE expects for the image array is demonstrated in the following example:
var tinyMCEImageList = new Array( // Name, URL ["Logo 1", "logo.jpg"], ["Logo 2 Over", "logo_over.jpg"] );
As you can see, it is an associative array where the index is the image description and the value is the image path. The embedded view takes care of outputting this format for the image list. The view design is highly specific for your situation as your view selection and field names will differ from the ones used in Blogo. Still, the "vwResourcesRETPickList" view should give you a good start.
The first column of the view is sorted and hidden. This ensures that the array that we will output is sorted as well. The second column produces the array in the format mentioned above. In this column Blogo filters the attachments, it only allows image attachments to make it into the array. Another feature is that Blogo simulates a file system by using nested image descriptions. Three extra tips:
- The embedded view has its content type set to html, and the lines to display to 1000
- Make sure that the column formula that outputs the javascript array ends with a colon, to seperate the array elements
- Debug the format of your javascript by directly opening the Page in your browser
If all went well, you should now be able to insert Domino images into your rich text content:
Saving the rich text content
Now that we have the rich text capabilities working in the front-end, we need to make sure that upon a document save (submit), the content of the editor is saved into the Notes field. In essence, your editor is still just a textarea element, and by setting the name attribute to the name of your Notes field, the save should work. Still, TinyMCE offers a way to enforce the content of the editor to be pushed to the underlying text area, after which Domino will do the rest. In the bottom of the "Page Edit" subform, the TinyMCE triggersave method is called:
if ( QuerySave(this.form) ){ tinyMCE.triggerSave(false,false);this.form.submit()}
Your implementation may vary, perhaps you make the call in the onsubmit event of your form.
Conclusion
Integrating TinyMCE into your Domino application is a big usability improvement. I wrote this article in TinyMCE, and it took me about half the time it would cost if I would type it in HTML. Using this article, hopefully you will find it easy to integrate TinyMCE into your application.
Note that this article did not try to demonstrate the full feature set of TinyMCE. TinyMCE has a wealth of extra functions and ways to customize them. Consider the excellent documentation and forum for more information.
I've been skeptic about web rich text editors for years, considering their cross-browser problems and inconsistent and unreliable behavior. I have delayed implementing them in my own applications. I can now happily confirm that to me, those days are over. I fully trust this editor and I've had zero problems using it, across browsers. I hope this article convinces you to take the same step, if you have not already done so.


Comments: 28
Reviews: 7
Average rating:
Highest rating: 5
Lowest rating: 4
COMMENT: VITOR PEREIRA
DEC 22, 11:46:42
COMMENT: KATHIR PERI
DEC 22, 03:11:47 PM
COMMENT: DIETMAR
DEC 24, 12:09:43
COMMENT: DGO

DEC 26, 01:31:53 PM
i use tinyMce in our domino development since i've read the Jake's article 2 years ago.
All the pages of our site were created with tinymce without problems (excep with cut and paste from Ms Word )
The latest version provide a new parameter called file_browser_callback.
When you activate this one, tinymce add a button next the "image url" field. This button call a user's function in javascript who open a popup with for example a notes view with all the image of our intranet.
an abstract of our code :
the function to call the popup :
function fileBrowserCallBack(field_name, url, type, win) {
var fileBrowserWindow = new Array();
var cmsURL = _hbase+'(v.actimgtit)?open&count=-1'; // script URL
fileBrowserWindow["file"] = cmsURL + searchString;
fileBrowserWindow["title"] = "Répertoire Image";
fileBrowserWindow["width"] = "700";
fileBrowserWindow["height"] = "450";
fileBrowserWindow["close_previous"] = "no";
tinyMCE.openWindow(fileBrowserWindow, {
window : win,
input : field_name,
resizable : "yes",
inline : "yes"
});
}
the function who send back the choice :
function returnF4tiny(thisObj)
{
var win = tinyMCE.getWindowArg("window");
var fld = tinyMCE.getWindowArg("input")
// insert information now
win.document.getElementById(fld).value = thisObj;
// close popup window
win.tinyMCE.setWindowArg('editor_id','mce_editor_0');
if (win.getImageData) win.updateImageData();
if (win.showPreviewImage) win.showPreviewImage(thisObj);
tinyMCEPopup.close();
};
Sorry about my english, feel free to mail if you want more explanation.
Hope it will be usefull.. «
COMMENT: DGO
DEC 26, 01:33:56 PM
http://tinymce.moxiecode.com/tinymce/docs/option_file_browser_callback.html «
COMMENT: BENOIT
DEC 27, 08:27:32
COMMENT: LANCE SPELLMAN

DEC 28, 10:30:08 PM
COMMENT: JUAN F. RUIZ

DEC 29, 01:44:45
And it will be translated too! I will navigate through JS files, form's, to translate all that messages ...
mmm ... well, JS files may be not because i guess TinyMCE has been translated yet.
«
COMMENT: FERDY
DEC 29, 08:11:10 AM
You cannot include an outside image. You first have to upload the image to the web server (in Blogo this is done using a Resource forum with upload controls), and then you can insert it into your content.
Juan,
Thanks in advance, I look forward to the translated version «
COMMENT: BEN POOLE

JAN 2, 14:06:17
As Ferdy points out, this code can be augmented to that you can provide users with a "picklist" of images stored in a Domino database (or indeed elsewhere -- you only need provide a Javascript array to detail these images), but the end result is the same: an img link.
In other words, inserting an image in a TinyMCE instance does NOT result in either an in-line Base64-encoded entity or an attachment.
Does that help?
«
COMMENT: GUSTAF
JAN 8, 07:35:20
one problem that I've had... though I still like this and use it since a year or so...:
Applying it to already existing documents with a RTF containing a long text with linebreaks and such. I didn't manange to convert the text to HTML without losing layout on the linebreaks - the best and easiest way was to leave them, andthen they did convert to , but the layout was then different than it was before editing...
They should have been shift-entered to get a more correct result. «
COMMENT: PATRICK KWINTEN

FEB 2, 07:58:51
COMMENT: BJORN LARSEN
MAR 12, 12:43:44
COMMENT: OYUN


APR 7, 18:32:56
COMMENT: DANIEL SCHADE

JUN 27, 09:32:46 AM
Did you plan to enable special characters in the title of pages like
germans äüöß? All of them will be replaced by a ? sign and the rest
of the word will be lost during the saving progress.
Greetings Daniel «
COMMENT: MATT
AUG 20, 17:51:57
I do have a small problem which I can replicate in your sample Blogo template. In Opera, when adding images it uses the absolute URL instead of the relative one. It is fine in IE and Mozilla e.g. I added a smiley to the Blogo sample and it came out as:
SRC="http://localhost/Blogo/s3_blog_160.nsf/resources/MyResource/$FILE/emoticon.gif"
Any ideas what might be causing this or how to get around it?
cheers Matt «
COMMENT: PATEL NASRULLAH

SEP 7, 12:20:02 PM
Thank you..... Very excellent.
Please can you help me how to set path for image upload.......
«
COMMENT: SANDY
SEP 18, 04:10:11 PM
I my tinymce is working in firefox but not in any version of ie,
please help me fix it.
Sandy «
COMMENT: FREDRIC BERLING
NOV 15, 14:02:30
I integrated tinymce in an application where i have documents containing a richtext item.. These documents show up nicely when i am in read mode, but when swithing to EditMode and TinyMce gets hold of my field i loose all images and linebreaks and formatting.
I have played around with Content as Mime Html" etc without luck.
Can domino feed TimyMce with the HTML rendered from the RTF field? «
COMMENT: FERDY
NOV 20, 10:28:41 AM
I believe it is somewhat possible, but it definitely is not trivial and probably hard to get stable. This is why I have chosen not to go that way and only offer a web-based rich text editor. «
COMMENT: ALAN WHITE


MAY 2, 2008 - 11:06:52
and like you I decided to only allow editing via a brwoser cleint
so this article was a great help
before integrating TinyMCE into my real application I decide to build a prototype.
I've tried to pare down your example to the minimum code and I'm having problems
In my prototype I have
1. loaded all tresources
2. created a subform equivalent to your Rich TextEditor subform
(marked with with passthru HTML throughout)
3. Created a form iths
a. the subform
b. HTML to create the text area
c. HTML to create a simple save button
d. Javascript in theJSHeader to handle the click
function saver() {
tinyMCE.triggerSave(false,false);
document.forms[0].submit()
}
when I try this the editor comes up nicely
you can put in formatted text
the document saves
BUT ...
there is no item on the document that is created containing the HTML equivalent of the
WHERE AM I GOING WRONG? «
COMMENT: RENATE
AUG 1, 2008 - 12:01:35
I create an anchor link. Give it a name, ie XyZ. Then I mark the text I want to link to this anchor - and click the create link button, and types inn #xyz, and saves. However, in your blog, it cannot open the link, because it misses the document id in the url...
I tried this in the old demo, and it worked, but maybe I am doing it wrong?? It would be very nice if anyone can point me in the right direction, as this is cruical for selecting a Rich Text Editor...
Thanks, Renate «
COMMENT: RENATE
AUG 1, 2008 - 12:05:30
Hope you can help me out with the anchor stuff...
Ren «
COMMENT: JAVIER
AUG 22, 2008 - 10:09:29
I´m trying build an application which allows editing RTF both notes and browser but when i save changes in browser with TinyMCE I only can read plain text in notes client like: "Hello World!".
Now I am creating a Java agent to read this text and create a new Rich text field using NotesRichTextStyle but is quite heavy and difficult.
Any suggestions?
Thank you and congratulations on the article! «
COMMENT: FERDY
AUG 22, 2008 - 07:09:36 PM
What you want is not easy and hard to make bullet-proof. The reason is that TinyMCE stores the rich text in plain text HTML, whilst the Notes client uses a proprietary format to store rich text.
I believe Jak Howlett of CodeStore has a solution to this on his site (codestore.net), where he uses an agent to mess with mime types. Give it a try
«
COMMENT: FREDRIK
SEP 1, 2008 - 12:33:42
I have a for that I have implemented Tiny MCE in and it works great but below this field I have an upload control that you counld upload files to the document. And the problem seams to be that Domino is attaching the files to the Richtext field that I have the text in now.
Any Ideas how to get the attachments just to be uploaded into the document and not too my richtext field ? «
COMMENT: FERDY
SEP 2, 2008 - 07:45:21 AM
It's been a while since I've last done this, but I think you can do this by placing a $$V2AttachmentOptions field on the form. «
COMMENT: FREDRIK
SEP 2, 2008 - 09:46:35