I want to add Liferay's CKEditor to my JSF portlet. I tried to find a way to add the CKEditor in JSF, but all the examples/solutions show how to add the CKEditor in a JSP not JSF.
I am using Liferay Portal 6.0 EE.
您可以通过在项目中包含Liferay Faces Portal jar *并将 CKEditor 添加到 JSF 页面,并编写类似于以下示例之一的代码:
Liferay 6.2+ 示例:
<portal:inputRichText value="#{backing.value}" />
查看Liferay Faces Showcase以获取实时示例和更多详细信息。
已弃用的 Liferay 6.2 和 6.1 示例:
<liferay-ui:input-editor editorImpl="editor.wysiwyg.default" value="#{backing.value}">
已弃用的 Liferay 6.0 EE 示例:
<liferay-ui:input-editor editorImpl="ckeditor" value="#{backing.value}">
*由于您使用的是 Liferay 6.0 EE,因此您需要使用 LF Portal 版本3.0.5-ga6
。有关兼容 Liferay Faces 和 Liferay Portal 版本的更多信息,请参阅Liferay Faces 版本方案。
使用下面的代码。参考Liferay Faces 展示
输入RichText.xhtml
<alloy:outputStylesheet library="css" name="input-rich-text.css" />
<alloy:form id="exampleForm">
<alloy:field id="commentsField" label="#{i18n['comments']}" styleClass="input-rich-text-field">
<alloy:message id="commentsMessage" for="comments" />
</alloy:field>
<!-- Note: In this example, portal:inputRichText is intentionally not a child of alloy:field in order -->
<!-- to prevent it from being unnecessarily reinitialized when the alloy:field is re-rendered via Ajax. -->
<portal:inputRichText id="comments" label="#{i18n['comments']}"
required="#{showcaseModelBean.selectedComponent.required}"
value="#{inputRichTextBacking.applicant.comments}" />
<alloy:commandButton actionListener="#{inputRichTextBacking.submit}"
render=":exampleForm:commentsField :modelValue" value="#{i18n['submit']}" />
</alloy:form>
<alloy:outputText id="modelValue" value="#{inputRichTextBacking.applicant.comments}" />
InputRichTextBacking.java
@ManagedBean
@RequestScoped
public class InputRichTextBacking {
private static final Logger logger = LoggerFactory.getLogger(InputRichTextBacking.class);
private Applicant applicant;
private boolean resizable = true;
@PostConstruct
public void init() {
applicant = new Applicant();
if (ViewParamUtil.getUsage().equals("default-value")) {
applicant.setComments(
"<p>This is some <strong>bold</strong> text\nand this is some <em>italic</em> text.</p>");
}
}
public void submit() {
logger.info("You entered comments: " + applicant.getComments());
}
public void valueChangeListener(ValueChangeEvent valueChangeEvent) {
FacesContext facesContext = FacesContext.getCurrentInstance();
PhaseId phaseId = facesContext.getCurrentPhaseId();
logger.debug("valueChangeListener: phaseId=[{0}]", phaseId.toString());
String phaseName = phaseId.getName();
FacesMessage facesMessage = new FacesMessage("The valueChangeListener method was called during the " +
phaseName + " phase of the JSF lifecycle.");
facesContext.addMessage(null, facesMessage);
}
public Applicant getApplicant() {
return applicant;
}
public boolean isResizable() {
return resizable;
}
public void setResizable(boolean resizable) {
this.resizable = resizable;
}
}
申请人.java
public class Applicant implements Serializable {
private static final long serialVersionUID = 4661552363081858711L;
private String city;
private String comments;
private Date dateOfBirth;
private String emailAddress;
private String firstName;
private String lastName;
private String phoneNumber;
private String postalCode;
private Long provinceId;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public Long getProvinceId() {
return provinceId;
}
public void setProvinceId(Long provinceId) {
this.provinceId = provinceId;
}
}
输入富文本.css
/* The Liferay Portal margin-bottom is 30px for div elements with class="control-group" (such as alloy:field). */
/* Set the margin-bottom to zero since the portal:inputRichText is not a child of the alloy:field component tag. */
.aui div.input-rich-text-field.control-group {
margin-bottom: 0px;
}
.aui div.portal-input-rich-text {
margin-bottom: 30px;
}
输入富文本.properties
#
# The default key used by the editorImpl attribute is found in the Liferay portal.properties file:
#
# editor.wysiwyg.default=ckeditor
#
# For more information, see:
#
# https://github.com/liferay/liferay-portal/blob/6.2.1-ga2/portal-impl/src/portal.properties#L5282
#
# Alternate keys for BBCode and Creole can be specified in a custom portal-ext.properties file.
#
# For example:
#
com.liferay.faces.demos.showcase.ckeditor=ckeditor
com.liferay.faces.demos.showcase.ckeditor_bbcode=ckeditor_bbcode
com.liferay.faces.demos.showcase.ckeditor_creole=ckeditor_creole
您可以使用:
<aui:fieldset>
<script type="text/javascript">
function <portlet:namespace />initEditor() {
}
</script>
<aui:field-wrapper label="content">
<liferay-ui:input-editor width="100%" />
<aui:input name="content" type="hidden" />
</aui:field-wrapper>
</aui:fieldset>