AdoptOS

Assistance with Open Source adoption

ECM

Liferay Symposium North America Attendee Spotlight

Liferay - Fri, 06/23/2017 - 15:54

The Liferay Symposium is a gathering for Liferay users, developers, business influencers, community members and thought leaders to stay current on best practices with Liferay and get fresh insights on customer experience and digital transformation. In the spirit of community we’re introducing some of this year’s attendees and highlighting what they look forward to at Liferay Symposium North America.

In recognizing our community, we spoke with Bijan Vakili, a developer and entrepreneur, about his own use of Liferay, how digital transformation has impacted his company and why he’s attending (and keeps attending) Liferay Symposium North America.

Bijan Vakili, Owner, SEEB Group, Inc.

Bijan Vakili, Owner, SEEB Group, Inc.

Why are you attending Liferay Symposium 2017? Have you attended before?

This will be my seventh Symposium. I’m attending to catch up with the Liferay community. And to seek out new win-win relationships.

Why do you keep coming back to Symposium?

Symposium tells me Liferay’s direction, which helps me prepare for new features; it helps me plan. Ultimately, Symposium helps me understand and impact my clients, to make the best promises I can possibly make.

Tell us a little bit about SEEB Group. Does SEEB Group use Liferay?

SEEB Group, Inc. offers SaaS using Liferay. I am the owner of the company. A majority of our end users are building residents and building staff that require the administrative tools of a portal. And yes, internally we use Liferay to share files.

What kind of relationships has Liferay Symposium helped you build?

It's helped me build client relationships from within the real estate industry. Keeping up to date with Liferay’s roadmap helps me get a good pulse of Liferay and then match these features to my clients’ needs.

Are you able to share a little more about your work in the real-estate industry? How does attending Symposium help develop those relationships?

Three years ago we started targeting condominium buildings to create a portal that could optimize management and common tasks. One notable example is how much this improves tracking residents’ packages, from scanning to pick-up. With an interface we can use workflow and data definition language (DDLs) for that.

What changes across the digital landscape over the last decade have had the most impact on your organization? What solutions did this require?

The company's been around just five years. Besides Liferay, mobile has had the most impact. We needed to easily take pictures and upload them into a document library. With minimal staff interaction modern smartphones made this possible.

Are there any trends or tools in new technology that you’re excited about right now?

Kubernetes, Docker, Openshift, CI-CD, DevOps, Kanban, OSGi, Microservices.

XBox One or Nintendo Switch? If yes, what game?

I haven't used either gaming device, though I'm sure I will soon since I have a 2-year-old!

 

Liferay Symposium North America (LSNA) will be held in Austin, TX from October 16–17. For more information, or to register, click here.

William Jameson 2017-06-23T20:54:15Z
Categories: CMS, ECM

Fixing Your Biggest Customer Pain Points

Liferay - Fri, 06/23/2017 - 11:37

This is part two of a two-part blog series. For information on how to discover your company’s unique pain points, including how to create an effective and honest customer journey map, read Finding Your Biggest Customer Pain Points.

Now that you’ve learned how to find your business’ customer pain points, let’s discuss how to solve these issues to satisfy your customers and increase the return on investment for your sales efforts.

Every company’s pain points are unique, even when compared to other businesses in the same industry. However, there are multiple steps that every business can take to eliminate customer pain points, each of which can be tailored to their own current issues.

By applying these tactics to your company's unique customer journey and the types of problems that most often create negative emotions in your customer's experiences with your brand, you can steadily improve satisfaction and loyalty. As discussed by MarketStrategies.com, there are many different areas that companies can focus their time and effort on improving, but businesses should take three factors into account when making decisions:

  1. What changes will drive the greatest improvements?
  2. Which tactical areas are underperforming the most?
  3. What critical pain points will cause the largest improvements in loyalty if fixed?

Pain points often come from a lack of coordination within a business’ operations, leading to confusion and frustrating customer experiences. The following four actions can address some of the most common causes of customer pain points and will frequently meet the criteria listed above, depending on your company. If you are devising a customer pain point strategy, take the following ideas into consideration and reference them against the previously mentioned three criteria in order to create a list of actionable and effective ideas that are right for your business.

1. Eliminate Gaps Between Devices

Common Pain Points Addressed:

  • Needing to Restart Progress in Online Shopping
  • Being Forced to Re-enter Personal Information

Omnichannel experiences are on the minds of digitally-focused companies everywhere, and with good reason. A true omnichannel experience means that a consumer can jump between any device without skipping a beat in order to continue their ongoing and growing interactions with a brand. While omnichannel experiences show your company is on the cutting edge of innovation, they also combat the very real and very much growing lack of customer patience.

More customers than ever expect to transition between their devices without having to re-enter information or search for what they were seeing somewhere else. And they’re also more willing than ever to abandon their journey and look for a competitor that will give them a satisfactory experience.

By seamlessly continuing the experience across devices, customers can remain engaged and, according to Rosetta Consulting research, engaged customers are five times more likely to buy only from the same brand in the future.

2. Break Down Silos Between Departments

Common Pain Points Addressed:

  • Important Customer Information Lost by Companies
  • Unnecessary Additional Steps Needed to Complete a Purchase

Departments are the natural result of companies growing and needing to break down their many different types of work into manageable, successful approaches. However, they also get in the way of intra-company data sharing, which has become an increasingly difficult problem in the era of digital marketing.

During a customer’s journey, he or she will almost certainly move between several departments within a company, such as marketing, sales and customer service. If your company has not properly connected these departments, it is likely that the customer will have to start from scratch each time that he or she changes departments, causing complications, lost time and frustration.

If a piece of marketing has caused a customer to submit their information to your company, then that data should be made available to the sales team in order to understand what the customer is interested in. Once a sale has been completed, data concerning what the customer bought should be accessible by customer service representatives so that they can quickly answer questions and solve problems without the customer needing to re-enter all of their information in order to be helped. Breaking down silo walls within your company can fix customer pain points quickly.

3. Improve Integration Between Social Media and Websites

Common Pain Points Addressed:

  • Inability to Purchase Desired Products Found on Social Media
  • Feeling Ignored by a Company When Voicing Needs Online

Many companies see their social media presences as a separate, supplemental piece of their online world, and not the integrated, useful tool that it should be today. Social media can generate interest in products and foster a community around a business in ways that typical websites cannot. However, when a customer becomes interested in a product through social media and cannot find what they like on your company’s site, social media quickly generates pain points.

In addition, social media is quick to provide customers with a feeling of being known and seen as an individual. Should they shift to your main website or interact with your brand in other ways, only to be set back to square one, the good will generated by social media will quickly be squandered.

Not only that, but social media offers insight into the interests and habits of customers, which can be leveraged to create a better understanding of each person. These insights provide a key component to create a single view of every customer.

4. Create the Right Personalized Experiences to Avoid Irritating Marketing Habits

Common Pain Points Addressed:

  • Receiving Ads for Disliked Products
  • Being Sent Improperly Addressed Communications
  • Long-Term Customers Being Treated as New Ones

There’s nothing quite so off-putting as receiving a piece of marketing material that has clearly been designed to appear personalized, only for a simple mistake to show that you are only one of thousands to have received it. Maybe it’s a missing name in the opening address of an email, or a social media ad presenting a product you just bought. In any case, it can easily make a customer feel completely unseen.

According to AccessDevelopment.com, 57% of consumers they surveyed cited receiving offers for products after submitting a negative review of a related product as being a top reason to stop buying a brand. The message is clear; today’s customers want to feel seen and there are more ways than ever to make them feel unseen by your company.

You will need to take the data you collect from your customers’ online actions and use them to make consistently updated marketing tactics that shift with the audience’s ever-changing needs.

Solving Pain Points with Great Customer Experiences

Creating a pain-free and consistently successful customer experience will play a large role in the continuing success of any company. If you are looking for more ways to digitally empower your business and create great customer experiences, learn more in our helpful whitepaper on effective customer experience strategies.

Read Four Strategies to Transformation Your Customer Experience

Matthew Draper 2017-06-23T16:37:46Z
Categories: CMS, ECM

Disabling LPKG Index Validation

Liferay - Wed, 06/21/2017 - 15:56

Just a quick blog today...

When you start up LR 7 CE/LR DXP, you'll often see it stop while trying to validate LPKGs. This is a security measure which is used to verify that the LPKG files have not been tampered with.

In development, though, this delay is just painful.

Fortunately it can be disabled. Add the following line to portal-ext.properties:

module.framework.properties.lpkg.index.validator.enabled=false

That's all there is to it.

Note that I probably would not do this in my production environments. It is, after all, in there to protect your environment. Disabling it in production removes that small bit of protection and doesn't seem wise.

David H Nebinger 2017-06-21T20:56:29Z
Categories: CMS, ECM

Four Steps to Turn New Customers into Lifelong Patrons

Liferay - Tue, 06/20/2017 - 12:20

Customer loyalty to brands is at an all-time low, with people more willing than ever to leave behind companies in favor of more effective customer service or due to dissatisfaction with their treatment. An Accenture report found that 78 percent of consumers they surveyed are retracting brand loyalty at a faster pace than three years prior.

This means that the idea of a lifelong customer is much more difficult to achieve. While some companies may embrace the idea of customer churn and try to make up for continuous turnover by grabbing as many new clients as possible, the amount of money and time invested into such plans make profit margins increasingly slim. However, according to research from Bain & Company, just a five percent increase in customer retention can lead to profits increasing anywhere from 25 to 95 percent.

While the modern age of business means that lifelong customers are increasingly rare, they are still possible by providing your target audience with what they truly want from companies: to be known and treated as an individual.

The following four steps are crucial for any company seeking to create an effective snapshot of the customer in order to understand and support their interests and needs over the long-term. This is the transition from impersonal marketing and sales to one-on-one customer experiences that allow for consistent tailoring and tweaking.

Consider whether your business has implemented all four of the following steps and take action in the areas you have not yet completed for successful personalized digital marketing strategies.

1. Consolidate Data for a Single Customer View

When you have properly integrated analytics with your company’s digital presence, you will have access to large, robust volumes of data gathered from many interactions with customers. However, companies who do not consolidate their data from various sources keep themselves from creating detailed, unique single customer views. Use the massive amounts of data at your fingertips through digital interactions to create a robust, real profile of who customers really are in order to create personalized digital marketing attuned to their preferences.

According to a Vision Critical study, 42 percent of Americans will stop shopping with a brand after just two bad customer experiences, even if they are part of a company’s loyalty program. It’s clear that the threshold for losing a customer is lower than before and competition is accelerating across industries. However, putting the focus on the individual through a single customer view strategy can not only combat customer churn, but create more positive customer experiences than what was previously possible.

By creating effective, well-rounded and accurate customer profiles, you can have greater success in the three remaining steps.

2. Understand Social Media Sentiment Toward Your Brand

We live in an age where people are expressing their feelings concerning a company in ways where everyone can see them. That may feel intimidating when considering negative reactions, but it's also easier than ever to see when and how a brand should respond to customer reactions. Do not neglect when customers express positive or negative reactions to your company.

In the event that such an occurrence happens, you will be given an opportunity to demonstrate a one-on-one focus in your customer service. This can come in the form of reaching out to dissatisfied customers and helping to solve the needs they have expressed via social media or through a personal expression of gratitude when someone compliments your brand. In doing so, you can demonstrate that you care about their unique needs and are actually listening to their opinions on your company.

In addition, being able to see a person’s actions and interests on social media, which can be accessed when given express permission through apps, will help to further establish their unique identities through a single customer view. Social media will only become a more and more crucial aspect of every company’s online presence, so embracing it and using it to your advantage via personalized digital marketing is for the best in making long-term customer relationships work.

3. Establish a Human Relationship Between Your Customers and Your Brand

Whether it's through in-person interactions or how you communicate online, a human connection is a lasting one, especially in an age where business is becoming increasingly automated and impersonal. Consider where you can implement interactions between customers and your team in your personalized digital marketing strategy in order to increase and maintain emotional connections.

For example, Apple provides both existing and potential customers with one-on-one interactions in their stores through sales representatives and their Genius Bar. Whether customers are looking to learn more about the product they own or are in need of repairs, knowledgeable and friendly Apple employees give them personalized assistance for a more human connection to what could otherwise be seen as an impersonal brand.

Research from Forrester found that a strong emotional connection between a customer and a brand is a stronger driver of loyalty than other factors, such as ease and effectiveness. It’s difficult for anyone to have a true emotional connection to an impersonal, sales-focused brand, so it’s important that you put the humanity back into your customer interactions.

While steps 1 and 2 will give you the data you need to see the individual characteristics of customers, it is vital that you put that data into human hands. Empower your employees with software that lets them better understand the clients they serve, but stay flexible and focused on meeting customer needs.

4. Don't Forget the Post-Purchase Timeline

Most companies will do everything they can to complete a purchase, but will forget their customers once the sale has been completed. By showing your clients that you care about them after the sale through customer support and personalized communication, you establish a relationship outside a direct sale and encourage lifetime connections.

Customers value companies that actively engage with them, as establishing a relationship that is not purely about making a sale will help forge a more personal and trust-based bond. A study from Rosetta Consulting found that highly-engaged customers buy 90 percent more often and spend 60 percent more per transaction than those who are not engaged.

Conversely, according to Accenture research, 81% of U.S. consumers feel loyalty to brands that are there for them when they need them, but respect their time and privacy when they are not needed. This means that there is a fine line that each company needs to walk in order to emphasize their appreciation and understanding of customers without overstepping boundaries and causing people to dislike being contacted.

By utilizing a single customer view, you can better understand when to engage and not engage with your clientele in order to make communications as effective and positive as possible.

Connect with Customers More Effectively

Keeping your customers loyal to your company and continuing to stay in sync for years to come takes consistent effort and the willingness to adapt with changing times. Read about how Ampersand used Liferay to create effective hotel loyalty programs and provide customized products for both employees and customers in order to create greater customer experiences.

Learn How Ampersand Used Liferay to Improve Customer Loyalty

Matthew Draper 2017-06-20T17:20:16Z
Categories: CMS, ECM

Liferay Portal 7.0 CE GA4 Release

Liferay - Mon, 06/19/2017 - 11:45
I am pleased to announce the immediate release of Liferay Portal CE GA4! 
Download Now!

Update: Ext Plugin type will be reintroduced in GA5 due to some missing fixes for Tomcat.  I apologize for the inconvenience. 

Update 2:  Linked to the documentation in the Upgrade section below.

What’s New:
  • WAB Generator Fixes -  Many fixes have been included around the WAB Generator.  The WAB Generator creates a compatibility layer with Liferay 7 when a more traditional WAR file is needed to create a project.  Spring MVC is one example where a fully compliant OSGi module won’t work due to the fact that Spring MVC still requires xml based descriptors for configuring the application.  For more information see: LPS-71435 and LPS-71194
     
  • Upgrade Duplicate Field Names - Previous versions of Liferay Portal allows you to create structures and templates that let you to use multiple fields with the same name.  If you receive the errors highlighted in the following article then you may need to run the script before running your upgrade to Liferay 7. For more details see: 
https://dev.liferay.com/discover/deployment/-/knowledge_base/6-2/upgrading-liferay#find-and-remove-duplicate-field-names
  • Many Fixes - Liferay 7 CE GA4 contains over 2000 fixes from CE GA3.  Many of these improvements were added to help ease migrations and upgrades to Liferay 7.  We hope that this version will help your projects be more successful.    For a complete list of enhancements see the complete fix list.

Known Issues As with any release there a few known issues.  We felt these weren’t show stoppers because they all have documented workarounds or they were only displaying an incorrect message
  • Marketplace requires an update to the plugin to allow signon.  There are two ways to work around this one:
    1. Right-click “Sign-In” and open in a new tab.  Sign into Marketplace normally.  Switch back to the original session and refresh.  The plugin should prompt to auto update.
       
    2. Go to https://web.liferay.com/marketplace/download and download the latest version of the plugin.  Copy the plugin into osgi/marketplace on your installation.  
  • There are some issues with Staging when using Wildfly as your application server.   See LPS-73081 for more details and a workaround for the issue.
     
  • Web Form displays incorrect error message for mandatory fields.  See LPS-72573 for more details.
Source Code The source code for GA4 is provided as a zip on the downloads page and also on our home page on GitHub.   As we indicated on the new community website we are currently looking at ways to improve the contribution process.  Please stay tuned for more details!
  Compatibility Matrix Liferay Portal CE is testing extensively against different Open Source App Server/Database server combinations.    Application Servers: Apache Tomcat 8.0 with Java 8 Wildfly 10.0 with Java 8 Liferay CE Databases:   Database Servers: HSQLDB 2 (only for demonstration, development, and testing) MySQL 5.6 MariaDB 10 PostgreSQL 9.4   Search: ElasticSearch 2.2.2   Documentation The Liferay Documentation Team has been hard at work updating all of the documentation for the new release.  This includes updated (and vastly improved/enlarged) javadoc and related reference documentation, and updated installation and development documentation can be found on the Liferay Developer Network. Our community has been instrumental in identifying the areas of improvement, and we are constantly updating the documentation to fill in any gaps.   Bug Reporting If you believe you have encountered a bug in the new release you can report your issue on issues.liferay.com, selecting the "7.0.0 CE GA4" release as the value for the "Affects Version/s" field.
  Upgrading The upgrade experience for Liferay 7 has been completely revamped  There are some caveats though, so be sure to check out the Upgrading section on the Liferay Developer Network for more details on upgrading to 7.0.
  Getting Support Support for Liferay 7.0 CE is provided by our awesome community.  Please visit our new community website for more details on how you can receive support for Liferay Portal 7.0 CE.   Liferay and its worldwide partner network also provides services, support, training, and consulting around its flagship enterprise offering, Liferay DXP.     Also note that customers on existing releases such as 6.1 and 6.2 continue to be professionally supported, and the documentation, source, and other ancillary data about these releases will remain in place.
  What's Next? As you may have saw we launched a new community site: community.liferay.com this past week.  This is only the beginning and have many other exciting things in the works.  Also work has begun on Liferay 7.1 so stay tuned as we announce more details.
  Kudos A special thanks goes out to our Build, Release and Engineering Teams for all of the hard work and effort they put into making this release a reality.  And thanks to everyone in our community! It is thanks to your constant support that makes each release as great as they are!    Jamie Sammons 2017-06-19T16:45:27Z
Categories: CMS, ECM

Fixing Module Package Access Modifiers

Liferay - Sat, 06/17/2017 - 00:48

If you're a Java Architect or Senior Developer, you know just how important the Java access modifiers are.

Each choice about what to make public, protected, private or package protected is important from an architectural perspective. If you make the wrong choices you can expose too much of your implementation or not enough, you can give subclasses unlimited ability to change internal functionality or little access at all.

If you've ever worked on a library or framework project, either public or a company internal project, you know that these decisions are even more important. With these types of projects, if you make the wrong decision about access modifiers you can end up with irate users or an unused library.

So there exists two different sets of rules, one for app developers and one for lib developers.  App developers are going to use a lot of private to hide stuff and public to expose; they'll define pojos w/ getters but no setters and perhaps a package private constructor to initialize final fields. Methods are typically public or private and protected only comes into play if there are known plans to subclass.

Library developers swing the other way, allowing for every class to potentially be subclassed, extensive use of protected over private, no use of package protected, etc. Basically implementation details will be protected from those using the class yet exposed for subclasses to extend or override.

Rules for lib developers are not hard and fast, some libraries certainly do a better job than others for exposing necessary access points.

I'm sure most of us have been there... Using a class in someone's jar where they declare, for example, a private field with a public getter but no setter, resulting in a class that is difficult to extend and customize. Then we have to break out our Reflection skills to access the field, change the access and update the value. Obviously we don't want to do these things, but we get forced into it because the library developer used application developer rules when defining the access modifiers.

OSGi Access Modifiers

OSGi bundles has its own set of "access modifiers".  We've seen those in the bnd.bnd files, at a package level you can choose to export packages or mark them as private.

Choices you make along these lines affect what you can extend/override in other bundles. If you mark a package as private, the classes are not available to another bundle to leverage and use.

Just like app vs lib developer access modifier rules, there is a similar distinction for OSGi application bundle developer rules and OSGi library bundle developer rules.  For the app bundle developer, packages are exported if they can be used by other modules, otherwise they are private to protect them. For lib bundle developers, you're going to export pretty much every package because you can never know how your library module will be used.

How Liferay Gets This Wrong

Probably my biggest complaint with the Liferay 7 CE / Liferay DXP modules is that I believe the developers were creating modules as though they are app bundle developers when, in fact, they should have been library bundle developers.

For example, the Liferay chat portlet... The Liferay chat portlet does not export a single package; every package in the module is private. As an application portlet bundle developer, this is probably exactly the decision I would make to protect my code, it won't need to be extended or overridden, as the developer if that comes up in the future I can just do it.

But the Liferay developers, they should not have built it this way in my opinion. Me, I may have a need to make some significant changes to the chat portlet, not just for JSP changes but perhaps also some logic. From that point of view, the Liferay chat portlet is a library bundle, a "base" bundle that I want to be able to extend or override. The com.liferay.chat.web.portlet.ChatPortlet is not full Liferay MVC, so all business logic is tied up in that class. If I want to customize the chat portlet, I need to copy the class and make my change and hope that Liferay doesn't update the portlet.

In order to complete my customization, I might need to change a method in the ChatPortlet itself. Sure, with OSGi I can replace the OOTB portlet class with my own, but I really want to be able to do something like:

@Component(...) public class MyChatPortlet extends ChatPortlet {...}

This would allow me to replace the OOTB portlet using a higher service ranking for mine, yet I can keep as much of the original logic as-is without taking over responsibility for maintaining the full class myself.

For another concrete example, take the Liferay Login portlet.  This portlet is full-on Liferay MVC so, if I want to override the create account action, I just need to register an instance of MVCActionCommand with the right mvc.command.name and a higher service ranking. But again, since most of the packages in the Liferay Login portlet are private, I cannot do something like:

@Component(...) public class CustomCreateAcountMVCActionCommand extends CreateAccountMVCActionCommand {...}

If my requirement is just to do some additional work in the addUser() method, I don't want to copy the whole Liferay class just to be able to tweak one method.  What happens when the next release comes out? I'd have to copy the whole class in and release again. At least by extending I only have to worry about keeping in sync the stuff I change, everything else is extended.

Can We Fix It?

As Bob the Builder says, "Yes We Can!", and it turns out it is really, really easy!

Let's say we want to tackle being able to extend Liferay's CreateAccountMVCActionCommand class. Our requirement is that we need to log whenever an account is being created. I know, pretty lame, but the point here is to extend a class which Liferay didn't plan on our extending - once we're over that hump, any additional requirements will be easy to tackle.

So let's get started. The first thing we need is a Fragment bundle. That's right, you read correctly, a Fragment bundle.

blade create -t fragment -h com.liferay.login.web -H 1.0.0 open-liferay-web

That gets us started. We need to open the bnd.bnd file and we're going to be doing two basic things:

  1. Copy in most of the stuff from the original bnd.bnd file. The only change we want to make is with the exported packages, so we want to keep everything else.
  2. Change the exported package line (or add one) to include the packages we want to export, and we'll also change to a version range.

I've gone ahead and done this, and here's what I ended up with:

Bundle-Name: Open Liferay Login Web Bundle-SymbolicName: open.login.web Bundle-Version: 1.1.19 Fragment-Host: com.liferay.login.web;bundle-version="[1.0.0,2.0.0)" Export-Package: com.liferay.login.web.constants,\ com.liferay.login.web.internal.portlet.action Import-Package:\ javax.net.ssl,\ \ * Liferay-Releng-Module-Group-Description: Liferay-Releng-Module-Group-Title:

So you can see that I satisfied #1 above, I've kept the import packages and the Liferay-Releng guys.

For #2, my export package statement was updated so now we're going to be exporting the com.liferay.login.web.internal.portlet.action package. This will allow us to subclass Liferay's action command by making it visible.

I also tweaked the Fragment-Host version. Instead of using a single version, I've changed it to a version range. Why? Because this fragment bundle doesn't care what version is actually deployed, we're just planning on exporting the package regardless of version.

And that's it! See, I said it was easy. You don't really need any other files, you're basically just going to be building and deploying a jar w/ the overriding OSGi manifest information.

Testing

Testing is also kind of easy. We know we want to extend the CreateAccountMVCActionCommand, so we just create a bundle and specify the contents. I did that already, too, and here's what I got:

@Component( property = { "javax.portlet.name=" + LoginPortletKeys.FAST_LOGIN, "javax.portlet.name=" + LoginPortletKeys.LOGIN, "mvc.command.name=/login/create_account", "service.ranking:Integer=100" }, service = MVCActionCommand.class ) public class CustomCreateAccountMVCActionCommand extends CreateAccountMVCActionCommand { @Override protected void addUser(ActionRequest actionRequest, ActionResponse actionResponse) throws Exception { _log.info("About to create a new account."); super.addUser(actionRequest, actionResponse); } @Reference(unbind = "-") protected void setLayoutLocalService( LayoutLocalService layoutLocalService) { super.setLayoutLocalService(layoutLocalService); } @Reference(unbind = "-") protected void setUserLocalService(UserLocalService userLocalService) { super.setUserLocalService(userLocalService); } @Reference(unbind = "-") protected void setUserService(UserService userService) { super.setUserService(userService); } @Reference(unbind = "-") protected void setAuthenticatedSessionManager(AuthenticatedSessionManager sessionMgr) { update("_authenticatedSessionManager", sessionMgr); } @Reference(unbind = "-") protected void setListTypeLocalService(ListTypeLocalService listTypeLocalService) { update("_listTypeLocalService", listTypeLocalService); } @Reference(unbind = "-") protected void setPortal(Portal portal) { update("_portal", portal); } protected void update(final String fieldName, final Object value) { try { Field f = getClass().getSuperclass().getDeclaredField(fieldName); f.setAccessible(true); f.set(this, value); } catch (IllegalAccessException e) { _log.error("Error updating " + fieldName, e); } catch (NoSuchFieldException e) { _log.error("Error updating " + fieldName, e); } } private static final Log _log = LogFactoryUtil.getLog(CustomCreateAccountMVCActionCommand.class); }

Oh, crap. What is all of this junk?

Well, first let's get the necessary stuff out of the way. Our @Component reference has the necessary properties and service ranking so OSGi will use our action command class, which we are now extending Liferay's CreateAccountMVCActionCommand. We also have the overriding addUser() method to log when we are about to create an account, so we have satisfied our requirement.

The rest of the class, well that is necessary to inject the right OSGi references into the super class that it expects. Some of these are easy, such as the layout service and the two user services. The others are hard, the authenticated session manager, list type service and the portal instance.

Remember I started this blog saying that the rules for a library developer are different than an app developer, and when you have a bad library class you're left to using Reflection to update a super class? Yep, here's an example. Now, I can't really fault Liferay here for this because they created the module as though they were an app module developer, so the fact that they used app developer rules here is no surprise. Fortunately though I could use Reflection to get to the super field and update it appropriately.

Conclusion

So, when we build and deploy these two modules and create a new account, we find we have been successful:

13:30:31,360 INFO [http-nio-8080-exec-6][CustomCreateAccountMVCActionCommand:39] About to create a new account.

Through a simple (really simple) fragment bundle we were able to export a package that Liferay did not export. From there, we can extend classes from that package to introduce our own modifications without having to copy everything from the original.

It's important to note the hurdles we had to bypass for the OSGi stuff, especially the Reflection usage to update the super class.

If you're going to go down this path, you will be doing things like this. There's no way around it, not all @Reference usage in Liferay classes are tied to methods; when they are, great, but when they're not you'll have to peel them open yourself.

Hope this helps you on your Liferay 7 CE / Liferay DXP developer journey!

 

David H Nebinger 2017-06-17T05:48:17Z
Categories: CMS, ECM

REST Custom Context Providers

Liferay - Fri, 06/16/2017 - 20:51

So a question came up today how to access the current user as part of a REST method body.

My friend, Andre Fabbro, was trying to build out the following application:

@ApplicationPath("/myapp") @Component(immediate = true, service = Application.class) public class MyApplication extends Application { @GET @Path("/whoami") @Produces(MediaType.APPLICATION_JSON) public String getUserFullName() { User user = ????; return user.getFullName(); } }

He was stuck trying to get the current user in order to finish the whoami handler.

So, being a long-time Liferay guy, I fell back on what I knew, and I pointed him towards the PrincipalThreadLocal and the getName() method to get the current user id.  Of course ThreadLocals kind of smell, they're almost like global variables, but I knew it would work.

My other friend, Rafael Oliveira, showed us both up and introduced me to the new concept of a custom context provider. You see, he knew that sometime soon a new module, com.liferay.portal.workflow.rest was coming and it was going to bring with it a new class, com.liferay.portal.workflow.rest.internal.context.provider.UserContextProvider. He did us one better by providing an implementation of Andre's app using @Context and the new UserContextProvider:

import javax.ws.rs.core.Context; @ApplicationPath("/myapp") @Component(immediate = true, service = Application.class) public class MyApplication extends Application { @GET @Path("/whoami") @Produces(MediaType.APPLICATION_JSON) public String getUserFullName(@Context User user) { return user.getFullName(); } }

I was kind of blown away having learned something completely new with DXP and I needed to know more.

Before going on, though, all credit for this blog post goes to Rafael, all I'm doing here is putting it to electronic paper for us all to use for Liferay REST application implementations.

Basic @Context Usage

So when you create a new module using "blade create -t rest myapp", BLADE is starting a new JAX-RS-based RESTful application that you can build and deploy as an OSGi module. Using JAX-RS standard conventions, you can build out your RESTful methods using common annotations and (hopefully) best practices.

JAX-RS actually provides the javax.ws.rs.core.Context annotation and is used to inject common servlet-based values. Using @Context, you can define a method parameter that is not part of the RESTful call but are injected by the JAX-RS framework, kind of like the automagic ServiceContext injection in ServiceBuilder remote services.

Out of the box, JAX-RS Context annotation supports injecting the following parameters in methods:

Type Description javax.ws.rs.core.Application Provides access to metadata information on the JAX-RS application. javax.ws.rs.core.UriInfo Provides access to application and request URI information. javax.ws.rs.core.Request Provides access to the request used for the method. javax.ws.rs.core.HttpHeaders Provides access to the HTTP header information for the request. javax.ws.rs.core.SecurityContext Provides access to the security-related information for the request. javax.ws.rs.ext.Providers Provides runtime lookup of provider instances.

To use these, you just add appropriately decorated parameters to the REST method. If necessary, we could easily add a method to the application above such as:

@GET @Path("/neato") @Produces(MediaType.APPLICATION_JSON) public String getStuff(@Context Application app, @Context UriInfo uriInfo, @Context Request request, @Context HttpHeaders httpHeaders, @Context SecurityContext securityContext, @Context Providers providers) { .... }

The above getStuff() method will be handling all requests to the /neato path, but all of the parameters are injected, none are provided in the URL or as parameters; they are injected automagically by JAX-RS.

Custom @Context Usage

So these types are really nice, but they really don't do anything for our Liferay integration. What would be really cool is if we could use @Context to inject some Liferay parameters.

And we can! As Rafael pointed out, there is a new module in the pipeline for workflow to invoke RESTful methods on the backend. The new module is the portal-workflow-rest project. I'm not sure, but I believe this is going to be part of the upcoming GA4 release, but don't hold me to that.

Once available, this project will provide three new types that can be injected into RESTful method parameters:

Type Description com.liferay.portal.kernel.model.Company The Liferay Company associated with the request. java.util.Locale The locale associated with the request. com.liferay.portal.kernel.model.User The Liferay User associated with the request.

So, like the out of the box parameters, we could extend our getStuff() method with these parameters too:

@GET @Path("/neato") @Produces(MediaType.APPLICATION_JSON) public String getStuff(@Context Application app, @Context UriInfo uriInfo, @Context Request request, @Context HttpHeaders httpHeaders, @Context SecurityContext securityContext, @Context Providers providers, @Context Company company, @Context Locale locale, @Context User user) { .... }

Just pick from all of these different available types to get the data you need and run with it.

Remember these will not be available in GA3 nor in DXP just yet - I'm sure they'll make it in soon, but I'm not aware of the schedule for either product lines. Writing Custom Context Providers

So to me, the biggest value of this new module is this package: https://github.com/liferay/liferay-portal/tree/master/modules/apps/forms-and-workflow/portal-workflow/portal-workflow-rest/src/main/java/com/liferay/portal/workflow/rest/internal/context/provider

Why? Because they expose how we can write our own custom context provider implementations so we can inject custom parameters into REST methods.

Say, for example, that we want to inject a ServiceContext instance. I'm not sure if the portal source already has one of these fellas, but if so let's pretend it doesn't exist and we want to write our own. Where are we going to start?

So first you need a project, we'll create a blade workspace:

blade init custom-context-provider

We also need a new module to develop, so we'll change to the custom-context-provider/modules directory to create an initial module:

blade create -t api -p com.dnebinger.rest.internal.context.provider service-context-context-provider

This will give us a nearly empty API module. We'll end up cleaning out most of the generated files, but we will end up with the com.dnebinger.rest.internal.context.provider.ServiceContextContextProvider class:

package com.dnebinger.rest.internal.context.provider; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.service.ServiceContextFactory; import org.apache.cxf.jaxrs.ext.ContextProvider; import org.apache.cxf.message.Message; import org.osgi.service.component.annotations.Component; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.ext.Provider; /** * class ServiceContextContentProvider: A custom context provider for ServiceContext instantiation. * * @author dnebinger */ @Component(immediate = true, service = ServiceContextContentProvider.class) @Provider public class ServiceContextContentProvider implements ContextProvider { /** * Creates the context instance * * @param message the current message * @return the context */ @Override public ServiceContext createContext(Message message) { ServiceContext serviceContext = null; // get the current HttpServletRequest for building the service context instance. HttpServletRequest request = (HttpServletRequest) message.getContextualProperty(PROPKEY_HTTP_REQUEST); try { // now we can create a service context serviceContext = ServiceContextFactory.getInstance(request); // done! } catch (PortalException e) { _log.warn("Failed creating service context: " + e.getMessage(), e); } // return the new instance. return serviceContext; } private static final String PROPKEY_HTTP_REQUEST = "HTTP.REQUEST"; private static final Log _log = LogFactoryUtil.getLog(ServiceContextContentProvider.class); }

So this is pretty much the whole module. Easy, huh?

Conclusion

Now that we can create custom context providers, we can use this one for example in the original code:

@ApplicationPath("/myapp") @Component(immediate = true, service = Application.class) public class MyApplication extends Application { @GET @Path("/whoami") @Produces(MediaType.APPLICATION_JSON) public String getUserFullName(@Context ServiceContext serviceContext) { User user = _userLocalService.fetchUser(serviceContext.getUserId()); return user.getFullName(); } @Reference private UserLocalService _userLocalService; }

These custom context providers become the key for being able to create and inject non-REST parameters into your REST methods.

Check out the code from GitHub: https://github.com/dnebing/custom-context-provider

Enjoy!

David H Nebinger 2017-06-17T01:51:27Z
Categories: CMS, ECM

Liferay7 theme creation using Eclipse IDE & Gradle as build tool

Liferay - Fri, 06/16/2017 - 06:31

Installations: 

Need to download and install the following for a workspace :

  • Eclipse Neon with IDE - 3.1.0
  • Liferay Plugins ce sdk 7.0- ga3
  • Liferay Portal ce 7.0-ga3(tomcat)

Now configure workspace and start the server.

Creating Liferay 7 Theme using Gradle :

To create a theme

Go to File  > New > Liferay Module project and give a project name and select Gradle as build type and select theme for Project Template Name and click on Finish. (Refer attached screenshot below)

                 

 So now a Theme is created as Liferay7(Project name as given).

Once the theme is created, the structure is as follows :

                

 

Now Gradle needs to be added to eclipse for bulding the theme.

Go to Eclipse menu bar Window > show view nad search for Gradle, form Gradle select Gradle tasks and gradle executions and click ok. Refer screen shot attached.

                 

 

Build Theme :

To build a theme Go to Gradle Tasks tab and doublick on buildTheme. If your theme is built successfully, a success message is shown in console. Refer Screenshot below

                

 

Go to the created theme and refresh it, build folder gets created with all the folders & files (css, images, js & templates). For folder structure refer below screen shot

                       

 

Now from Gradle Tasks double click on build, this will download all the dependencies needed.

Screenshot attached.

                             

 

Once you build the theme, folders like libs, resources and tmp gets created inside build folder.

                  

 

For any customizations replicate the folder structure as in buildTheme to src > main > webapp.

For css changes the pre-existing _custom.scss file can be used.

For a simple check i am changing the background-color of the wrapper.

After adding the changes, Go to Gradle Tasks and first do buildCss and then build.

A war file will be created in liferay7 > build > libs

                    

 

This war file file can be deployed either by dropping to deploy folder in liferay-ce-portal-7.0-ga3 or from portal, Go to control panel > Apps > App Manager

In App Manager click on the options from the right top corner and upload the file and install. Screen shot attached for reference.

                    

 

 

 

Theme is now deployed. To check Go to Navigation > Public Pages > Configure

                             

 

 

Now Go to Change current theme and the deployed theme will be visible in available themes popup

 

                                     

 

Select the theme and save it. Changes done to the theme are reflected.

Here i have changed the background-color of wrapper to dark grey, See the attached screen shot

 

                              

 

 

gulnaaz Shaik 2017-06-16T11:31:56Z
Categories: CMS, ECM

Resolving Missing Components

Liferay - Thu, 06/15/2017 - 22:05

So if you've started developing for Liferay 7 CE / Liferay DXP, I'm sure you've been hit at one point or another with the old "unresolved reference" issue that prevents your bundle from starting.

You would have seen it by now, the Gogo shell where you list the beans and find your bean there stuck in the Installed state. You try starting it and Gogo tells you about the unresolved reference you have and you're stuck going back to your bnd.bnd file to resolve the dependency issue.

This is so common, in fact, that I wrote a blog post to help resolve them: https://web.liferay.com/web/user.26526/blog/-/blogs/osgi-module-dependencies

While this will be your issue more often than not, there's another form of "unsatisfied reference" problem that leads to missing components rather than non-started bundles.

The Case of the Missing Component

You can have a case where your module starts but your component is not available. This sounds kind of strange, right? You've taken the time to resolve all of those 3rd party dependency jars, the direct and transitive ones, and your bean starts cleanly and there are no errors.

But your component is just not available. It seems to defy logic.

So, here's the skinny... Any time your component has an @Reference with default binding, you are basically telling OSGi that your component just has to have the reference injected or else it cannot be used.

That's where this comes from - you basically have an unsatisfied reference to some object that was supposed to be @Reference injected but could not be found; since the reference is missing, your component cannot start and it is therefore not available.

There's actually a bunch of different ways that this scenario can happen:

  • The @Reference refers to an object from another module that was not deployed or has not started (perhaps because of normal unresolved references). This is quite common if you deploy your Service Builder API module but forget to deploy the service module.
  • You have built in circular references (more below).
  • You use a target filter for the @Reference that is too narrow or incorrect, such that suitable candidates cannot be used.

In all of these cases you'll be stuck with a clean component, just one that cannot activate because of unsatisfied references.

Sewing (@Reference) Circles

Reference circles are real pains to resolve but they rise out of your own code. Understanding reference circles is probably best started through an example.

Let's say we are building a school planning system. We focus on two major classes, a ClassroomManager and an InstructorManager. The ClassroomManager has visibility on all classrooms and is aware of the schedule and availability. The InstructorManager has the instructor roll and is aware of their schedule and availability.

It would be quite natural for a ClassroomManager to use an InstructorManager to perhaps find an available instructor to substitute in a class. Likewise it would be natural for an InstructorManager to need a ClassroomManager to try to reschedule a class to another time in an available room.

So you might find yourself creating the following classes:

@Component public class ClassroomManager { @Reference private InstructorManager instructorManager; } @Component public class InstructorManager { @Reference private ClassroomManager classroomManager; }

If you look at this code, it seems quite logical.  Each class has a need for another component, so it has been @Reference injected. Should be fine, right?

Well actually this code has a problem - there's a circular reference.

When OSGi is processing the ClassroomManager class, it knows that the class cannot activate unless there's an available, activated InstructorManager instance to inject. Which there isn't yet, so this class cannot activate.

When OSGi is processing the InstructorManager class, it knows that the class cannot activate unless there's an available, activated ClassroomManager instance to inject. Which there isn't yet, so this class cannot activate.

But wait, you say, we just did the ClassroomManager, we should be fine! We're stuck, though, because the ClassroomManager could not activate because of the unsatisfied reference.

This is your reference circle - neither component can start because they are circularly dependent upon each other.

Resolving Component Unsatisfied References

Resolution is not going to be the same for every unsatisfied component reference.

If the problem is an undeployed module, resolving is as simple as deploying the missing module.

If the problem is an unstarted module, resolving is a matter of starting the module (perhaps fixing whatever problem that might be preventing it from starting in the first place).

For a reference target filter issue, well those are going to be challenging. You'll have to figure out if the target is not right or too narrow and make appropriate adjustments.

The circular reference resolutions can be resolved by refactoring code - instead of big ClassroomManager and InstructorManager classes, perhaps use a bunch of smaller classes that don't result in similar reference circles.

Another option is to use different ReferenceCardinality, ReferencePolicy and ReferencePolicyOption values (see my blog post on annotations, specifically the section on the @Reference annotation). You could switch both from MANDITORY to OPTIONAL ReferenceCardinalities, DYNAMIC for the ReferencePolicy, ...  The right set is usually mandated by what the code can handle and requires, but the outcome would allow the components to activate without the initial references being satisfied, but once activated the references will be post-injected.

How Do You Fix What You Can't Find?

This, for me, has been kind of a challenge. Of course the answer lies within one of the Gogo shell commands, but I've always found it hard to separate the wheat (the components with unsatisfied references) from the chaff (the full output with all component status details from the bundle).

For me, I've found it easiest to use TripWire CE or TripWire DXP. After going to the TripWire panel in the control panel, click on the Take Snapshot card and you can actually drill into and view all unsatisfied references.  The following screen capture is an actual view I used to resolve an unsatisfied reference issue:

The issue I was looking at was the first unsatisfied reference line for my com.liferay.metrics.health.portal.layouts.LayoutHealthCheck component. It just wouldn't activate and I didn't know why; I knew it wasn't available, it wasn't doing its thing, but the module was successfully started so what could the problem be?

Well the value for the key spells it out - I have two unsatisfied references for two different gauge instances. And you know what? it is totally true. Those two missing references happen to be the 2nd and 3rd lines in the list above, and they in turn had unsatisfied references that needed to be resolved, ...

Conclusion

The point here is that in order to resolve unsatisfied references, you need to be able to identify them. Once you can identify the problem, you can resolve them and move on.

For me, I've found it easiest to use TripWire CE or TripWire DXP to identify the unsatisfied references, it does so quickly, easily, and doesn't require memorizing Gogo shell commands to get it done.

 

David H Nebinger 2017-06-16T03:05:39Z
Categories: CMS, ECM

What’s next for the Liferay Community?

Liferay - Thu, 06/15/2017 - 18:49
Today I’m writing to announce several new and exciting initiatives within the Liferay Community.  We consider this to be the starting point for a completely revamped community experience. We also have other changes in the works and can’t wait to share the details of what we have been working on. Read on for more details and let us know what you think.   Advocates Our first initiative is to create a new team of Developer Advocates to reassure our commitment with the community. Their mission is to inspire, educate, assist and encourage our community to build amazing applications using Liferay open source technology. We believe it’s important to have a dedicated group of people that can listen to you and take action.
  This doesn’t mean that they are now the only ones responsible for the community. For us to have a healthy and vibrant ecosystem, we need everybody to have a sense of ownership, we need everybody to care. But the Advocates will make sure the “wheels are greased” to keep things in the community moving forward.    Read more about the Liferay Developer Relations team   New Home We want to revamp the overall community experience and we’re starting it by announcing a completely new site for the community!     The old Community Home page was primarily focused on Liferay Portal, but Liferay has now grown to support several open source projects (and communities), like Sennajs, Metal, and Electric. Our new Community Home will help you discover new Liferay open source projects, stay connected to important announcements, and get in touch with other community members. This a new beginning with huge potential to grow.   Read more about the new Liferay Community site   Chat Today, there are pretty much two main channels that community members use to communicate. Technical questions are often asked on the Forums. Stories and tutorials are often written on the Blogs.   Those places are great and serve their purposes really well, but we kind of miss a more instant channel. Because of that, we’re introducing a new chat that will allow people to communicate in a quick and direct way.     Chat will foster ongoing conversations among community members, help us feel closer together, and let you answer quick questions for each other.   Read more about the new chat room   Forums Our forums have always been a good place for people to ask questions and get answers. As of today, we’ve seen more than 363,100 posts from 33,296 different participants over there.   Although those numbers can show how vibrant this community is, we know we can do better, especially when it comes to the number of unanswered questions.     In order to identify opportunities and drive more engagement on our forums, we signed a contract with Network Activator. Their tool allow us to list experts in each area and automatically assign questions to them.   Before Network Activator we had an average of 30 unanswered questions/week. After, we had an average of 10-15 unanswered questions/week. This 67% reduction is great, but need to decrease it even more.   We’re even thinking about how to identify experts in the community so you can help us answer questions, too. Your participation is crucial for this to work. Keep asking, keep answering!   Bug Reporting As you may know, many of our projects use Jira for issue tracking. Recently, we upgraded our self-hosted Jira instance from 6.4.10 to 7.3.3. It may not sound very interesting, but this update comes with several improvements that will be useful for bug reporters, including a better experience for editing issue descriptions.   We have also created a new Community Dashboard that will summarize how we are doing responding to Community bug reports.     Besides that, our product management team has grown in the last year. That means more people resposible to filter what is being reported and taking action. They are identifying bugs reported by the community and prioritizing them. Last week, for example, 13 bugs were reported by community members, and now only 5 of them remain open.   Code Contributions Modularity has been a very important topic to us for many reasons. By splitting our code into small pieces we think there's a lot of potential for increasing open source participation in Liferay by lowering the barrier to entry for new contributors.   As a result of that work, you can now see 97 public repositories that were extracted from Liferay Portal Community Edition.   In addition, we’re currently evaluating the contribution process for all our open source projects. We've already identified opportunities for improvements, from documenting core development to signing the contributor's agreement, and we'll announce these changes in the near future.   User Groups One of the most exciting parts of belonging to a community is meeting other members in person. In fact, we believe that personal contact is the richest experience, not matched by any media or technology. That's why we like user groups so much.     Today, there are more than 44 Liferay user groups in 32 different countries, but not all of them are active.   In the next couple weeks, we’ll reach out to organizers to see how we can help their groups to be up and running. If they can’t find places to meet, we could help. If they can’t find speakers, we could help. If there’s anything that you need as a user group organizer or if you want to become one, please let us know.   Conferences Worldwide Liferay conferences are a great way to network with other community members from all around the globe. They also provide an excellent way to meet with Liferay engineers and experts face to face to ask questions and provide direct feedback on your projects.     This year we’re continuing with our three core conference formats: LDSF is primarily for business or “digital transformation” audiences, DevCon is deeply technical, and Symposium is a healthy mix of both.   All conferences are an excellent opportunity to learn about upcoming new features and to learn best practices to help your projects be successful. We’ll be in 11 different countries this year so I hope to see you there!   Special Activities In the past we launched several special activities like BugSquad, Liferay Ideas, Community Expedition, Top Contributors, Community Pulse Awards, Official User Groups, and Community Verifiers.   Those initiatives helped with engagement and provided some clear guidelines for participating within the Liferay community.     We’ll be reviving some of these programs, which were crucial in improving product quality, building relationships, and recognizing and rewarding our community's talent.   Clustering On a very pragmatic note, we are working on a new clustering module for Liferay Portal Community Edition. After speaking with many of you throughout the last 14 months, we came to the conclusion that we can find a way to meet the clustering needs of the community and still address the issues that originally led to our decision to ship Liferay Portal Community Edition without clustering. Please stay tuned for more details regarding this!
  Conclusion We’ll continue to do our best to understand your needs, see how the market responds, and make adjustments as necessary. We are taking seriously our commitment to invest our success back in our community, and excited to do much more. Bryan Cheung 2017-06-15T23:49:11Z
Categories: CMS, ECM

A New Way To Connect With The Liferay Community

Liferay - Wed, 06/14/2017 - 14:23
Originally Published on the Liferay Community site   We have exciting news about a brand new way you can connect with others in the Liferay Community.   Right now, you have two platforms to share your thoughts and get your questions answered by other community members.
  • Blogs: A great place for sharing stories and writing extensive technical posts or findings.
     
  • Forums:The ideal place for asking questions to the community about Liferay technology.

But today, we are excited to announce a new communication channel.

  • Chat:This platform will provide a perfect environment for ongoing conversations and quick questions or insights.

Slack is the solution we chose for our chat platform

We are thrilled about this new medium but even more excited to see how this community develops and grows with it. Our hope as the Developer Relations Team is to be mere facilitators and let you all drive the conversation and shape this communication channel.   Your Space

Here's how we are envisioning this new tool to operate.

Channels for each project

There are many projects projects under the Liferay umbrella and we wanted to give a designated space for those interested in each specific one. That's why we created a channel for each Liferay project.

Channels for each user group

We also realize that we have a global community, and so we wanted to give you areas for your user groups so you can chat in your own language and even coordinate meetups!

A sneak peak of the new chatroom

So what are you waiting for? Join our Slack Channel

 

 

Jamie Sammons 2017-06-14T19:23:28Z
Categories: CMS, ECM

Announcing the new Liferay Community site

Liferay - Wed, 06/14/2017 - 13:11

Originally published on Liferay Community site

Today we're announcing a new place for the Liferay Community! This is something we've been waiting for a long time and we're super excited to finally show it to you.

"Wait, what? Yet another website?"

Uhh ... well ... yes! But it all makes perfect sense! Please, let me explain.

The evolution of liferay.com

Few years ago when Liferay was a single-product-company, it was natural that the main website was about the product! There was no clear distinction between technical and business audience. This seemed to be a good idea at the time and worked quite well. But as they say, if something is for everyone it's not good enough for anyone.

 

As Liferay grew from product vendor to a company that builds software to solve more and more complicated business problems, the website also changed to address those goals. Today it perfectly responds to our business audience's needs. Unfortunately this also means technical folks feel somewhat abandoned.

dev.liferay.com to the rescue!

Liferay Developer Network was developed to serve as new home for technical audience. It was designed to be a one stop shop for everything related to Liferay Portal - from basic information, through community guides, documentation and sample code, to tools and Marketplace plugins! The feedback after it was launched was more than optimistic and pretty much all Liferay developers and users I've talked to, said LDN is great!

The only issue is - it focuses on a single product and therefore does not show you the big picture! Today Liferay provides a number of open source projects, which can be used independently or together. Meanwhile LDN only focuses on the portal platform!

One site to rule them all - community.liferay.com!

With about 12 or so (at the time of writing) independently developed open source projects, each of which has its own website, it becomes a challenge to keep things in sync. While we want to allow project teams evolve their web presence in any way they find to fit best, we also need to serve well our vibrant and diverse community! This is how the Liferay Community website was born!

So what is it and what it will be in the future?

With Liferay's main website focusing on business goals and LDN being focused on a single product, we needed a place where developers like you will feel right at home! So we have laid the foundations of what we hope to quickly become a modern, cozy and functional space, where developers get to know better the whole family of Liferay projects!

At the time of writing this, the website is in what we consider phase 0 - a new beginning with huge potential to grow quickly! It features the most significant projects and publishes relevant news (one of which you are reading right now). It's very much a one way communication channel, but it won't stay that way for long! We plan to make it a lot more dynamic and interactive but we need your help!

This website is meant to best serve you so let us know what do you like and what you don't like! Share your ideas, concerns and expectations! Report bugs, typos, rendering issues! Feel free to reach us at developer-relations@liferay.com anytime.

We really hope, together we can make this place an awesome home for all of us!

Milen Dyankov 2017-06-14T18:11:11Z
Categories: CMS, ECM

Introducing the Liferay Developer Relations team

Liferay - Wed, 06/14/2017 - 12:56
Originally published on Liferay Community

Liferay evolved from being a single-product company to a much broader organization. Most of the code we write every day is open source and we continue to launch new projects.

As these projects are getting bigger, the communities behind them are gaining momentum as well. Therefore, we needed people that would not only hear, but would also execute in favor of community interests.

That's why we created the Liferay Developer Relations team.

What is our goal?

Our primary focus is to make sure Liferay technologies bring more and more value to developers while fitting nicely in their toolsets. Our mission is to inspire, educate, assist and encourage our community to build the next generation of amazing applications. Our job is to help you be successful!

This means understanding what you're trying to do, learning about your developer experiences and listening to all the feedback you provide! Developer Relations team is here to help you bring ideas and concerns to our engineers, so you can help us improve all these projects for everybody.

Who are the members? We came up with a multi-cultural team made of well recognized faces in the Liferay community. We have people from different countries, backgrounds, and skills. The main thing we have in common is that we want to help the community succeed.   Keep in mind - we are not "in charge" of the community. For us to have a healthy and vibrant ecosystem, we need everybody to feel responsible for it. We are simply advocates.   Jamie Sammons Before joining Liferay, Jamie was an active member of the Liferay community, trying out different products, reporting bugs, and participating on special activities.   Because of that, he comes with a good understanding of how we can improve the community in a way that positively and uniquely resonates with them.   Today he fosters community activities, engages with new contributors, and spreads the word about Liferay Portal features. Jonathan Lundy

From wedding photographer to developer, Jonni decided to give his career path a 180 when he joined Liferay last year and started working on the WeDeploy team.   Since then he has fallen in love with web development, and now devotes his time to promoting, sharing, and contributing to Liferay technologies.   He brings a fresh blood to the team and a different perspective to the onboarding journey. Milen Dyankov

Milen used to spent most of his time working as a senior consultant and trainer at Liferay.   This role that allowed him to learn a lot while helping some of the biggest European companies engage with their customers, partners, and employees in this rapidly changing digital world.   Now he's traveling the world talking about Java and modularity related aspects, sharing his experience with fellow developers, and collecting important feedback from users. Zeno Rocha

After working as a front-end engineer for some of the top companies in Brazil, Zeno decided to join Liferay to help our projects on a global scale.   He's been a very active open source developer, building libraries that are widely used around the world and giving over a hundred talks in the last five years. He's also passionate about inspiring other developers and getting them out of the comfort zone.   Today he dedicates most of his time building WeDeploy and improving the developer experience of the whole Liferay ecosystem. What about you? We hope this article gives you an idea of how this team can help the community. But the truth is - it's not about us, it's about you!   Is there anything you're struggling with? Do you have ideas on how to make our community even more awesome? We would love to hear how can we help you.   Feel free to reach us out at developer-relations@liferay.com. Zeno Rocha 2017-06-14T17:56:35Z
Categories: CMS, ECM

Damascus, a scaffolding service builder portlet with CRUD + Search, Workflow and more functionalities for Liferay DXP / 7.0

Liferay - Tue, 06/13/2017 - 00:09
What's Damascus? Damascus generates scaffoldings of *-service, *-api and *-web bundles with CRUD functionality and integrating other Liferay related functionality based on a configuration, base.json.   Code https://github.com/yasuflatland-lf/damascus   Wiki https://github.com/yasuflatland-lf/damascus/wiki/1.-Getting-Started   Motivation Looking at other frameworks such as Ruby on rails, CakePHP, e.g, they all have CRUD scaffolding functionality for a quick start. Those scaffoldings also help to understand how the framework works and save developers time to figure out basics if you know the framework well.    While working with partners and other vendors for projects in Japan for past 5 years, I've seen developers struggled to implement custom portlets on Liferay platform, say how to use assets, permissions, workflow or search, e.g. Because Liferay is much more powerful than other frameworks. In other words, Liferay is more complicated software than others.   Even for those who already know the basics of Liferay framework, there are repetitive implementations, like basic CRUD functionality.   Damascus aims for resolving that pain points.   Any feedbacks or contributions are always welcome!   Yasuyuki Takeo 2017-06-13T05:09:26Z
Categories: CMS, ECM

Securing The /api/jsonws UI

Liferay - Mon, 06/12/2017 - 23:19

The one thing I never understood was why the UI behind the /api/jsonws is publicly viewable.

I mean, there's lots of arguments for it to be secured:

  • Exposing all of your web service APIs exposes attack vectors to hackers. Security by obscurity is often one of the best and easiest form of security that you can have1.
  • Just because users may have permission to do something, that doesn't mean you want them to. They might not be able to get to a portlet to delete some web content or document, but if they can get to /api/jsonws and know anything about Liferay web services and parameters, they might have fun trying to do it.
  • It really isn't something that non-developers should ever be looking at.

I'm sorry, but I've tried really hard and I can't think of a single use case where making the UI publicly available is a good thing. I guess there might be one, but at this point it seems like it should just be an edge case and not a primary design requirement.

A client recently asked about how to secure the UI, and although I had wondered why it wasn't secured, I decided it was time for me to figure out how to do it.

The UI Implementation

It was actually a heck of a lot easier than what I thought it was going to be.

I had in my head some sort of complicated machinery that was aware of all locally deployed remote services and perhaps was leveraging reflection and stuff to expose methods and parameters and ...

But it wasn't that complicated at all.

The UI is implemented as a basic JSP-based servlet. Whether in Liferay 6.2 or Liferay 7 CE or Liferay DXP, there are core JSPs in /html/portal/api/jsonws that implement the complete UI servlet code.

For incoming remote web service calls, the portal will look at the request URI - if it is targeting a specific remote service, the request is handed off to the service for handling. However, if it is just /api/jsonws, the portal passes the request to the /html/portal/api/jsonws/index.jsp page for presentation.

Securing the UI

All I'm going to do is tweak the JSP to make sure the current user is an OmniAdmin if they get to see the UI. Nothing fancy, I admit, but it gets the job done. If you have more complicated requirements, you're free to use this blog as a guide but you're on your own for implementing them.

My JSP change is basically going to be wrapping the content area to require OmniAdmin to view the content, otherwise you will see a permission failure. Here's what I came up with:

<div id="content"> <%-- Wrap content in a permission check --%> <c:if test="<%= permissionChecker.isOmniadmin() %>"> <div id="main-content"> <aui:row> <aui:col cssClass="lfr-api-navigation" width="<%= 30 %>"> <liferay-util:include page="/html/portal/api/jsonws/actions.jsp" /> </aui:col> <aui:col cssClass="lfr-api-details" width="<%= 70 %>"> <liferay-util:include page="/html/portal/api/jsonws/action.jsp" /> </aui:col> </aui:row> </div> </c:if> <c:if test="<%= !permissionChecker.isOmniadmin() %>"> <liferay-ui:message key="you-do-not-have-permission-to-view-this-page" /> </c:if> </div>

This code I took mostly from the DXP version of the file, so use the file from the version of Liferay you have so you don't introduce some sort of source issue. I've highlighted the real code that I added so you can work it into your override.

Creating the Project

So regardless of version, we're going to be doing a JSP hook, they just get implemented a little differently.

For Liferay 6.2, it is just a JSP hook. Build a JSP hook and pull in the original /html/portal/api/jsonws/index.jsp file and edit in the change outlined above. I'm not going to get into details for building a 6.2 JSP hook, those have been rehashed a number of times now, so there's no reason for me to rehash it again. Just build your JSP hook and deploy it and you should be fine.

For Liferay 7 CE, well let me just say that what I'm about to cover for DXP is how you will be doing it once GA4 is released.  Until then, the path I'm using below won't be available to you.

For Liferay DXP (and CE GA4+), we'll follow the instructions from https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/overriding-core-jsps to override the core JSPs using an OSGi module.

So first I created a new workspace using the command "blade init api-jsonws-override".

Then I entered the api-jsonws-override/modules directory and created my new module using the command "blade create -t service -p com.liferay.portal.jsonwebservice.override api-jsonws-override".

I don't like building code myself, so the first thing I did was add a dependency to a module which has a base implementation of the CustomJspBag in my build.gradle file:

dependencies { compileOnly group: "com.liferay.portal", name: "com.liferay.portal.impl", version: "2.0.0" compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.6.0" compileOnly group: "com.liferay", name: "com.liferay.portal.custom.jsp.bag", version: "1.0.0" compileOnly group: "org.osgi", name: "org.osgi.core", version: "5.0.0" compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations", version: "1.3.0" }

It's actually that com.liferay.portal.custom.jsp.bag guy which makes my project not work for Liferay 7 CE, it's not available in GA3 but I expect it to be released with GA4. If you don't want to wait for GA4, you can of course not extend the BaseCustomJspBag class like I'm about to and can build out the complete CustomJspBag interface in your class.

NOTE: I really, really dislike the fact that I have to pull in the com.liferay.portal.impl dependency above. I have to do that because for some reason the CustomJspBag interface is only in the portal-impl project and not portal-kernel as we would normally expect. Do not import this dependency yourself unless you are really, really, really sure that you gotta have it. 95% of the time you're actually going to be wrong, so if you think you need it you really have to question whether that is true or whether you're perhaps missing something.

Since I have the module with the base class, I can now write my JsonWsCustomJspBag class:

package com.liferay.portal.jsonwebservice.override; import com.liferay.portal.custom.jsp.bag.BaseCustomJspBag; import com.liferay.portal.deploy.hot.CustomJspBag; import org.osgi.framework.BundleContext; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; /** * class JsonWsCustomJspBag: This is the custom jsp bag used to replace the core JSP files for the jsonws UI. * * @author dnebinger */ @Component( immediate = true, property = { "context.id=JsonWsCustomJspBag", "context.name=/api/jsonws Permissioning Custom JSP Bag", "service.ranking:Integer=20" } ) public class JsonWsCustomJspBag extends BaseCustomJspBag implements CustomJspBag { @Activate protected void activate(BundleContext bundleContext) { super.activate(bundleContext); // we also want to include the jspf files in the list Enumeration enumeration = bundleContext.getBundle().findEntries( getCustomJspDir(), "*.jspf", true); while (enumeration.hasMoreElements()) { URL url = enumeration.nextElement(); getCustomJsps().add(url.getPath()); } } }

Pretty darn simple, huh? That's because I could leverage the BaseCustomJspBag class. Without that, you need to implement the CustomJspBag interface and that makes this code a lot bigger. You'll find help for implementing the complete interface from https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/overriding-core-jsps.

Don't forget your override file in src/main/resources/META-INF/resources/custom_jsps/html/portal/api/jsonws/index.jsp file with the override code as discussed previously.

Conclusion

That's it. Build and deploy your new module and you can hit the page as a guest and you'll get the permission message. Hit the page as a non-OmniAdmin user and you get the same. Navigate there as the OmniAdmin and you see the UI so you can browse the services, try them out, etc. as though nothing changed.

I'm making the project available in GitHub: https://github.com/dnebing/api-jsonws-override

 

 

1 A friend of mine called me out on the "security by obscurity" statement and thought that I was advocating for only this type of security.  Security by obscurity should never, ever be your only barrier to prevent folks with malicious intent from hacking your site. I do see it as a first line of defense, one that can keep script kiddies or inexperienced hackers from discovering your remote APIs. But you should always be checking permissions, securing access, monitoring for intrusions, etc.

David H Nebinger 2017-06-13T04:19:00Z
Categories: CMS, ECM

A Checkbox Named Cacheable

Liferay - Mon, 06/12/2017 - 11:58
Every now and then, there comes a time in a CMS developer's life when the sin of taking default settings for granted takes its toll.    There. I phrased that carefully so it would make a list of quotable quotes some day. Now, let me get to it.   Like many developers out there, I am a huge fan of content-driven solutioning. Yes, it is easy to overdo, but the fear of overdoing it should never hold us back. Why, you ask? Because underdoing content-driven solutions is just plain stupid, in my ought-to-be-humbler opinion.   With that in mind, I immediately latched on to the idea of pulling content markup into the theme using the CMS API. (This is ideal for secondary navigation links and such.) I prefer this approach to the embedded portlet approach - keeps my theme code a bit more maintainable, more straighforward to debug for the next guy.    Here's an example snippet from the theme that pulls the markup for a content item having a url title of "top-nav-links".   #set ($journalArticleLocalService = $serviceLocator.findService("com.liferay.portlet.journal.service.JournalArticleService")) #set($journalArticle = $journalArticleLocalService.getArticleByUrlTitle($group_id, "top-nav-links")) #set ($contentMarkup = $journalContentUtil.getContent($themeDisplay.getScopeGroupId(), $journalArticle.getArticleId(), null, $locale.toString(), $themeDisplay)) $contentMarkup   And I've been doing this for a long time. All seemed well.   ...until a few days back.   I found myself alone in a room with this one bit of fussy content that no matter how many times I edited it, the updated markup did not show in my theme. I would have to go in and try combinations of regenerating my search indexes and deleting prior versions of my content and re-saving my template. And then, eventually, for no clear reason, the update would show up. Flaky!   Anyway, here is what I had to do to make this madness stop. In my template, I unchecked this box named Cacheable.      That tooltip says it all!   Take a look at the velocity code snippet I pasted above. It basically calls into the CMS API to find the content item by its title, #set($journalArticle = $journalArticleLocalService.getArticleByUrlTitle($group_id, "top-nav-links")) and then retrieves the content markup with another API call, #set ($contentMarkup = $journalContentUtil.getContent($themeDisplay.getScopeGroupId(), $journalArticle.getArticleId(), null, $locale.toString(), $themeDisplay)) and finally, includes the markup in the theme. $contentMarkup   So, a Cacheable template is not good here. Uncheck and reap the benefits. You may want to consider any performance implications of not caching your template. In fact, if this content rarely changes, then keep it cacheable. But all philosophy and performance considerations aside, the feature functions as designed.   And one more tidbit. If you have this sort of code distributed all over your theme, i.e. you are pulling more than one or two content items into your theme: consider using a velocity macro. For example, drop this into your init_custom.vm where you initialize theme variables.   #* This file allows you to override and define new Velocity variables. *# #set ($headerScript = $theme.getSetting("header-scripts")) #set ($bodyScript = $theme.getSetting("body-scripts")) #set ($journalArticleLocalService = $serviceLocator.findService("com.liferay.portlet.journal.service.JournalArticleService")) #macro ( includeContent $contentTitle ) #set($journalArticle = $journalArticleLocalService.getArticleByUrlTitle($group_id, $contentTitle)) #set ($contentMarkup = $journalContentUtil.getContent($themeDisplay.getScopeGroupId(), $journalArticle.getArticleId(), null, $locale.toString(), $themeDisplay)) $contentMarkup #end   One last thing. I had to recreate my content item to get this to take effect. Not sure if that is a bug or not. It is possible the Cacheable setting itself is cached. Regardless, the content updates are showing up reliably now in my navigation bar.   And that, is that. Javeed Chida 2017-06-12T16:58:16Z
Categories: CMS, ECM

Finding Your Biggest Customer Pain Points

Liferay - Thu, 06/08/2017 - 11:00

Like the services and products they provide, a customer’s interactions with a business should be a pleasant and helpful experience. However, there are many complications and shortcomings within customer journeys that can turn these interactions into difficult, frustrating experiences.

These moments are known as pain points, which indicate real or perceived problems experienced by customers during interactions with your company. A few types of pain points felt by all types of customers, as discussed by MyCustomer.com, include:

  • Waiting too long for answers to questions
  • Being unable to order the desired product
  • Receiving unsatisfactory customer service
  • Experiencing confusion during shopping experiences
  • Not finding a product or service within budget

However, these many types of pain points look different for every business and can only be determined by devoting time and effort to finding your company’s specific issues. The benefits for both satisfaction and sales completion will make the effort well worth it.

How Do I Find Customer Pain Points?

Now that you’ve understood what the problems are, you’ll need to find how and when they happen in your customers’ journeys. While these issues will be unique for each company, there are multiple approaches to finding them that can be applied to all businesses and customers. There are many potential methods, including:

  • Interviewing Your Team - Whatever industry your company may be in, it’s crucial that you incorporate members of all departments in order to gain varied and unique insights into potential customer pain points. The more you do so, the less likely you are to overlook crucial elements.
  • Walking in the Customer’s Shoes - It can be beneficial to walk through entire business interactions on your own, pretending to be a customer and completing all aspects of a sale like anyone else. By experiencing what customers experience, you can live out the reality of interacting with your business instead of only hypothesizing.
  • Surveying Your Customers - Sometimes, the direct approach is best. Send online surveys to your customers or provide in-person interviews, where they can openly and honestly provide feedback concerning their best and worst experiences with your company.
  • Reviewing Support Calls and Claims - Your customer service team will often have the most direct and honest contact with customers in their pain. Recorded support calls, online chats and claims sent can detail these issues, as well as how they were resolved.
  • Collecting and Analyzing Website Data - If you have properly integrated your online presence with back-end data analytics, you will have massive amounts of information that detail your customers’ actions, including their pain points, when interacting with your company. When used correctly, a business can see trends and issues that may be preventing sales completions and return visits, as well as what solutions to implement in as little time as possible.
  • Reading Online Feedback - As discussed by Clariant Creative, people are more willing than ever to express their opinions online concerning companies through social media, blogs, review sites and comment sections. Public feedback can often spell out the areas to improve in clear, emotionally-relatable ways.

All of these elements of insight gathering can be combined for a larger, more complete way to find customer pain points: the creation of a journey map.

Creating a Journey Map that Identifies Pain Points

Journey maps can help create detailed layouts of how customers interact with your business, showing how they move from their first interaction to their eventual sales completion.

However, customer journey maps should include the reality of lost customers and pain points that are encountered in day-to-day business interactions. While some may be tempted to create an optimal journey map that does not include their company’s shortcomings, these will do little to eliminate pain points and improve future customer experiences. Journey maps can be made more accurate by cataloging your company's touchpoints to see how you interact with potential and existing customers.

The hallmarks of a successful journey map are honesty and factual basis. As discussed by I-Scoop.eu, it is important to pay attention to the emotions of customers, as these emotions often become the most influential and memorable moments in the customer journey. By understanding and eliminating pain, as well as reinforcing positive interactions throughout the customer journey, your conversion and sales-focused business goals can be better met without forgetting the people who support your business.

Once you’ve found your biggest customer pain points, the question becomes, what do I do about them? Strategies and more can be found in the upcoming part 2: Addressing Your Customer Pain Points.

Give Your Customers What They Want

Improving customer journeys is possible through the digital transformation of both how clients experience your brand and how your company is run. Learn more about how to create consistent customer experiences and improve journeys through our informative whitepaper.

Three Key Strategies for Consistent Customer Experiences

Matthew Draper 2017-06-08T16:00:35Z
Categories: CMS, ECM

How to Successfully Scale Your Customer Experience

Liferay - Wed, 06/07/2017 - 17:01

Creating and scaling great customer experiences are more crucial than ever to the success of businesses, but what does it mean to scale customer experience (CX)? And how can your company scale successfully?

Scaling means being able to create and control customer experiences for any type of customer, any size group of customers and for any or all portions of a business.

According to Walker research, CX will become the key differentiator between brands by 2020, instead of price or product. Companies will find it to their advantage to better scale their experiences, no matter the size of business or type of customer. When applied correctly, scaling customer experience for your company can save time and money while improving customer satisfaction and retention rates.

Scaling customer experience goes in two directions: personalizing company-wide business processes to individual customers and taking individual interactions employees have with customers and using those insights to reshape business processes. By applying both approaches to a flexible and digitally transformed business, you can be better equipped to adapt to the ever-shifting nature of modern business. The key to any successful scaling of CX is to learn the right lessons from day-to-day business and be willing to rethink how you meet your customers’ needs.

Strategy #1: Applying One-on-One Experiences to Larger Processes

As outlined by Ericsson in their report, “Generating actionable insights from customer experience awareness,” a customer-centric organization is characterized by being attentive to requests, proactive in addressing concerns, consistent with their experiences and adaptive to changing needs.

Imagine a moment when someone contacts your customer service to help find answers to a source of frustration. It’s easy to do so, it happens every day. He or she can’t seem to complete a needed service request on your website or is running into a consistent error with your product. If you’ve enabled your customer service representatives well, they will be able to quickly understand and solve the problem the customer has presented over the phone or via chat. As a result, that customer will leave the conversation satisfied and with a renewed sense of trust in your company. According to an American Express Survey, 78% of consumers have decided to not make an intended purchase because of poor customer service experiences. However, the value of a properly equipped and connected customer service center does not stop there.

If a customer has reached out to your customer service branch due to confusion and complications in their journey, such as trying to complete a purchase online, it’s likely that they are not alone in their frustration. Take the customer’s frustrations into consideration and consider what can be done to simplify this process for all customers, whether or not they ever contact your customer service.

Successfully scaling solutions to customer pain points can result in greater satisfaction and a higher sales completion rate, as unresolved frustrations can lead to abandoned carts and lower rates of return business. The biggest challenge is in scaling correctly in order to apply these takeaways to a potentially massive corporate network while also retaining the individual customer-level detail that made these applicable customer experiences a success in the first place.

Strategy #2: Using Technology to Scale Effectively

The challenge for every business in the age of digital transformation is to run massive everyday operations while making each customer feel like he or she is seen and treated as an individual. It’s no simple task, but a major factor in its success is to correctly scale customer metrics, which analyzes feedback concerning experiences for actionable insights. Research from Ericsson shows that customer metrics can be scaled by evaluating insights based on several metrics, including:

  • Scope - If the feedback concerned an individual, a group or the entire organization.
  • Outreach - The number of customers who provided the feedback.
  • Subjectivity - How objective or subjective the feedback is determined to be.
  • Predictive - If the insight is based on measurable facts or predicted for the future.
  • Latency - How quickly experiences should be changed to reflect insights.
  • Frequency - How often the score should be updated.

By evaluating the feedback you receive based on these scores, you can have a greater awareness of how to scale effectively.

The ever-increasing use of automation in data analytics can play a crucial role in effectively scaling your metrics without putting additional strain on your workforce. Through successful back-end integration, your digital business can receive in-depth data from customer interactions, process it for valuable insights and then modify experiences based on what that data shows. In doing so, takeaways based on real, insightful customer interactions can be applied in scalable ways that make the most of technology to adapt to unique business sizes, structures and approaches to customers.

The End Goal: Stay Focused on the Customer

Companies are constantly striving toward effective innovation in the way they run their businesses through digital transformation that improves customer experience. Using great takeaways from individual customer experiences to improve the brand as a whole can have widespread success, but it’s also crucial to remain focused on personalizing these experiences. Customer expectations concerning personalized experiences with companies are more widespread than ever thanks to their increasingly common occurrence across industries.

If your company has equipped its workforce with the right technology, employees will be able to respond flexibly and quickly to the demands of customers, even if they do not have a set protocol for new situations. For example, if a customer enters a store and has a question about a brand new product that was just announced, a digitally transformed business will have that information ready and waiting at an employee’s fingertips even if he or she has not personally heard about the product yet.

It’s this fast and adaptable approach to CX that will make individual customers feel seen and heard in their everyday interactions with your brand, reinforcing positive impressions and loyalty.

Personalize Your Company’s Customer Experience

As scalable customer experiences become a more and more common expectation in industries around the world, businesses will need to prepare themselves to reach such goals. Read our whitepaper to learn more strategies for CX transformation and begin your journey today.

Read “4 Strategies to Transform Your Customer Experience”

Matthew Draper 2017-06-07T22:01:05Z
Categories: CMS, ECM

5 claves para aumentar la competitividad de la banca tradicional

Liferay - Tue, 06/06/2017 - 06:05

Los comportamientos de los clientes están cambiando. El uso de múltiples canales digitales para hacer una única operación se está convirtiendo rápidamente en la norma. Es importante que los bancos innoven y se transformen de manera constante para hacer frente a los desafíos de la era digital en un entorno cambiante motivado por la irrupción de startups tecnológicas y fintechs, por los nuevos canales de relación con los clientes y por los cambios en sus comportamientos.

A continuación mostramos algunas claves estratégicas, en concreto cinco, que pueden ayudar a la banca “tradicional” a mantener la competitividad en su camino hacia la transformación digital.

1. Innovar para acelerar los desarrollos y transformar los procesos

En lugar de reaccionar a las expectativas de los clientes, los bancos deben adelantarse a ellas, y pensar en cómo quieren relacionarse los clientes. Para poner en marcha una buena estrategia digital, deben comprender previamente el comportamiento y las necesidades de sus clientes. ¿Combina el cliente la web, el móvil y la sucursal para acceder a sus cuentas y tomar decisiones? ¿Qué canal utiliza primero? ¿En cuál convierte más? ¿Con qué frecuencia accede a cada canal? Los clientes están cada vez más interesados en utilizar los servicios móviles e Internet, pero el lento desarrollo y transformación de los servicios por parte de los bancos tradicionales están forzando a muchos consumidores a buscar otras soluciones. Potenciar la orientación continua a la innovación y tener las herramientas adecuadas para afrontar los cambios que vienen es esencial para responder a las necesidades cambiantes tanto del entorno como de los clientes.

2. Análisis y personalización de la experiencia del cliente para una mayor eficiencia en las ventas

A través de un mejor conocimiento y comprensión de las experiencias de los clientes en todos los canales (online, móvil, call center, en la sucursal…) se puede obtener una mayor eficiencia. Potenciar la lealtad del cliente y su vinculación a través de servicios personalizados repercutirá decisivamente en el rendimiento del negocio. Manejar y procesar la información que se obtiene de los diferentes canales para obtener una imagen detallada y precisa de las preferencias, hábitos y comportamiento del cliente, junto con una comunicación selectiva, pueden conducir a mejores márgenes. Esto implica administrar de una forma inteligente datos provenientes de los diferentes canales y mantener una comunicación con el cliente basada en sus experiencias pasadas, es decir, transformar los datos en valor competitivo. Esta información, además, debería estar a disposición de todo el personal del banco, de todas las sucursales, de todos los departamentos, que podrán acceder a ella en todo momento, obteniendo una imagen clara y una visión completa sobre el cliente.

3. Apoyarse en plataformas que permitan unificar sistemas y procesos

Combinar la presencia puramente informativa con la parte más transaccional del banco y los servicios financieros ayudará a controlar mejor la experiencia del usuario y proporcionará el contexto para el engagement y la fidelización de los clientes. Integrar los silos de información y los procesos de gestión internos es el primer paso para afrontar la transformación de los servicios bancarios omnicanal, a lo que hay que sumar el fomento de los entornos colaborativos en los que las personas rompan barreras a la hora compartir conocimiento. Un enfoque de plataforma única que permita la integración de sistemas y personas es la base de las estrategias omnicanal.

4. Omnicalidad, concepto clave Hoy en día, muchos bancos operan bajo un modelo multicanal

Pero no hay que confundir “multicanal” con “omnicanal”: La estrategia multicanal –que implica el uso de múltiples canales– es por lo general un modelo fragmentado, que puede llegar a ser frustrante para los clientes. El modelo omnicanal, por el contrario, ofrece a los clientes acceso a servicios financieros a lo largo de los canales como si fueran uno solo con interacciones más consistentes. Con un modelo omnicanal, un cliente podría iniciar cualquier operación a través de cualquier canal, con la misma comodidad y con las mismas condiciones, o incluso iniciando la transacción en un canal y finalizándolo en uno diferente.

5. Un cambio cultural

Crear una nueva cultura digital no es sencillo, pero es inevitable. Requiere no sólo un cambio tecnológico, sino también un cambio en el enfoque tradicional del propio negocio de la banca, pasando de un modelo operativo centrado en los productos a otro, más innovador, centrado en los clientes. Obviamente, será necesario invertir en tecnología, en consultoría, en recursos y en reciclaje. La entidad va a operar de manera diferente, y necesitará adaptar su estructura para operar con este nuevo modelo que elimina los silos a nivel operativo y organizacional. Y, por supuesto, será necesaria la educación continua de todos los empleados a lo largo de la organización en estos nuevos modelos centrados en el cliente, para superar otros modelos anteriores, centrados sobre todo en el producto.

En definitiva, es un hecho que, en la actualidad, para atraer y retener a sus clientes, los bancos han de ser capaces de entender que éstos ya no son como antes, que han evolucionado, y que deben acompañar esta evolución. Ahora, los clientes son más exigentes y esperan experiencias personalizadas. Por por ejemplo, esperan, poder realizar consultas y operaciones las 24 horas, 7 días a la semana, desde cualquier dispositivo o en persona; agrupar sus gastos bajo conceptos generales, o compararlos con periodos anteriores; pagar con su móvil o poder ampliar el crédito de las tarjetas a través del móvil mientras están de viaje. Si los bancos tradicionales no son capaces de hacer esto, otros lo harán.

La utilización de las tecnologías de experiencias digitales como base para gestionar las experiencias de los clientes bajo un modelo omnicanal permitirá al banco mantener su competitividad, retener a sus clientes y facilitar el crecimiento.

Descargar Whitepaper: Omnicalidad, mucho más que una palabra de moda para la banca >

Maria Sanchez 2017-06-06T11:05:18Z
Categories: CMS, ECM

Three Hurdles to Digital Transformation

Liferay - Thu, 06/01/2017 - 13:29

Liferay Symposium North America is more than just a chance to study Liferay features and support, it’s also a space to explore the current challenges facing digital businesses. But what does digital transformation really mean? To prepare for this year’s event, it’s important to understand what digital transformation looks like, and what prevents many companies from achieving real transformation.

Liferay Symposium North America is equal parts instruction and invitation. This year’s theme, “Discover what real transformation can do,” is a challenge for attendees to consider how and why cultural and operational change is so important today. We invite you to discover, alongside the Liferay community, how real transformation can be effective and valuable for your business.

What Is Real Transformation?

According to analysts at Forrester’s Digital Transformation summit, “business transformation is digital transformation.” In other words, real transformation means transformation across the entire enterprise; it’s not enough to just keep adding digital front-end experiences. By coupling digital experiences with deep operational change, a total transformation makes it possible for companies to better serve customers and accelerate innovation. In a recent webinar, Liferay CEO Bryan Cheung discussed this transformation in his own words. He presented three main problems that companies must address in order to see success.

1. Lack of Urgency

It’s obvious that technology is changing quickly, but Cheung believes that this rate of change will continue to increase exponentially. As the pace of technological disruption increases exponentially, businesses must recognize this urgency and transform operating and revenue models in order to remain competitive; they must prepare to move faster. To do this companies must reframe the competition and recognize that the playing field is less segmented than in years past. For example, PayPal is not just in competition with Venmo, it must compete with Facebook Messenger now, too.

However, recognizing this urgency can also be a tool. The reality of a competitive climate can empower companies to take risks and make changes they otherwise would not. Today, one of the largest barriers to digital transformation is competing for priorities with other departments. Businesses must recognize this urgency and overcome departmental differences, for immediate and future benefit.

2. Failure to Value the Customer

Even though conventional wisdom reminds us that “the customer is always right,” this does not mean the customer is always valued. Cheung points to his own experience with a major airline as an example. Despite being a frequent flyer with nearly one million miles to his credit, the system still doesn’t recognize that Cheung lives in Los Angeles. When he books a return flight to LA, he is offered a coupon for a rental car, for which he has no need. But having one wrong choice is as impersonal as having too many right choices. When banking online, Cheung explains that he has seven options to transfer money, but no context for what tool is most appropriate for what task. Too many options make the process more complicated and less convenient.

The issue with these products is that they lack an indication that the company really knows him; the service isn’t personalized. Companies that recognize and engage customers on a very personal level stand the best chance to increase customer loyalty. To respond, companies must support a culture that can respond to failure and quickly improve. Companies must invest in knowing the customer, using this knowledge to serve and delight the customer’s needs.

3. Inability to Change Business Culture

With so much emphasis on efficiency, it can be problematic when a business prioritizes process over people. In order for a culture to innovate and adapt, it must support a fast-paced and agile work environment, with some permission to deviate from the rules.

But culture can be very hard to change. To start, it’s useful to isolate small projects and test accordingly to prove results—before tackling the next small project. At the Forrester summit, executives at Gap discussed their real attention to speed, by only allowing only 48 hours to make business decisions. This forced them to embrace a “learn fast, fail fast” mentality, without getting restrained by indecision and inaction. According to Mary Ransom, the Global Vice President of Ecommerce at Bloomingdales, “Data should have the loudest voice in the room.” Using data to set goals and review success is an authority that can make this kind of transformation easier.

Make Real Transformation Happen

Disruptions across every channel of business will continue to impact digital businesses in a significant way. Forrester predicts digital transformation will separate the leaders from the laggards in even just the next few years. In essence, transformation happens when digital business leaders change business culture to match customer expectations. To prepare for this change, and to equip your company with the necessary tools and practices, attend Liferay Symposium North America to learn more!

Liferay Symposium North America 2017 will be held in Austin, from October 16–17. Register now, or learn more to convince your boss.

William Jameson 2017-06-01T18:29:44Z
Categories: CMS, ECM
Syndicate content