Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Christos Melas
Asset Publisher Link to Other Page
September 13, 2010 1:19 AM
Answer

Christos Melas

Rank: New Member

Posts: 8

Join Date: September 12, 2010

Recent Posts

Hello everyone!
I have deployed liferay 6.0.5 with tomcat and I would like to ask how to display an asset from an asset publisher of page A on an asset plublisher of page B.

The concept is simple and very common, page A is i.e. frontpage with a small asset publisher or even web content list displaying asset links of a certain news category. Page B is the main page of the news category having an asset publisher displaying the news assets. So when one clicks on a link of page A I would like to redirect to page B and display the specific asset.

I have found several related threads but I can't really find an answer on this.

I understand that the solution is around the option " Link Portlet URLs to Page " found in the Look and Feel configuration, but all I get is a navigation to page B without displaying a specific asset only the asset publisher with all the assets.

By the way when I tried it with the web content list I get "You do not have the roles required to access this portlet. " message within the asset publisher....

Your time and help is greatly appreciated
Thanks in advance
Christos Melas
RE: Asset Publisher Link to Other Page
September 18, 2010 7:14 AM
Answer

Christos Melas

Rank: New Member

Posts: 8

Join Date: September 12, 2010

Recent Posts

OK, after some thought i noticed the following,

when clicking from the asset publisher of page A that redirects to the asset publisher of page B (this is done from the look and feel option of the portlet "Link Portlet URLs to Page "), the url of the http request instead of having the id of the target asset publisher portlet instance of page B it had the id of the asset publisher portlet instance of page A. If i replace the id of asset-publisher of page A with the id of asset-publisher of page B on the url address bar (the portlet instance IDs can be found from the look and feel option > Advanced Styling tab) everything works just fine!! In other words by clicking the asset links (title, or read more) from the asset-publisher of page A, with correct href values having the correct portlet instance id, it is redirected to page B and the asset publisher displays the specific asset!!

So, the conclusion is that it would be great if inside the look and feel option in conjunction with specifying "Link Portlet URLs to Page" it could be possible to specify inside a field the exact id of the portlet instance that it is desired to view that asset.

Since i'm not even sure if that functionality exists, (please guys shed some light if i'm missing the correct procedure !!) and since i'm sure that the dev team will probably supply similar techniques the proper way on the server side (as i have also read in relevant liferay issue entries - sorry for not posting links, i'm sure i have seen a couple), I decided to this with some plain old javascript and share in case anyone is interested,

the code is written using jQuery (but I suppose it is easy to manipulate it in any js flavour)

 1
 2function mapPortletToPortlet(fromPortletId, toPortletId){
 3    $('.portlet').each(function(){
 4   
 5        if($(this).attr('id').indexOf(fromPortletId)!=-1){
 6            $(this).find('a').each(function(){
 7                if($(this).attr('href').indexOf(fromPortletId)!=-1){
 8                    var oldURL = $(this).attr('href');
 9                    var newURL = oldURL.replace(fromPortletId,toPortletId);
10                    $(this).attr('href',newURL);
11                }       
12            });
13        }
14    });
15}
16mapPortletToPortlet('Ht6u','ve0K');
17//where Ht6u is the ending of my asset publisher portlet instance of page A
18//and veOK is the ending of my asset publisher portlet instance of page B


the code above can be placed inside the javascript text area of page A when going
to manage page option. However the method can also go in the theme and just place the call mapPortletToPortlet('Ht6u','ve0K'); inside the js textarea.

The code below is placed in the js text area of Page B and it is used to fix the "back" href url of the asset on asset-publisher of Page B in order to navigate to asset-publisher of Page B....(it may make more sense if you try it out)
 1
 2function mapPortletFromPortlet(fromPortletId, toPortletId){
 3    $('.portlet').each(function(){
 4   
 5        if($(this).attr('id').indexOf(toPortletId)!=-1){
 6            $(this).find('a').each(function(){
 7                if($(this).attr('href').indexOf(fromPortletId)!=-1){
 8                    var oldURL = $(this).attr('href');
 9                    var newURL = oldURL.replace(fromPortletId,toPortletId);
10                    $(this).attr('href',newURL);
11                }       
12            });
13        }
14    });
15}
16mapPortletFromPortlet('Ht6u','ve0K');

The code above can be used with any portlet instance of a specific page and other portlet types as well i.e. between web content list and asset-publisher etc....

I would greatly appreciate if someone could tell me whether the desired feature already exists. Thanks in advance....
Jelmer Kuperus
RE: Asset Publisher Link to Other Page
October 20, 2010 1:12 PM
Answer

Jelmer Kuperus

Rank: Liferay Legend

Posts: 1190

Join Date: March 10, 2010

Recent Posts

I was looking into this as well. It seems to be a thorny problem that liferay doesn't really address well
I looked at a few things


1) view in specific portlet

For most asset types you can change the "Asset Link Behaviour" property to "view in specific portlet"

What will happen when you do this is that liferay will look at all pages within the group and search for a page that contains a portlet that is able to display the asset.

So in the case of a BlogsEntry it will search for a page that has the blog portlet on it and will link to that page. If there are multiple pages that contain the blog portlet. It will use the first page it finds

But web content is used on pretty much every page so this wouldn't work well for this type of asset. Liferay developers realized this as well and so the behaviour is different for journal content


2) Link Portlet URLs to Page

As you already mentioned the look and feel dialog allows you to check this option. but it won't work for web content because webcontent portlets are "instantiable" which means means that if you add two or more instances of this portlet to a page they would all have their own configuration (no point displaying the same content 5 times afterall) Instantiable portlets get assigned an 4 letter instance identifier that uniquely identifies an instance on a page so if you have 4 web content portlets each will have a different identifier.

When you use the "Link Portlet URLs to Page" the link that is generated will still contain the instance id of the asset publisher portlet the click orginated from. And the portlet that is linked to will not be able to read the passed in parameters because it has a different instance id.

Rewriting the urls using javascript as you did would work but has a hacky feel about it.


3) Change the jsp's used for rendering

This is what i actually settled on for now

The following files are used for rendering :

/portal-web/docroot/html/portlet/asset_publisher/display/abstracts.jsp
/portal-web/docroot/html/portlet/asset_publisher/display/full_content.jsp
etc.

Which one is used, is dependent on the "display style" setting you choose when you configure the asset publisher

You can define a jsp hook and "overload" these files by placing a file called liferay-hook.xml in the WEB-INF folder of a plugin, that looks like this :


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.0.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_0_0.dtd">

<hook>
<custom-jsp-dir>/META-INF/custom_jsps</custom-jsp-dir>

</hook>


Then when you add a file called /META-INF/html/portlet/asset_publisher/display/abstracts.jsp to your plugin, it will use that jsp instead of the one shipped with the portal

It's also possible to create your own templates and leave those alone by defining setting the asset.publisher.display.styles property in portal.properties and creating the corresponding jsp file in /html/portlet/asset_publisher/display/


In the view jsp i add the following code

<%
if (viewInContext && com.liferay.portlet.journal.asset.JournalArticleAssetRenderer.class.isAssignableFrom(assetRenderer.getClass())) {

JournalArticleResource resource = JournalArticleResourceLocalServiceUtil.getArticleResource(assetRenderer.getClassPK());

String articleId = resource.getArticleId();

Layout articleLayout = LayoutLocalServiceUtil.getFriendlyURLLayout(assetRenderer.getGroupId(), false, "/article");
LayoutTypePortlet articleLayoutTypePortlet = (LayoutTypePortlet)articleLayout.getLayoutType();

List<Portlet> allPortlets = articleLayoutTypePortlet.getAllPortlets("column-2");

String portletId = null;

for (Portlet p: allPortlets) {
if (PortletKeys.JOURNAL_CONTENT.equals(p.getRootPortletId())) {
portletId = PortletKeys.JOURNAL_CONTENT + PortletConstants.INSTANCE_SEPARATOR + p.getInstanceId();
break;
}
}

PortletURL portletURL = new PortletURLImpl(request, portletId , articleLayout.getPlid(), PortletRequest.RENDER_PHASE);
portletURL.setParameter("articleId", articleId);
portletURL.setParameter("groupId", String.valueOf(themeDisplay.getScopeGroupId()));

viewURL = portletURL.toString();
}

%>



It assumes that there is a page with a friendly url /article that has a webcontent portlet in the second column. It does not have to be configured because i am dynamically passing in the arguments that define which article should be loaded. But you might considering configuring a placeholder text there that explains that content there will be dynamically loaded

This is still hardly ideal because this way i need to modify all the view templates,

Instead i would prefer to be able to create my own implementation of AssetRenderer and AssetRendererFactory, or better still, be able to wrap an existing AssetRenderer like i can a service.
But this seems problematic at this point
Christos Melas
RE: Asset Publisher Link to Other Page
September 19, 2010 9:31 AM
Answer

Christos Melas

Rank: New Member

Posts: 8

Join Date: September 12, 2010

Recent Posts

Thank you for your assistance jelmer !
I haven't tried your approach yet, but if i understood correctly, as i read your code, i'll have to tweak your code in order to use it with a page having a friendly url "/article" and an asset-publisher portlet (i.e. the
1if (PortletKeys.JOURNAL_CONTENT.equals(p.getRootPortletId()))
part and possibly the passing of arguments part to load the correct asset). Since the aim is to have a news/articles page with all news/articles gathered (this is the Page B with an asset publisher mentioned previously), but also be able to place a small asset publisher portlet with say the five latest news, on the front page (page A mentioned previously), redirecting to the news page.

However I insist, hopefully without being stubborn or annoying emoticon , that it would be much nicer if liferay developers implement this on the server side by including a field for specifying the exact portlet instance to view the asset at the targeted "Link Portlet URLs to Page" page. This way it would be much more flexible to choose the exact asset publisher or even better any portlet (i.e. web content portlet ) at the targeted page to display the content. In addition this kind of behavior would be excellent if it is available from any portlet i.e. tag navigation portlet, web content list etc to any portlet at a target page.

One other thing that would also be nice is to have an option for a behavior similar to the search portlet, which when clicking an entry redirects you to the context page that includes the content of the selected entry. Instead of displaying the content within the asset-portlet itself.

I believe these are really useful options used in common scenarios.
Jelmer Kuperus
RE: Asset Publisher Link to Other Page
September 19, 2010 10:22 AM
Answer

Jelmer Kuperus

Rank: Liferay Legend

Posts: 1190

Join Date: March 10, 2010

Recent Posts

haven't tried your approach yet, but if i understood correctly, as i read your code, i'll have to tweak your code


Yes you would have to tweak it a bit, because i am using the webcontent portlet to display the article on the page you link to from the front page, and you would have to use another asset publisher portlet,

but the general idea is the same.

I agree that you would like be useful to be able to specify a layout and portlet instance as the target of clicking the "more link"

I think it's rather inflexible as it is now,

being able to register your own AssetRenderers for existing types would go a long way tho, but ideally you would want to be able to have this kind of control via the gui


One other thing that would also be nice is to have an option for a behavior similar to the search portlet, which when clicking an entry redirects you to the context page that includes the content of the selected entry


It actually works like that for many asset types, thats basically what i discuss under 1)
Christos Melas
RE: Asset Publisher Link to Other Page
September 20, 2010 12:27 AM
Answer

Christos Melas

Rank: New Member

Posts: 8

Join Date: September 12, 2010

Recent Posts

jelmer thank you very much for all your help,

jelmer kuperus:


One other thing that would also be nice is to have an option for a behavior similar to the search portlet, which when clicking an entry redirects you to the context page that includes the content of the selected entry


It actually works like that for many asset types, thats basically what i discuss under 1)


Yes indeed i've noticed it works for blog and wiki asset entries, but i was thinking of web content entries....

It is not that i'm obsessed with web content portlets emoticon , it is only that i'm trying to figure out in what extent they can be used as news materials etc . I've also noticed that liferay.com uses blog entries for news emoticon
Charles de Courval
RE: Asset Publisher Link to Other Page
October 18, 2010 11:55 AM
Answer

Charles de Courval

Rank: Junior Member

Posts: 55

Join Date: July 31, 2010

Recent Posts

Hi,

check this post out : Asset publisher to display articles in another page. It might be of some help.
Jelmer Kuperus
RE: Asset Publisher Link to Other Page
October 18, 2010 2:23 PM
Answer

Jelmer Kuperus

Rank: Liferay Legend

Posts: 1190

Join Date: March 10, 2010

Recent Posts

Thanks for that. That's a nice little trick Vidya Sagar Padigela is using. It seems that when you select copy parent when creating a page it also copies the 4 letter instance id.

So then the "Link Portlet URLs to Page" trick works without having to hack jsp's or play around with javascript. Selecting copy page in the page edit screen will accomplish the same thing (and does not impose the requirement that the details page should be a child page)

Of course there are still some issues with this.

- all asset types will open in the same page
- if someone removes the asset publisher from the details page and re-adds it the functionality will stop working

but I guess it's a simple and pretty good option in many cases.

I wish liferay would make this easier tho. Even letting you change the instance id from the gui would go a long way
Gaurang G
RE: Asset Publisher Link to Other Page
October 20, 2010 4:34 AM
Answer

Gaurang G

Rank: New Member

Posts: 16

Join Date: April 28, 2010

Recent Posts

<%
if (viewInContext && com.liferay.portlet.journal.asset.JournalArticleAssetRenderer.class.isAssignableFrom(assetRenderer.getClass())) {

JournalArticleResource resource = JournalArticleResourceLocalServiceUtil.getArticleResource(assetRenderer.getClassPK());

String articleId = resource.getArticleId();

Layout articleLayout = LayoutLocalServiceUtil.getFriendlyURLLayout(assetRenderer.getGroupId(), false, "/article");
LayoutTypePortlet articleLayoutTypePortlet = (LayoutTypePortlet)articleLayout.getLayoutType();

List<Portlet> allPortlets = articleLayoutTypePortlet.getAllPortlets("column-2");

String portletId = null;

for (Portlet p: allPortlets) {
if (PortletKeys.JOURNAL_CONTENT.equals(p.getRootPortletId())) {
portletId = PortletKeys.JOURNAL_CONTENT + PortletConstants.INSTANCE_SEPARATOR + p.getInstanceId();
break;
}
}

PortletURL portletURL = new PortletURLImpl(request, portletId , articleLayout.getPlid(), PortletRequest.RENDER_PHASE);
portletURL.setParameter("articleId", articleId);

viewURL = portletURL.toString();
}

%>


Hi Jelmer,

I tried this approach and seems appropriate except that when I click on the generated links (viewURL), it open the page with friendly url /article, but does not show the the web content in it.
This is one of the links generated:-
/web/guest/article?p_p_auth=G9wJv4S1&p_p_id=56_INSTANCE_6JSi&p_p_lifecycle=0&p_p_col_id=column-1&p_p_col_pos=1&p_p_col_count=5&_56_INSTANCE_6JSi_articleId=11471
Am I missing something here.
Thanks in advance.
Jelmer Kuperus
RE: Asset Publisher Link to Other Page
October 20, 2010 1:12 PM
Answer

Jelmer Kuperus

Rank: Liferay Legend

Posts: 1190

Join Date: March 10, 2010

Recent Posts

Hmmm i think something was changed between liferay 6.0.4 and 6.0.5

If you do this

1PortletURL portletURL = new PortletURLImpl(request, portletId , articleLayout.getPlid(), PortletRequest.RENDER_PHASE);
2portletURL.setParameter("articleId", articleId);
3portletURL.setParameter("groupId", String.valueOf(themeDisplay.getScopeGroupId()));


instead of this

1PortletURL portletURL = new PortletURLImpl(request, portletId , articleLayout.getPlid(), PortletRequest.RENDER_PHASE);
2portletURL.setParameter("articleId", articleId);


It works again

I also updated the post above
Gaurang G
RE: Asset Publisher Link to Other Page
October 20, 2010 11:01 PM
Answer

Gaurang G

Rank: New Member

Posts: 16

Join Date: April 28, 2010

Recent Posts

Hi Jelmer,

It works just fine with the the extra parameter emoticon. However, how were you able to figure out this change? By adding the parameter directly to the url?
Jelmer Kuperus
RE: Asset Publisher Link to Other Page
October 21, 2010 12:53 AM
Answer

Jelmer Kuperus

Rank: Liferay Legend

Posts: 1190

Join Date: March 10, 2010

Recent Posts

I put a breakpoint on the struts action that displays journal content, and followed the flow
Pooja Shah
RE: Asset Publisher Link to Other Page
November 15, 2010 9:39 PM
Answer

Pooja Shah

Rank: New Member

Posts: 3

Join Date: August 5, 2010

Recent Posts

Christos Melas:
OK, after some thought i noticed the following,

when clicking from the asset publisher of page A that redirects to the asset publisher of page B (this is done from the look and feel option of the portlet "Link Portlet URLs to Page "), the url of the http request instead of having the id of the target asset publisher portlet instance of page B it had the id of the asset publisher portlet instance of page A. If i replace the id of asset-publisher of page A with the id of asset-publisher of page B on the url address bar (the portlet instance IDs can be found from the look and feel option > Advanced Styling tab) everything works just fine!! In other words by clicking the asset links (title, or read more) from the asset-publisher of page A, with correct href values having the correct portlet instance id, it is redirected to page B and the asset publisher displays the specific asset!!

So, the conclusion is that it would be great if inside the look and feel option in conjunction with specifying "Link Portlet URLs to Page" it could be possible to specify inside a field the exact id of the portlet instance that it is desired to view that asset.

Since i'm not even sure if that functionality exists, (please guys shed some light if i'm missing the correct procedure !!) and since i'm sure that the dev team will probably supply similar techniques the proper way on the server side (as i have also read in relevant liferay issue entries - sorry for not posting links, i'm sure i have seen a couple), I decided to this with some plain old javascript and share in case anyone is interested,

the code is written using jQuery (but I suppose it is easy to manipulate it in any js flavour)

 1
 2function mapPortletToPortlet(fromPortletId, toPortletId){
 3    $('.portlet').each(function(){
 4   
 5        if($(this).attr('id').indexOf(fromPortletId)!=-1){
 6            $(this).find('a').each(function(){
 7                if($(this).attr('href').indexOf(fromPortletId)!=-1){
 8                    var oldURL = $(this).attr('href');
 9                    var newURL = oldURL.replace(fromPortletId,toPortletId);
10                    $(this).attr('href',newURL);
11                }       
12            });
13        }
14    });
15}
16mapPortletToPortlet('Ht6u','ve0K');
17//where Ht6u is the ending of my asset publisher portlet instance of page A
18//and veOK is the ending of my asset publisher portlet instance of page B


the code above can be placed inside the javascript text area of page A when going
to manage page option. However the method can also go in the theme and just place the call mapPortletToPortlet('Ht6u','ve0K'); inside the js textarea.

The code below is placed in the js text area of Page B and it is used to fix the "back" href url of the asset on asset-publisher of Page B in order to navigate to asset-publisher of Page B....(it may make more sense if you try it out)
 1
 2function mapPortletFromPortlet(fromPortletId, toPortletId){
 3    $('.portlet').each(function(){
 4   
 5        if($(this).attr('id').indexOf(toPortletId)!=-1){
 6            $(this).find('a').each(function(){
 7                if($(this).attr('href').indexOf(fromPortletId)!=-1){
 8                    var oldURL = $(this).attr('href');
 9                    var newURL = oldURL.replace(fromPortletId,toPortletId);
10                    $(this).attr('href',newURL);
11                }       
12            });
13        }
14    });
15}
16mapPortletFromPortlet('Ht6u','ve0K');

The code above can be used with any portlet instance of a specific page and other portlet types as well i.e. between web content list and asset-publisher etc....

I would greatly appreciate if someone could tell me whether the desired feature already exists. Thanks in advance....


Hello Christos,
I have got your idea...I have applied it, but its not working. It seems like my pages are not able to understand the above jQery code, and so doing nothing.
As i have configured Link To page(in look and feel of Ist page to 2nd page), it is just forwarding me to the 2nd page.(I have put asset publisher on both pages, and put correct instanceId of both asset publishers)
Please help me out.
Andrius Kurtinaitis
RE: Asset Publisher Link to Other Page
February 24, 2011 6:36 AM
Answer

Andrius Kurtinaitis

Rank: Junior Member

Posts: 62

Join Date: January 24, 2010

Recent Posts

Jelmer, thank you for your code snippet. I hacked it a little bit so that it takes the taget page from the preferences set using "Look and Feel" configuration and then to make link to the first AssetPublisher instance on that page:

 1
 2// get linked page uuid
 3String linkToLayoutUuid = GetterUtil.getString(
 4    preferences.getValue("portlet-setup-link-to-layout-uuid", null));
 5if(linkToLayoutUuid!=null) {
 6   // get linked layout
 7   Layout linkedLayout = null;
 8   try {
 9       linkedLayout = LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
10           linkToLayoutUuid, themeDisplay.getScopeGroupId());
11   }
12   catch (PortalException pe) {
13       pe.printStackTrace();
14   }
15   if (linkedLayout!=null) {
16       // find first AssetPublisher portlet on that layout
17       LayoutTypePortlet detailLayoutTypePortlet = (LayoutTypePortlet)linkedLayout.getLayoutType();
18       List<Portlet>     allPortlets = detailLayoutTypePortlet.getAllPortlets();
19       String            portletId = null;
20       for (Portlet p: allPortlets) {
21           if (PortletKeys.ASSET_PUBLISHER.equals(p.getRootPortletId())) {
22               portletId = PortletKeys.ASSET_PUBLISHER + PortletConstants.INSTANCE_SEPARATOR + p.getInstanceId();
23               break;
24           }
25       }
26       if (portletId!=null) {
27           // make an url to this portlet
28           PortletURL portletURL = new PortletURLImpl(request, portletId , linkedLayout.getPlid(), PortletRequest.RENDER_PHASE);
29
30           portletURL.setParameter("struts_action", "/asset_publisher/view_content");
31           portletURL.setParameter("assetEntryId", String.valueOf(assetEntry.getEntryId()));
32           portletURL.setParameter("type", assetRendererFactory.getType());
33           portletURL.setParameter("groupId", String.valueOf(assetRenderer.getGroupId()));
34           portletURL.setParameter("urlTitle", assetRenderer.getUrlTitle());            
35
36           viewURL = portletURL.toString();
37           viewURL = HttpUtil.setParameter(viewURL, "redirect", PortalUtil.getLayoutURL(linkedLayout,themeDisplay));
38       }
39   }
40}   
enrico sodacci
RE: Asset Publisher Link to Other Page
March 23, 2011 12:35 PM
Answer

enrico sodacci

Rank: New Member

Posts: 5

Join Date: March 15, 2011

Recent Posts

Hi Andrius,
i'm trying something similar but i'm unable to get the value in 'linkToLayoutUuid' with this code:

1
2String linkToLayoutUuid = GetterUtil.getString(
3                  preferences.getValue("portlet-setup-link-to-layout-uuid", null));


It works if i set the link to 'current page', it doesn't if i change it to something else.

My portlet is an MVCPortlet and i'm triyng to read that preference from a the resource phase.

Any suggestions?
tnx
Brian Scott Schupbach
RE: Asset Publisher Link to Other Page
September 21, 2012 5:52 AM
Answer

Brian Scott Schupbach

Rank: Expert

Posts: 331

Join Date: October 23, 2008

Recent Posts

checkout this post

http://www.liferay.com/community/forums/-/message_boards/message/16588582
Jukka Pelto-aho
RE: Asset Publisher Link to Other Page
February 13, 2013 4:57 AM
Answer

Jukka Pelto-aho

Rank: New Member

Posts: 1

Join Date: February 13, 2013

Recent Posts

The use of Alloy UI is possible simply by adding javascript code to Manage -> Page -> Javascript
 1
 2AUI().ready(function(A) {
 3    var elements = A.all('a.taglib-icon');
 4    elements.each(function (ele) {
 5        if(ele.get('href').indexOf('4lhE6CeGp509')!=-1){
 6            var oldURL = ele.get('href');
 7            var newURL = oldURL.replace('4lhE6CeGp509','vaWL1mw2XG6u');
 8            ele.set('href', newURL);
 9        }
10    });
11});