Web Content in Custom Module

Adding/Updating Webcontent in Custom Module

Liferay Web Content is very powerful feature , which is used in almost every portal developed using Liferay  , we might have situations where we may need to add ,edit and save the Web content from our Custom Module /Portlet .

1. Rendering the Web Content Form based on Structure 
2. Creating Web Content from the rendered form
3. Pre populating the Web Content Form

1 . Rendering the Web Content Form based on Structure

First we need to create a structure and template this can be referred from
https://help.liferay.com/hc/en-us/articles/360017892912-Creating-Structured-Web-Content
https://help.liferay.com/hc/en-us/articles/360018171891-Adding-Templates-with-Structures

In my example i have created structure with name, address and document link and also created a simple template: 

 

 

 

 

 

 

 

 

Once you create the structure and template you can refer with the ID .

Now in our custom module jsp we need to create a form and render this ddmstructure form

Rendering the form use the below code 
<%@ taglib uri="http://liferay.com/tld/ddm" prefix="liferay-ddm"%>

<portlet:actionURL name="saveWebContent" var="saveWebContentURL" />
<aui:form action="${saveWebContentURL}" method="POST" enctype="multipart/form-data" >
    <liferay-ddm:html  defaultLocale="<%=locale %>" groupId="<%=themeDisplay.getScopeGroupId() %>" defaultEditLocale="<%=locale %>" localizable="true"  requestedLocale="<%=locale %>"  classPK="35702" classNameId="<%= PortalUtil.getClassNameId(DDMStructure.class) %>" ></ddm:html>
        <aui:button type="submit" value="save" />
    </aui:form>

Once u add the above code the form will render in your custom module as below

Note - 35702 which is structure ID can be referred  by giving option in configuration or taking input from  user also. For this example i am Hard cording .

2. Creating Web Content 

To save the above rendered form we will be adding the below code in our action class

public void saveWebContent(ActionRequest actionRequest, ActionResponse actionResponse)
            throws IOException, PortletException {
        long ddmStructureId = 35702;
        ServiceContext serviceContext = null;
        try {
            serviceContext = ServiceContextFactory.getInstance(JournalArticle.class.getName(), actionRequest);
        } catch (PortalException e) {
            _log.error(e.getMessage());
        }
        Fields fields = null;
        try {
            fields = DDMUtil.getFields(ddmStructureId, serviceContext);
        } catch (PortalException e) {
            _log.error(e.getMessage());
        }
        DDMStructure ddmStructure = _ddmStructureLocalService.fetchDDMStructure(ddmStructureId); 
        Map<Locale, String> titleMap = new HashMap<Locale, String>(0);
        titleMap.put(Locale.getDefault(), "Title");
        String content = null;
        try {
            content = _journalConverter.getContent(ddmStructure, fields);
        } catch (Exception e) {
            _log.error(e.getMessage());
        }
        try {
            _journalArticleLocalService.addArticle(serviceContext.getUserId(), serviceContext.getScopeGroupId(),
                    JournalFolderConstants.DEFAULT_PARENT_FOLDER_ID, titleMap, titleMap, content,
                    ddmStructure.getStructureKey(), ddmStructure.getTemplates().get(0).getTemplateKey(),
                    serviceContext);
        } catch (PortalException e) {
            _log.error(e.getMessage());
        }
    }
    @Reference
    private DDMStructureLocalService _ddmStructureLocalService;
    @Reference
    private JournalArticleLocalService _journalArticleLocalService;
   @Reference
    private JournalConverter _journalConverter;        

 

3. Pre populating the Web Content Form

To Pre populate the Web content  form we will be using the same taglib which was used for rendering , but we will add new attribute "ddmFormValues" for populating the form  data

   <liferay-ddm:html ddmFormValues="${ddmFormValues}"  defaultLocale="<%=locale %>" groupId="<%=themeDisplay.getScopeGroupId() %>" defaultEditLocale="<%=locale %>" localizable="true"  requestedLocale="<%=locale %>"  classPK="35702" classNameId="<%= PortalUtil.getClassNameId(DDMStructure.class) %>" ></liferay-ddm:html>

To get the ddmFormValues i will be adding code in my doView method for this example 

@Override
    public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
            throws IOException, PortletException {
        ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest.getAttribute(WebKeys.THEME_DISPLAY);
        long ddmStructureId = 35702;
        DDMStructure ddmStructure = _ddmStructureLocalService.fetchDDMStructure(ddmStructureId);
        JournalArticle journalArticle = JournalArticleLocalServiceUtil.fetchArticle(themeDisplay.getScopeGroupId(),
                "35925");
        Fields fields = null;
        DDMFormValues ddmFormValues = null;
        try {
            fields = _journalConverter.getDDMFields(ddmStructure, journalArticle.getContent());
        } catch (PortalException e) {
            _log.error(e.getMessage());
        }
        try {
            ddmFormValues = _journalConverter.getDDMFormValues(ddmStructure, fields);
        } catch (PortalException e) {
            _log.error(e.getMessage());
        }
        renderRequest.setAttribute("ddmFormValues", ddmFormValues);
        super.doView(renderRequest, renderResponse);
    }

Note - 35925 which is Article ID can be referred  by giving option in configuration or taking input from user also. For this example i am Hard cording.
 Once i will the add the  above code in doview , prepopulated form will be rendered 

When Updating the prepopulated form,  _journalArticleLocalService.updateArticle(...) can be used along with Article ID

Note - Above example is done on Liferay 7.3  

Blogs