Get portlet/page containing web content in Liferay - liferay

I'm trying to make the Liferay (6.0.6) Asset Publisher publish all changes across multiple communities on the portal homepage. By clicking on a link the user is supposed to be redirected to another community and see the new web content. The problem is that the default behaviour of asset publisher (even with the hook to gather info from all communities) tries to get the url by searching the group of the current page (in which the content is not).
I decided to change the jsp showing the page to search all pages across all communities and find the first one containing the portlet with the desired web content. So
How could I get the portlet containing the web content by journal id of the web content?
How could I get the page containing the portlet?
Thanks

The PortletPreferences table in the database contains the configurations of each portlet in the system. The configuration of an articleId for a Web Content Display portlet is stored as a preference in this table. If you look at that table, there are 3 important columns:
plid contains the id of the Layout (=page) on which the portlet was dropped.
portletid contains the instance id of the portlet. For Web Content Display portlet, this ID has the format 56_INSTANCE_XXXX where XXXX is a unique hash.
preferences is an XML formatted string of all preferences and their values for this portlet.
An example of the preferences XML:
<portlet-preferences>
<preference><name>group-id</name><value>10139</value></preference>
<preference><name>article-id</name><value>14295</value></preference>
</portlet-preferences>
So it's just a question of getting your SQL queries right. As far as I know, there is no service you can call directly for this.
SELECT l.friendlyURL
FROM PortletPreferences p, Layout l
WHERE p.plid=l.plid
AND p.portletid LIKE '56_INSTANCE_%'
AND p.preferences LIKE '<preference><name>article-id</name><value>14295</value></preference>';

Something like the following allows you to find the Layout on which an article is Rendered.
List<Long> layoutIds = JournalContentSearchLocalServiceUtil.getLayoutIds(groupId, false, articleId);
long layoutId = 0;
if (!layoutIds.isEmpty()) {
layoutId = layoutIds.get(0).longValue();
Layout layout = LayoutLocalServiceUtil.getLayout(groupId, false, layoutId);
String url = PortalUtil.getLayoutURL(layout, themeDisplay);
...
}

Related

SharePoint WebPart zoneId

I am using SharePoint online.
I want to use this CSOM code to add a WebPart to a page:
SP.File oFile = _web.GetFileByUrl(SiteUrl + "/SitePages/" + pageName);
oFile.CheckOut();
LimitedWebPartManager limitedWebPartManager = oFile.GetLimitedWebPartManager(PersonalizationScope.Shared);
var importedWebPart = limitedWebPartManager.ImportWebPart(webPartSchemaXml);
var webPart = limitedWebPartManager.AddWebPart(importedWebPart.WebPart, zoneid, zoneIndex);
oFile.Update();
await SiteCtx.ExecuteQueryAsync();
oFile.CheckIn(String.Empty, CheckinType.MinorCheckIn);
The problem is how to assign correct values to the zoneid string variable,
which is the name of the Web Part zone to which to add the Web Part.
When I run this code nothing happens!
(it doesn't add the WebPart to the page and I am suspecting it is related to the wrong zoneId).
I have read various post, ranging from accessing the code behind of the .aspx page trying to find the WebPartZone, accessing the WebPartManager class (which should list the ZoneId's but I don't know how to get it, since that I am using the LimitedWebPartManager class).
I have tried various values for zoneId, but at the moment none of them work:
Zone 1 (just a guess!)
Zone 2 (i see it in the right tab when manually editing the webpart through Edit page)
Body (with this the code worked some days ago! but now it doesn't anymore)
Header
Left
Bottom
What is the proper method of findind zoneId's?
EDIT
The page is the homepage, I have read somewhere that it is a wiki page so maybe it has different ZoneId's.
ZoneIDs might be different depending on the page layout, but usually out-of-the-box SharePoint layouts use the following ID's for webpart zones:
TitleBar
Header
LeftColumn
MiddleColumn
RightColumn
Footer
Make sure that you invoke the update() method on your file object and executeQueryAsync() method on your context after importing the webpart - the latter function especially is responsible for sending the request to server and applying your changes.
Here's a nice article about adding webparts to pages programatically: How to programmatically add a ClientSide Web Part to a SharePoint page

Template to provide static HTML wrapping a page-specific value

I am creating a page template. Each page using the template will have a single unique value that gets embedded into the page HTML. The rest of the HTML is constant for all pages. Assume the following is the desired result:
click me
I want a template that provides click me, while allowing the individual pages (content admins) to provide id.
I've tried using an Editable Text web part, and putting the "before" and "after" HTML in the HTML Envelope before and after sections, and adding the ID on the "Page" tab. However, that is not quite working. What is the best way to accomplish this?
This can be done. What you'd want to do is add that field to the page type fields you're adding those pages with. For instance, say you have a list of locations under /locations.
i.e.:
/location/chicago
/location/new-york
/location/minneapolis
The locations themselves (Chicago, New York, Minneapolis) are your custom page type and have a unique field called LocationID. On your template, add a static text webpart (not static HTML because the WYSIWYG editor overwrites the markup you add) and simply add this:
click me
If the LocationID field has a exists AND has a value, it will output it, otherwise it will just leave the URL http://www.example.com/
If you didn't want to show that link at all on other pages, then set the Show for page types property based on the page type you want it to show for in the Visibility section of the static text webpart.

Extend Liferay 6.1 polls display to show a specific poll by GET param

Our portal editors want to share the polls display portlets in other portal content by using the widget url in an iframe.
The problem is they use (most times) the same portlet instances and only add a new question, so the shared widgets will also change.
So our idea was to extend the widget url with a GET param and overwrite the questionId in the JSP for polls_display:
// display a specific question
long questionIdFromParam = GetterUtil.getLong(ParamUtil.getString(request,"questionId"));
questionId = questionIdFromParam;
but the original questionId from init.jsp isn't recognized for getting the preferences as far i can see.

Is there any way we can display web-content on public page randomly on page refresh?

We are using liferay 6.1
On Public page we want to display web-content in one portlet, but it should not be only selected one.
we want to display it randomly on page refresh. Like on page refresh it should display different web content from group of web content.
Any hint ?
Thanks.
Consider to use structures & templates: With structures you give some contents of an article - this might be alternative content, or just a description of a filter that you want to display.
A simple structure (that contains all of the content in just one article, not exactly what you ask for) just has repeatable HTML text fields. Edit all of them with the content you want to show alternating.
In your template you read an article with this content, generate a random number and only show the fragment from the content that the random number suggests.
Another way is to have a template that queries Liferay's API for several articles. Then you randomly select one of them and display it.
Templates can be written in Velocity, Freemarker or XSL. The nice thing is they're completely runtime-configurable.
Liferay Blogs, particularly those of James Falkner, have a few articles on how to work with the API from templates.
You can customized the "Web Content Display" portlet with a hook.
Add to config-page the "show randomized" checkbox, get the list of existing journal articles and choose random one of them.

How to add content query webpart to publishing page layout?

How do you add a content query webpart to a apublishing page layout and configure it to aggregate content from the pages in the page library??Can some one give me some insight on this?? Do I drop a content query webpart in SP designer?? If I do that, how do I configure the query??
Or do I add a content query webpart using ribbon and then export it and make customizations and import and drop that one on the page layout??? Please someone???
SCENARIO: I have to insert a content query webpart to a publishing page layout for Physicians profile site. Based on the page layout, there will be profile pages for each physicians. Now, each physician's' profile page will have his/her primary practice location name, address, phone etc as well as other multiple practice locations. Say Mr Tom's primary location is listed as hospital 'x' on his profile page, now I want to be able to also aggregate the names of all the other lawyers that also work in hospital 'X' as Tom's office members on his bio page using content query webpart on the page layout. How do I add and configure the webpart? I mean it's easy to add a content query webpart in just one page and configure it but I want to add it on a page layout so all the content pages will have its implementation as the pages are created by the authors.
say there are 10 profile pages in the pages library and 5 of them have at least one of their pracice locations as hopital X(they may be working at hospital Y, Z..etc at the same time too), now I want all 5 doctors name aggregated on the Tom's profile pages as his office members!?
Lots of question marks... yes you can add the content query webpart to a layout by using SP designer. This will COPY that webpart to every page that is created using that layout (or has its layout switched to that one). That makes the query to set up tricky because it needs to get the input on WHICH physician from somewhere - check out this article here. Using the PageFieldValue option should do the trick.
To change a CQWP, don't modify the default version. Instead, navigate to your XSL file in the Style Library in SPD and copy the ItemStyle.XSL and rename the copy to something else (such as CUSTOMItemStyle.xsl). Then go to a test page, place a blank CQWP, and click "Export". Open the .webpart file that you exported and modify the properties to link to your CUSTOMItemStyle.xsl.
Save the .webpart file and import it back to the gallery through the browser. Rename the new CQWP (to something like CUSTOM_CQWP.webpart or whatever).
Now you can modify the CUSTOMItemStyle.xsl to use custom XSL. Shape the XSL file how your requirements dictate, then in your test page, change the Web Part properties to use your new custom ItemSTyle. Once your web part look like you want it to, you can export it again and then reimport it back into the gallery and all your settings will be saved.
Now you can go to Designer and add this web part to your page layouts. When the user uses that layout, the web part is already placed on the page and wired up accordingly. Additionally, by usign this method, they can change teh web part properties of the web part or even delete the web part altogether if they don't want it, without affecting your page layout.
http://msdn.microsoft.com/en-us/library/bb447557(v=office.12).aspx

Resources