Setting up the most Popular Journal Articles in your Personalized Community in Liferay Portal

Exclusive offer: get 50% off this eBook here
Liferay Portal 5.2 Systems Development

Liferay Portal 5.2 Systems Development — Save 50%

Liferay Portal 5.2 Systems Development

$32.99    $16.50
by Jonas X. Yuan | May 2009 | Java

In this article by Jonas Yuan, you will learn how to set up the most popular journal articles in your personalized community and view the counter for other assets.

Personal community is a dynamic feature of Liferay portal. By default, the personal community is a portal-wide setting that will affect all of the users. It would be nice to have more features in the personal community such as showing the most popular journal articles. This article by Jonas Yuan will address how to set up the most popular journal articles in you personalized community and view the counter for other assets.

In a web site, we will have a lot of journal articles (that is, web content) for a given article type. For example, for the article type Article Content, we will have articles talking about product family. We may want to know how many times the end users read each article. Meanwhile, it would be nice if we could show the most popular articles (for example, TOP 10 articles) for this given article type.

As shown in the following screenshot, a journal article My EDI Product I is shown via a portlet Ext Web Content Display. Rating and comments on this article are also exhibited. At the same time, the medium-size image, polls, and related content of this article are listed, too. A view counter of this article is especially displayed under the ratings. Moreover, the most popular articles are exhibited with article title and number of views under related content. All these articles belong to the article type article-content. That is, the article in the current portlet Ext Web Content Display has the most popular articles only for the article type article-content.

Of course, you can customize the portlet Web Content Display directly through changing JSP files. For demo purposes, we will implement the view counter in the portlet Ext Web Content Display. Meanwhile, we will implement the mostly popular articles via VM services and article templates. In addition, we will analyze the view counter for other assets such as Image Gallery images, Document Library documents, Wiki articles, Blog entries, Message Boards threads, and so on.

Liferay Portal 5.2 Systems Development

Adding a view counter in the Web Content Display portlet

First of all, let's add a view counter in the Ext Web Content Display portlet. As the function of view counter for assets (including journal articles) is provided in the model TagsAssetModel of the com.liferay.portlet.tags.model package in the /portal/portal-service/src folder, we could use this feature in this portlet directly. To do so, use the following steps:

  1. Create a folder journal_content in the folder /ext/ext-web/docroot/html/portlet/.
  2. Copy the JSP file view.jsp in the folder /portal/portal-web/docroot/html/portlet/ to the folder /ext/ext-web/docroot/html/portlet/journal_content and open it.
  3. Add the line <%@ page import="com.liferay.portlet.tags.model.TagsAsset" %> after the line <%@ include file="/html/portlet/journal_content/init.jsp" %>, and check the following lines:
      JournalArticleDisplay articleDisplay = (JournalArticleDisplay)
      request.getAttribute(
      WebKeys.JOURNAL_ARTICLE_DISPLAY);
      if (articleDisplay != null) {
      TagsAssetLocalServiceUtil.incrementViewCounter(
      JournalArticle.class.getName(),
      articleDisplay.getResourcePrimKey());
      }
  4. Then add the following lines after the line <c:if test="<%=enableComments %>"> and save it:
      <span class="view-count">
      <% TagsAsset asset = TagsAssetLocalServiceUtil.getAsset
      (JournalArticle.class.getName(),
      articleDisplay.getResourcePrimKey());%>
      <c:choose>
      <c:when test="<%= asset.getViewCount() == 1 %>">
      <%= asset.getViewCount() %>
      <liferay-ui:message key="view" />,
      </c:when>
      <c:when test="<%= asset.getViewCount() > 1 %>">
      <%= asset.getViewCount() %>
      <liferay-ui:message key="views" />,
      </c:when>
      </c:choose>
      </span>

The code above shows a way to increase the view counter via the TagsAssetLocalServiceUtil.incrementViewCounter method. This method takes two parameters className and classPK as inputs. For the current journal article, the two parameters are JournalArticle.class.getName() and articleDisplay.getResourcePrimKey(). Then, this code shows a way to display view counted through the TagsAssetLocalServiceUtil.getAsset method. Similarly, this method also takes two parameters, className and classPK, as inputs. This approach would be useful for other assets, as the className parameter could be Image Gallery, Document Library, Wiki, Blogs, Message Boards, Bookmark, and so on.

Setting up VM service

We can set up the VM service to exhibit the most popular articles. We can also add the getMostPopularArticles method in the custom velocity tool ExtVelocityToolUtil.

To do so, first add the following method in the ExtVelocityToolService interface:

public List<TagsAsset> getMostPopularArticles(String companyId, 
String groupId, String type, int limit);

And then add an implementation of the getMostPopularArticles method in the ExtVelocityToolServiceImpl class as follows:

public List<TagsAsset> getMostPopularArticles(String companyId, 
String groupId, String type, int limit) {
List<TagsAsset> results = Collections.synchronizedList(new
ArrayList<TagsAsset>());
DynamicQuery dq0 = DynamicQueryFactoryUtil.forClass(
JournalArticle.class, "journalarticle").
setProjection(ProjectionFactoryUtil.property
("resourcePrimKey")).add(PropertyFactoryUtil.
forName("journalarticle.companyId").
eqProperty("tagsasset.companyId")).
add(PropertyFactoryUtil.forName(
"journalarticle.groupId").eqProperty(
"tagsasset.groupId")).add(PropertyFactoryUtil.
forName("journalarticle.type").eq(
"article-content"));
DynamicQuery query = DynamicQueryFactoryUtil.forClass(
TagsAsset.class, "tagsasset")
.add(PropertyFactoryUtil.forName(
"tagsasset.classPK").in(dq0))
.addOrder(OrderFactoryUtil.desc(
"tagsasset.viewCount"));
try{ List<Object> assets = TagsAssetLocalServiceUtil.
dynamicQuery(query);
int index = 0; for (Object obj: assets) {
TagsAsset asset = (TagsAsset) obj;
results.add(asset);
index ++;
if(index == limit)
break;
}
}
catch (Exception e){
return results;
}
return results;
}

The preceding code shows a way to get the most popular articles by company ID, group ID, article type, and limited articles to be returned. DynamicQuery API allows us to leverage the existing mapping definitions through access to the Hibernate session. For example, DynamicQuery dq0 selects the journal articles by companyID, groupId, and type; DynamicQuery query selects tagsassets by classPK, which exists in DynamicQuery dq0; and tagsassets are ordered by viewCount as well.

Finally, add the following method to register the above method in ExtVelocityToolUtil:

public List<TagsAsset> getRelatedArticles(String companyId, String 
groupId, String articleId, int limit){
return _extVelocityToolService.getRelatedArticles(companyId,
groupId, articleId, limit);
}

The code above shows a generic approach to get TOP 10 articles for any article types. Of course, you can extend this approach to find TOP 10 assets. This can include Image Gallery images, Document Library documents, Wiki articles, Blog entries, Message Boards threads, Bookmark entries, slideshow, videos, games, video queue, video list, playlist, and so on. You may practice these TOP 10 assets feature.

Building article template for the most popular journal articles

We have added view counter on journal articles. We have already built VM service for the most popular articles too. Now let's build an article template for them.

Setting up the default article type

As mentioned earlier, there is a set of types of journal articles, for example, announcements, blogs, general, news, press-release, updates, article-tout, article-content, and so on. In real case, only some of these types will require view counter, for example article-content. Let's configure the default article type for mostly popular articles. We can add the following line at the end of portal-ext.properties.

ext.most_popular_articles.article_type=article-content

The code above shows that the default article type for most_popular_articles is article-content.

Liferay Portal 5.2 Systems Development Liferay Portal 5.2 Systems Development
Published: May 2009
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

Setting up the article template

Let's create a template named MOST_POPULAR_ARTICLES via the portlet Web Content with the following content:

The code above shows how to use the extVelocityToolUtil.getMostPopularArticles method to get the most popular articles via companyId, groupId, article_type and the number of articles (10). Then it shows the most popular articles with title and view count.

Putting all article templates together

Finally, we need to update the ARTICLE_CONTENT template via the portlet Web Content in order to merge the POLL, RELATED_CONTENT, and MOST_POPULAR_ARTICLES templates. Thus, we will have one integrated view for polls, related articles, and the most popular articles. To do so, add the following line after the line #parse("$journalTemplatesPath/RELATED_Content") in the ARTICLE_CONTENT template:

#parse ("$journalTemplatesPath/MOST_POPULAR_ARTICLES")

Cool! You have built dynamic articles with polls, related content, and the most popular articles successfully. If you created an article with the Article Content type and tags, the polls, related content, and most popular articles (TOP 10) will come out altogether.

Having a handle on view counter for assets

Assets could be journal articles, Wiki articles, blog entries, Message Boards threads, Image Gallery images, Document Library documents, bookmark entries, and so on. Although the function of view counter for these assets is provided in the TagsAssetModel model at the com.liferay.portlet.tags.model package in the folder /portal/portal-service/src, Message Boards threads and bookmark entries still use their own models. At the same time, Image Gallery images and Document Library documents do not use the TagsAssetModel model for view counter yet. Therefore, it would be nice to look at view counter for these assets in detail.

Using journal article tokens

We have added the view counter feature in JSP file successfully. Here we have one more option: adding the views counter through the journal articles token. You can just add a @view_counter@ token to either the content of journal article or the output of article template used. This token is automatically translated to the logic of view counter increment. To find out the logic, locate the Java file ViewCounterTransformerListener.java at the com.liferay.portlet.journal.util package in the folder /portal/portal-impl/src and open it. Check out the following lines:

protected String replace(String s) {
Map<String, String> tokens = getTokens();
String articleResourcePK = tokens.get("article_resource_pk");
String counterToken = StringPool.AT + "view_counter" +
StringPool.AT;
StringBuilder sb = new StringBuilder();
sb.append("<script type="text/javascript">");
sb.append("Liferay.Service.Tags.TagsAsset.
incrementViewCounter");

sb.append("({className:'");
sb.append("com.liferay.portlet.journal.model.
JournalArticle',");

sb.append("classPK:");
sb.append(articleResourcePK); sb.append("});");
sb.append("</script>");
s = StringUtil.replace(s, counterToken, sb.toString());
return s;
}

The code above shows the same logic as that of the journal article JSP file that was mentioned earlier. Because it is AJAX-based, even if the page is cached somewhere in a proxy, you will get the correct number of views counted.

For example, when editing the text of the article named My EDI Product I, you can simply add @view_counter@ anywhere in the text and save it. That's it. Besides the @view_counter@ token, there is a set of tokens you can use at runtime, translating to their applicable runtime value at processing time. The following is a complete list of tokens and their runtime values:

@cdn_host@: themeDisplay.getCDNHost()
@company_id@: themeDisplay.getCompanyId()
@group_id@: groupId
@cms_url@: themeDisplay.getPathContext() + "/cms/servlet"
@image_path@: themeDisplay.getPathImage()
@friendly_url_private_group@: themeDisplay.
getPathFriendlyURLPrivateGroup()
@friendly_url_private_user@: themeDisplay.
getPathFriendlyURLPrivateUser()
@friendly_url_public@: themeDisplay.getPathFriendlyURLPublic()
@main_path@: themeDisplay.getPathMain()
@portal_ctx@: themeDisplay.getPathContext()
@portal_url@: Http.removeProtocol(themeDisplay.getURLPortal())
@root_path@: themeDisplay.getPathContext()
@theme_image_path@: themeDisplay.getPathThemeImages()
@language_id@: the language_id of the current request

Get view count on Wiki articles

The view count of Wiki articles is provided by default via the TagsAssetModel model at the com.liferay.portlet.tags.model package in the folder /portal/portal-service/src. You can find it out from view.jsp in the folder /portal/portal-web/docroot/html/portlet/wiki as follows:

TagsAssetLocalServiceUtil.incrementViewCounter(WikiPage.class.
getName(), wikiPage.getResourcePrimKey());
<!-- ignore details -->
<% TagsAsset asset = TagsAssetLocalServiceUtil.getAsset(WikiPage.
class.getName(), wikiPage.getResourcePrimKey()); %>
<c:choose>
<c:when test="<%= asset.getViewCount() == 1 %>">
<%= asset.getViewCount() %> <liferay-ui:message key="view" />,
</c:when>
<c:when test="<%= asset.getViewCount() > 1 %>">
<%= asset.getViewCount() %>
<liferay-ui:message key="views" />,
</c:when>
</c:choose>

The code above shows an increasing view counter of the current Wiki article via the TagsAssetLocalServiceUtil service. Then it shows the views counted for the current Wiki article.

Getting views count on blog entries

Similarly, the view count of blog entries is provided by default via the TagsAssetModel model too. You can find it from the view_entry.jsp and view_entry_content.jsp file in the folder /portal/portal-web/docroot/html/portlet/blogs as follows:

TagsAssetLocalServiceUtil.incrementViewCounter(BlogsEntry.class.
getName(), entry.getEntryId());
<!-- ignore details -->
<span class="view-count">
<% TagsAsset asset = TagsAssetLocalServiceUtil.getAsset(
BlogsEntry.class.getName(), entry.getEntryId());%>
<c:choose>
<c:when test="<%= asset.getViewCount() == 1 %>">
<%= asset.getViewCount() %> <liferay-ui:message key="view" />,
</c:when>
<c:when test="<%= asset.getViewCount() > 1 %>">
<%= asset.getViewCount() %>
<liferay-ui:message key="views" />,
</c:when>
</c:choose>
</span>

The code above first shows an increasing view counter of the current blog entries via the TagsAssetLocalServiceUtil service in the view_entry.jsp file. Then it shows the views counted for the current blog entry in view_entry_content.jsp.

Getting views on Message Boards threads

Message Board threads have their own model to manage the views counted. You can find related methods—locate the Java file MBThreadModel.java at the com.liferay.portlet.messageboards.model package in the /portal/portal-service/src folder and open it. Check the following lines:

public int getViewCount();
public void setViewCount(int viewCount);

The code above shows get and set methods for view counts.

Then you can check the method which is used to increase views count. Locate the Java file MBMessageLocalServiceImpl.java in the com.liferay.portlet.messageboards.service.impl package in the /portal/portal-impl/src folder and open it. Check the following lines:

public MBMessageDisplay getMessageDisplay(MBMessage message)
throws PortalException, SystemException {
// ignore details
MBThread thread = mbThreadPersistence.findByPrimaryKey(
message.getThreadId());
thread.setViewCount(thread.getViewCount() + 1);
mbThreadPersistence.update(thread, false);
// ignore details
}

The code above reuses the setter to increase the views counted when displaying Message Boards message.

Setting up view counter on the Image Gallery images

Although the function of the view count for Image Gallery images is provided in the TagsAssetModel model, the feature of view counter is not provided in the portal by default. Of course, we can set up view counter on the Image Gallery images simply by using the following steps:

  1. Create a package com.liferay.portal.servlet in the folder /ext/ext-impl/src.
  2. Copy the Java file ImageServlet.java from the package com.liferay.portal.servlet in the folder /portal/portal-impl/src to the package com.liferay.portal.servlet in the folder /ext/ext-impl/src.
  3. Locate the Java file ImageServlet.java at the package com.liferay.portal.servlet in the /ext/ext-impl/src folder and open it.
  4. Add the following lines after the line image = ImageLocalServiceUtil.getImage(imageId); in the getImage method :
      try{ 
      IGImage igImage = IGImageLocalServiceUtil.getImageByLargeImageId (
      imageId);
      TagsAssetLocalServiceUtil.incrementViewCounter(
      IGImage.class.getName(), igImage.getPrimaryKey());
      }
      catch (Exception e) {}
  5. Then add the following lines before the line image = ImageLocalServiceUtil.getImage( in the getImage method .
      TagsAssetLocalServiceUtil.incrementViewCounter( IGImage.class.
      getName(), igImage.getPrimaryKey());

The code above shows a way to set up a view count for the Image Gallery images. When getting an image via either imageId or uuid and groupId, it uses the TagsAssetLocalServiceUtil service to increase view counter for the current image

Setting up view counter on Document Library documents

Similar to view counter of the Image Gallery images, the feature of view counter for Document Library documents is not provided in the portal by default. But we can set it up easily by using the following steps:

  1. Create a package com.liferay.portlet.documentlibrary.action in the folder /ext/ext-impl/src.
  2. Copy the Java file GetFileAction.java from the package com.liferay.portlet.documentlibrary.action in the /portal/portal-impl/src folder to the package com.liferay.portlet.documentlibrary.action in the /ext/ext-impl/src folder.
  3. Locate the Java file GetFileAction.java at the package com.liferay.portlet.documentlibrary.action in the /ext/ext-impl/src folder and open it.
  4. Add the following lines after the line String contentType = MimeTypesUtil.getContentType(fileName); in the GetFile method and save it:
      TagsAssetLocalServiceUtil.incrementViewCounter(DLFileEntry
      .class.getName(), fileEntry.getFileEntryId());

The code above shows a way to increase view counter for Document Library documents. When called, the getFile method uses the TagsAssetLocalServiceUtil service to increase the view counter for the current document.

Getting visits on bookmark entries

Similar to Message Boards threads, bookmark entries have their own model to manage views counter. You can find related methods in the Java file BookmarksEntryModel.java in the package com.liferay.portlet.bookmarks.model in the folder /portal/portal-service/src. Open it and then check the following lines:

public int getVisits();
public void setVisits(int visits);

The code above shows the get and set methods for visits. Then check the method to increase visits: locate the Java file BookmarksEntryLocalServiceImpl.java in the package com.liferay.portlet.bookmarks.service.impl in the /portal/portal-impl/src folder and open it; check the following lines:

public BookmarksEntry openEntry(long entryId)
throws PortalException, SystemException {
BookmarksEntry entry = bookmarksEntryPersistence.
findByPrimaryKey(entryId);
entry.setVisits(entry.getVisits() + 1);
bookmarksEntryPersistence.update(entry, false);
return entry;
}

As shown in the code above, it reuses the set method to increase visits (as explained earlier) when a Bookmark entry is opened.

Summary

A web site has many journal articles for a given article. We may also want to know how many times the end users read each article. This article showed us how to set up the most popular journal articles and view counter for assets.


If you have read this article you may be interested to view :

Liferay Portal 5.2 Systems Development Liferay Portal 5.2 Systems Development
Published: May 2009
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

About the Author :


Jonas X. Yuan

Jonas X. Yuan is a Chief Architect of ForgeLife LLC and an expert on Liferay Portal, e-commerce, and Content Management Systems (CMS). As an open source community contributor, he has published five Liferay books from 2008 to 2012. He is also an expert on Liferay integration with Ad Server OpenX, different search engines, enterprise content including videos, audio, images, documents, and web contents, and other technologies, such as BPM Intalio and Business Intelligence Pentaho, LDAP, and SSO. He holds a Ph.D. in Computer Science from the University of Zurich, where he focused on Integrity Control in federated database systems.

He earned his M.S. and B.S. degrees from China, where he conducted research on expert systems for predicting landslides. Previously, he worked as a Project Manager and a Technical Architect in Web GIS (Geographic Information System).
He is experienced in Systems Development Lifecycle (SDLC) and has deep, hands-on skills in J2EE technologies. He developed a BPEL (Business Process Execution Language) engine called BPELPower from scratch at the NASA data center. As the chief architect, Dr. Yuan successfully led and launched several large-scale Liferay/Alfresco e-commerce projects for millions of users each month.

He has worked on the following books: Liferay Portal Enterprise Intranets, 2008; Liferay Portal 5.2 Systems Development, 2009; Liferay Portal 6 Enterprise Intranets, 2010; Liferay User Interface Development, 2010; Liferay Portal Systems Development, 2012.

Books From Packt


Apache Maven 2 Effective Implementations: RAW
Apache Maven 2 Effective Implementations: RAW

Pentaho Reporting 1.0 for Java Developers
Pentaho Reporting 1.0 for Java Developers

Drools JBoss Rules 5.0 Developer's Guide
Drools JBoss Rules 5.0 Developer's Guide

Grails 1.1 Web Application Development
Grails 1.1 Web Application Development

Seam 2.x Web Development
Seam 2.x Web Development

JBoss Drools Business Rules
JBoss Drools Business Rules

JBoss Tools 3 Developers Guide
JBoss Tools 3 Developers Guide

Spring Web Flow 2 Web Development
Spring Web Flow 2 Web Development


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software