最近在使用Liferay开发一个门户网站的过程中遇到默认的在线文章编辑器无法满足用户需求的问题。Liferay默认的文章编辑器功能比较简单,且可扩展性较差。经过再三权衡,决定采用tinyMCE作为Liferay的默认在线文章编辑器。但是,官方下载的tinyMCE的advimage插件不具有图片上传的功能,需要对该插件进行扩展。经过反复琢磨,终于解决了以上的问题。现在把解决方法写出来,希望能给有需要的网友一点帮助。
需要注意的是早期的liferay-3.6.1集成tinyMCE存在问题,在IE浏览器环境下不能正确显示编辑器,显示“timyMCE为定义”错误。在firefox浏览器下可以正确显示,但是页面初始化时非常慢。经过很多尝试这些问题忍让没有解决,估计问题与Liferay的页面缓存有关。另外在liferay-3.6.1环境下上传图片时会出现图片文件大小发生变化,且文件被破坏的问题。Liferay的更新版本已经发布,且以上存在的问题可能与Liferay本身的实现机制有关,解决这些问题可能比较棘手(呵呵,如果哪位大侠知道还望不吝赐教啊!),因此实现中使用的软件版本如下:
tinyMCE:tinymce_2_0_8
Liferay:liferay-portal-tomcat-4.1.2
在使用tinyMCE前先解决tinyMCE的中文化以及中文字体的使用问题。
(一)tinyMCE的中文化以及中文字体 中文化方法:
tinyMCE的中文化问题解决非常简单。首先到tinyMCE的官方下载中文语言包tinymce_lpackage_zh-cn.jar,并将其解压(假设解压后的路径为{$LANGUAGE_PATH})。然后将解压后的{$LANGUAGE_PATH}\tinymce\jscripts\tiny_mce目录下的所有文件复制到liferay安装路径(假设liferay的安装路径为{$LIFERAY_HOME})的/webapps/ROOT/html/js/editor/tinymce目录下,修改该路径下的timymce.jsp,在tynyMCE.init中增加配置项 language : "zh_cn"。
中文字体设置方法:
默认情况下,tinyMCE编辑工具栏的字体下拉框中没有中文字体,需要在下拉框中增加需要的中文字体。修改方法如下,分别修改{$LIFERAY_HOME}/webapps/ROOT /html/ js/editor/ tinymce/themes/ 目录下的两个子目录advanced和simple目录下的editor_template.js。在var iFonts='…'和var nFonts='…'中增加中文字体,如增加“宋体=宋体;方正姚体=方正姚体”等。
(二)集成Liferay和tinyMCE 1.下载tinymce_2_0_8.zip,并解压(假设解压目录为{$TINYMCE_PATH})。然后将解压后的文件夹{$TINYMCE_PATH}\tinymce\jscripts\tiny_mce复制到{$LIFERAY_HOME}\ \webapps\ROOT\html\js\editor下,并改名为tinymce;
2. 设置Liferay应用的默认html编辑器为tinymce;(可以修改配置文件system.properties或直接修改{$LIFERAY_HOME}\webapps\ROOT\html\js\editor\editor.jsp); 修改后的editor.jsp如下:
<%@ page import="com.liferay.portal.util.Constants" %>
<%@ page import="com.liferay.portal.util.PropsUtil" %>
<%@ page import="com.liferay.util.BrowserSniffer" %>
<%@ page import="com.liferay.util.ParamUtil" %>
<%
String editorImpl = "simple";
if (BrowserSniffer.is_rtf(request)) {
editorImpl = ParamUtil.get(request, "editorImpl", PropsUtil.get(EDITOR_WYSIWYG_IMPL_KEY));
}
//editorImpl = "fckeditor";
//editorImpl = "liferay";
//editorImpl = "simple";
editorImpl = "tinymce";
// Resin won't allow dynamic content inside the jsp:include tag
RequestDispatcher rd = application.getRequestDispatcher(Constants.TEXT_HTML_DIR + "/js/editor/" + editorImpl + ".jsp");
rd.include(request, response);
%>
<%--<jsp:include page='<%= Constants.TEXT_HTML_DIR + "/js/editor/" + editorImpl + ".jsp" %>' />--%>
(三)为tinyMCE增加图片上传功能 本实现采用Struts实现图片的上传。 步骤如下:
1.编写文件上传类。代码清单如下:
FileUploadAction.java代码清单如下:
package com.family.fileupload.web.action;
import java.util.Calendar;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.family.fileupload.web.form.FileUploadForm;
import com.family.fileupload.web.utils.FileUpload;
public class FileUploadAction extends DispatchAction {
public ActionForward uploadImage(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
FileUploadForm uploadForm = (FileUploadForm) form;
FileUpload fu = new FileUpload(uploadForm.getFile());
String realPath = this.getRealPath("/pictures");
String fileName = this.getFileKeyRule() + "." + fu.getExtendName().toLowerCase();
String filePath = realPath + "/" + fileName;
fu.saveToFile(filePath);
request.setAttribute("fileUrl", this.getRootUrl(request) + "/pictures/" + fileName);
return mapping.findForward("image.success");
}
private String getRootUrl(HttpServletRequest request) {
StringBuffer buf = request.getRequestURL();
int length = request.getRequestURI().length();
buf.delete(buf.length() - length, buf.length());
return buf.toString();
}
private String getRealPath(String floder) {
return this.getServlet().getServletConfig().getServletContext().getRealPath(floder);
}
private String getFileKeyRule() {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
int iYear = cal.get(Calendar.YEAR);
int iMonth = cal.get(Calendar.MONDAY) + 1;
int iDay = cal.get(Calendar.DAY_OF_MONTH);
int iHour = cal.get(Calendar.HOUR_OF_DAY);
int iMinute = cal.get(Calendar.MINUTE);
int iSecond = cal.get(Calendar.SECOND);
StringBuffer strKey = new StringBuffer(15);
strKey.append(iYear);
if (iMonth < 10) {
strKey.insert(4, '0');
strKey.insert(5, iMonth);
} else {
strKey.insert(4, iMonth);
}
if (iDay < 10) {
strKey.insert(6, '0');
strKey.insert(7, iDay);
} else {
strKey.insert(6, iDay);
}
if (iHour < 10) {
strKey.insert(8, '0');
strKey.insert(9, iHour);
} else {
strKey.insert(8, iHour);
}
if (iMinute < 10) {
strKey.insert(10, '0');
strKey.insert(11, iMinute);
} else {
strKey.insert(10, iMinute);
}
if (iSecond < 10) {
strKey.insert(12, '0');
strKey.insert(13, iSecond);
} else {
strKey.insert(12, iSecond);
}
return strKey.toString();
}
}
FileUploadForm.java代码清单如下:
package com.family.fileupload.web.form;
import org.apache.struts.action.ActionForm;
import org.apache.struts.upload.FormFile;
public class FileUploadForm extends ActionForm {
private static final long serialVersionUID = 1L;
private FormFile file = null;
public FormFile getFile() {
return file;
}
public void setFile(FormFile file) {
this.file = file;
}
}
FileUpload.java代码清单如下:
package com.family.fileupload.web.utils;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.struts.upload.FormFile;
public class FileUpload {
private FormFile file;
private int fileSize;
private String fileName;
private String extendName;
private String contentType;
public FileUpload (FormFile file) {
this.file = file;
fileName = this.file.getFileName();
fileSize = this.file.getFileSize();
contentType = this.file.getContentType();
int position = this.file.getFileName().indexOf(".");
extendName = this.file.getFileName().substring(position + 1, this.file.getFileName().length());
}
public void saveToFile(String fileName) {
try {
InputStream is = this.file.getInputStream();
int bytesRead = 0;
byte[] buffer = new byte[8912];
OutputStream os = new FileOutputStream(fileName);
while ((bytesRead = is.read(buffer, 0, 8912)) != -1) {
os.write(buffer, 0, bytesRead);
}
is.close();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String getContentType() {
return contentType;
}
public String getExtendName() {
return extendName;
}
public FormFile getFile() {
return file;
}
public String getFileName() {
return fileName;
}
public int getFileSize() {
return fileSize;
}}
2.将以上文件编译后打包成 upload.jar,并发布到Liferay应用的包路径下({$LIFERAY_HOME}/webapps/ROOT/WEB-INF/lib);
3.编写upload.jsp并复制到liferay应用的的{$LIFERAY_HOME}/webapps/ROOT\html\js\editor\ tinymce\ plugins\advimage\目录下;
Upload.jsp的代码清单如下:
<form action="/c/portal/fileUpload?method=uploadImage" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit">
</form>
4.编写imagePath.jsp并复制到\webapps\ROOT\html下;
代码清单如下:
<script>
function insertImage() {
var imageUrl = '<%=(String) request.getAttribute("fileUrl")%>';
if (imageUrl != '') {
opener.document.all("src").value = imageUrl;
window.close();
}
}
</script>
5. 在tinymce.jsp中增加如下代码
*/
function fileBrowserCallBack(field_name, url, type, win) {
//打开文件上传窗口
win.open("upload.jsp");
}
6. 在liferay的配置文件struts-config.xml或struts-config-ext.xml文件中增加如下配置:
增加formbean配置:
<form-beans>
......
<form-bean name="fileUploadForm" type="com.family.fileupload.web.form.FileUploadForm" />
</form-beans>
增加action配置:
<action-mappings>
……
<action
name="fileUploadForm"
path="/portal/fileUpload"
scope="request"
type="com.family.fileupload.web.action.FileUploadAction"
parameter="method">
<forward name="file.success" path="/filePath.jsp"/>
<forward name="image.success" path="/imagePath.jsp"/>
</action>
</action-mappings>
注:本实现中有关文件上传的组件与liferay集成在同一个web应用中,事实上也可以根据实际情况将文件上传的组件独立成一个单独的web应用。但是需要对tinymce.jsp代码做适当的修改。大家不妨试试:)
相关推荐
在Liferay中整合GWT(Google Web Toolkit)是一项常见的任务,尤其对于开发复杂的企业级Web应用来说,这种集成可以利用GWT的强大力量来创建高性能的用户界面,同时利用Liferay的门户功能和社区特性。这篇博文提供了...
【Liferay Portlet 对象详解】 在 Liferay 平台中,Portlet 是核心组件,它负责呈现内容和提供互动功能。Portlet 技术的理解和应用是开发 Liferay 应用程序的关键。本文将深入解析 Portlet 的关键概念,包括 ...
### Liferay 6 整合 Oracle 10g 步骤详解 在当前的企业级应用环境中,Liferay作为一款强大的企业门户系统,被广泛应用于构建各类业务应用平台。然而,在实际部署过程中,尤其是在与数据库的整合方面,经常会遇到...
在这个"liferay 整合struts例子"中,我们可以学习到以下几个关键知识点: 1. **Liferay Portal架构**:Liferay的核心在于其portlet架构,portlet是可重用的Web组件,可以独立于其他portlet运行。Liferay提供了一个...
本文将以“liferay表结构详解”为主题,聚焦于Liferay数据库中的Layout表,旨在详尽解读此表的功能与结构,以及它在Liferay门户系统中的关键作用。 ### Layout表:存储页面布局信息 **功能概述**:Layout表在...
liferay-portal详解 Liferay Portal 是一个基于 Java 的开源门户平台,提供了一个灵活的框架来构建企业门户和 web 应用程序。本文档将从架构解析、portal 规范、portlet 容器、portlet 生命周期、liferay portal ...
在本文中,我们将深入探讨Liferay插件的开发过程,包括环境配置、Portlet开发、Layout和Theme开发等关键步骤。Liferay是一个开源的企业级门户平台,它允许开发者通过插件扩展其功能,以满足不同业务需求。 首先,...
### Liferay Portal的内容和布局详解 #### 一、布局(Layout) **布局**是Liferay Portal中用于管理Portlet的关键概念之一。布局不仅决定着Portlet的呈现方式,还影响着用户的交互体验。在Liferay中,布局是通过一...
2. **Portlet开发**:Portlet是Liferay中的基本展示单元,类似于Web应用中的MVC组件。开发者需要掌握如何创建、配置和部署Portlet,包括MVCPortlet、JSR286 Portlet和Freemarker或JSP模板的使用。 3. **服务构建器...
在"liferay-SSI-portlet"这个压缩包中,包含了实现上述整合的具体代码和配置文件。开发者可以通过这个案例学习如何在Liferay中创建portlet,然后引入Struts2进行前端请求处理,利用Spring进行业务逻辑和服务管理,...
Portlets是Liferay中的核心组件,可以视为网页上的小型应用。通过学习这份文档,开发者能够理解portlet生命周期、渲染机制以及如何利用MVC Portlet模式进行开发。此外,文档还涵盖了portlet与Liferay服务的集成,如...
本超学习文档将深入探讨Liferay的核心特性、开发环境、Java技术的应用以及Hibernate在Liferay中的整合。 一、Liferay 框架 Liferay 框架基于Java EE(Enterprise Edition)标准,它提供了丰富的API和工具,允许...
4. **工作流程整合**:利用Alfresco的工作流程引擎,可以为Liferay中的portlet定义和执行复杂的业务流程,提高工作效率。 为了实现这样的整合,我们需要进行以下步骤: 1. **配置CAS服务器**:首先,要在CAS服务器...
对于熟悉或正在学习Liferay的用户来说,这些中文资源将提供极大的帮助,尤其是对于那些在英语环境中遇到困难的开发者。 描述中的博文链接指向了ITEYE博客上的一篇文章,作者是Jyao。虽然没有具体的博文内容,我们...
【Liferay 门户集成CAS实现单点登录与应用系统集成】是将开源门户平台Liferay与中央认证服务(CAS)相结合,以实现用户在多个应用系统间的统一登录体验。Liferay是一个基于Java的企业级门户解决方案,它具备强大的...