Liferay Unify Corporate Theme - Demo video

 



Unify is an incredibly #beautiful and fully #responsive #Bootstrap 4 #Liferay #Template for any type of #creative #professionals, startups and established #business New #Theme #Liferay 7.3 version available to download : https://www.themeray.com/themes/unify-corporate Download the theme in Liferay Marketplace : https://web.liferay.com/marketplace/-/mp/application/125361591

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------




Unify Dashboard Liferay Theme - Demo video

 



#Unify #Dashboard is an incredibly beautiful and fully #responsive #Bootstrap 4 #Liferay #Template for quickly creating #dashboards and web #applications. Download from #Themeray : https://www.themeray.com/themes/unify-dashboard Demo Page : http://lr7.themeray.com/web/Unify-Dashboard ------------------------------------------------------------------------------------------------------------------------------------------------------------ Credit : Music from https://mixkit.co/free-stock-music/

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------




Liferay Unify Marketing Theme - Demo video

 


#Unify is an incredibly beautiful and fully #responsive #Bootstrap 4 #Template for any type of #creative #professionals, startups and established #business. It allows you built any size of high quality #web #products. You can download the #Unify #Marketing from the #Liferay #MarketPlace, It is ready for use and compatible with #liferay 7.1+ : https://web.liferay.com/market.../-/mp/application/151730139 Themeray : https://www.themeray.com/themes/unify-marketing -------------------------------------------------------------------------------------------------------- Credit : Music from https://mixkit.co/free-stock-music/

------------------------------------------------------------------------------------------------------------------------------------------------------------



Liferay Unify Education Theme - Demo video


 


#Unify is an incredibly beautiful and fully #responsive #Bootstrap 4 Liferay #Template for any type of #creative #professionals, startups and established #business.

- Responsive design. - Cross browsers. - Various custom templates. - Different theme settings. - Ready to use site template. Demo: http://lr7.themeray.com/web/unify-education/home Download from Themeray : www.themeray.com/themes/unify-education Download from Liferay MarketPlace : https://web.liferay.com/marketplace/-/mp/application/125843281 -------------------------------------------------------------------------------------------------------- Credit : Music from https://mixkit.co/free-stock-music/

------------------------------------------------------------------------------------------------------------------------------------------------------------



Create Spring Portlet in Liferay 7

 


In the first versions of Liferay DXP, it was difficult to create spring portlets but in the latest version of the Liferay IDE, it has been made so simple to create a Spring Portlet.

1. Create A Module Project:

- Open Liferay developer studio and create a new Liferay spring Mvc Portlet project

- Add a name for your project: themeray-spring-mvc-portlet


- Click Next button and add the package name: com.themeray.mvcportlet


- Click Finish, Then You can see the project directory structure as shown below.




2. Portlet Controller Class:



package com.themeray.mvcportlet.controller;

import com.themeray.mvcportlet.dto.User;

import com.liferay.portletmvc4spring.bind.annotation.ActionMapping;
import com.liferay.portletmvc4spring.bind.annotation.RenderMapping;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import java.util.Calendar;
import java.util.Locale;

import javax.portlet.ActionResponse;
import javax.portlet.MutableRenderParameters;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.support.SessionStatus;

/**
 * @author innotall
 */
@Controller
@RequestMapping("VIEW")
public class UserController {

	@ModelAttribute("user")
	public User getUserModelAttribute() {
		return new User();
	}

	@RenderMapping
	public String prepareView() {
		return "user";
	}

	@RenderMapping(params = "javax.portlet.action=success")
	public String showGreeting(ModelMap modelMap) {

		DateFormat dateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy G");

		Calendar todayCalendar = Calendar.getInstance();

		modelMap.put("todaysDate", dateFormat.format(todayCalendar.getTime()));

		return "greeting";
	}

	@ActionMapping
	public void submitApplicant(
		@ModelAttribute("user") User user, BindingResult bindingResult,
		ModelMap modelMap, Locale locale, ActionResponse actionResponse,
		SessionStatus sessionStatus) {

		_localValidatorFactoryBean.validate(user, bindingResult);

		if (!bindingResult.hasErrors()) {
			if (_logger.isDebugEnabled()) {
				_logger.debug("firstName=" + user.getFirstName());
				_logger.debug("lastName=" + user.getLastName());
			}

			MutableRenderParameters mutableRenderParameters =
				actionResponse.getRenderParameters();

			mutableRenderParameters.setValue("javax.portlet.action", "success");

			sessionStatus.setComplete();
		}
		else {
			bindingResult.addError(
				new ObjectError(
					"user",
					_messageSource.getMessage(
						"please-correct-the-following-errors", null, locale)));
		}
	}

	private static final Logger _logger = LoggerFactory.getLogger(
		UserController.class);

	@Autowired
	private LocalValidatorFactoryBean _localValidatorFactoryBean;

	@Autowired
	private MessageSource _messageSource;

}

Annotations In Spring MVC Portlet

@Controller 

When we use this annotation in the class The Spring Bean Container Considers the Class as a Portlet Controller which handles all the portlet requests comes to the portlet 

@RequestMapping 

As we know there are different modes of portlet such as VIEW, EDIT and HELP, We can configure the portlet to handle the request only for a specific mode, in our case we are going to use the Portlet Controller only for handling requests in VIEW mode, so it will be @RequestMapping("VIEW")

@ActionMapping 

In Liferay Portlet MVC we have processAction() method to handle the Action Requests comes to the portlet, similarly we can define Action Methods for Action URLs using this Annotation

@RenderMapping 

We can use the @RenderMapping annotation to handle the Render Requests for Render URLs, We can Return the Page Name in the Render Methods, the returned page will be rendered in the portlet.

@ResourceMapping 

In Liferay Portlet MVC we have serveResource() method to handle the Resource Requests, similarly we can define Resource Methods for Resource URLs using this annotation with an id

3. Web.xml File:

web.xml is the root file for spring portlet, Spring Portlet Configurations starts from this file.



<?xml version="1.0"?>

<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring-context/portlet-application-context.xml</param-value>
	</context-param>
	<servlet>
		<servlet-name>ViewRendererServlet</servlet-name>
		<servlet-class>com.liferay.portletmvc4spring.ViewRendererServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>ViewRendererServlet</servlet-name>
		<url-pattern>/WEB-INF/servlet/view</url-pattern>
	</servlet-mapping>
	<filter>
		<filter-name>delegatingFilterProxy</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>delegatingFilterProxy</filter-name>
		<url-pattern>/WEB-INF/servlet/view</url-pattern>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>INCLUDE</dispatcher>
	</filter-mapping>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
</web-app>

4. Portlet-Application-Context.Xml File:

View Resolver Configurations can be made in this file


<?xml version="1.0"?>

<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
>
	<context:annotation-config />
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
		<property name="contentType" value="text/html;charset=UTF-8" />
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jspx" />
		<property name="viewClass" value="com.liferay.portletmvc4spring.PortletJstlView" />
	</bean>
	<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
		<property name="basenames">
			<list>
				<value>content.Language</value>
			</list>
		</property>
		<property name="defaultEncoding" value="UTF-8" />
	</bean>
	<bean id="springSecurityPortletConfigurer" class="com.liferay.portletmvc4spring.security.SpringSecurityPortletConfigurer" />
	<bean id="delegatingFilterProxy" class="org.springframework.web.filter.DelegatingFilterProxy">
		<property name="targetBeanName" value="springSecurityFilterChain" />
	</bean>
</beans>

  • - contentType : view character encoding
  • - prefix : view Files Path
  • - suffix : view (File)Type
  • - viewClass : View Resolver class for Markup language

5. build.gradle File:


buildscript {
	repositories {
		maven {
			url "https://repository-cdn.liferay.com/nexus/content/groups/public"
		}
	}

	dependencies {
		classpath group: "com.liferay", name: "com.liferay.gradle.plugins.css.builder", version: "3.0.3"
	}
}

apply plugin: "com.liferay.css.builder"

dependencies {
	compile group: "com.liferay.portletmvc4spring", name: "com.liferay.portletmvc4spring.framework"
	compile group: "com.liferay.portletmvc4spring", name: "com.liferay.portletmvc4spring.security"
	compile(group: "org.hibernate.validator", name: "hibernate-validator") {
		exclude group: "javax.validation", module: "validation-api"
	}
	compile group: "org.springframework", name: "spring-aop"
	compile group: "org.springframework", name: "spring-beans"
	compile group: "org.springframework", name: "spring-context"
	compile group: "org.springframework", name: "spring-core"
	compile group: "org.springframework", name: "spring-expression"
	compile group: "org.springframework", name: "spring-jcl"
	compile group: "org.springframework", name: "spring-web"
	compile group: "org.springframework", name: "spring-webmvc"
	compile group: "org.springframework.security", name: "spring-security-config"
	compile group: "org.springframework.security", name: "spring-security-core"
	compile group: "org.springframework.security", name: "spring-security-web"

	compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel"
	providedCompile group: 'javax.portlet', name: 'portlet-api', version: '3.0.0'
	compileOnly group: "javax.servlet", name: "javax.servlet-api"
	compileOnly group: "javax.validation", name: "validation-api"
	compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations"
	cssBuilder group: "com.liferay", name: "com.liferay.css.builder", version: "3.0.2"

	portalCommonCSS group: "com.liferay", name: "com.liferay.frontend.css.common", version: "4.0.0"
	compileOnly group: 'org.slf4j', name: 'slf4j-api', version: '1.7.26'
	compile 'org.springframework.boot:spring-boot-starter-validation:2.3.0.RELEASE'
}

war {
	dependsOn buildCSS
	exclude "**/*.scss"

	filesMatching("**/.sass-cache/") {
		it.path = it.path.replace(".sass-cache/", "")
	}

	includeEmptyDirs = false
}

You need to add these dependencies to resolve some compilation issues

  • - compileOnly group: 'org.slf4j', name: 'slf4j-api', version: '1.7.26'
  • - compile 'org.springframework.boot:spring-boot-starter-validation:2.3.0.RELEASE'

Create Servlet Filter in Liferay 7.2

 


Servlet filter provides a filter layer between the client and the servlet. When the client invokes the request, at that time servlet filter will perform the pre-process steps to filter the request before completing the request, also it will perform the post-processing steps before sending it to the client.

You can apply the filter on:

  • Logging
  • Auditing
  • Transaction management
  • Security

1. Create a module project:

Steps to create a Liferay module:
- Go to Liferay workspace project → modules → new.
- Select other → Liferay → Liferay Module Project and Click on "Next".
- Enter the project name "ThemerayServletFilter"
- Select “Project Template Name” as “war-hook” and click on "Next".



- Enter a Package name "com.themeray.servlet.filter", component Class Name "ThemerayServletFilter" and click on the “Finish”. 



The necessary file structure will be created as below.


2. Create a servlet filter class:

 Create a new Class "ServletFilter" with implemented "Filter" Class
  package com.themeray.servlet.filter;
  import com.liferay.portal.kernel.util.WebKeys;
  import java.io.IOException;
  import javax.servlet.Filter;
  import javax.servlet.FilterChain;
  import javax.servlet.FilterConfig;
  import javax.servlet.ServletException;
  import javax.servlet.ServletRequest;
  import javax.servlet.ServletResponse;
  
  public class ServletFilter implements Filter {

      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
          System.out.println("Called ServletFilter.init(" + filterConfig + ") where hello="
                  + filterConfig.getInitParameter("hello"));

      }

      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
              FilterChain filterChain)throws IOException, ServletException {

          String uri = (String) servletRequest.getAttribute(WebKeys.INVOKER_FILTER_URI);

          System.out.println("Called ServletFilter.doFilter(" + servletRequest + ", " 
                  + servletResponse + ", "+ filterChain + ") for URI " + uri);

          filterChain.doFilter(servletRequest, servletResponse);

      }

      @Override
      public void destroy() {
      }

  }
  

Filter interface provides the following life cycle methods:

  • init(): It is used to initialize the filter.
  • doFilter(): It is used to perform filtering tasks.
  • destroy(): Clean up the filter’s unneeded resources.


3. Edit Liferay-hook.xml:

Add the mapping in liferay-hook.xml file:
  
      <?xml version="1.0"?>
  <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 7.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_7_2_0.dtd">

  <hook>
      <portal-properties>portal.properties</portal-properties>
      <servlet-filter>
          <servlet-filter-name>ServletFilter</servlet-filter-name>
          <servlet-filter-impl>com.themeray.servlet.filter.ServletFilter</servlet-filter-impl>
          <init-param>
              <param-name>hello</param-name>
              <param-value>world</param-value>
          </init-param>
      </servlet-filter>
      <servlet-filter-mapping>
      <servlet-filter-name>ServletFilter</servlet-filter-name>
          <url-pattern>/group/*</url-pattern>
          <url-pattern>/user/*</url-pattern>
          <url-pattern>/web/*</url-pattern>
          <url-pattern>*.jsp</url-pattern>
          <dispatcher>REQUEST</dispatcher>
          <dispatcher>FORWARD</dispatcher>
      </servlet-filter-mapping>
  </hook>
  

4. Deploy the module:

When you deploy the module you can see in the logs:




Create Scheduler in Liferay 7

 



The goal of this tutorial is to create a scheduler in Liferay 7. Results of tasks will be used in wide variety of applications - data annotation, multimedia, sentiment analysis and search engine result evaluation.

You need to create a Liferay module project in eclipse IDE.

1. Create scheduler class:

Create a new class in your module named EmailSchedulear and add the cron expression


	
    package com.themeray.emailschedulear.schedulear;
    
    import com.liferay.portal.kernel.messaging.BaseMessageListener;
    import com.liferay.portal.kernel.messaging.Message;

    import org.osgi.service.component.annotations.Component;

    @Component(
        immediate = true,
        property = {
            "cron.expression= 0 0/05 1/1 1/1 * ?"   // scheduler runs every 5 min.
        },
        service = EmailSchedulear.class
    )

    public class EmailSchedulear extends BaseMessageListener {

        @Override
        protected void doReceive(Message message) throws Exception {
            // TODO Auto-generated method stub

        }
    }
    

In this Class you can specify your cron expression in ‘cron.expression’ property. Cron expressions are based on the timezone of your server. More about corn expression here https://www.freeformatter.com/cron-expression-generator-quartz.html

2. Override the doReceive method in your scheduler class:

This method will be called periodically based on your cron expression. You can write your business logic here which you want to execute periodically. i.e. you can write email sending and newsletter sending code here.


@Override
protected void doReceive(Message message) throws Exception {
    log.info("Scheduled task executed...");
}

3. Register The scheduler:


@Activate
@Modified
protected void activate(Map<String, Object> properties) throws SchedulerException {
 
    try {
        String cronExpression = GetterUtil.getString(properties.get("cron.expression"), "cronExpression");
        log.info(" cronExpression: " + cronExpression);
 
        String listenerClass = getClass().getName();
        Trigger jobTrigger = TriggerFactoryUtil.createTrigger(listenerClass, listenerClass, new Date(), null, cronExpression);
 
        SchedulerEntryImpl schedulerEntryImpl = new SchedulerEntryImpl();
        schedulerEntryImpl.setEventListenerClass(listenerClass);
        schedulerEntryImpl.setTrigger(jobTrigger);
 
        SchedulerEngineHelperUtil.register(this, schedulerEntryImpl, DestinationNames.SCHEDULER_DISPATCH);
 
    } catch (Exception e) {
        log.error(e);
    }
}

4. Deactivate the scheduler:


@Deactivate
protected void deactive() {
    SchedulerEngineHelperUtil.unregister(this);
}