Set display order of different elements in the journal article.

General Blogs November 19, 2014 By priti parmar

If content creator wants to decide during creation in which order the different elements will be displayed in the article then there should be a field like DisplayOrder which decide the position of elements in the article , By using structure and templates it is possible to achive this requirment.

Lets have a simple example of structure and template .

Structure has Content_Title , Display_Order1 ,Body &  Display_Order2 elements .

  • Display_Order1  is a child element of Content_Title
  • Display_Order2 is a child element of Body field. 

Cotnent_Title and Body both are repeated fields.

Now in template read all elements and decide their positions based on its display order.

so as a result end user will able to view the content based on decided order.

Step1 : create a structure:

 <root available-locales="en_US" default-locale="en_US">

     <dynamic-element dataType="string" indexType="keyword" name="Content_Title" readOnly="false"            
                    repeatable="true" required="false" showLabel="true"  type="text" width="small">
                       <dynamic-element dataType="number" fieldNamespace="ddm" indexType="keyword"
                               name="Display_Order1" readOnly="false"                
                               repeatable="false" required="true" showLabel="true" type="ddm-number" width="small">
                                 <meta-data locale="en_US">
                                  <entry name="label"><![CDATA[Display Order]]></entry>
                                  <entry name="predefinedValue"><![CDATA[1]]></entry>
                                  <entry name="tip"><![CDATA[]]></entry>
                           <meta-data locale="en_US">
                                <entry name="label"> <![CDATA[Content Title]]></entry>
                               <entry name="predefinedValue"> <![CDATA[]]></entry>
                                <entry name="tip"><![CDATA[]]></entry>
             <dynamic-element dataType="html" fieldNamespace="ddm" indexType="keyword" name="Body"
                         readOnly="false" repeatable="true"            
                         required="true" showLabel="true" type="ddm-text-html" width="small">
                           <dynamic-element dataType="number" fieldNamespace="ddm" indexType="keyword" n              
                                      name="Display_Order2" readOnly="false"          
                                      repeatable="false" required="false" showLabel="true" type="ddm-number" width="small">
                                      <meta-data locale="en_US">
                                           <entry name="label"><![CDATA[Display Order]]></entry>
                                           <entry name="predefinedValue"><![CDATA[2]]></entry>
                                           <entry name="tip"><![CDATA[]]></entry>
                           <meta-data locale="en_US">
                            <entry name="label"><![CDATA[Body]]></entry>
                            <entry name="predefinedValue"><![CDATA[]]></entry>
                            <entry name="tip"><![CDATA[]]></entry>
Step 2: create template
    " #set($displayItems = [])
      #if (!$Content_Title.getSiblings().isEmpty())
              #foreach($cur_Content_Title in $Content_Title.getSiblings())
                            #set($void = $displayItems.add({"sortOrder" : $cur_Content_Title.Display_Order1.getData(), 
                                   "itemField" : $cur_Content_Title.getData() }))
      #if (!$Body.getSiblings().isEmpty())
              #foreach ($cur_Body in $Body.getSiblings())
                             #set($void = $displayItems.add({"sortOrder" : $cur_Body.Display_Order2.getData(), 
                                    "itemField" : $cur_Body.getData()}))
      #foreach($obj in $displayItems)
                 #if($getterUtil.getNumber($obj.sortOrder) > $size)
      #foreach ($number in [1..$size])
             #foreach($items in $displayItems)
                 #if($items.sortOrder == $number)

Search Organization using Facets Search

General Blogs July 16, 2013 By priti parmar

Liferay provide facet search with great features ,we can add new entries in search using configuration of portlet  to achive this follow the below steps,

Step 1 : create a hook

  • override init.jsp in hook add organization model entry


if (displayAssetTypeFacet) {

sb.append("{className: '',

data: {frequencyThreshold: 1, values:

[ 'com.liferay.portlet.blogs.model.BlogsEntry',







displayStyle: 'asset_entries', fieldName: 'entryClassName',

label: 'asset-type',

order: 'OrderHitsDesc',

static: false,

weight: 1.5},




  • override main_search_result_form.jsp and add url entry for organization detail view


PortletURL portletURL = (PortletURL)request.getAttribute("search.jsp-portletURL");

//Condition for Organization redirection

PortletURL orgURL = PortletURLUtil.clone(portletURL, renderResponse);

orgURL.setParameter("struts_action", "/search/view_organization");

orgURL.setParameter("organizationId", document.get(Field.ORGANIZATION_ID));




viewURL =orgURL.toString();




viewURL = _checkViewURL(themeDisplay, viewURL, currentURL);


  • Create view_organization.jsp to display the organization detail

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



Organization organization = (Organization) request.getAttribute("organization");

long organizationId = BeanParamUtil.getLong(organization, request,"organizationId");

request.setAttribute(WebKeys.ORGANIZATION, organization);



request.setAttribute("addresses.classPK", organizationId);



request.setAttribute("emailAddresses.classPK", organizationId);



request.setAttribute("phones.classPK", organizationId);



request.setAttribute("websites.classPK", organizationId);

String redirect = ParamUtil.getString(request, "redirect");

String backURL = ParamUtil.getString(request, "backURL", redirect);


<liferay-ui:header backURL="<%=backURL.toString()%>" title="organization" />

<div class="organization-information">

<div class="section entity-details">

<liferay-util:include page="/html/portlet/directory/organization/details.jsp" />



<div class="section entity-email-addresses">


        page="/html/portlet/directory/common/additional_email_addresses.jsp" />



<div class="section entity-websites">

<liferay-util:include  page="/html/portlet/directory/common/websites.jsp" />



<div class="section entity-addresses">

<liferay-util:include page="/html/portlet/directory/organization/addresses.jsp" />



<div class="section entity-phones">

<liferay-util:include page="/html/portlet/directory/organization/phone_numbers.jsp" />



<div class="section entity-services">

<liferay-util:include page="/html/portlet/directory/organization/services.jsp" />



<div class="section entity-comments">

<liferay-util:include page="/html/portlet/directory/organization/comments.jsp" />




Step 2 : add new Struts action in liferay-hook.xml










Step 3 : add struts action entry in



Step 4 : Create a package com.liferay.portal.hook.action and add


package com.liferay.portal.hook.action;


import com.liferay.portal.kernel.struts.BaseStrutsPortletAction;

import com.liferay.portal.kernel.struts.StrutsPortletAction;

import com.liferay.portal.kernel.util.ParamUtil;

import com.liferay.portal.model.Organization;

import com.liferay.portal.service.OrganizationLocalServiceUtil;


import javax.portlet.ActionRequest;

import javax.portlet.ActionResponse;

import javax.portlet.PortletConfig;

import javax.portlet.RenderRequest;

import javax.portlet.RenderResponse;

import javax.portlet.ResourceRequest;

import javax.portlet.ResourceResponse;


public class OrganizationSearchAction extends BaseStrutsPortletAction {

public void processAction(

StrutsPortletAction originalStrutsPortletAction,

PortletConfig portletConfig, ActionRequest actionRequest,

ActionResponse actionResponse)

throws Exception {



originalStrutsPortletAction, portletConfig, actionRequest,




public String render(

StrutsPortletAction originalStrutsPortletAction,

PortletConfig portletConfig, RenderRequest renderRequest,

RenderResponse renderResponse)

throws Exception {

long organizationId = ParamUtil.getLong(renderRequest, "organizationId");

Organization org = OrganizationLocalServiceUtil.getOrganization(organizationId);

renderRequest.setAttribute("organization", org);

return "/portlet/search/view_organization.jsp";



public void serveResource(

StrutsPortletAction originalStrutsPortletAction,

PortletConfig portletConfig, ResourceRequest resourceRequest,

ResourceResponse resourceResponse)

throws Exception {



originalStrutsPortletAction, portletConfig, resourceRequest,





Step 5: Deploy hook now organization is available for search in search portlet.



Open Document Library popup in custom portlet

General Blogs July 11, 2013 By priti parmar

Step 1 : create document library URL in your jsp

    <% long dlScopeGroupId = themeDisplay.getScopeGroupId();

          LiferayPortletURL documentLibURL = PortletURLFactoryUtil.create(request,          

          PortletKeys.JOURNAL, themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);




          documentLibURL.setParameter("groupId", String.valueOf(dlScopeGroupId));



Step 2: Create a div or html content

         <input type="hidden" name="<portlet:namespace/>documentLibraryInput" 

               id="<portlet:namespace/>documentLibraryInput" />

         <div class="profile-image">

          <img class="journal-image" hspace="0" id="<portlet:namespace/>article-image" src=""   

           style="width:82px;height:83px" vspace="0" />


<div class="image-data">


<a style="text-decoration: none;cursor: pointer;"

onclick="javaScript:<portlet:namespace/>showImages()" >

Select a thumbnail image





Step 3: Create javascript Function

<script charset="utf-8" type="text/javascript">

function <portlet:namespace/>showImages()


AUI().ready('aui-dialog','aui-dialog-iframe','aui-overlay-manager','liferay-portlet-url', function(A) {

var url = '<%= documentLibURL %>';

window.myDialog = new A.Dialog(


title: '',

width: 1050,

draggable: true,

modal: true,

xy: [150, 50],






uri: url,

iframeCssClass: 'dialog-iframe'








Step 4 : after completion of step 3 on click of Select a thumbnail image Document Library popup will be open, now after choosing an image from poprup we need to keep those values in parameters of jsp

<script charset="utf-8" type="text/javascript">

function _15_selectDocumentLibrary(url) {

document.getElementById("<portlet:namespace/>documentLibraryInput").value = url;

var pic1 = document.getElementById("<portlet:namespace/>article-image");

pic1.src = url;

var iframe = document.getElementById('documentDetails');




kaleo configuration for custom portlet in liferay 6.0 EE.

General Blogs July 10, 2013 By priti parmar

Step1 : Add following reference and column to your service.xml (service in which you would like add workflow),out of these some of fields must be there which will help in mapping between workflow tables and your custom table.

<column name="resourcePrimKey" type="long"></column>

<column name="title" type="String"></column>

<column name="status" type="int"></column>

<column name="statusByUserId" type="long"></column>

<column name="statusByUserName" type="String"></column>

<column name="statusDate" type="Date"></column>

<!-- Finder methods -->

<finder name="R_S" return-type="Collection">

<finder-column name="resourcePrimKey"></finder-column>

<finder-column name="status"></finder-column>


<reference package-path="com.liferay.portal" entity="WorkflowInstanceLink"></reference>

<reference package-path="com.liferay.portlet.asset" entity="AssetEntry"></reference>

<reference package-path="" entity="SocialActivity"></reference>


Step 2 :Build service to make sure there is no compile time error.


Step 3: Once you Confirm with service just add following line in liferay-portlet.xml <portlet> tag on which you wish to apply workflow.





- path : This is path of your own workflow handler class and your own

AssetRendererFactory handler class

- Note : This tag should before initialize of portlet.








Step 4: You need to extend com.liferay.portal.kernel.workflow.BaseWorkflowHandler class and override four abstract method.


  • String getClassName()
  • String getType(Locale locale)
  • Object updateStatus(int status,Map workflowContext)
  • String getIconPath(ThemeDisplay themeDisplay)


public class ArticleWorkflowHandler extends BaseWorkflowHandler






Note : Here one thing is very important updateStatus() method called another method which you gonna developed in Step5.



public Object updateStatus(int status, Map<String, Serializable> workflowContext)


return DemoLocalServiceUtil.updateStatus(userId, resourcePrimKey, status,      serviceContext);



Step 5: Now you need to implement one method called updateStatus() in you LocalServiceImpl class. which will return object of your model class.



public class DemoLocalServiceImpl extends DemoLocalServiceBaseImpl


public Demo updateStatus(long userId, long resourcePrimKey, int status,ServiceContext serviceContext)


User user = userPersistence.findByPrimaryKey(userId);

Date now = new Date();

// Article

Demo dempObj = null;





demoPersistence.update(dempObj, false);

if (status != WorkflowConstants.STATUS_APPROVED)


return dempObj;


return dempObj;




Step6: You need to extend com.liferay.portlet.asset.model.BaseAssetRendererFactory class and override abstract method.


  • String getClassName()
  • String getType(Locale locale)
  • Object getAssetRenderer(long classPK, int type)


public class ArticleAssetRendererFactory extends BaseAssetRendererFactory




public static final String CLASS_NAME = Article.class.getName();

public static final String TYPE = "article";


public AssetRenderer getAssetRenderer(long classPK, int type)

throws PortalException, SystemException {

// TODO Auto-generated method stub

int status = WorkflowConstants.STATUS_ANY;


status = WorkflowConstants.STATUS_APPROVED;


Article article = ArticleLocalServiceUtil.getLatestArticle(

classPK, status);

return new ArticleAssetRenderer(article);



Note : Here one thing is ArticleAssetRenderer Class which you gonna developed in Step7.


Step7: Now you need to create one class called ArticleAssetRenderer and extends BaseAssetRenderer and override 7 abstract method.


  • long getClassPK()
  • long getGroupId()
  • String getSummary()
  • String getTitle()
  • long getUserId()
  • String render(RenderRequest renderRequest,
  • RenderResponse renderResponse, String template)


public class ArticleAssetRenderer extends BaseAssetRenderer





public String render(

RenderRequest renderRequest, RenderResponse renderResponse,

String template) throws Exception {

if (template.equals(TEMPLATE_FULL_CONTENT)) {

   return "/admin/asset/fullcontent.jsp";

}else {

return null;







Step8: Now Deploy service and portlet you will find out your asset in control panel as showing below .now you can apply any definition on that.



Step9: Start workflow

  • Now you need to start Workflow at the time of add content there.
  • You have to write following method in your addContent() and updateContent() in your ***LocalServiceImpl class.


  • assetEntryLocalService.updateEntry(

userId, article.getGroupId(), Article.class.getName(),

article.getClassPK(), article.getUuid(), assetCategoryIds,

assetTagNames, article.isApproved(), null, null, null, null,

ContentTypes.TEXT_HTML, article.getTitle(),

article.getDescription(), null, null, 0, 0, null, false);

  •  WorkflowHandlerRegistryUtil.startWorkflowInstance(

     user.getCompanyId(), groupId, userId, Demo.class.getName(),

     resourcePrimKey, article, serviceContext);


public class ArticleLocalServiceImpl extends ArticleLocalServiceBaseImpl{

   public Article addArticle(long userId, long parentResourcePrimKey, String title,String content, String description, int priority, String dirName, ServiceContext serviceContext)

    throws PortalException, SystemException      


User user = userPersistence.findByPrimaryKey(userId);

long groupId = serviceContext.getScopeGroupId();

long articleId = counterLocalService.increment();

long resourcePrimKey = counterLocalService.increment();

Article article = articlePersistence.create(articleId);

articlePersistence.update(article, false);

    // Asset


     userId, article, serviceContext.getAssetCategoryIds(),


    // Workflow


     user.getCompanyId(), groupId, userId, Article.class.getName(),

     resourcePrimKey, article, serviceContext);

return article;


public void updateAsset(long userId, Article article, long[] assetCategoryIds,String[] assetTagNames)throws PortalException, SystemException {

   assetEntryLocalService.updateEntry(userId, article.getGroupId(), Article.class.getName(),article.getClassPK(), article.getUuid(), assetCategoryIds,assetTagNames, article.isApproved(), null, null, null, null,ContentTypes.TEXT_HTML, article.getTitle(), article.getDescription(), null, null, 0, 0, null, false);



Static Navigation for Liferay Portal

General Blogs June 28, 2013 By priti parmar

create a ServicePreAction, which will create a new
custom NavItem object and a change in navigation.vm of the theme, which
will show the custom navigation.

Here are the steps to create the custom navigation

1) Create a new ServicePreAction hook
2) In the run() method of ServicePreAction, retrieve the your community
group object

ThemeDisplay themeDisplay = (ThemeDisplay)
Group baseCommunity = GroupLocalServiceUtil.getGroup(themeDisplay.getCompanyId(), "yourcommunitName");
long defaultLayoutId = LayoutLocalServiceUtil.getDefaultPlid(baseCommunity.getGroupId());
Layout defaultLayout = LayoutLocalServiceUtil.getLayout(defaultLayoutId);
List<Layout> layoutSet = LayoutLocalServiceUtil.getLayouts(baseCommunity.getGroupId(), false);
List<Layout> publicNonHiddenLayouts = newArrayList<Layout>(layoutSet.size());
for(Layout layout:layoutSet) {

    if(!layout.isHidden() && layout.getParentLayoutId()==0)
RequestVars requestVars = new RequestVars(req,themeDisplay,
defaultLayout.getAncestorPlid(), defaultLayout.getAncestorLayoutId());
List navItems = NavItem.fromLayouts(requestVars,publicNonHiddenLayouts);
Map vmVariables = new HashMap();
vmVariables.put("baseNavItems", navItems);
req.setAttribute(WebKeys.VM_VARIABLES, vmVariables);
Now, in the navigation.vm of the Theme,
replace  #foreach ($nav_item in $nav_items)  with  #foreach ($nav_item in $baseNavItems)

Most Visited Pages Count in Liferay 6.1

General Blogs June 28, 2013 By priti parmar

Liferay 6.1 provides Custom Fileds for Pages , set viewCount as a Custom Field and update it using a servicePreAction Hook.

public class CustomServicePreAction extends Action {

     * This Method is used for Creating the Map Variable of the Pages
     * @param HttpServletRequest
     * @param HttpServletResponse
    public void run(HttpServletRequest req, HttpServletResponse res)
            throws ActionException {
              ThemeDisplay themeDisplay = (ThemeDisplay) req
        if (!themeDisplay.getURLCurrent().contains("control_panel")) {
            Layout layout = themeDisplay.getLayout();
            try {
                } catch (Exception e) {

    protected void setupExpandos(Layout layout) throws Exception {
        ExpandoTable table = null;
        try {
            table = ExpandoTableLocalServiceUtil.addTable(layout.getCompanyId(), Layout.class.getName(),ExpandoTableConstants.DEFAULT_TABLE_NAME);
        } catch (DuplicateTableNameException dtne) {
            table = ExpandoTableLocalServiceUtil.getTable(layout.getCompanyId(), Layout.class.getName(),ExpandoTableConstants.DEFAULT_TABLE_NAME);
         String column = "viewCount";
         ExpandoColumn expcolumn = null;
         try {
              expcolumn = ExpandoColumnLocalServiceUtil.addColumn(table.getTableId(), column,ExpandoColumnConstants.LONG,0L);
         catch (DuplicateColumnNameException dcne)
               expcolumn =        ExpandoColumnLocalServiceUtil.getColumn(layout.getCompanyId(),PortalUtil.getClassNameId(Layout.class.getName()), table.getName(), column);
        long count = Long.valueOf(ExpandoValueLocalServiceUtil.getData(layout.getCompanyId(),Layout.class.getName(),      table.getName(), expcolumn.getName() , layout.getPrimaryKey(),0L));
        ExpandoValueLocalServiceUtil.addValue(layout.getCompanyId(),Layout.class.getName(), table.getName(), expcolumn.getName() , layout.getPrimaryKey(),count+1L);



Configure solr 4.0 with Liferay 6.1.2 EE

General Blogs June 28, 2013 By priti parmar


Step 1: Download Solr. It's just a zip file.

Step 2: Copy from your SOLR_HOME_DIR/dist/apache-solr-1.3.0.war to your tomcat webapps directory: $CATALINA_HOME/webapps/solr.war – Note the war file name change. That’s important.

Step 3: Create your solr home directory at a location of your choosing. This is where the configuration for that solr install resides. The easiest way to do this is to copy the SOLR_HOME_DIR/examples/solr directory to wherever it is you want your solr home container to be. Say place it in C:\solr.

Step 4: Hope you have set your environment variables, if not then please set JAVA_HOME, JRE_HOME, CATALINA_OPTS, CATALINA_HOME. Note that CATALINA_HOME refers to your Tomcat directory & CATALINA_OPTS refers to the amount of heap memory you want to give to your Solr.

Step 5: Start tomcat. Note this is only necessary to allow tomcat to unpack your war file. If you look under $CATALINA_HOME/webapps there should now be a solr directory.

Step 6: Stop tomcat

Step 7: Go into that solr directory and edit WEB-INF/web.xml. Scroll down until you see an entry that looks like this:

<!-- People who want to hardcode their "Solr Home" directly into the
     WAR File can set the JNDI property here...

Set your Solr home (for example: C:\solr) and uncomment the env entry.

Step 8: Start Tomcat again, and things should be going splendidly. You should be able to verify that solr is running by trying the url http://localhost:8080/solr/admin/.


    Once the Solr instance is set, install the Solr plug-in in the portal. How does it work? The following is a sample which could bring the plugin Solr into the portal.

Step 1:    Download required WAR file ${solr.web.war}.  

Step 2:    Drop the WAR file ${solr.web.war} to the folder $LIFERAY_HOME/deploy when the portal is running

           After deploying successfully, you should shut down the portal and Solr instance, and moreover, configure the Solr instance with the Solr plugin as follows.

Step 3:    Open $AS_WEB_APP_HOME/solr-web/WEB-INF/classes/META-INF/solr-spring.xml and update Solr instance settings as follows

            <bean id=”solrServer”     class=””>
            <constructor-arg type=”java.lang.String” value=” http://${}:$    {solr.port.number}/solr” />

            <bean id=""


            <property name="clusteredWrite" value="false" />

            <property name="indexSearcher"

            ref="" />

            <property name="indexWriter" ref="" />

            <property name="luceneBased" value="true" />

            <property name="vendor" value="SOLR" />



            <!-- Configurator -->


            <bean id="searchEngineConfigurator.solr"


            <property name="searchEngines">

            <map key-type="java.lang.String" value-


            <entry key="SYSTEM_ENGINE_ID">

            <ref bean="" />




            <property name="defaultSearchEngineId" value="SYSTEM_ENGINE_ID" />


Step 4:    Drop the schema file schema.xml from $AS_WEB_APP_HOME/solr-web/WEB-INF/conf to $SOLR_HOME/example/solr/conf in the domain ${} – replacing the exiting the schema file schema.xml; and restart Solr instance and the portal

Showing 7 results.
Items 20
of 1