Re: [Liferay Forums][Liferay Core Developers]RE: linking a portlet to diffe

thumbnail
28386, modified 18 Years ago. Expert Posts: 310 Join Date: 3/25/07 Recent Posts
Yes, in that case I do think it would be very useful.

So here's another stab at a spec:

__________________________________________________________________________

Proposed way to enable links from within Portlet A on Page X to target Portlet B on Page Y.

Step 1:

Make the portlet instance id user configurable. It should autogenerate by default, to the same thing we have today.
Today portlet id's are [portlet_name] for non instanceable and [portlet_name]_INSTANCE_XXXX for instanceable portlets.
With this change I could give a portlet my own id.

From a GUI point of view I think the field for setting this belongs in a new tab in the portlet configuration, beside the "Permissions" tab.

Here we need a validation when updating portlet configuration, to make shure no two portlets cannot have the same user specified id.

We also need a check when creating a new page as a copy of an existing page. Portlets that have a user specified id in the original should have default autogenereated ids in the copy. Maybe we need a "HasCustomPortletId" boolean in the database for this?

We also need some logic to change Layout.typeSettings when a portlet id is changed.

All the above could also be implemented using a new field in PortletPreferences for the portlet custom id. But I belive it makes a lot of sense to use the actual portletId, because it will also make the page URL much more readable.

Let's say I want to link to news articles on a news page and I have named my target portlet "newsdisplay", the URL would become for example:

/web/guest/news?...p_p_id=newsdisplay&_newsdisplay_struts_action=%2Fjournal_articles%2Fview&_newsdisplay_articleId=....


Step 2:

Extend the PortletURL class/tag so that it is possible the specify a "target portlet id" when creating the link. Let's say for example we add a LiferayPortletURL.setTargetId( String id ) method, and a corresponding parameter in the tag.

If a target portlet is specified, we go to PortletPreferences to find out what page the portlet is on, and make the resulting PortletURL actually link to this page instead of the page we are presently on. All parameters on the PortletURL also targets this p_p_id.

From a performance standpoint, if we do a custom finder with cacheing for finding the page where the p_p_id is, it should be quite OK.

Something like:
SELECT b.plid,b.layoutid,b.friendlyURL,.... FROM PortletPreferences a, layout b WHERE portletId="[myname]" AND a.plid=b.plid;

And there is no performance impact on PortletURL if a target id is not specified.


Step 3:

Frontend additions in order to allow the user to specify that links in this portlet should go to a specific target id.

(Actually in our implementation the target id is associated with the Journal Article, not with the portlet where the article is displayed, but that can be a future thing for JA's...)
thumbnail
28386, modified 18 Years ago. Expert Posts: 310 Join Date: 3/25/07 Recent Posts
BTW, If we continue this, maybe the thread would get better visibility in the Core Developers forum?
Maybe repost it there?
thumbnail
10437, modified 18 Years ago. Liferay Legend Posts: 2871 Join Date: 8/31/06 Recent Posts
Agreed, I've split and moved this part of the conversation.
thumbnail
10437, modified 18 Years ago. Liferay Legend Posts: 2871 Join Date: 8/31/06 Recent Posts
Hi Jesper,


Jesper W:
Yes, in that case I do think it would be very useful.

So here's another stab at a spec:


Thanks!

Jesper W:

Proposed way to enable links from within Portlet A on Page X to target Portlet B on Page Y.

Step 1:

Make the portlet instance id user configurable. It should autogenerate by default, to the same thing we have today.
Today portlet id's are [portlet_name] for non instanceable and [portlet_name]_INSTANCE_XXXX for instanceable portlets.
With this change I could give a portlet my own id.

From a GUI point of view I think the field for setting this belongs in a new tab in the portlet configuration, beside the "Permissions" tab.

Here we need a validation when updating portlet configuration, to make shure no two portlets cannot have the same user specified id.

We also need a check when creating a new page as a copy of an existing page. Portlets that have a user specified id in the original should have default autogenereated ids in the copy. Maybe we need a "HasCustomPortletId" boolean in the database for this?

We also need some logic to change Layout.typeSettings when a portlet id is changed.

All the above could also be implemented using a new field in PortletPreferences for the portlet custom id. But I belive it makes a lot of sense to use the actual portletId, because it will also make the page URL much more readable.

Let's say I want to link to news articles on a news page and I have named my target portlet "newsdisplay", the URL would become for example:

/web/guest/news?...p_p_id=newsdisplay&_newsdisplay_struts_action=%2Fjournal_articles%2Fview&_newsdisplay_articleId=....


Looks good except for some minor detail. First, the portletName/portletId is unique only within a given layout. So what you want is probably closer to the windowID (new concept of JSR-286) that for Liferay is implemented as portletName + SEPARATOR + plid.

Regarding how to save the custom value of the user, I agree that it should be in a db column because if we store it as a preference it would be very hard to search for it as we have to do in the next step. Although I think we should not do it in the portletId column of PortletPreferences, because that value is used in several places and a real portletId is expected.

So I see two options:
1) Add an extra column to PortletPreferences called customWindowID, or something like that
2) Create a new mapping table, which contains three columns: customWindowID, portletId, plid

Thoughts on this?

Jesper W:

Step 2:

Extend the PortletURL class/tag so that it is possible the specify a "target portlet id" when creating the link. Let's say for example we add a LiferayPortletURL.setTargetId( String id ) method, and a corresponding parameter in the tag.

If a target portlet is specified, we go to PortletPreferences to find out what page the portlet is on, and make the resulting PortletURL actually link to this page instead of the page we are presently on. All parameters on the PortletURL also targets this p_p_id.

From a performance standpoint, if we do a custom finder with cacheing for finding the page where the p_p_id is, it should be quite OK.

Something like:
SELECT b.plid,b.layoutid,b.friendlyURL,.... FROM PortletPreferences a, layout b WHERE portletId="[myname]" AND a.plid=b.plid;

And there is no performance impact on PortletURL if a target id is not specified.


This seems all pretty reasonable.

Jesper W:

Step 3:

Frontend additions in order to allow the user to specify that links in this portlet should go to a specific target id.

(Actually in our implementation the target id is associated with the Journal Article, not with the portlet where the article is displayed, but that can be a future thing for JA's...)



Definitely, this would be very useful for portlets like AssetPublisher which might be used to show a summary of the last assets of a certain type on the front page but when clicked should take the user to a different page. The current solution does not work well with instanciable portlets and breaks expectatinos when the current portlet is not in the target page.

Ok, so we are pretty close to having a design. I only have the doubts described above about the first step. What do you think about those?
thumbnail
28386, modified 18 Years ago. Expert Posts: 310 Join Date: 3/25/07 Recent Posts
Jorge Ferrer:
First, the portletName/portletId is unique only within a given layout.


True for normal portletIds. But the custom id will be unique across the site.
(To really enforce that would actually need the validator to check that a custom porlet id is not the same as any of the configured standard portlets)

Jorge Ferrer:
I think we should not do it in the portletId column of PortletPreferences, because that value is used in several places and a real portletId is expected.


Matter of opinion I guess. To me storing it as the portlet Id has the beauty of simplicity. It will actually be a very real portletId, useable in all places where a portletId is expected. (Again, the validator will have to enforce certain syntax restrictions when it is saved, so we don't get unusable portletIds)
thumbnail
18941, modified 18 Years ago. Expert Posts: 405 Join Date: 6/28/06 Recent Posts
Jesper W:
Make the portlet instance id user configurable. It should autogenerate by default, to the same thing we have today.
Today portlet id's are [portlet_name] for non instanceable and [portlet_name]_INSTANCE_XXXX for instanceable portlets.
With this change I could give a portlet my own id.


I just stumbled across this thread. While I'm working on something totally unrelated, I have had my nose in some of the code, and I'd like to give a word of caution w/ the above proposal:

There are several places in the code where the fact that the _INSTANCE_ separator exists in the portlet Id is used. The most obvious place is com.liferay.portal.model.impl.PortletImpl.java and its getRootPortletId() and getInstanceId() methods. At a very minimum, those two methods would have to be able to identify what is the root part, and what is the "instance" part.

If your proposal is you as an end user would get to define the "XXXX" part instead of using an auto-generated name, that would be fine. If you are thinking the entire portlet Id would be user definable, that could cause some serious problems.

I wouldn't be surprised in the slightest to find code scattered around (particuarlly in end user's custom code) that explicitly looks for the "_INSTANCE_" separator vs. using the PortletImpl.java methods. I don't even think that Hot deployable portlets even have access to the PortletImpl class.
thumbnail
10527, modified 18 Years ago. Liferay Legend Posts: 1197 Join Date: 2/8/05 Recent Posts
> If your proposal is you as an end user would get to define the "XXXX"
> part instead of using an auto-generated name, that would be fine. If
> you are thinking the entire portlet Id would be user definable, that
> could cause some serious problems.
>
> I wouldn't be surprised in the slightest to find code scattered around
> (particuarlly in end user's custom code) that explicitly looks for the
> "_INSTANCE_" separator vs. using the PortletImpl.java methods. I
> don't even think that Hot deployable portlets even have access to the
> PortletImpl class.


I 100% agree with Joel!

I think Jorge suggested the only logical and safe solution, which is to
define a reference between a given portletId (or instance, whichever the
case may be) and some "alias". This would add a level of de-referencing
logic, but I think it's still the only safe solution... it could even be
a many alias' per portletId if we feel it's needed.
thumbnail
28386, modified 18 Years ago. Expert Posts: 310 Join Date: 3/25/07 Recent Posts
Joel Kozikowski:
There are several places in the code where the fact that the _INSTANCE_ separator exists in the portlet Id is used.


Well that settles it then. I hadn't gone as far looking as that yet.

But in the choice between adding a new table and a bunch of join logic, and a new customWindowId column in PortletPreferences, I think I would prefer the latter. It's simpler and has less performace impact.

(And I must say I really dislike the _INSTANCE_ separator. It makes URLS really long and ugly emoticon One of these days I might make it configurable...)
931618, modified 17 Years ago. Junior Member Posts: 65 Join Date: 6/5/08 Recent Posts
Interesting discussion and the results are something I'll certainly be able to leverage. Any idea when this would be available and if I'll be able to use the user defined ID in the portlet:runtime tag?

I'm trying to create a single page and add some instanceable portlets, journal content, during runtime. To best describe what I'm trying to accomplish, let's say I have a site for the 50 states and each state has an article about it's population and an article about it's style of barbecue. I'd like to pass into this single page which state I'm interested in and have the corresponding articles on that states population and barbecue style added at runtime. I can see having the user defined ids as something like 53_INSTANCE_NC-BBQ and 53_INSTANCE_TX-BBQ and then I can build the portletID string on the fly in a JSP or possibly a template and use it in the liferay-portlet:runtime tag or the $processor.processPortlet("56_INSTANCE_NC-BBQ") to add the content to the page.

Thoughts?
thumbnail
10437, modified 17 Years ago. Liferay Legend Posts: 2871 Join Date: 8/31/06 Recent Posts
Hi Jeff,

As far as I know we never started implementing this. But I'm still interested in adding this functionality. Do you have the time and knowledge to give it a try?
931618, modified 17 Years ago. Junior Member Posts: 65 Join Date: 6/5/08 Recent Posts
Jorge,
As I just started with Liferay, I would say that no I don't have the time or knowledge. However, this is something that would save me alot of work on my side. The state and BBQ example is very simplistic, I actually have 4000+ "states" and 40 or so categories for each. However, with some guidance, I would probably tackle it. Do you know if I can pre-populate the database with the 160,000 empty articles and name them as I wish directly in the database? Or is there something in liferay which wouldn't work if I didn't use a sequence in naming the articles?
Thanks
Jeff
thumbnail
28386, modified 17 Years ago. Expert Posts: 310 Join Date: 3/25/07 Recent Posts
Point One: It's easy to prepopulate the database, either through the WebService interface, or if you want to be bold and keep track of creating the proper Resource table entries and update the proper counters you can do it straight to the database. You could use the article name with some key encoding of your state/category info.

Point two: What you want to do is not fully within the scope of the above discussion, which is more about how you create the link, than how you display the result....

I would solve your problem with a custom portlet that takes a couple of parameters (state and category/(-ies)) and displays the corresponding articles in the same portlet.

Then your link would be to this one fixed page with one fixed portlet which takes a couple of parameters to control its content.

You can't do it out of the box currently, but developing the custom Journal Content viewer portlet is a simple task.

/jesper
931618, modified 17 Years ago. Junior Member Posts: 65 Join Date: 6/5/08 Recent Posts
Creating a new journal content portlet sounds like the best option I've seen/heard, both in terms of programming time and content management.

Jesper W:
You could use the article name with some key encoding of your state/category info.


Re "article name", do you mean encoding the key up in JOURNALARTICLE.ARTICLEID?

Also, is there online/ available documentation on the webservice interface to pre-populate the database?
Thanks,
Jeff
thumbnail
28386, modified 17 Years ago. Expert Posts: 310 Join Date: 3/25/07 Recent Posts
Uh oh. Thread hijacked :-) (Start a new one if you want to continue...)

No I meant title. Title is normally not visible when displaying the article.
Both articleId and title are fields where you have free interpretation of the content.
Article Id is a bit controlled since it identifies a series of articles with the same user visible id but different versions.
id_ and resourcePrimKey are the id that really matter as database keys for the system.
931618, modified 17 Years ago. Junior Member Posts: 65 Join Date: 6/5/08 Recent Posts
Hijack moved to a new thread
http://www.liferay.com/web/guest/community/forums/-/message_boards/message/1211806