Rich text editor in custom portlet

Ever wanted to use a rich text editor (RTE) such as the CK Editor in your custom portlet?

Implementing an RTE in your view is (almost) as simple as using a jsp-tag:


<aui:field-wrapper label="description">
    <liferay-ui:input-editor name="descriptionEditor" toolbarSet="liferay-article" initMethod="initEditor" width="200" />
    <script type="text/javascript">
        function <portlet:namespace />initEditor() { return "<%= UnicodeFormatter.toString("default content") %>"; }
    </script>
</aui:field-wrapper>


The liferay-ui:input-editor tag does not have a label attribute. To include a label for the RTE, wrap the tag in a aui:field-wrapper tag as shown above.

Also, the liferay-ui:input-editor needs an initMethod defined in javascript that sets the initial value of the RTE. In my example above, the RTE will be initialized with the value "default content". In your own view, obviously you would want to exchange "default value" for a bean value.

Editor toolbar

Now, the code above works great and will provide you with a toolbar (the set of actions/operations in the editor) that looks like the one used when editing wcm-articles.

Liferay comes with four different predefined toolbar sets:

  • liferay
  • liferay-article
  • email
  • edit-in-place

Each toolbar sports its own set of actions/operations. The most slimmed one being the email toolbar set.

The toolbar sets are defined in a file called ckconfig.jsp which you'll find in /webapps/ROOT/html/js/editor/ckeditor/ in your Liferay bundle.

Changing a predefined toolbar

The toolbar set called "liferay-article" is defined in ckconfig.jsp like this:

CKEDITOR.config.toolbar_liferayArticle = [
    ['Styles', 'FontSize', '-', 'TextColor', 'BGColor'],
    ['Bold', 'Italic', 'Underline', 'Strike'],
    ['Subscript', 'Superscript'],
    '/',
    ['Undo', 'Redo', '-', 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'SelectAll', 'RemoveFormat'],
    ['Find', 'Replace', 'SpellChecker', 'Scayt'],
    ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
    ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
    '/',
    ['Source'],
    ['Link', 'Unlink', 'Anchor'],
    ['Image', 'Flash', 'Table', '-', 'Smiley', 'SpecialChar', 'LiferayPageBreak']
];

Thus, if we would like to remove the option for TextColor, we would need to remove this entry in the definition. This can be done by replacing the ckconfig.jsp file with a custom-jsp hook. If you don't know how to implement a custom jsp hook, you can check this wiki page.

Adding a new toolbar

Similar to the procedure above, you may add a new custom toolbar by adding a toolbar definition to the ckconfig.jsp file with a custom-jsp hook. Let's create one called "slimmed" that is just a simple editor with the option to make text bold, italic and underline. Also let's add the option to insert links:

CKEDITOR.config.toolbar_slimmed = [
    ['Bold', 'Italic', 'Underline'],
    ['Link', 'Unlink']
];

Deploy your custom jsp hook. Now change your liferay-ui:input-editor to use the slimmed toolbar set:

<aui:field-wrapper label="description">
    <liferay-ui:input-editor name="descriptionEditor" toolbarSet="slimmed" initMethod="initEditor" width="200" />
    <script type="text/javascript">
        function <portlet:namespace />initEditor() { return "<%= UnicodeFormatter.toString("default content") %>"; }
    </script>
</aui:field-wrapper>

That's it. Your customized RTE is being used in your custom portlet.

Cheers, Erik

Blogs
Nice post!!! But the part where you have to convert your content to xml is missing...
Could you please advise if/how the CK editor can be integrated with the Comments?
Thanks for the post! I didn't get this:
by adding a toolbar definition to the ckconfig.jsp
ckconfig is a normal jsp file, the definition you said:
CKEDITOR.config.toolbar_slimmed = [
['Bold', 'Italic', 'Underline'],
['Link', 'Unlink']
];
ist not jsp format. Are you sure it should be added to ckconfig.jsp? If yes, to which part of it exactly?
Thanks for the post! I was looking for a solution to change the default toolbar of the blogs entry editor and it worked perfectly at first try.

Puj Z, it worked for me that way. Try it!
Rodrigo, great to hear it worked out for!

Puj Z. You are correct that the syntax is not JSP but javascript. The file ckconfig.jsp is included in the file ckeditor.jsp:

<script type="text/javascript">
function initCkArea() {
...
CKEDITOR.config.customConfig = '<%= request.getContextPath() %>/html/js/editor/ckeditor/ckconfig.jsp?p_l_id=<%= plid %>&p_main_path=<%= HttpUtil.encodeURL(mainPath) %>&doAsUserId=<%= HttpUtil.encodeURL(doAsUserId) %>&cssPath=<%= HttpUtil.encodeURL(cssPath) %>&cssClasses=<%= HttpUtil.encodeURL(cssClasses) %>';

...
</script>
thanks for the info! well I tried it but it doesn't work. I already have a standard liferay editor for the content field, and I would like to add a simple editor for description field. Here is what I did:
I wrote a hook and added the slimmed editor as mentioned in the ckconfig.jsp
then I replaced my simple aui:input with this:
<aui:field-wrapper label="my-description">
<liferay-ui:input-editor name="descriptionEditor" toolbarSet="slimmed" initMethod="initDescriptionEditor" width="200" />
<script type="text/javascript">
function <portlet:namespace />initDescriptionEditor() { return "<%= (myModel!=null)?myModel.getAward():"" %>"; }
</script>
</aui:field-wrapper>
<%-- <aui:input name="description" style="width:550px;" type="textarea" label="challenge-award"/>--%>

the commented line is what is was before. Now I don't see an html input field or editor field, all I see is the label. Have I missed anything?
by the way, for content, we did this approach to use the liferay standard editor:

<script type="text/javascript">

function <portlet:namespace />initEditor() {
$("#<portlet:namespace />editor").contents().find("iframe").contents().find("body").html(document.getElementById("<portlet:namespace />content").value);
return document.getElementById("<portlet:namespace />content").value;
}

function extractCodeFromEditor() {
document.getElementById("<portlet:namespace />content").value = window.<portlet:namespace />editor.getHTML();
<%--alert(document.getElementById("<portlet:namespace />content").value);--%>
}
</script>
and then in the aui:form:

<liferay-ui:input-editor />
<aui:input name="content" type="hidden" />


This works.
to be preciser, I overwrote this file with a hook:
portal-web/docroot/html/js/editor/ckeditor_diffs/ckconfig.jsp
Thanks a lot! But how to process and insert the xml from database to rich text area? and how to do the the reverse process (HTML->XML)
Hello
Please Help Me
How To Add Customize Fonts To Default HTML Editor Of Liferay?