I'm trying to use a Web content Display to show all the files in a particular folder of document library.
I would like to keep customize the choice of the folder.
Do you know if exist a dynamic element in template that point to a folder not to a specific field in the document library?
If is not possible someone know a different way to do that?
thanks in advance
Sabrina
You can create structure that holds text field for folderId named "folderId".
Than create template
#set($service = $serviceLocator.findService("com.liferay.portlet.documentlibrary.service.DLFileEntryLocalService"))
#set($gid = $getterUtil.getLong($request.get("theme-display").get("scope-group-id")))
#set($fid = $getterUtil.getLong($folderId.getData()))
#set($files = $service.getFileEntries($gid, $fid))
#foreach($doc in $files)
#set($uet = $httpUtil.encodeURL($htmlUtil.unescape($doc.getTitle())))
$doc.getTitle()<br />
#end
Create article by that template/structure and enter folder id that you want to display. Add "Web content display" portlet that displays this article.
UPDATE:
For Liferay 6.1 method signature was changed and is
List<DLFileEntry> getFileEntries(long groupId, long folderId, int start, int end, OrderByComparator obc)
So for liferay 6.1 you should change call to be at least
#set($files = $service.getFileEntries($gid, $fid, -1, -1, null))
or change for start/end/sort.
You could use the Document Library Display portlet to accomplish this.
Related
Has anyone found a way to automatically add a jslink URL to lists by default instead of having to add the URL to every list manually when they are created? Ultimately we'd like to have default jslink for each type of app the editors have access to.
yes, this was described perfectly by Chris O'Brien here: http://www.sharepointnutsandbolts.com/2013/01/using-jslink-to-change-ui-of-sharepoint_20.html
short story - you should create list template and define jslink there, so all lists based on this template would have the js link. If you don't want to assosiate lists with templates by any reason, you should look into event receivers. (for List created event.)
Another solution is to write your own code to update all of your pages.
On this page Tobias Zimmergren shows a code updating JSLink with PowerShell:
PowerShell: Configure the JSLink property of a Web Part
I personally use C# CSOM to update JSLink on all requested pages.
Here is the sample code which updates JSLink on one page (for simplicity I have stripped out exception handling and all non-happy-path logic):
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.WebParts;
void UpdateWebPart(ClientContext webpartContext, string RelativeUrl, string JSLink)
{
File page = webpartContext.Web.GetFileByServerRelativeUrl(RelativeUrl);
LimitedWebPartManager wpm = page.GetLimitedWebPartManager(PersonalizationScope.Shared);
webpartContext.Load(page);
webpartContext.Load(wpm.WebParts, wps => wps.Include(w => w.WebPart.Title, w => w.WebPart.Properties));
webpartContext.ExecuteQuery();
if (wpm.WebParts.Count > 0)
{
// You can find your WebPart inside wpm.WebParts e.g. by Title. On each page I have only 1 WebPart, so I just take the first.
WebPartDefinition wpd = wpm.WebParts[0];
WebPart myWP = wpd.WebPart;
if ((string)myWP.Properties["JSLink"] != JSLink)
{
myWP.Properties["JSLink"] = JSLink;
wpd.SaveWebPartChanges();
webpartContext.ExecuteQuery();
}
}
}
webpartContext is SharePoint ClientContext created earlier
RelativeUrl is something like: "/Lists/Sample%20Tasks/AllItems.aspx"
JSLink is new value for JSLink of WebPart, which you want to update
We are looking for information on how to add content to an Editable Image programatically (with the Kentico C# API). Essentially, the equivalent of this Editable Region article for an Editable Image.
Any suggestions?
Thanks,
Victor
References:
CMSEditableImage Docs
Devnet Update EditableRegion Programatically
CMSEditableImage Class
You Sure Can
Each individual editable cms page control is stored in the document's DocumentContent field and can be accessed using an indexer field. For example:
TreeNode document = DocumentContext.CurrentDocument;
string editableImageControlId = "EditableImage1";
// get the field value
string editableImageContent = document.DocumentContent.EditableRegions[editableImageControlId];
// set it to something new
document.DocumentContent.EditableRegions[editableImageControlId] = newValue;
HOWEVER
If you look at the DocumentContent field in CMS_Document in the database you'll notice that all of the content is XML. That's because each control is serialized into XML and then nested inside this field. Thus, in this case, the value of the editableImageContent variable is an XML string:
<image>
<property name="imagepath">
~/Folder/ImageName.png
</property>
</image>
I wouldn't recommend trying to modify this directly since there's no telling if Kentico would ever change this code, or the individual control would ever change its serialization output.
But if you really must
You've got a couple of options:
1. Per #josh, you could create a new control that wraps the existing one and do some method override magic so that the control continues to do the serialization on your behalf and you just modify it after the fact. However this requires that the control is currently loading.
2. You could just hard code the beast and deal with it if it ever changes (which it likely will). Try:
// get the node from wherever you need to get the node
TreeNode document = DocumentHelper.GetDocuments().TopN(1).FirstObject;
var relativeMediaFilePath = "~/NewImage.png";
var xmlImage = string.Format("<image><property name=\"imagepath\">{0}</property></image>", relativeMediaFilePath);
var cmsControlId = "editableImage1";
if (document.DocumentContent.EditableRegions.ContainsKey(cmsControlId)) {
document.DocumentContent.EditableRegions[cmsControlId] = xmlImage;
}
else {
document.DocumentContent.EditableRegions.Add(cmsControlId, xmlImage);
}
// a little hack to get this field to be indicated as updated
document.SetValue("DocumentContent", document.DocumentContent.GetContentXml());
document.Update(true);
You could clone the editableimage webpart and then work in the prerender or change the override for the GetContent() method and add your own part of the string or do a string replace and add your code.
What is that you want to add to an Editable Image? - image path?! Not sure why you'd do that, but I'd take another direction: I'd add a field to a page type, which makes it much easier to work with through API. Having this field set up with API is should be quite easy to get it on the page... e.g. place editable image and use a macro to get field value.
Use
node.DocumentContent.EditableWebParts
and
node.DocumentContent.EditableRegions
collections to programmatically update editable content.
The best code example can be spotted at \CMS\CMSModules\Content\CMSDesk\Properties\Advanced\EditableContent\Main.aspx.cs
It's the dialog under Pages->General->Advanced->Edit regions & web parts.
I'd like to use custom fields to display some page specific strings in the theme.
I have created a custom field "intro" of type Textbox.
How do I access the data in the theme template (velocity)?
As there is no "introspection" which variables are declared, I find it very difficult to figure out how to access them. The documentation is far from usable on the topic of custom fields :-/
If you definde custom attribute in a page than you can use
$layout.getExpandoBridge().getAttribute("intro")
Also see javadoc or source for com.liferay.portlet.expando.model.ExpandoBridge
if you need use in template FTL, in my case for menu navigation template
<#assign prop = navItem.getLayout().getExpandoBridge().getAttribute("prop_name") >
Work for me in Liferay 7+:
Create a custom field type "site", fill data into site settings, and use into theme template for call this data into liferay theme:
If a VM file:
#set ($site_custom_field = $layout.getGroup().getExpandoBridge().getAttribute("site_custom_field_key"))
<h1>$site_custom_field</h1>
If a FTL file:
<#assign site_custom_field = layout.getGroup().getExpandoBridge().getAttribute("site_custom_field_key")>
<h1>${site_custom_field}</h1>
Have a nice day!
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);
...
}
If anyone is having idea how to customize properties in a smartpart. I have created usercontrol and i m wrappin it in a smartpart.I want to upload my xml from Document library.
private string feedXML;
[Browsable(true),
Personalizable(true) ]
public string FeedXML
{
get
{ return feedXML; }
set
{ feedXML = value; }
}
and I am using this like
//
feedXML="\customxml.xml";
XPathDocument doc = new XPathDocument(Server.MapPath(feedXML));
but this thing is not working . When I am clicking on modify shared webpart of sharepoint page is not rendering. Any clue where I m getting wrong.
You might want to verify the result of your server.mappath statement. It will be something like C:\Inetpub...
So your code is trying to retrieve a file from the filesystem that really lives in SharePoint because you have uploaded it to a Document Library.
If you want that file you'll have to retrieve it using the SharePoint object model, have a look at the GetFileAsString method.
I agree with Denni..
Seems like Smartpart is only making it more difficult? What advantages does it have?
I make my own webpart containers for ascx controls.. very little work and all the control you need. No problems with trust settings either.
Are you sure this is correct?
feedXML="\customxml.xml";
Perhaps, what you want is:
feedXML="\\customxml.xml"; //escape the back-slash.
or
feedXML="/customxml.xml"; // use the forward-slash.
Anyway, if you just want to wrap your user control inside a Web part, you don't need the SmartPart. You can write your custom Web part yourself quite easily.