Showing posts with label enterprise portal. Show all posts
Showing posts with label enterprise portal. Show all posts

Thursday, 28 January 2016

Liferay Themes

This is a followup of the blog entry about Liferay1 2 3.

As I wished to tailor the website layout of my Liferay instance, I started looking at themes. What I found was a bit of a surprise for me, as it seems themes for Liferay needs to be compiled/build using ant or maven.

There is a big body of documentation regarding the creation of Themes, but the procedure seems a bit brittle. It uses ant, needs to be able to reach the files of the classic theme, is dependent of the type of Application Server you are using, and a bit of other stuff.

Below are some of the error messages I got and had to solve before I got anything that worked.

Creating a Theme with Ant

  • Download the Plugins SDK that compiles new themes (and plugins) using Ant.
  • Create a properties file like build.<username>.properties
    [glassfish@localhost glassfish]$ cat liferay-plugins-sdk-6.2/build.glassfish.properties
    app.server.type=glassfish
    app.server.parent.dir=/home/glassfish
    app.server.glassfish.dir=${app.server.parent.dir}/glassfish4/glassfish
    javac.compiler=modern
  • In this directory, there should be a directory themes, where we can create our new theme6.
    [glassfish@localhost themes]$ ./create.sh mine "Mine"
    Parallel execution with configuration on demand is an incubating feature.
    :createTheme

    BUILD SUCCESSFUL

    Total time: 2.377 secs
  • Changed the build.xml in mine-theme, to use 'classic' as the parent theme.
    <property name="theme.parent" value="classic" />
    If you create your own theme with the Plugins SDK, place the icon in themes/Your_theme/docroot/_diffs/images/favicon.ico if you want to have your own favicon to bookmark.
  • Then "ant war"
  • Then "ant deploy" (or just copy the war into glassfish4/deploy)
The first problem I ran into was a problem with the xml file.
[2015-09-19T20:45:06.136+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=140 _ThreadName=Thread-8] [timeMillis: 1442695506136] [levelValue: 800] [[
20:45:06,136 INFO  [AutoDeployer][HotDeployEvent:145] Plugin mine-theme requires marketplace-portlet]]

[2015-09-19T20:45:06.142+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=140 _ThreadName=Thread-8] [timeMillis: 1442695506142] [levelValue: 800] [[
20:45:06,136 INFO  [AutoDeployer][HotDeployImpl:217] Deploying mine-theme from queue]]

[2015-09-19T20:45:06.149+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=140 _ThreadName=Thread-8] [timeMillis: 1442695506149] [levelValue: 800] [[
20:45:06,142 INFO  [AutoDeployer][PluginPackageUtil:1016] Reading plugin package for mine-theme]]

[2015-09-19T20:45:06.193+0000] [glassfish 4.1] [INFO] [] [javax.enterprise.web] [tid: _ThreadID=140 _ThreadName=AutoDeployer] [timeMillis: 1442695506193] [levelValue: 800] [[
WebModule[null] ServletContext.log():Initializing Spring root WebApplicationContext]]

[2015-09-19T20:45:06.204+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=140 _ThreadName=Thread-8] [timeMillis: 1442695506204] [levelValue: 800] [[
20:45:06,204 INFO  [AutoDeployer][ThemeHotDeployListener:98] Registering themes for mine-theme]]

[2015-09-19T20:45:06.236+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=140 _ThreadName=Thread-8] [timeMillis: 1442695506236] [levelValue: 800] [[
20:45:06,228 ERROR [AutoDeployer][ThemeLocalServiceImpl:278] com.liferay.portal.kernel.xml.DocumentException: Error on line 8 of document  : Element type "theme" must be followed by either attribute specifications, ">" or "/>". Nested exception: Element type "theme" must be followed by either attribute specifications, ">" or "/>".
com.liferay.portal.kernel.xml.DocumentException: Error on line 8 of document  : Element type "theme" must be followed by either attribute specifications, ">" or "/>". Nested exception: Element type "theme" must be followed by either attribute specifications, ">" or "/>".
at com.liferay.portal.xml.SAXReaderImpl.read(SAXReaderImpl.java:429)
at com.liferay.portal.xml.SAXReaderImpl.read(SAXReaderImpl.java:447)
at com.liferay.portal.kernel.xml.SAXReaderUtil.read(SAXReaderUtil.java:187)
at com.liferay.portal.service.impl.ThemeLocalServiceImpl._readThemes(ThemeLocalServiceImpl.java:472)
at com.liferay.portal.service.impl.ThemeLocalServiceImpl.init(ThemeLocalServiceImpl.java:272)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175)
at com.sun.proxy.$Proxy269.init(Unknown Source)
at com.liferay.portal.service.ThemeLocalServiceUtil.init(ThemeLocalServiceUtil.java:118)
at com.liferay.portal.deploy.hot.ThemeHotDeployListener.doInvokeDeploy(ThemeHotDeployListener.java:103)
at com.liferay.portal.deploy.hot.ThemeHotDeployListener.invokeDeploy(ThemeHotDeployListener.java:49)
at com.liferay.portal.deploy.hot.HotDeployImpl.doFireDeployEvent(HotDeployImpl.java:227)
at com.liferay.portal.deploy.hot.HotDeployImpl.fireDeployEvent(HotDeployImpl.java:96)
at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil.java:28)
at com.liferay.portal.kernel.servlet.PluginContextListener.fireDeployEvent(PluginContextListener.java:164)
at com.liferay.portal.kernel.servlet.PluginContextListener.doPortalInit(PluginContextListener.java:154)
at com.liferay.portal.kernel.util.BasePortalLifecycle.portalInit(BasePortalLifecycle.java:44)
at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:74)
at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:58)
at com.liferay.portal.kernel.util.BasePortalLifecycle.registerPortalLifecycle(BasePortalLifecycle.java:54)
at com.liferay.portal.kernel.servlet.PluginContextListener.contextInitialized(PluginContextListener.java:116)
at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:5394)
at com.sun.enterprise.web.WebModule.contextListenerStart(WebModule.java:743)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5932)
at com.sun.enterprise.web.WebModule.start(WebModule.java:691)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1041)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:1024)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:747)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2286)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1932)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:139)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:122)
at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:291)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:352)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:500)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
at org.glassfish.deployment.autodeploy.AutoOperation.run(AutoOperation.java:164)
at org.glassfish.deployment.autodeploy.AutoDeployer.deploy(AutoDeployer.java:597)
at org.glassfish.deployment.autodeploy.AutoDeployer.deployAll(AutoDeployer.java:484)
at org.glassfish.deployment.autodeploy.AutoDeployer.run(AutoDeployer.java:412)
at org.glassfish.deployment.autodeploy.AutoDeployer.run(AutoDeployer.java:403)
at org.glassfish.deployment.autodeploy.AutoDeployService$1.run(AutoDeployService.java:233)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
Caused by: org.dom4j.DocumentException: Error on line 8 of document  : Element type "theme" must be followed by either attribute specifications, ">" or "/>". Nested exception: Element type "theme" must be followed by either attribute specifications, ">" or "/>".
at org.dom4j.io.SAXReader.read(SAXReader.java:482)
a]]

[2015-09-19T20:45:06.236+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=140 _ThreadName=Thread-8] [timeMillis: 1442695506236] [levelValue: 800] [[
t org.dom4j.io.SAXReader.read(SAXReader.java:365)
at com.liferay.portal.xml.SAXReaderImpl.read(SAXReaderImpl.java:426)
... 82 more]]
Seems the problem was Quotes (") around the name of the theme "Mine" in the docroot/WEB-INF/liferay-plugin-package.properties file. Removed quotes, and things get picked up now.

Creating a Theme with Maven

mvn archetype:generate \
    -DarchetypeArtifactId=liferay-theme-archetype \
    -DarchetypeGroupId=com.liferay.maven.archetypes \
    -DarchetypeVersion=6.1.0 \
    -DartifactId=sample-theme \
    -DgroupId=com.liferay.sample \
    -Dversion=1.0-SNAPSHOT
I tried with Maven4 5 instead of Ant to develop a theme, but I couldn't rightly get it to work. Needs some time to work on it.

Uploading a theme

So there's a war file created containing the files. You can deploy the file into the application server.

There are several ways to do this. You can upload it to glassfish4/glassfish/domains/domain1/autodeploy.

But I find that in some cases the theme is not recorded by Liferay. Liferay listens to specific directories for new war files that are theme related. In my case the additional directory could well be glassfish4/deploy, because glassfish4 is the "home" of Liferay in my case.

You can verify if the theme was successfully picked up in your glassfish server log. You should see something lke:
[2016-01-11T14:38:26.668+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523106668] [levelValue: 800] [[
14:38:26,667 INFO  [com.liferay.portal.kernel.deploy.auto.AutoDeployScanner][AutoDeployDir:204] Processing mine-theme-6.2.0.1.war]]

[2016-01-11T14:38:26.673+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523106673] [levelValue: 800] [[
14:38:26,673 INFO  [com.liferay.portal.kernel.deploy.auto.AutoDeployScanner][ThemeAutoDeployListener:51] Copying themes for /home/glassfish/glassfish4/deploy/mine-theme-6.2.0.1.war]]

[2016-01-11T14:38:26.723+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523106723] [levelValue: 800] [[
14:38:26,722 INFO  [com.liferay.portal.kernel.deploy.auto.AutoDeployScanner][BaseDeployer:863] Deploying mine-theme-6.2.0.1.war]]

[2016-01-11T14:38:27.119+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523107119] [levelValue: 800] [[
Expanding: /home/glassfish/glassfish4/deploy/mine-theme-6.2.0.1.war into /tmp/20160111143826861]]

[2016-01-11T14:38:27.563+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523107563] [levelValue: 800] [[
Copying 1 file to /tmp/20160111143826861/WEB-INF]]

[2016-01-11T14:38:27.568+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523107568] [levelValue: 800] [[
Copying 1 file to /tmp/20160111143826861/WEB-INF]]

[2016-01-11T14:38:27.581+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523107581] [levelValue: 800] [[
Copying 1 file to /tmp/20160111143826861/WEB-INF/classes]]

[2016-01-11T14:38:27.589+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523107589] [levelValue: 800] [[
Copying 1 file to /tmp/20160111143826861/WEB-INF/classes]]

[2016-01-11T14:38:27.606+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523107606] [levelValue: 800] [[
Copying 1 file to /tmp/20160111143826861/WEB-INF]]

[2016-01-11T14:38:27.760+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523107760] [levelValue: 800] [[
14:38:27,760 INFO  [com.liferay.portal.kernel.deploy.auto.AutoDeployScanner][BaseDeployer:2391] Modifying Servlet 2.4 /tmp/20160111143826861/WEB-INF/web.xml]]

[2016-01-11T14:38:27.860+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523107860] [levelValue: 800] [[
Building war: /tmp/20160111143827761]]

[2016-01-11T14:38:28.307+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523108307] [levelValue: 800] [[
Deleting directory /tmp/20160111143826861]]

[2016-01-11T14:38:28.331+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=112 _ThreadName=Thread-8] [timeMillis: 1452523108331] [levelValue: 800] [[
14:38:28,330 INFO  [com.liferay.portal.kernel.deploy.auto.AutoDeployScanner][ThemeAutoDeployListener:57] Themes for /home/glassfish/glassfish4/deploy/mine-theme-6.2.0.1.war copied successfully. Deployment will start in a few seconds

[2016-01-11T14:38:29.675+0000] [glassfish 4.1] [INFO] [NCLS-DEPLOYMENT-02027] [javax.enterprise.system.tools.deployment.autodeploy] [tid: _ThreadID=221 _ThreadName=AutoDeployer] [timeMillis: 1452523109675] [levelValue: 800] [[
Selecting file /home/glassfish/glassfish4/glassfish/domains/domain1/autodeploy/mine-theme.war for autodeployment]]

[2016-01-11T14:38:30.239+0000] [glassfish 4.1] [INFO] [] [javax.enterprise.system.tools.deployment.common] [tid: _ThreadID=221 _ThreadName=AutoDeployer] [timeMillis: 1452523110239] [levelValue: 800] [[
visiting unvisited references]]

[2016-01-11T14:38:31.349+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=221 _ThreadName=Thread-8] [timeMillis: 1452523111349] [levelValue: 800] [[
14:38:31,348 INFO  [AutoDeployer][HotDeployEvent:145] Plugin mine-theme requires marketplace-portlet]]

[2016-01-11T14:38:31.350+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=221 _ThreadName=Thread-8] [timeMillis: 1452523111350] [levelValue: 800] [[
14:38:31,349 INFO  [AutoDeployer][HotDeployImpl:217] Deploying mine-theme from queue]]

[2016-01-11T14:38:31.350+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=221 _ThreadName=Thread-8] [timeMillis: 1452523111350] [levelValue: 800] [[
14:38:31,350 INFO  [AutoDeployer][PluginPackageUtil:1016] Reading plugin package for mine-theme]]

[2016-01-11T14:38:31.404+0000] [glassfish 4.1] [INFO] [] [javax.enterprise.web] [tid: _ThreadID=221 _ThreadName=AutoDeployer] [timeMillis: 1452523111404] [levelValue: 800] [[
WebModule[null] ServletContext.log():Initializing Spring root WebApplicationContext]]

[2016-01-11T14:38:31.414+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=221 _ThreadName=Thread-8] [timeMillis: 1452523111414] [levelValue: 800] [[
14:38:31,413 INFO  [AutoDeployer][ThemeHotDeployListener:98] Registering themes for mine-theme]]

[2016-01-11T14:38:33.507+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=221 _ThreadName=Thread-8] [timeMillis: 1452523113507] [levelValue: 800] [[
14:38:33,507 INFO  [AutoDeployer][ThemeHotDeployListener:113] 1 theme for mine-theme is available for use]]

[2016-01-11T14:38:33.736+0000] [glassfish 4.1] [INFO] [AS-WEB-GLUE-00172] [javax.enterprise.web] [tid: _ThreadID=221 _ThreadName=AutoDeployer] [timeMillis: 1452523113736] [levelValue: 800] [[
Loading application [mine-theme] at [/mine-theme]]]

[2016-01-11T14:38:33.992+0000] [glassfish 4.1] [INFO] [] [javax.enterprise.system.core] [tid: _ThreadID=221 _ThreadName=AutoDeployer] [timeMillis: 1452523113992] [levelValue: 800] [[
mine-theme was successfully deployed in 4,148 milliseconds.]]

[2016-01-11T14:38:33.998+0000] [glassfish 4.1] [INFO] [NCLS-DEPLOYMENT-02035] [javax.enterprise.system.tools.deployment.autodeploy] [tid: _ThreadID=221 _ThreadName=AutoDeployer] [timeMillis: 1452523113998] [levelValue: 800] [[
[AutoDeploy] Successfully autodeployed : /home/glassfish/glassfish4/glassfish/domains/domain1/autodeploy/mine-theme.war.]]

Setting your theme

See Control Panel -> Configuration -> Portal settings -> Display Settings and below there's Look & Feel.

Also, there's this place: Control Panel -> Sites -> Your site -> Site Pages -> Look and Feel + Current Theme. You can select another theme from a list below in the same configuration page.

Your theme is actually a Plugin, and can be found among the Theme Plugins. Navigate to Control Panel -> Apps -> Plugins Configuration. Select the tab "Theme Plugins". Your theme should be visible in the list.

If not, you are likely to receive something like this in your logs7 8:
[2015-12-31T23:38:41.633+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=29 _ThreadName=Thread-8] [timeMillis: 1451605121633] [levelValue: 800] [[
23:38:41,633 WARN [http-listener-1(4)][ThemeLocalServiceImpl:156] No theme found for specified theme id mine_WAR_minetheme. Returning the default theme.]]
I don't know why this happened in my case, but I found a reference in the Liferay database to the old mine-theme. Even though I thought I got rid of it permanently, but removing it from the autodeploy directory. If I remove it from the glassfish autodeploy directory, it is also removed from the Application Server. Liferay is listening to what happenes on the autodeploying front, detects the deletion, and starts cleaning up after itself as well.

Apparently, there still was an entry left hanging. I had to update the database manually to reset a database tablerow back to "classic".

Adapting your theme

It is possible to adapt your theme, by replacing images and css and html files judiciously.

The interesting bit of theming is that you specify the parent theme. So, you've got "styled" and "unstyled" and the default theme called "classic" to choose from. But it would also be easy to create for example a "Christmas" theme, that is derived from the theme that you normally use. So it's kind of an Inheritance structure, similar to Object Oriented Programming.

I also like the fact that in your new theme you specify the "changes" compared to the parent theme in the _diffs folder. This way, when a parent theme changes (upon a new release of Liferay Portal), you automatically get the new updates, and if you do not change these defaults in your theme, they are just build into the target war upon the next release.

If you wish to start making bigger changes, there is the possibility of using the Liferay Application Display Templates9 (ADT).

Liferay uses Apache Velocity10 as its templating engine.

Adding JQuery to the Liferay portal can be done as described at [11].

References

[1] Randomthoughts - Liferay
http://randomthoughtsonjavaprogramming.blogspot.nl/2015/12/liferay.html
[2] Liferay
http://www.liferay.com/
[3] Wikipedia - Liferay
https://en.wikipedia.org/wiki/Liferay
[4] Liferay Company Blogs - Creating Liferay Themes with Maven
https://www.liferay.com/web/mika.koivisto/blog/-/blogs/creating-liferay-themes-with-maven#_33_message_13069757
[5] Liferay Developer Network - Developing Liferay Theme Plugins with Maven
https://dev.liferay.com/develop/tutorials/-/knowledge_base/6-2/developing-liferay-theme-plugins-with-maven
[6] Liferay Developer Network - Creating a Theme Project in the Plugins SDK
https://dev.liferay.com/develop/tutorials/-/knowledge_base/6-2/creating-a-theme-project-in-the-plugins-sdk
[7] StackOverflow - Error occures when deploying theme to liferay portal. “No theme found for specified theme id .”
http://stackoverflow.com/questions/11721220/error-occures-when-deploying-theme-to-liferay-portal-no-theme-found-for-specif
[8] Techspace - No theme found for specified theme id abc_WAR_xyztheme
http://parasjain.net/2012/07/11/no-theme-found-for-specified-theme-id-abc_war_xyztheme/
[9] LiferaySavvy - List of Velocity Variables in Liferay
http://www.liferaysavvy.com/2015/02/list-of-velocity-variables-in-liferay.html
[10] Wikipedia - Apache Velocity
https://en.wikipedia.org/wiki/Apache_Velocity
[11] Liferay Company Blogs - Using jQuery (or any Javascript library) in Liferay 6.0
http://www.liferay.com/web/nathan.cavanaugh/blog/-/blogs/using-jquery-or-any-javascript-library-in-liferay-6-0

Thursday, 31 December 2015

Liferay

My website has been using Drupal 70 for a while now, ever since I started working with Drupal in my previous job. It seemed like a good idea to get some experience with my first CMS/Webportal/thing by toying with it at home.

I have recently switched over to Liferay1. I was looking for a CMS/Webportal/thingie that is more in tune with the rest of my applications (which are written in Java/Glassfish). I could have chosen Hippo2, but I didn't. Liferay seems to align very good with Vaadin3, which is something I plan on perhaps using in the future.

Installing Liferay on GlassFish 4

Liferay comes with a choice of pre-defined application servers, which is very handy. But I already had a Glassfish server installed, so I wished to use that one, and then things do get a bit more complicated4 5.

What follows are some of the things that I ran up against, and how to do some of the administration that I required.

Global site

Apparently, since version 6, there's a Global6 site that is used for defining resources that are accessible for all other sites. Something I don't need, as I only required a one-site install. But it does show that the product seems defined for many websites of an Enterprisy nature.

Making the site private

Control panel -> Sites -> Configuration -> Site Settings -> Membership Type = Private
There are three settings for the site: open, restricted and private.
Open
Users can become members of the site at any time. Users can join sites from the My Sites portlet.
Restricted
Users can request site membership but site administrators must approve requests in order for users to become members. Requests can be made from the My Sites portlet.
Private
Users are not allowed to join the site or request site membership. Private sites don’t appear in the My Sites portlet. Site administrators can still manually select users and assign them as site members.
See [11] for more information regarding these settings.
It is also possible to define how new users are registered on the site12

Favicon

See for changing the favicon7 the (future) blog on "Liferay Themes".

Apple Icons

I got the following warning in my glassfish logs. Apparently I need to get some apple icons in there:
[2015-09-19T17:58:16.236+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=29 _ThreadName=Thread-8] [timeMillis: 1442685496236] [levelValue: 800] [[
17:58:16,235 WARN [http-listener-1(5)][code_jsp:114] {code="404", msg="Not Found", uri=/apple-touch-icon.png}]]

[2015-09-19T17:58:16.399+0000] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=28 _ThreadName=Thread-8] [timeMillis: 1442685496399] [levelValue: 800] [[
17:58:16,398 WARN [http-listener-1(4)][code_jsp:114] {code="404", msg="Not Found", uri=/apple-touch-icon-precomposed.png}]]

Unable to change default Display Icon

When attempting to change the display icon prominently displayed in the left-upper corner of the Liferay website, I ran into a little problem.

Changing it can be done using
Control Panel -> Portal Settings -> Display Settings (Under Miscellaneous)
The error message was:
GRIZZLY0039: Request URI is too large.
java.nio.BufferOverflowException
Apparently, it was necessary to increase the buffer size of the glassfish application server8 9:
Configurations -> cluster-config -> Network Config -> Transports -> tcp -> Buffer Size' to 131072 or more.

Liferay site

You can probably remove the Liferay Inc company site that is available standard in the demo.

Issues with the server.policy file

The server.policy file of Glassfish needs to be adapted for Liferay to work properly10.

I added the following which seemed to do the trick:
grant codeBase "file:${com.sun.aas.instanceRoot}/applications/-" {
permission java.security.AllPermission;
};

grant codeBase "file:${com.sun.aas.instanceRoot}/generated/-" {
permission java.security.AllPermission;
};

What version?

You can see the version of the Liferay instance you are running, by going to:
Control panel -> Configuration -> Server Administration
There you will find
Liferay Portal Community Edition 6.2 CE GA4 (Newton / Build 6203 / April 16, 2015)
Uptime: 3 Days, 14:53:03

References

[0] Drupal
https://www.drupal.org/
[1] Liferay
http://www.liferay.com/
[2] Hippo
http://www.onehippo.com/en
[3] Vaadin
https://vaadin.com/home
[4] Liferay Documentation - Installing Liferay on GlassFish 4
http://www.liferay.com/documentation/liferay-portal/6.2/user-guide/-/ai/installing-liferay-on-glassfish-3-liferay-portal-6-2-user-guide-15-en
[5] Liferay Dev - Installing Liferay on GlassFish 4
https://dev.liferay.com/discover/deployment/-/knowledge_base/6-2/installing-liferay-on-glassfish-4
[6] Liferay Wiki - Global Scope
https://www.liferay.com/community/wiki/-/wiki/Main/Global+Scope
[7] Liferay Wiki - How to change the favorites icon
https://www.liferay.com/community/wiki/-/wiki/Main/How+to+change+the+favorites+icon
[8] Stackoverflow - Glassfish 3.1 maximum uri length
http://stackoverflow.com/questions/5936165/glassfish-3-1-maximum-uri-length
[9] Iliachemodanov Blog - Configuration of long URLs in GlassFish
http://www.iliachemodanov.ru/en/blog-en/13-tools/glassfish/24-long-urls-in-glassfish-en
[10] Liferay Forums - Deployment problem on Liferay6.2 Glassfish4
https://www.liferay.com/community/forums/-/message_boards/view_message/52843459#_19_message_48023536
[11] Leveraging Liferay’s Multi-site Capabilities
https://dev.liferay.com/discover/portal/-/knowledge_base/6-2/leveraging-liferays-multi-site-capabilities
[12] Time for action – disabling the Register option for a guest user
https://www.packtpub.com/packtlib/book/Web-Development/9781849517003/6/ch06lvl1sec91/Time%20for%20action%20%20disabling%20the%20Register%20option%20for%20a%20guest%20user