Try this out.And suggestions invited
All the posts here are for sharing knowledge.
For more info:-http://www.liferay.com/
© 2013 LIFERAY INC. ALL RIGHTS RESERVED
The following are useful reference resources for developers working with the Liferay Platform:
Liferay specific resources:
What is a portal? http://www.liferay.com/products/what-is-a-portal
Platform Javadocs: http://docs.liferay.com/portal/6.1/javadocs/
Reference documentation for Liferay's XML files: http://docs.liferay.com/portal/6.1/definitions/
Reference documentation for Liferay's taglibs: http://docs.liferay.com/portal/6.1/taglibs/
Sources for version 6.1:
Sources of the development version:
Related specifications and standards:
Java 5 Javadocs: http://download.oracle.com/javase/1.5.0/docs/api/
JavaEE 5 Javadocs: http://download.oracle.com/javaee/5/api/
JavaEE Overview: http://www.oracle.com/technetwork/java/javaee/tech/index.html
Portlet Specification 2.0 (JSR-286): http://jcp.org/en/jsr/detail?id=286
Web Services for Remote Portlets (WSRP): http://www.oasis-open.org/committees/wsrp/
Java Content Repository (JSR-170): http://jcp.org/en/jsr/detail?id=170
Java Server Faces 1.2 (JSR-252): http://www.jcp.org/en/jsr/detail?id=252
Java Server Faces 2.0 (JSR-314): http://www.jcp.org/en/jsr/detail?id=314
OpenSocial: http://www.opensocial.org/
Sitemap protocol: http://sitemaps.org/
WebDAV: http://webdav.org/
HTML 5: http://html5.org/
WCAG 2.0: http://www.w3.org/WAI/intro/wcag20.php
Related and commonly used technologies:
Spring Framework: http://www.springsource.org/
Hibernate: http://www.hibernate.org/
Struts 1: http://struts.apache.org/1.x/
Lucene: http://lucene.apache.org/
Alloy UI: http://alloy.liferay.com/
jQuery: http://jquery.com/
IceFaces: http://www.icefaces.org/main/home/
PortletFaces: http://www.portletfaces.org/
Vaadin: http://vaadin.com/home
Apache ant: http://ant.apache.org/
Maven: http://maven.apache.org/
Selenium: http://seleniumhq.org/
Tomcat: http://tomcat.apache.org/
JBoss Application Server: http://www.jboss.org/
Lieray 6.1 CE is released and many of you have started using it. There are lots of features in Liferay 6.1 and one among them is the facility to use SASS in Liferay.
SASS:
SASS( http://sass-lang.com ) stands for Syntactically Awesome StyleSheets. It is a tool that allows you to write CSS more easily . It is an extension of CSS3 which means whatever CSS file is a valid SassyCSS (SCSS). It allows you to use variables, nested rules, mixins, inline imports, interpolation, arguments, manipulating colors and more with a fully CSS-compatible syntax. Sass generates well formatted CSS and it is much easier to organize and maintain your stylesheets.
Compass :
Compass( http://compass-style.org ) is an open-source CSS authoring framework which makes easier to build and maintain your markup and stylesheets. By using compass, you can write your own stylesheet in Sass instead of CSS.
How does Compass Work?
It can be imported using @import "compass" in CSS. SCSS is built based on the CSS3 specification which means that it is highly compatible with CSS3. SCSS also has all the power of Sass.
We’ll see here as how to use the variables, nested rules, mixins, inline imports, interpolation and arguments through CSS files.
Variables:
We’ll see how to use variables and a custom mixin to show how Compass makes it easy to reuse colors, sizes, and other values without repeating.
/* Variable Declaration */
/*These variables can be used globally throughout your stylesheets */
Example:
Liferay6.1 Liferay 6.0.x
Mixins:
By using the mixin, you can re-use the styles, properties & selectors without copying to other selectors. To achieve this , you need to package the properties with @mixin and to include it in other element with @include.
Example:
Liferay 6.1 Liferay 6.0.x
Nested Rules:
Nesting avoids repeating CSS selectors and also keeps the style compact for a certain area of the User Interface.
Let us have a look at an example of custom.css code for navigation part in themes. After using the nesting rule, the code should look like this :
Liferay 6.1 Liferay 6.0.x
Parent Reference:
Parent reference allows you to reference a parent selector in the case of pseudo-classes like :hover, :link, :visited and :active states.
Liferay 6.1 Liferay 6.0.x
Interpolation:
We can also use SassScript variables in selectors and property names using #{} interpolation. Here’s the example:
Liferay 6.1 Liferay 6.0.x
Liferay6.1 allows you to use Sass which helps the code be simpler for mobile site design. (Thanks to BradleyWood’s solution in this forum post ).
As said in Sass , it makes CSS fun again and with Liferay 6.1, you can easily create manageable style sheets and start updating to Liferay 6.1 and use Sass to manage your style sheets .
Liferay upgrades are fairly straightforward. A consistent set of steps is all you need to follow to upgrade a standard Liferay installation. Things do get more complicated if your organization has used Ext plugins to customize Liferay. It's possible that API changes in the new version will break your existing code. This, however, is usually pretty easy for your developers to fix. Portlet plugins which use Liferay APIs should be reviewed and their services rebuilt against the new release. Theme plugins may require some modifications in order to take advantage of new features, and if they're using Liferay APIs, they should be reviewed. Much effort has been made to make upgrades as painless as possible; however, this is not a guarantee that everything will work without modification. Ext plugins are the most complicating factor in an upgrade, so it is important to test as much as possible.
As a general rule, you can upgrade from one major release to the next major release. For example, you can upgrade directly from Liferay 5.2.x to 6.0.x, but not from 5.2.x to 6.1.x. If you need to upgrade over several major releases, you'll need to run the upgrade procedure for each major release until you reach the release you want. This doesn't mean you need to run the procedure for every point release or service pack; you only need to run the procedure for the major releases. A good practice is to use the latest version of each major release to upgrade your system.
Now that we've gotten the general philosophy of upgrading out of the way, let's outline the procedure you'll undergo for upgrading a Liferay 6.0 installation to a 6.1 installation. If you're running a previous version of Liferay and need to upgrade to 6.0 first, please see the instructions in the previous version of this document.
There are a few things you'll want to prepare before you actually perform the upgrade. Specifically, you'll need to review your image gallery usage, review new Liferay 6.1 defaults, and catalog all the plugins you have installed. After you've performed these three tasks, you'll be ready to upgrade.
Liferay 6.1 introduces a major change to how Liferay handles files. No longer do we have a separate Document Library and Image Gallery; instead, these have been combined into Documents and Media. If you were using Liferay's Image Gallery to store images, these can be migrated over during an upgrade, but you'll have to take some extra steps first.
In Liferay 6.0, you had three ways you could store images in the Image Gallery. You could use the
DatabaseHook
and store them as BLOBs in the database; you could use the
DLHook
to store them in the Document Library, or you could use the
FileSystemHook
to store them in a folder on your server's file system. Before you upgrade, you'll need to set whichever property you were using in your 6.0
portal-ext.properties
file, because by default, none of them are enabled in 6.1. Setting one of the properties triggers the migration during the upgrade process. Below are the three properties; you'll need to set only
one
of them (the one you were using).
image.hook.impl=com.liferay.portal.image.DatabaseHook image.hook.impl=com.liferay.portal.image.DLHook
image.hook.impl=com.liferay.portal.image.FileSystemHook
The next thing you'll need to look at are the defaults that have changed from 6.0 to 6.1. These are preserved in
portal-legacy-6.0.properties
in the source. The 6.0 values are:
users.last.name.required=true layout.types=portlet,panel,embedded,article,url,link_to_layout editor.wysiwyg.portal-web.
docroot.html.portlet.message_boards.edit_message.bb_code.jsp=bbcode
setup.wizard.enabled=false discussion.subscribe.by.default=false message.boards.subscribe.by.default=false
The 6.1 values have changed to:
users.last.name.required=false layout.types=portlet,panel,embedded,url,link_to_layout editor.wysiwyg.portal-web.
docroot.html.portlet.message_boards.edit_message.bb_code.jsp=ckeditor_bbcode
setup.wizard.enabled=true discussion.subscribe.by.default=true message.boards.subscribe.by.default=true
If you don't like the defaults, you can change them back in one shot by adding a system property to your JVM's startup. This differs by application servers. In Tomcat, you'd modify
setenv.sh
/
setenv.bat
and append the option
-Dexternal-properties=portal-legacy-6.0.properties
to the environment variable JAVA_OPTS. The scripts
setenv.sh
or
setenv.bat
are not delivered with default Tomcat, but do exist in the bundles. If they're there, Tomcat uses them in the startup process, so it's a nice way to separate your own settings from Tomcat's default shell scripts. Alternatively, of course, you can override some or all of them in your
portal-ext.properties
along with your other overrides.
Finally, you need to take note of any plugins you have installed. Liferay's plugins are usually version-specific, so you'll need to obtain new versions of them for the new release of Liferay. If you have custom plugins created by your development team, they'll need to build, test, and optionally modify them to work with the new release of Liferay. Don't attempt an upgrade without collecting all the plugins you'll need first.
Once you've reviewed your properties and collected all the plugins you'll need, you're ready to follow the upgrade procedure. Remember to back up your system before you begin.
There are two different procedures to upgrade Liferay. The first one, upgrading a Liferay bundle, is the most common. The second procedure is for upgrading a Liferay installation on an application server. We'll go over both.
In both cases, Liferay auto-detects whether the database requires an upgrade the first time the new version is started. When Liferay does this, it upgrades the database to the format required by the new version. In order to perform this task, Liferay
must
be accessing the database with an ID that can create, drop, and modify tables. Make sure that you have granted these permissions to the ID before you attempt to upgrade Liferay. And, of course, we'll run the risk of overly repeating ourselves: back up your database.
Let's look at upgrading a bundle, which is the easiest upgrade path.
If you're running a Liferay bundle, the best way to do the upgrade is to follow the steps below. The new Liferay is installed in a newer version of your bundle runtime. For example, the Liferay/Tomcat bundle for 6.0 used Tomcat 6 by default; the 6.1 bundle uses Tomcat 7. Though there is a Tomcat 6 bundle of Liferay 6.1, that bundle also uses a newer release of Tomcat than the one from 6.0. This is the case for all runtimes that Liferay supports. We generally recommend that you use the latest version of your runtime bundle, as it will be supported the longest.
portal-ext.properties
file and your
data
folder to the new bundle.
portal-ext.properties
file as described above. If you were using the Image Gallery, make the necessary modifications so that your files are migrated to Documents and Media. Review the new defaults and decide whether you want to use them. Review any other modifications you've made.
As you can see, upgrading a bundle is generally pretty simple. But not everybody can use bundles: sometimes, specific application servers or application server versions are mandated by the environment you're in or by management. For this reason, Liferay also ships as an installable .war file that can be used on any supported application server.
Running a manual upgrade is almost as easy as upgrading a bundle:
portal-ext.properties
file to a safe place and review it as described above, making all the appropriate changes.
That's all there is to it. Most everything is handled by Liferay's upgrade procedure. Note that as stated above, if you have to upgrade over several Liferay versions, you will need to repeat these steps for each major release.
I'd like to mention one of the new features in the upcoming release of Liferay 6.1, which is the remote development and deployment support from Liferay IDE. The idea is that with this feature you can build Liferay projects in Liferay IDE like normal but instead of the Liferay server running locally it is running on a remote host. This is accomplished through two things, 1) new remote server adapter in Liferay IDE and 2) Server manager plugin (new in 6.1) deployed to the remote Liferay server
This feature will be officially available with the Liferay 6.1 CE release, but since it is only in beta, now is a good time to try it out and give feedback.
For those who wish to try this out here are the steps to setting it up.
1. Download the Liferay Portal 6.1 Beta4 Tomcat bundle (Only tomcat is supported in beta4, both JBoss and Glassfish will be supported by 6.1 GA release)
2. Start Tomcat bundle on remote host (or even localhost)
3. Download the Server Manager plugin for 6.1 Beta4 (This plugin provides the API needed by Liferay IDE to administer remote plugins)
4. Deploy Server Manager plugin into remote Tomcat server
5. Install the latest stable or nightly version of Liferay IDE (links are updatesite URLs to use in Eclipse install manager)
6. Create a new server in Liferay IDE, File > New > Server > Liferay > Remote Liferay Server
7. Specify a local tomcat bundle for the runtime stub (this is needed for libraries to compile project)
8. Specify the IP address of remote tomcat server along with Omni admin username/password
Once you have done this you should see the server console log messages printed in the normal Eclipse console view.
9. Create and deploy Liferay projects as usual then publish (deploy) them to the server, see Liferay IDE getting started guide for a walkthrough of this.
Now when you modify files in your project, every 15 seconds it will publish the delta of any changes to remote server. However, you can publish changes immediately using the "publish" action in the servers view. If you want to change the automatic publish rate you can do that in the server configuration editor (double click server in Servers view).
For anyone who decides to try this out and want to give feedback with suggestions or problems please either open a JIRA ticket for the IDE project or enter a new topic on the IDE forums .
One of the often overlooked features of Liferay's WCM system is the ability to write non-trivial apps using it. There have been a few blog posts about this, notably Ray Augé's Advanced Web Content Example With AJAX . In the community, it's great for me because I can quickly create interesting visualizations of community data and share it with you immediately. There are some pros and cons to this approach:
Benefits:
Drawbacks:
In my opinion, Liferay WCM is a very good solution for app prototyping or for non-trivial apps that don't have tons of logic or page flows in them. You have already seen an example of this in the Community Activity Map , and the example I use below forms the basis for the Hot Topics app that you can now see on liferay.org .
To get started creating an app of this nature, you need to start with simple Web Content Template that is itself a template:
#if ($request.lifecycle == "RENDER_PHASE") ## This phase will handle the presentation code (i.e. HTML/CSS/JS). Any calls ## to the ${request.resource-url} will retrieve the result of evaluating the below ## RESOURCE_PHASE below. #elseif ($request.lifecycle == "RESOURCE_PHASE") ## This phase will handle the AJAX request like a portlet's serveResource() method #end
So decide what needs to be executed on the server side, and put it in the
RESOURCE_PHASE
. This is typically where most if not all of the business (i.e. non-presentation) logic goes. Put the presentation logic in the
RENDER_PHASE
.
For this app, I want to show which threads have the most posts in the last week. So, I needed to query Liferay's Message Boards. Since there is no
getMostActiveThreadsInTheLastWeek()
method (I know.. what's up with that??), I needed a custom query. This means using Liferay's
DynamicQuery
feature. But from Velocity? Turns out it's not that bad. Here's the full
RESOURCE_PHASE
code to create and execute a Dynamic Query, and generate a JSON object as a result which contains the most active threads in the last week:
#set ($portletNamespace = $request.portlet-namespace) #set ($scopeGroupId = $getterUtil.getLong($request.theme-display.scope-group-id)) #if ($request.lifecycle == "RENDER_PHASE") ## bunch of display logic to show the JSON result nicely #elseif ($request.lifecycle == "RESOURCE_PHASE") #set ($logFactory = $portal.getClass().forName('com.liferay.portal.kernel.log.LogFactoryUtil')) #set ($log = $logFactory.getLog('mylog')) #set ($portalBeanLocator = $portal.getClass().forName("com.liferay.portal.kernel.bean.PortalBeanLocatorUtil")) #set ($jsonFactory = $portalBeanLocator.locate("com.liferay.portal.kernel.json.JSONFactoryUtil")) #set ($mbMessageLocalService = $portalBeanLocator.locate("com.liferay.portlet.messageboards.service.MBMessageLocalService.velocity")) #set ($mbThreadLocalService = $portalBeanLocator.locate("com.liferay.portlet.messageboards.service.MBThreadLocalService.velocity")) #set ($calClass = $portal.getClass().forName("java.util.GregorianCalendar")) #set ($mbMessageClass = $portal.getClass().forName("com.liferay.portlet.messageboards.model.MBMessage")) #set ($mbThreadClass = $portal.getClass().forName("com.liferay.portlet.messageboards.model.MBThread")) #set ($dqfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil")) #set ($pfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil")) #set ($ofu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.OrderFactoryUtil")) #set ($now = $calClass.getInstance()) #set ($weeksago = $calClass.getInstance()) #set ($prevweeks = 0 - $getterUtil.getInteger($period.data)) #set ($V = $weeksago.add(3, $prevweeks)) #set ($q = $dqfu.forClass($mbThreadClass)) #set ($rfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil")) #set ($groupIdCriteria = $rfu.ne("categoryId", $getterUtil.getLong("-1"))) #set ($V = $q.add($groupIdCriteria)) #set ($groupIdCriteria = $rfu.eq("groupId", $getterUtil.getLong($scopeGroupId))) #set ($V = $q.add($groupIdCriteria)) #set ($companyIdCriteria = $rfu.eq("companyId", $getterUtil.getLong($companyId))) #set ($V = $q.add($companyIdCriteria)) #set ($statusCriteria = $rfu.eq("status", 0)) #set ($V = $q.add($statusCriteria)) #set ($lastPostDateCriteria = $rfu.between("lastPostDate", $weeksago.getTime(), $now.getTime())) #set ($V = $q.add($lastPostDateCriteria)) #set ($V = $q.setProjection($pfu.property("threadId"))) #set ($res1 = $mbMessageLocalService.dynamicQuery($q)) #set ($q2 = $dqfu.forClass($mbMessageClass)) #set ($inCriteria = $rfu.in("threadId", $res1)) #set ($V = $q2.add($inCriteria)) #set ($createDateCriteria = $rfu.between("createDate", $weeksago.getTime(), $now.getTime())) #set ($V = $q2.add($createDateCriteria)) #set ($V = $q2.setProjection($pfu.projectionList().add($pfu.groupProperty("rootMessageId")).add($pfu.alias($pfu.rowCount(), "msgCount")))) #set ($V = $q2.addOrder($ofu.desc("msgCount"))) #set ($V = $q2.setLimit(0, 7)) #set ($res2 = $mbMessageLocalService.dynamicQuery($q2)) #set ($jsonArray = $jsonFactory.createJSONArray()) #foreach ($msgSum in $res2) #set ($rootMsgId = $msgSum.get(0)) #set ($msgCount = $msgSum.get(1)) #set ($subject = $mbMessageLocalService.getMessage($rootMsgId).getSubject()) #set ($jsonObject = $jsonFactory.createJSONObject()) #set ($V = $jsonObject.put("subject", $stringUtil.shorten($htmlUtil.escape($subject), 55))) #set ($V = $jsonObject.put("msgid", $rootMsgId)) #set ($V = $jsonObject.put("msgCount", $msgCount)) #set ($V = $jsonArray.put($jsonObject)) #end { "jsonArray": $jsonArray } #end
There are many things going on here:
#set ($logFactory = $portal.getClass().forName('com.liferay.portal.kernel.log.LogFactoryUtil')) #set ($log = $logFactory.getLog('mylog'))
$log.error($msgCount)
or
$log.error("Hi There").
#set ($calClass = $portal.getClass().forName("java.util.GregorianCalendar"))
#set ($now = $calClass.getInstance()) #set ($weeksago = $calClass.getInstance()) #set ($prevweeks = 0 - $getterUtil.getInteger($period.data)) #set ($V = $weeksago.add(3, $prevweeks))
period
structure element.
$q
) queries for
MBThread
entities that have a
categoryId
of -1 (MBThreads that do not have a
categoryId
of -1 are not threads from the message boards portlet, instead they are threads for things like comments on document library entries, etc). The query also includes other criteria, like groupId/companyId must match the "current" groupId/companyId of the site in which the web content is placed, the status must be 0 (indicating it is an approved (i.e. not draft or deleted) entry), and most importantly the
lastPostDate
must be between my desired time period start and end. Finally, I am not interested in all of the
MBThread
entity - I just need the
threadId
. So my query includes a
Projection
that only returns the
threadId
.
$q2
) queries for all
MBMessage
entities that match my new critieria: they must have a
threadId
of one of the threads identified in the first query (hence the
in
criteria), and the message's
createDate
must also be between my start/end dates. This is to avoid counting messages in the thread that occured before the cutoff dates. Finally, this gem:
#set ($V = $q2.setProjection($pfu.projectionList().add($pfu.groupProperty("rootMessageId")).add($pfu.alias($pfu.rowCount(), "msgCount")))) #set ($V = $q2.addOrder($ofu.desc("msgCount"))) #set ($V = $q2.setLimit(0, 7))
rootMessageId
, since each message in the same thread will have the same
rootMessageId
(which I eventually use to construct the URL to the message), and includes a count of the messages that match (with an alias defined so I can refer to the row count when specifying the order of the results via
addOrder()
). I also limit the results to 7 because I don't want to show any more than that (this is a simple app). This second query returns a result table that looks like:
So after the Dynamic Queries executes, it's just a matter of constructing a JSONObject (and sanitizing/sizing the actual text of the subject of the thread) and returning it.
Calendar.MONTH
to be 3 ? You can't reference static member variables of a class unless it is already part of the Velocity context in which a template is evaluated). There are many other perils awaiting the adventurous Velocity coder. I learned many things through trial and error (and the help of my IRC friends on the #liferay channel!). Here are some more:
$var
instead of
var
. If you forget the $, you won't get syntax errors, just silent errors and half of your code will next execute.
#* @vtlvariable name="request" type="java.util.Map" *# #* @vtlvariable name="httpUtil" type="com.liferay.portal.kernel.util.HttpUtil" *# #* @vtlvariable name="htmlUtil" type="com.liferay.portal.kernel.util.HtmlUtil" *# #* @vtlvariable name="obc" type="com.liferay.portal.util.comparator.UserLastNameComparator" *# #* @vtlvariable name="serviceLocator" type="com.liferay.portal.velocity.ServiceLocator" *# #* @vtlvariable name="teamLocalService" type="com.liferay.portal.service.TeamLocalServiceUtil" *# #* @vtlvariable name="mbMessageLocalService" type="com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil" *# #* @vtlvariable name="mbThreadLocalService" type="com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil" *#
${request.theme-display}
, or access one of your WCM structure fields that represent a number (but are of type "Text" in the template), they are probably not of the the type that you want. You need to use generous amounts of
$getterUtil.getXXX
calls to make sure. For example,
#set ($scopeGroupId = $getterUtil.getLong($request.theme-display.scope-group-id))
$scopeGroupId
a Long), whereas
#set ($scopeGroupId = $request.theme-display.scope-group-id)
new HashMap()
. Velocity does not know what "
new
" is - after all, you're using a presentation/templating language, not Java! But we're using it for more than display. So as a workaround you can do things like
$portal.getClass().forName("java.util.HashMap").newInstance()
.
$array[0]
. You have to use
$array.get(0)
.
#* @vtlvariable name="portletNamespace" type="java.lang.String" *# #* @vtlvariable name="portal" type="com.liferay.portal.util.Portal" *# #* @vtlvariable name="getterUtil" type="com.liferay.portal.kernel.util.GetterUtil" *# #* @vtlvariable name="stringUtil" type="com.liferay.portal.kernel.util.StringUtil" *# #* @vtlvariable name="max-members" type="com.liferay.portlet.journal.util.TemplateNode" *# #* @vtlvariable name="team-name" type="com.liferay.portlet.journal.util.TemplateNode" *# #* @vtlvariable name="section-members" type="com.liferay.portlet.journal.util.TemplateNode" *# #* @vtlvariable name="groupId" type="java.lang.String" *# #* @vtlvariable name="sectionMembers" type="java.lang.String" *# #* @vtlvariable name="locale" type="java.util.Locale" *# #* @vtlvariable name="companyId" type="java.lang.String" *# #* @vtlvariable name="scopeGroupId" type="java.lang.String" *# #* @vtlvariable name="sectionName" type="java.lang.String" *# #* @vtlvariable name="section-name" type="com.liferay.portlet.journal.util.TemplateNode" *# #* @vtlvariable name="params" type="java.util.LinkedHashMap" *# #* @vtlvariable name="users" type="java.util.List" *# #* @vtlvariable name="user" type="com.liferay.portal.model.User" *# #* @vtlvariable name="themeDisplay" type="com.liferay.portal.theme.ThemeDisplay" *# #* @vtlvariable name="languageUtil" type="com.liferay.portal.kernel.language.LanguageUtil" *# #* @vtlvariable name="request" type="java.util.Map" *# #* @vtlvariable name="httpUtil" type="com.liferay.portal.kernel.util.HttpUtil" *# #* @vtlvariable name="htmlUtil" type="com.liferay.portal.kernel.util.HtmlUtil" *# #* @vtlvariable name="obc" type="com.liferay.portal.util.comparator.UserLastNameComparator" *# #* @vtlvariable name="serviceLocator" type="com.liferay.portal.velocity.ServiceLocator" *# #* @vtlvariable name="teamLocalService" type="com.liferay.portal.service.TeamLocalServiceUtil" *# #* @vtlvariable name="mbMessageLocalService" type="com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil" *# #* @vtlvariable name="mbThreadLocalService" type="com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil" *# #* @vtlvariable name="imageToken" type="com.liferay.portal.kernel.servlet.ImageServletToken" *# #* @vtlvariable name="userLocalService" type="com.liferay.portal.service.UserLocalServiceUtil" *# #* @vtlvariable name="groupIdCriteria" type="com.liferay.portal.kernel.dao.orm.Criterion" *# #* @vtlvariable name="groupIdProp" type="com.liferay.portal.kernel.dao.orm.Property" *# #* @vtlvariable name="threadMap" type="java.util.Map<java.lang.Long, java.lang.Integer>" *# #* @vtlvariable name="q" type="com.liferay.portal.kernel.dao.orm.DynamicQuery" *# #* @vtlvariable name="q2" type="com.liferay.portal.kernel.dao.orm.DynamicQuery" *# #* @vtlvariable name="rfu" type="com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil" *# #* @vtlvariable name="pfu" type="com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil" *# #* @vtlvariable name="ofu" type="com.liferay.portal.kernel.dao.orm.OrderFactoryUtil" *# #* @vtlvariable name="msgs" type="java.util.List<com.liferay.portlet.messageboards.model.MBMessage>" *# #set ($portletNamespace = $request.portlet-namespace) #set ($scopeGroupId = $getterUtil.getLong($request.theme-display.scope-group-id)) #if ($request.lifecycle == "RENDER_PHASE") <body onload="${portletNamespace}getTable();"> <article> <h1 class="section-heading section-heading-b"> <div>$title.data</div> <div class="section-heading-hr"></div> </h1> <div id='${portletNamespace}tablediv' style='width: 85%;'><!-- --></div> </article> </body> <script type="text/javascript"> var ${portletNamespace}table = new Object(); var ${portletNamespace}ICON = '<img class="icon" \ src="http://my-liferay-site-cdn.com/osb-theme/images/spacer.png" \ alt="Message Boards" title="Message Boards" \ style=" background-image: url(\'/html/icons/_sprite.png\');\ background-position: 50% -736px; \ background-repeat: no-repeat; height: 16px; width: 16px;">'; function ${portletNamespace}drawChart() { var html = '<div> \ <table style="margin-bottom:0em;"> \ <tbody>'; for (i = 0; i < ${portletNamespace}table.length; i++) { html += '<tr> \ <td class="portlet-icon" style="padding-right:6px;"> \ <table style="margin-top:-4px; margin-bottom:0px;">\ <tr>\ <td>\ <span>' + ${portletNamespace}ICON + '</span> \ </td>\ </tr>\ <tr>\ <td>\ <span style="color:#908E91; font-size:9px;">'+ ${portletNamespace}table[i].msgCount + '</span>\ </td>\ </tr>\ </table>\ </td> \ <td>\ <div>\ <h3 class="txt-n fs-11 m-0 o-h">\ <span class="display-b m-tn3 m-b6">\ <a href="/community/forums/-/message_boards/message/' + ${portletNamespace}table[i].msgid +'">'+ ${portletNamespace}table[i].subject + '</a>\ </span>\ </h3>\ </div>\ </td>\ </tr>'; } html += '</tbody>\ </table>\ </div>'; document.getElementById('${portletNamespace}tablediv').innerHTML = html; } function ${portletNamespace}getTable() { AUI().use( "aui-base", "aui-io-plugin", "aui-io-request", function(A) { A.io.request( '${request.resource-url}', { data: { }, dataType: "json", on: { success: function(event, id, obj) { var responseData = this.get("responseData"); ${portletNamespace}table = responseData.jsonArray || []; ${portletNamespace}drawChart(); }, failure: function(event, id, obj) { } } } ); } ); } </script> #elseif ($request.lifecycle == "RESOURCE_PHASE") #set ($logFactory = $portal.getClass().forName('com.liferay.portal.kernel.log.LogFactoryUtil')) #set ($log = $logFactory.getLog('mylog')) #set ($portalBeanLocator = $portal.getClass().forName("com.liferay.portal.kernel.bean.PortalBeanLocatorUtil")) #set ($jsonFactory = $portalBeanLocator.locate("com.liferay.portal.kernel.json.JSONFactoryUtil")) #set ($mbMessageLocalService = $portalBeanLocator.locate("com.liferay.portlet.messageboards.service.MBMessageLocalService.velocity")) #set ($mbThreadLocalService = $portalBeanLocator.locate("com.liferay.portlet.messageboards.service.MBThreadLocalService.velocity")) #set ($calClass = $portal.getClass().forName("java.util.GregorianCalendar")) #set ($mbMessageClass = $portal.getClass().forName("com.liferay.portlet.messageboards.model.MBMessage")) #set ($mbThreadClass = $portal.getClass().forName("com.liferay.portlet.messageboards.model.MBThread")) #set ($dqfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil")) #set ($pfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil")) #set ($ofu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.OrderFactoryUtil")) #set ($now = $calClass.getInstance()) #set ($weeksago = $calClass.getInstance()) #set ($prevweeks = 0 - $getterUtil.getInteger($period.data)) #set ($V = $weeksago.add(3, $prevweeks)) #set ($q = $dqfu.forClass($mbThreadClass)) #set ($rfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil")) #set ($groupIdCriteria = $rfu.ne("categoryId", $getterUtil.getLong("-1"))) #set ($V = $q.add($groupIdCriteria)) #set ($groupIdCriteria = $rfu.eq("groupId", $getterUtil.getLong($scopeGroupId))) #set ($V = $q.add($groupIdCriteria)) #set ($companyIdCriteria = $rfu.eq("companyId", $getterUtil.getLong($companyId))) #set ($V = $q.add($companyIdCriteria)) #set ($statusCriteria = $rfu.eq("status", 0)) #set ($V = $q.add($statusCriteria)) #set ($lastPostDateCriteria = $rfu.between("lastPostDate", $weeksago.getTime(), $now.getTime())) #set ($V = $q.add($lastPostDateCriteria)) #set ($V = $q.setProjection($pfu.property("threadId"))) #set ($res1 = $mbMessageLocalService.dynamicQuery($q)) #set ($q2 = $dqfu.forClass($mbMessageClass)) #set ($inCriteria = $rfu.in("threadId", $res1)) #set ($V = $q2.add($inCriteria)) #set ($createDateCriteria = $rfu.between("createDate", $weeksago.getTime(), $now.getTime())) #set ($V = $q2.add($createDateCriteria)) #set ($V = $q2.setProjection($pfu.projectionList().add($pfu.groupProperty("rootMessageId")).add($pfu.alias($pfu.rowCount(), "msgCount")))) #set ($V = $q2.addOrder($ofu.desc("msgCount"))) #set ($V = $q2.setLimit(0, 7)) #set ($res2 = $mbMessageLocalService.dynamicQuery($q2)) #set ($jsonArray = $jsonFactory.createJSONArray()) #foreach ($msgSum in $res2) #set ($rootMsgId = $msgSum.get(0)) #set ($msgCount = $msgSum.get(1)) #set ($subject = $mbMessageLocalService.getMessage($rootMsgId).getSubject()) #set ($jsonObject = $jsonFactory.createJSONObject()) #set ($V = $jsonObject.put("subject", $stringUtil.shorten($htmlUtil.escape($subject), 55))) #set ($V = $jsonObject.put("msgid", $rootMsgId)) #set ($V = $jsonObject.put("msgCount", $msgCount)) #set ($V = $jsonArray.put($jsonObject)) #end { "jsonArray": $jsonArray } #end
source