Foren

User Personal Bar modification

Peter Helgren, geändert vor 6 Jahren.

User Personal Bar modification

Regular Member Beiträge: 124 Beitrittsdatum: 14.11.13 Neueste Beiträge
I am running LR 7 GA4 on Windows and pretty sure my development environment is current. I need to make a couple of small changes to the User Personal Bar and found this tutorial and this set of sample code that was referenced by the tutorial. As most LR7 tutorial go, this one leaves out a complete explanation of the code and how it works. So I am left to guess.

The only departures from the sample code I have made are that the tutorial says you can create any package and class name you want (so I did) and I am using Freemarker as the template rather than a JSP. The tutorial fails to mention the purpose and connections between the two .java files in the portlet folder and the two in the constants folder but I think I have puzzled it all out. If I understand the connection I have made, the most important is the property


"model.class.name=" + PortalUserPersonalBarApplicationType.UserPersonalBar.CLASS_NAME


I have this in the in the relevant class:

@Component(
		immediate = true,
		property = {
			"model.class.name=" + PortalUserPersonalBarApplicationType.UserPersonalBar.CLASS_NAME
		},
		service = ViewPortletProvider.class
	)

public class ProfileBarPortletViewPortletProvider 
extends BasePortletProvider implements ViewPortletProvider{
	
	@Override
	public String getPortletName() {
		return ProfileBarPortletKeys.ProfileBar;
	}
	
}


There are a couple of things that I have questions about. Since the code sample is an exact replica of what is in production, I am always wondering if there is some "magic" in the naming conventions or if departing from them, as the tutorial suggests, is OK. For example the .java file in the sample code has this defined in java class in the constants folder:


	public static final String PRODUCT_NAVIGATION_USER_PERSONAL_BAR =
		"com_liferay_product_navigation_user_personal_bar_web_portlet_" +
			"ProductNavigationUserPersonalBarPortlet";


I assume that it could be named anything . The fact that it is a snake cased package and class name that matches what is currently in production is merely convention and coincidence, correct? It is only used to reference the portlet that is being extended, correct? The final question had to do with this property which the tutorial tosses out at the end without much explanation (where to add it would be helpful...I guessed):


property= {"service.ranking:Integer=10"}



So, all that being said, I don't see why when I build and deploy this guy, it isn't invoked. I am pretty sure when it IS invoked, it will die a painful death because of other assumptions and errors in the code, but "Debugging is the beginning of wisdom" and I can't debug until I can invoke . So, what about my code or assumptions here is getting in the way of at least this thing being invoked...?

Code can be found in my github repository:

https://github.com/phelgren/Liferay-tweaks/tree/master/problems/projects/user_personal_bar
thumbnail
Andrew Jardine, geändert vor 6 Jahren.

RE: User Personal Bar modification

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
Hi Peter,

I'm not sure I can help, but I will give it a shot. Please note though that, as of now anyway, I have not tried to do what you are doing -- so some of this is guess work, or what I have learned along the way that might be applicable to your case.

1
public static final String PRODUCT_NAVIGATION_USER_PERSONAL_BAR =
"com_liferay_product_navigation_user_personal_bar_web_portlet_" +
"ProductNavigationUserPersonalBarPortlet";


I assume that it could be named anything . The fact that it is a snake cased package and class name that matches what is currently in production is merely convention and coincidence, correct? It is only used to reference the portlet that is being extended, correct?


I'm not sure that it can be ANYTHING exactly. the value you use for the constant should match the package name / portlet class that you created. I learned this the hard way early on and even since have made the mistake a few times where I have "com.abc.something.portlet.MyPortlet", with dots instead of underscores, and the portlet urls never find their way to the component. So I think the answer for you is to make sure that the portlet name in your component uses the constant, and that the constant value is the package name from your component (portlet) class.


The final question had to do with this property which the tutorial tosses out at the end without much explanation (where to add it would be helpful...I guessed):

property= {"service.ranking:Integer=10"}


This is is just used at runtime to prioritize two components that are referencing the same service. if the service ranking is not specified, I believe it is automatically assigned a value of 0. So if you want to make sure that YOUR service definition takes priority over another, one way to do it is to use a higher service ranking value. It's not fool proof though because there are other filters that you can specify (on the @Reference) that will allow you to target based on other properties.

So your case not working could be that the request is not routing to your portlet (perhaps?) ... or that there is another service that has a higher ranking than 10? to see if it is the ranking that is blocking, just try using something bigger -- like 500 or something.

There may be some other tricks you can use as well -- someone else might have another suggestion, but those things have helped me with similar issues in the past.
Peter Helgren, geändert vor 6 Jahren.

RE: User Personal Bar modification

Regular Member Beiträge: 124 Beitrittsdatum: 14.11.13 Neueste Beiträge
Thanks. In my case, if you happened to glance at the code, the javax.portlet.name property points to the actual portlet name in the constants java file so my only concern was that it HAD to be:


public static final String PRODUCT_NAVIGATION_USER_PERSONAL_BAR =
"com_liferay_product_navigation_user_personal_bar_web_portlet_ProductNavigationUserPersonalBarPortlet";


I thought that MAYBE there was some magic in the name, that it had to match the name of the portlet being overridden in the production code. I didn't THINK so, but since it wasn't working, I started guessing....

Which brings me around to your comments about "property= {"service.ranking:Integer=10"}" . I absolutely understand its purpose, my uncertainty was WHERE to put the entry. I have two java files which BOTH have @Component annotations and the tutorial says " To do this, set the following property in your @Component declaration:" Well, isn't that helpful! I guess we can choose any java file that has a @Component annotation! (I don't think so) . Any guess as to where that guy should go? I added it originally to the properties of the Portlet class I extended but maybe it should go elsewhere?
Peter Helgren, geändert vor 6 Jahren.

RE: User Personal Bar modification

Regular Member Beiträge: 124 Beitrittsdatum: 14.11.13 Neueste Beiträge
So, I'll answer my own question: The entry goes in the class that is implementing the ViewPortletProvider class!

I had a 50/50 chance of getting it right so when it failed I should have gone ahead and tried the other 50% shot.

The portlet is now being invoked! It's broken but that is just grunt work at this point....
thumbnail
Andrew Jardine, geändert vor 6 Jahren.

RE: User Personal Bar modification

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
Hi Peter,

You beat me to it emoticon. If you have the time, maybe edit the docs on GitHub with the proposed changes to make it more clear so that the next poor soul that comes along doesn't have to suffer your same plight. Glad you got it to work.
Peter Helgren, geändert vor 6 Jahren.

RE: User Personal Bar modification

Regular Member Beiträge: 124 Beitrittsdatum: 14.11.13 Neueste Beiträge
I'll try that...

One last question for you since you seem to show up in posts regarding Freemarker and this portlet is a Freemarker portlet. Even though the I can now tell that the portlet is being invoked, the UI is not. IOW, the Freemarker template isn't being rendered. That usually happens "automagically" because the template is referenced in the @Component property directive. But I see nothin, zada, zip. I even created just a very simple template along the lines of "Hello World" that would display when the portlet was invoked. Nothing... I am fairly certain that the template and path are correct. The most significant difference between the JSP version (which IS working) and the Freemarker on is this code:


	@Override
	protected void doDispatch(
			RenderRequest renderRequest, RenderResponse renderResponse)
		throws IOException, PortletException {

		ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
			WebKeys.THEME_DISPLAY);

		User user = themeDisplay.getUser();

		if (!user.isDefaultUser()) {
			renderRequest.setAttribute(
				UserBarWebKeys.NOTIFICATIONS_COUNT,
				getNotificationsCount(themeDisplay));
		}

		super.doDispatch(renderRequest, renderResponse);
	}


Of course this wouldn't be the correct method in Freemarker but I am not sure what to replace it with in Freemarker. It's the old jsp to Freemarker struggle I regularly go through when attempting to use an existing Liferay example most of which use JSP's in the view layer.

Any idea of how I might accomplish a "jsp-free" result? Again, I CAN get the "user personal bar" to work with a jsp, just can't seem to crack it with an FM template.
thumbnail
Andrew Jardine, geändert vor 6 Jahren.

RE: User Personal Bar modification

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
Hey Peter,

Is your portlet class extending the FreemarkerPortlet base class? I was just looking at the class, and the only method in it is the include one. It extends the MVCPortlet that Liferay provides, so you should be able to access the render method. From there I suspect that the way you add the FTL is the same as the way you specify the JSP page you want to use, using the mvcPath.
Peter Helgren, geändert vor 6 Jahren.

RE: User Personal Bar modification (Antwort)

Regular Member Beiträge: 124 Beitrittsdatum: 14.11.13 Neueste Beiträge
Many thanks again. Your suggestion is where my instincts took me initially but I just couldn't get the guy to render. So I did a line by line comparison of the jsp version and the FTL version and the problem was in the @Component property directives. I THINK I got it working by adding "com.liferay.portlet.use-default-template=false" . At least at this point it is dying when it renders the template, which is actually a good thing since it indicates that the FTL template is being used...

I'll update my Github repo with the corrected functioning code...uh, when I get it functioning....
Peter Helgren, geändert vor 6 Jahren.

RE: User Personal Bar modification

Regular Member Beiträge: 124 Beitrittsdatum: 14.11.13 Neueste Beiträge
Working code (FINALLY sorted out) can be found here:

https://github.com/phelgren/Liferay-tweaks/tree/master/problems/projects/user_personal_bar
thumbnail
Andrew Jardine, geändert vor 6 Jahren.

RE: User Personal Bar modification

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
Great! glad you got it sorted out. Thanks for closing out the thread by providing your solution. I'll be sure to check it out.