在Liferay中集成ueditor编辑器

2016年06月01日 Liferay 暂无评论 阅读 4,857 views 次

本文章基于Liferay6.2。

按照此文说明,可以完成集成,如果是想要现成的,请到淘宝购买,不免费。

淘宝链接:https://item.taobao.com/item.htm?id=533006976450

 

Liferay中自带的富文本编辑器为ckeditor,此编辑器基本功能还好,但是文件上传的体验实在是太差,而且界面也不是很美观,国内百度前端团队提供的Ueditor,应该是国内目前最好用了编辑器了。下文说明,如何在Liferay中集成此编辑器。

在Liferay集成Ueditor一般有两种场景。

1、在自己写的Portlet插件中使用Ueditor;

2、替换Liferay的内容管理,网页内容发布里面编辑器为ueditor;

其实我们所说的集成ueditor,主要是来处理文件和图片的上传,如果不涉及文件或图处上传,针对场景1我们在自己开发的Portlet里面将ueditor相关的内容引入,然后在页面中引入相应的js就和普通的web一样使用了。场景2则有点麻烦。

本文章所采用的方法为开发一个Hook插件,完成后的效果为:

1、针对上面的场景1,我们使用下面的标签即引入Ueditor。

<liferay-ui:input-editor name="detail" editorImpl="editor.wysiwyg.ueditor" >

2、针对上面的场景2,我们在portal-setup-wizard.properties里面建立下面的配置,重启后,内置的网页内容管理的编辑顺即使用Ueditor,图片上传等功能正常。

editor.wysiwyg.portal-web.docroot.html.portlet.journal.configuration.jsp=ueditor
editor.wysiwyg.portal-web.docroot.html.portlet.journal.edit_article_content.jsp=ueditor

第一步:建立hook插件工程

在Liferay的IDE中,我们建立一个Hook的插件工程。

1、从网上下载ueditor的UTF-8的JSP版本。http://ueditor.baidu.com/website/download.html

2、在hook工程下面WEB-INF目录下面找到liferay-hook.xml文件,打开在里面的<hook></hook>之前输入<custom-jsp-dir>/custom_jsps</custom-jsp-dir>。

3、在docroot目录下面建立,custom_jsps目录(和2里面配置的路径保持一致),再在此目录下面依次建立html/js/editor目录。

4、将从网上下载的ueditor解压,然后重命为ueditor,复制到上面的editor目录下面。并建立一个uedtor.jsp文件。目录结构如下:

ueditor的hook工程结构

5、删除ueditor下面JSP目录里面的lib目录。这里放的是相关的jar包,做文件上传手,我们后面处理。

第二步:修改ueditor.jsp文件。

ueditor.jsp文件是来负责<liferay-ui:input-editor>标签的显示的,也就是说当我们在页面中使用此标签的时候调用的是ueditor.jsp文件。此文件的写法我们可以参考Liferay默认提供的编辑器的写法,可以在源码的portal-web/docroot/html/js/editor下面找到,里面的bbcode.jsp、ckeditor.jsp、fckeditor.jsp、tinymce.jsp等等,都是类似的文件,可以打开参考。

1、我们可以重点参考ckeditor.jsp和tinymce.jsp。将上面的java小代码部分复制到ueditor.jsp里面来。重点的部分为引入ueditor和设置相关的JS调用。

2、ueditor的代码引入:

最前面的<%%>里面的java小代码就不再另述了。可以直接从ckeditor.jsp或者tinymce.jsp里面复制。

ueditor的JS的引入

<c:if test="<%= !skipEditorLoading %>">
 <liferay-util:html-top outputKey="js_editor_ueditor">

<%
 long javaScriptLastModified = ServletContextUtil.getLastModified(application, "/html/js/", true);
 %>

<script src="<%= HtmlUtil.escape(PortalUtil.getStaticResourceURL(request, 
themeDisplay.getCDNHost() + themeDisplay.getPathJavaScript() + "/editor/ueditor/ueditor.config.js", 
javaScriptLastModified)) %>" type="text/javascript"></script>
 <script src="<%= HtmlUtil.escape(PortalUtil.getStaticResourceURL(request, themeDisplay.getCDNHost() 
+ themeDisplay.getPathJavaScript() + "/editor/ueditor/ueditor.all.min.js", javaScriptLastModified)) %>" 
type="text/javascript"></script>
 <script src="<%= HtmlUtil.escape(PortalUtil.getStaticResourceURL(request, themeDisplay.getCDNHost() 
+ themeDisplay.getPathJavaScript() + "/editor/ueditor/lang/zh-cn/zh-cn.js", javaScriptLastModified)) %>"
 type="text/javascript"></script>
 <script type="text/javascript">
 Liferay.namespace('EDITORS')['<%= editorImpl %>'] = true;
 </script>
 <link rel='stylesheet' id='style-css' href='<%= HtmlUtil.escape(
PortalUtil.getStaticResourceURL(request, themeDisplay.getCDNHost() + themeDisplay.getPathJavaScript() 
+ "/editor/ueditor/themes/default/css/ueditor.min.css", javaScriptLastModified)) %>' type='text/css'/>
 </liferay-util:html-top>
</c:if>
<div class="<%= cssClass %>">
 <script id="<%= name %>" name="<%= name %>" type="text/plain"
 style="height: 100%; width: 100%;"></script>
</div>

3、上面算是引入ueditor相关的JS和CSS,下面的<script>里面的是我们存放内容的部分。

4、ueditor的初始化和相关的JS代码的调用。下面是我们做的uedtior的初始化,serverparam是上传图片是所需要的两个额外参数,groupid和userId。

 var ue = UE.getEditor('<%= name %>');
 ue.ready(function() {
 ue.execCommand('serverparam', {
 'groupId': '<%=doAsGroupId%>',
 'folderId':'0',
 'userId':'<%=userId%>'
 });
 ue.setContent(window['<%= HtmlUtil.escapeJS(namespace + initMethod) %>']());
 });

5、如果只是我们针对最开始说的场景1,那现在就可以了,但是如果要能够在场景2里面使用,liferay默认里面有一些编辑器初始化和获取内容的代码,需要我们照写。代码如下,这些代码为方便集成liferay内部如网页内容发布,博客等的JS而写。

window['<%= name %>'] = {
 onChangeCallbackCounter: 0,

destroy: function() {
 ue.destroy();
 window['<%= name %>'] = null;
 },

focus: function() {
 UE.getEditor('<%= name %>').focus();
 },

fileBrowserCallback: function(field_name, url, type) {
 },

getHTML: function() {
 var data;

if (!window['<%= name %>'].instanceReady && window['<%= HtmlUtil.escape(namespace + initMethod) %>']) {
 data = <%= HtmlUtil.escape(namespace + initMethod) %>();
 }
 else {
 data = ue.getContent();
 }

return data;
 },

init: function(value) {
 if (typeof value != 'string') {
 value = '';
 }

window['<%= name %>'].setHTML(value);
 },

initEditor: function() {
 <c:if test="<%= Validator.isNotNull(initMethod) %>">
 <%= name %>.setHTML(window['<%= HtmlUtil.escapeJS(namespace + initMethod) %>']());

<c:if test="<%= resizable && BrowserSnifferUtil.isIe(request) %>">
 new A.Resize(
 {
 handles: 'br',
 node: '#<%= name %>_container',
 wrap: true
 }
 );
 </c:if>
 </c:if>

window['<%= name %>'].instanceReady = true;
 },


 initInstanceCallback: function() {
 window['<%= name %>'].instanceReady = true;
 },

instanceReady: false,

<%
 if (Validator.isNotNull(onChangeMethod)) {
 %>

onChangeCallback: function() {


 var onChangeCallbackCounter = window['<%= name %>'].onChangeCallbackCounter;

if (onChangeCallbackCounter > 0) {

<%= HtmlUtil.escapeJS(onChangeMethod) %>(window['<%= name %>'].getHTML());

}

onChangeCallbackCounter++;
 },

<%
 }
 %>


 setHTML: function(value) {
 ue.ready(function() {
 ue.setContent(value);
 });
 
 }
 };

6、ueditor.jsp的完整代码点击这里进行下载。ueditor

第三步:文件上传处理。

1、下载ueditor的源码包,在里面找到jsp目录下面有src,相关的源码。

2、将此源码导入到eclipse工程里面为一个普通的java工程。

3、修改build path里面的jar包依赖,为liferay本身有的包commons-codec.jar,commons-fileupload.jar,commons-io.jar,json-java.jar。

ueditor buildpath

4、此时src里面的大部分错误已经消失了,但是在configmanager里面,由于json库不太一样有一些错误,我们进行修复调整即可。

5、找到com.baidu.uedtor.upload下面的BinaryUploader类,这是上传文件处理类。里面默认有这么一行代码,在80行左右。

State storageState = StorageManager.saveFileByInputStream(is,physicalPath, maxSize);

将这里代码替换为我们自己写的,如下:

//Liferay file upload
 long groupId = ParamUtil.getLong(request, "groupId");
 long folderId = ParamUtil.getLong(request, "folderId",0);
 long userId = ParamUtil.getLong(request, "userId");
 
 State storageState = StorageManager.saveFileToLiferay(is, fileStream.getName(),userId,groupId,folderId);
 //State storageState = StorageManager.saveFileByInputStream(is,physicalPath, maxSize);
 is.close();

if (storageState.isSuccess()) {
// storageState.putInfo("url", PathFormat.format(savePath));
 storageState.putInfo("type", suffix);
 storageState.putInfo("original", originFileName + suffix);
 }

其中的StorageManager.saveFileToLiferay方法为我们在StorageManager里面自己定义的,代码如下:

public static State saveFileToLiferay(InputStream is,String fileName,long userId,long repositoryId,long folderId){
 State state = null;
 ServiceContext serviceContext = new ServiceContext();

serviceContext.setAddGroupPermissions(true);
 serviceContext.setAddGuestPermissions(true);
 
 try {
 String description = StringPool.BLANK;
 String changeLog = StringPool.BLANK;
 
 byte[] bytes = FileUtil.getBytes(is);
 
 String mimeType = MimeTypesUtil.getContentType(fileName);
 
 //因为liferay默认情况下不能上传同名的文件,为了处理这个问题,添加一个时间戳
 String sourceFileName = System.currentTimeMillis() + "-" + fileName;
 
 FileEntry fileEntry = DLAppLocalServiceUtil.addFileEntry(userId, repositoryId, folderId, 
fileName, mimeType, sourceFileName, description, changeLog, bytes, serviceContext);
 
 String url = "/documents/" + fileEntry.getRepositoryId() + "/"+ fileEntry.getUuid();
 
 state = new BaseState(true);
 state.putInfo( "size", fileEntry.getSize());
 state.putInfo( "title", fileName);
 state.putInfo("url", url);
 
 return state;
 } catch (PortalException e) {
 e.printStackTrace();
 } catch (SystemException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 }
 
 return new BaseState(false, AppInfo.IO_ERROR);
 }

6、现在上传的代码处理完成,在此java工程上点击右键,导出成jar包。复制到portal的web-inf/lib目录下面即可。

第四步:代码的使用

首先:部署上面的hook工程,和将ueditor.jar包复制到了portal/web-inf/lib目录下面。

如果是在自己的Portlet插件中使用代码如下,如果在portal-setup-wizard.properties里面加入此行配置editor.wysiwyg.ueditor=ueditor

<liferay-ui:input-editor name="detail" editorImpl="editor.wysiwyg.ueditor"/>
 如果是想向编辑器里面设置内容:
<aui:script use="aui-base">
	window['<portlet:namespace />detail'].init('${question.detail}');
</aui:script>

如果是要替换网页内容管理,则在portal-setup-wizard.properties里面加上如下配置,重启之后即生效。

editor.wysiwyg.portal-web.docroot.html.portlet.journal.configuration.jsp=ueditor
editor.wysiwyg.portal-web.docroot.html.portlet.journal.edit_article_content.jsp=ueditor

按照此文说明,可以完成集成,如果是想要现成的,请到淘宝购买,不免费。

淘宝链接:https://item.taobao.com/item.htm?id=533006976450

用户头像

给我留言

您必须 登录 才能发表留言!

Copyright © IT人生录 保留所有权利.   主题设计 知更鸟 滇ICP备16001547号

用户登录

分享到: