`

Liferay中日历组件的使用

阅读更多
calendar Portlet的例子用法:在Liferay自带portlet中,calendar 是个不错的例子。

calendar Portlet包含7个选项:总结,天,星期,月,年,事项,出口/进口
默认显示“总结”选项的主页面,单击页面的“增加事项”按钮,跳转到edit_event.jsp页面,页面显示效果如下:

[img]http://fantasyyong840205.iteye.com/upload/picture/pic/8110/8955b435-7b90-33ed-95ef-17d4d4e01439.jpg [/img]

edit_event.jsp页面:

<%
// 只列出关键代码
String redirect = ParamUtil.getString(request, "redirect");

CalEvent event = (CalEvent)request.getAttribute(WebKeys.CALENDAR_EVENT);

long eventId = BeanParamUtil.getLong(event, request, "eventId");

Calendar startDate = CalendarUtil.roundByMinutes((Calendar)selCal.clone(), 15);

if (event != null) {
	if (!event.isTimeZoneSensitive()) {
		startDate = CalendarFactoryUtil.getCalendar();
	}

	startDate.setTime(event.getStartDate());
}

Calendar endDate = (Calendar)curCal.clone();

endDate.add(Calendar.YEAR, 1);

if (event != null) {
	if (!event.isTimeZoneSensitive()) {
		endDate = CalendarFactoryUtil.getCalendar();
	}

	if (event.getEndDate() != null) {
		endDate.setTime(event.getEndDate());
	}
}

%>

<!-- 省略中间代码 -->

<table class="liferay-table">
<tr>
	<td>
		<liferay-ui:message key="start-date" />
	</td>
	<td>
		<liferay-ui:input-field model="<%= CalEvent.class %>" bean="<%= event %>" field="startDate" defaultValue="<%= startDate %>" />
	</td>
</tr>


这样,将会显示日期控件,实现样式效果如上图所示。年月日分别显示,并且有一个日历按钮,可以弹出一个典型的日历界面。

生成的代码,主要分成以下几个部分:

1. 相应的JavaScript语句
这部分代码,一是创建一个Calendar对象,就是会弹出来的日历页面。

2.生成年月日的HTML代码
年月日代码,在Liferay里面,是三个单独的Select框。

3.一个弹出日历页面的图片
用了一个图片calendar.gif,单击就会显示日历页面。

4.生成时分的HTML代码
在Liferay里面,有两个Select框,分别选择时和分,还有一个AM、PM的Select框。

看到这里,可能会有一个疑问,几乎所有的input输入框,都是使用<liferay-ui:input-field>这个Taglib实现的,而且从JSP中,看不出在哪儿定义了这个input-field应该显示为日期,而不是普通的input窗口。

而这,可以通过阅读源代码来解释。具体代码为:
portal\portal-web\docroot\html\taglib\ui\input_field\page.jsp


<%@ include file="/html/taglib/init.jsp" %>

<%@ page import="com.liferay.portal.model.impl.BaseModelImpl" %>
<%@ page import="com.liferay.util.XSSUtil" %>

<%
// 得到liferay-ui:input-field 标签提交的 model 属性
String model = (String)request.getAttribute("liferay-ui:input-field:model");
// 得到liferay-ui:input-field 标签提交的 bean 属性
Object bean = request.getAttribute("liferay-ui:input-field:bean");
// 得到liferay-ui:input-field 标签提交的 field 属性
String field = (String)request.getAttribute("liferay-ui:input-field:field");
// 得到liferay-ui:input-field 标签提交的 fieldParam 属性
String fieldParam = (String)request.getAttribute("liferay-ui:input-field:fieldParam");
// 得到liferay-ui:input-field 标签提交的 defaultValue 属性
Object defaultValue = request.getAttribute("liferay-ui:input-field:defaultValue");
// 得到liferay-ui:input-field 标签提交的 disabled 属性
boolean disabled = GetterUtil.getBoolean((String)request.getAttribute("liferay-ui:input-field:disabled"));

// 得到配置文件中对应 model的 field 的 type属性
String type = ModelHintsUtil.getType(model, field);
Map hints = ModelHintsUtil.getHints(model, field);
%>

<c:if test="<%= type != null %>">
	<c:choose>
		<c:when test='<%= type.equals("boolean") %>'>

			<%
			boolean defaultBoolean = GetterUtil.DEFAULT_BOOLEAN;

			if (defaultValue != null) {
				defaultBoolean = ((Boolean)defaultValue).booleanValue();
			}
			else {
				if (hints != null) {
					defaultBoolean = GetterUtil.getBoolean((String)hints.get("default-value"));
				}
			}

			boolean value = BeanParamUtil.getBoolean(bean, request, field, defaultBoolean);
			%>

			<liferay-ui:input-checkbox param="<%= field %>" defaultValue="<%= value %>" disabled="<%= disabled %>" />
		</c:when>
		
		<!-- 配置文件中对应 model的 field 的 type属性值是“Date” -->
		<c:when test='<%= type.equals("Date") %>'>

			<%
			// 如果liferay-ui:input-field 标签没有提交fieldParam属性,fieldParam值等同于field属性值
			if (fieldParam == null) {
				fieldParam = field;
			}
			// defaultValue 属性值一般是表单提交当时的时间
			Calendar cal = (Calendar)defaultValue;

			int month = ParamUtil.getInteger(request, fieldParam + "Month", -1);

			if ((month == -1) && (cal != null)) {
				month = cal.get(Calendar.MONTH);
			}

			boolean monthNullable = false;

			if (hints != null) {
				monthNullable = GetterUtil.getBoolean((String)hints.get("month-nullable"), monthNullable);
			}

			int day = ParamUtil.getInteger(request, fieldParam + "Day", -1);

			if ((day == -1) && (cal != null)) {
				day = cal.get(Calendar.DATE);
			}

			boolean dayNullable = false;

			if (hints != null) {
				dayNullable = GetterUtil.getBoolean((String)hints.get("day-nullable"), dayNullable);
			}

			int year = ParamUtil.getInteger(request, fieldParam + "Year", -1);

			if ((year == -1) && (cal != null)) {
				year = cal.get(Calendar.YEAR);
			}

			boolean yearNullable = false;

			if (hints != null) {
				yearNullable = GetterUtil.getBoolean((String)hints.get("year-nullable"), yearNullable);
			}

			int yearRangeDelta = 5;

			if (hints != null) {
				yearRangeDelta = GetterUtil.getInteger((String)hints.get("year-range-delta"), yearRangeDelta);
			}

			int yearRangeStart = year - yearRangeDelta;
			int yearRangeEnd = year + yearRangeDelta;

			if (year == -1) {
				Calendar now = CalendarFactoryUtil.getCalendar(timeZone, locale);

				yearRangeStart = now.get(Calendar.YEAR) - yearRangeDelta;
				yearRangeEnd = now.get(Calendar.YEAR) + yearRangeDelta;
			}

			int firstDayOfWeek = Calendar.SUNDAY - 1;

			if (cal != null) {
				firstDayOfWeek = cal.getFirstDayOfWeek() - 1;
			}

			int hour = ParamUtil.getInteger(request, fieldParam + "Hour", -1);

			if ((hour == -1) && (cal != null)) {
				hour = cal.get(Calendar.HOUR);
			}

			int minute = ParamUtil.getInteger(request, fieldParam + "Minute", -1);

			if ((minute == -1) && (cal != null)) {
				minute = cal.get(Calendar.MINUTE);
			}

			int amPm = ParamUtil.getInteger(request, fieldParam + "AmPm", -1);

			if ((amPm == -1) && (cal != null)) {
				amPm = cal.get(Calendar.AM_PM);
			}

			boolean showTime = true;

			if (hints != null) {
				showTime = GetterUtil.getBoolean((String)hints.get("show-time"), showTime);
			}
			%>

			<liferay-ui:input-date
				monthParam='<%= fieldParam + "Month" %>'
				monthValue="<%= month %>"
				monthNullable="<%= monthNullable %>"
				dayParam='<%= fieldParam + "Day" %>'
				dayValue="<%= day %>"
				dayNullable="<%= dayNullable %>"
				yearParam='<%= fieldParam + "Year" %>'
				yearValue="<%= year %>"
				yearNullable="<%= yearNullable %>"
				yearRangeStart="<%= yearRangeStart %>"
				yearRangeEnd="<%= yearRangeEnd %>"
				firstDayOfWeek="<%= firstDayOfWeek %>"
				imageInputId='<%= fieldParam + "ImageInputId" %>'
				disabled="<%= disabled %>"
			/>

			<c:if test="<%= showTime %>">
				&nbsp;

				<liferay-ui:input-time
					hourParam='<%= fieldParam + "Hour" %>'
					hourValue="<%= hour %>"
					minuteParam='<%= fieldParam + "Minute" %>'
					minuteValue="<%= minute %>"
					minuteInterval="1"
					amPmParam='<%= fieldParam + "AmPm" %>'
					amPmValue="<%= amPm %>"
					disabled="<%= disabled %>"
				/>
			</c:if>
		</c:when>
		<c:when test='<%= type.equals("double") || type.equals("int") || type.equals("String") %>'>

			<%
			String defaultString = GetterUtil.DEFAULT_STRING;

			if (defaultValue != null) {
				defaultString = (String)defaultValue;
			}

			String value = null;

			if (fieldParam == null) {
				fieldParam = namespace + field;

				if (type.equals("double")) {
					value = String.valueOf(BeanParamUtil.getDouble(bean, request, field, GetterUtil.DEFAULT_DOUBLE));
				}
				else if (type.equals("int")) {
					value = String.valueOf(BeanParamUtil.getInteger(bean, request, field, GetterUtil.DEFAULT_INTEGER));
				}
				else {
					value = BeanParamUtil.getString(bean, request, field, defaultString);

					String httpValue = request.getParameter(field);

					if (httpValue != null) {
						boolean xssAllowByModel = GetterUtil.getBoolean(PropsUtil.get("xss.allow." + model), BaseModelImpl.XSS_ALLOW);
						boolean xssAllowByField = GetterUtil.getBoolean(PropsUtil.get("xss.allow." + model + "." + field), xssAllowByModel);

						value = XSSUtil.strip(httpValue);
					}
				}
			}
			else {
				fieldParam = namespace + fieldParam;
				value = defaultString;
			}

			String displayHeight = ModelHintsDefaults.TEXT_DISPLAY_HEIGHT;
			String displayWidth = ModelHintsDefaults.TEXT_DISPLAY_WIDTH;
			String maxLength = ModelHintsDefaults.TEXT_MAX_LENGTH;
			boolean upperCase = false;
			boolean checkTab = false;

			if (hints != null) {
				displayHeight = GetterUtil.getString((String)hints.get("display-height"), displayHeight);
				displayWidth = GetterUtil.getString((String)hints.get("display-width"), displayWidth);
				maxLength = GetterUtil.getString((String)hints.get("max-length"), maxLength);
				upperCase = GetterUtil.getBoolean((String)hints.get("upper-case"), upperCase);
				checkTab = GetterUtil.getBoolean((String)hints.get("check-tab"), checkTab);
			}
			%>

			<c:choose>
				<c:when test='<%= displayHeight.equals(ModelHintsDefaults.TEXT_DISPLAY_HEIGHT) %>'>

					<%
					if (Validator.isNotNull(value)) {
						int maxLengthInt = GetterUtil.getInteger(maxLength);

						if (value.length() > maxLengthInt) {
							value = value.substring(0, maxLengthInt);
						}
					}
					%>

					<input <%= disabled ? "disabled" : "" %> id="<%= fieldParam %>" name="<%= fieldParam %>" style="width: <%= displayWidth %>px; <%= upperCase ? "text-transform: uppercase;" : "" %>" type="text" value="<%= value %>" onKeyPress="Liferay.Util.checkMaxLength(this, <%= maxLength %>);">
				</c:when>
				<c:otherwise>
					<textarea <%= disabled ? "disabled" : "" %> id="<%= fieldParam %>" name="<%= fieldParam %>" style="height: <%= displayHeight %><%= Validator.isDigit(displayHeight) ? "px" : "" %>; width: <%= displayWidth %><%= Validator.isDigit(displayWidth) ? "px" : "" %>;" wrap="soft" onKeyDown="<%= checkTab ? "Liferay.Util.checkTab(this); " : "" %> Liferay.Util.disableEsc();" onKeyPress="Liferay.Util.checkMaxLength(this, <%= maxLength %>);"><%= value %></textarea>
				</c:otherwise>
			</c:choose>
		</c:when>
	</c:choose>
</c:if>


ModelHintsUtil.java:

package com.liferay.portal.model;

import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.util.InitUtil;
import com.liferay.portal.util.PropsUtil;
import com.liferay.util.CollectionFactory;
import com.liferay.util.ListUtil;

import java.io.StringReader;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * <a href="ModelHintsUtil.java.html"><b><i>View Source</i></b></a>
 * 
 * @author Brian Wing Shun Chan
 * 
 */
public class ModelHintsUtil {

	static {
		InitUtil.init();
	}

	public static Map getDefaultHints(String model) {
		return _instance._getDefaultHints(model);
	}

	public static Element getFieldsEl(String model, String field) {
		return _instance._getFieldsEl(model, field);
	}

	public static List getModels() {
		return _instance._getModels();
	}

	public static String getType(String model, String field) {
		return _instance._getType(model, field);
	}

	public static Map getHints(String model, String field) {
		return _instance._getHints(model, field);
	}

	public static String trimString(String model, String field, String value) {
		if (value == null) {
			return value;
		}

		Map hints = getHints(model, field);

		if (hints == null) {
			return value;
		}

		int maxLength = GetterUtil
				.getInteger(ModelHintsDefaults.TEXT_MAX_LENGTH);

		maxLength = GetterUtil.getInteger((String) hints.get("max-length"),
				maxLength);

		if (value.length() > maxLength) {
			return value.substring(0, maxLength);
		} else {
			return value;
		}
	}

	private ModelHintsUtil() {
		_hintCollections = CollectionFactory.getHashMap();
		_defaultHints = CollectionFactory.getHashMap();
		// 从CollectionFactory中得到新的HashMap对象
		_modelFields = CollectionFactory.getHashMap();
		_models = new TreeSet();

		try {
			ClassLoader classLoader = getClass().getClassLoader();

			String[] configs = StringUtil.split(PropsUtil
					.get(PropsUtil.MODEL_HINTS_CONFIGS));

			for (int i = 0; i < configs.length; i++) {
				_read(classLoader, configs[i]);
			}
		} catch (Exception e) {
			_log.error(e, e);
		}
	}

	private Map _getDefaultHints(String model) {
		return (Map) _defaultHints.get(model);
	}

	private Element _getFieldsEl(String model, String field) {
		Map fields = (Map) _modelFields.get(model);

		if (fields == null) {
			return null;
		} else {
			return (Element) fields.get(field + _ELEMENTS_SUFFIX);
		}
	}

	private List _getModels() {
		return ListUtil.fromCollection(_models);
	}

	/**
	 * Portal容器加载portal-model-hints.xml配置文件,按照节点解析为内存对象。
	 * 
	 * 把文件中的 model 的name属性作为 key 将所有的 model节点对象(Map类型)存入集合.
	 * 
	 * 根据配置文件中的 field 的name属性 + “_TYPE”字符串 作为 key 得到对应的field节点对象的type属性值。
	 * 
	 */
	private String _getType(String model, String field) {
		Map fields = (Map) _modelFields.get(model);

		if (fields == null) {
			return null;
		} else {
			return (String) fields.get(field + _TYPE_SUFFIX);
		}
	}

	private Map _getHints(String model, String field) {
		Map fields = (Map) _modelFields.get(model);

		if (fields == null) {
			return null;
		} else {
			return (Map) fields.get(field + _HINTS_SUFFIX);
		}
	}

	private void _read(ClassLoader classLoader, String source) throws Exception {

		String xml = null;

		try {
			xml = StringUtil.read(classLoader, source);
		} catch (Exception e) {
			_log.warn("Cannot load " + source);
		}

		if (xml == null) {
			return;
		}

		if (_log.isDebugEnabled()) {
			_log.debug("Loading " + source);
		}

		SAXReader reader = new SAXReader();

		Document doc = reader.read(new StringReader(xml));

		Element root = doc.getRootElement();

		Iterator itr1 = root.elements("hint-collection").iterator();

		while (itr1.hasNext()) {
			Element hintCollection = (Element) itr1.next();

			String name = hintCollection.attributeValue("name");

			Map hints = (Map) _hintCollections.get(name);

			if (hints == null) {
				hints = CollectionFactory.getHashMap();

				_hintCollections.put(name, hints);
			}

			Iterator itr2 = hintCollection.elements("hint").iterator();

			while (itr2.hasNext()) {
				Element hint = (Element) itr2.next();

				String hintName = hint.attributeValue("name");
				String hintValue = hint.getText();

				hints.put(hintName, hintValue);
			}
		}

		itr1 = root.elements("model").iterator();

		while (itr1.hasNext()) {
			Element model = (Element) itr1.next();

			String name = model.attributeValue("name");

			Map defaultHints = CollectionFactory.getHashMap();

			_defaultHints.put(name, defaultHints);

			Element defaultHintsEl = model.element("default-hints");

			if (defaultHintsEl != null) {
				Iterator itr2 = defaultHintsEl.elements("hint").iterator();

				while (itr2.hasNext()) {
					Element hint = (Element) itr2.next();

					String hintName = hint.attributeValue("name");
					String hintValue = hint.getText();

					defaultHints.put(hintName, hintValue);
				}
			}

			Map fields = (Map) _modelFields.get(name);

			if (fields == null) {
				fields = CollectionFactory.getHashMap();

				_modelFields.put(name, fields);
			}

			_models.add(name);

			Iterator itr2 = model.elements("field").iterator();

			while (itr2.hasNext()) {
				Element field = (Element) itr2.next();

				String fieldName = field.attributeValue("name");
				String fieldType = field.attributeValue("type");

				Map fieldHints = CollectionFactory.getHashMap();

				fieldHints.putAll(defaultHints);

				Iterator itr3 = field.elements("hint-collection").iterator();

				while (itr3.hasNext()) {
					Element hintCollection = (Element) itr3.next();

					Map hints = (Map) _hintCollections.get(hintCollection
							.attributeValue("name"));

					fieldHints.putAll(hints);
				}

				itr3 = field.elements("hint").iterator();

				while (itr3.hasNext()) {
					Element hint = (Element) itr3.next();

					String hintName = hint.attributeValue("name");
					String hintValue = hint.getText();

					fieldHints.put(hintName, hintValue);
				}

				fields.put(fieldName + _ELEMENTS_SUFFIX, field);
				fields.put(fieldName + _TYPE_SUFFIX, fieldType);
				fields.put(fieldName + _HINTS_SUFFIX, fieldHints);
			}
		}
	}

	private static final String _ELEMENTS_SUFFIX = "_ELEMENTS";

	private static final String _TYPE_SUFFIX = "_TYPE";

	private static final String _HINTS_SUFFIX = "_HINTS";

	private static Log _log = LogFactory.getLog(ModelHintsUtil.class);

	private static ModelHintsUtil _instance = new ModelHintsUtil();

	private Map _hintCollections;
	private Map _defaultHints;
	private Map _modelFields;
	private Set _models;

}


通过阅读这段代码,可以知道,不同类型的field,将会生成不同的HTML代码,而依据就是配置文件portal-model-hints.xml和ext-model-hints.xml。这里面有Field的类型的定义。

例如在 portal\portal-impl\classes\META-INF\portal-model-hints.xml 路径找到并打开portal-model-hints.xml文件:
calendar 里面的displayDate的定义则为:

	<model name="com.liferay.portlet.calendar.model.CalEvent">
		<field name="eventId" type="long" />
		<field name="groupId" type="long" />
		<field name="companyId" type="long" />
		<field name="userId" type="long" />
		<field name="userName" type="String" />
		<field name="createDate" type="Date" />
		<field name="modifiedDate" type="Date" />
		<field name="title" type="String" />
		<field name="description" type="String">
			<hint-collection name="TEXTAREA" />
		</field>
		
		<!-- startDate的field定义 -->
		<field name="startDate" type="Date" />
		
		<field name="endDate" type="Date" />
		<field name="durationHour" type="int" />
		<field name="durationMinute" type="int" />
		<field name="allDay" type="boolean" />
		<field name="timeZoneSensitive" type="boolean" />
		<field name="type" type="String" />
		<field name="repeating" type="boolean" />
		<field name="recurrence" type="String">
			<hint-collection name="CLOB" />
		</field>
		<field name="remindBy" type="String" />
		<field name="firstReminder" type="int" />
		<field name="secondReminder" type="int" />
	</model>


另外,通过源代码还可以看到,如果只是显示年月日,而不显示时分,可以设置为
  <field name=" displayDate" type="Date">
   <hint name="show-time">false</hint>
  </field>
分享到:
评论

相关推荐

    liferay portlet 站内消息组件

    Liferay Portlet是一种符合Java Portlet规范的组件,它可以嵌入到Liferay Portal的页面上,提供各种功能,如新闻展示、论坛讨论、日历管理等。Portlets通过Liferay的portlet容器运行,该容器负责渲染和管理portlet的...

    Liferay 使用手册

    Portlets 是 Liferay 中的功能模块,可以是内容展示、搜索框、日历、论坛等各种Web组件。开发者可以通过编写portlet代码,实现特定业务逻辑,并将其部署到Liferay平台中。 在Liferay中,内容管理是一个关键部分。...

    Liferay平台开发使用详细PPT演示文稿

    - **社区建设**:用户可以创建自定义社区,包含论坛、博客、日历等多种交互组件。 - **身份和访问管理**:通过LDAP、单点登录(SSO)等实现用户身份验证和授权。 - **工作流支持**:集成BPM引擎如Activiti,实现...

    liferay相关文档

    Liferay是一款开源的企业级门户平台,它...以上只是Liferay部分核心知识点的概述,实际使用中,还需要深入学习其配置、安全、性能调优等方面的知识。如果你对这些内容感兴趣,这个压缩包中的文档将是你宝贵的参考资料。

    liferay portlet demo

    2. **Portlet**:Portlet是Liferay中的核心组件,它们类似于小型的Web应用,可以嵌入到门户页面中,提供各种功能,如新闻显示、日历管理、搜索等。 3. **portlet生命周期**:包括初始化、加载、渲染、动作处理和...

    liferay6.2开发指南.pdf

    - **Portlets**:这是 Liferay 最主要的应用开发方式,它们是可嵌入到门户页面中的自包含组件,可以提供各种功能,如内容管理、论坛、日历等。 - **OpenSocial Gadgets**:基于 OpenSocial 标准,允许开发者创建可在...

    liferay 资料

    - Portlet 是 Liferay 中的基本组件,它可以是一个网页、应用程序或内容的展示单元。 - Liferay 支持多种portlet 开发框架,如 Vaadin、Wicket 和 Struts。 - 开发者可以使用 Liferay SDK 创建、部署和管理 ...

    liferay一个简单的portlet

    Portlet是Liferay中的核心组件,是构建门户应用程序的基本模块。这篇博文将深入探讨如何在Liferay中创建一个简单的Portlet,帮助开发者更好地理解Liferay的开发过程。 首先,让我们了解Portlet的基本概念。Portlet...

    liferay学习系列文章

    Liferay是一个基于Java的Web应用程序,它使用portlet技术来构建可重用的Web组件。portlet可以在门户页面上展示各种内容,如新闻、日历、论坛等。Liferay提供了丰富的API和插件机制,允许开发者根据需求定制和扩展...

    liferay架构

    Liferay的架构设计中,大量采用了自动化的组件生成工具。例如,通过解析service.xml文件,可以自动生成EJB、HBM(Hibernate Mapping)和Model组件,这一过程主要依赖于Xdoclet引擎。这种自动化机制大大提升了开发...

    liferay5.1资料

    Portlets是Liferay中可重用的UI组件,它们可以是动态的小应用,如新闻显示、日历或者论坛。该指南可能涵盖了portlet生命周期、MVC Portlet的创建、使用Liferay Service Builder以及portlet的部署等方面。 6. **...

    liferay 开发资料大全

    此外,手册可能会讲解如何使用Liferay的内置应用,如文档库、博客、论坛和日历等,以及如何自定义门户外观和行为。 《liferay二次开发指南》则专注于Liferay的扩展和定制。这可能包括portlet开发、主题和布局模板...

    liferay的主题

    Portlets是Liferay中的可重用组件,可以提供各种功能,如新闻展示、日历管理等。Apps可能指的是额外的应用或者扩展。 7. **lib**:这个目录通常存放第三方库和依赖,它们被主题或portlet使用,以实现特定的功能。 ...

    Liferay管理员手册

    - **安装一个捆绑**: 指导用户如何安装包含所有必需组件的Liferay捆绑包。 - **为企业安装Liferay**: 针对大型企业环境的特殊要求提供了安装指南。 - **样本数据**: 安装后可以使用的示例数据,有助于理解Liferay的...

    alloy_Liferay使用YUI封装的框架,含使用文档

    例如,文档可能会讲解如何创建和配置portlet,如何利用Alloy_Liferay实现数据的异步加载,以及如何利用其强大的UI组件如表格、日历等进行界面设计。 总的来说,Alloy_Liferay是一个强大的开发工具,它融合了YUI的...

    收集的liferay的相关资料(中文)

    4. **社交网络功能**:集成的社交组件如论坛、博客、日历、任务管理等,促进用户之间的交流和协作。 5. **身份和访问管理**(IAM):提供用户、角色和权限的管理,确保门户的安全性和访问控制。 6. **集成与API**...

    Liferay Portal 介绍

    通过使用这些工具,开发者可以高效地创建、测试和部署portlet、主题和布局等组件。 **内容管理** Liferay Portal 内置强大的内容管理系统(CMS),支持文档管理、网页发布、新闻和博客发布等功能。用户可以创建、...

    liferay + struts2 + spring + ibatis 修改版

    它支持多租户、内容管理、工作流、社交协作等功能,且提供了丰富的portlet(portlet是Liferay中的可重用组件)和主题定制能力。 【Struts2】Struts2是一个基于MVC设计模式的Java Web框架,用于简化Java Web应用程序...

Global site tag (gtag.js) - Google Analytics