I need to get all Web Content created with a specific Structure in a jsp portlet.
I try to use structureName but this throw a excepcion
ClassLoader cl = PortalClassLoaderUtil.getClassLoader();
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(JournalArticle.class, cl)
.add(PropertyFactoryUtil.forName("structureName").eq("Empresa"));
List <JournalArticle> journalArticles = JournalArticleLocalServiceUtil.dynamicQuery(dynamicQuery);
How i get the web content by structure?
You need to use the structureId field when query journalarticles and passing the structureKey as value like this way
DynamicQuery dynamicQueryStructure = DynamicQueryFactoryUtil.forClass(
DDMStructure.class).add(PropertyFactoryUtil.forName("name").like(
"%>Empresa</Name>%"));
List<DDMStructure> structures = DDMStructureLocalServiceUtil.dynamicQuery(dynamicQueryStructure, 0, 1);
if(!structures.isEmpty()) {
String structureKey = structures.get(0).getStructureKey();
ClassLoader cl = PortalClassLoaderUtil.getClassLoader();
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(JournalArticle.class, cl)
.add(PropertyFactoryUtil.forName("structureId").eq(structureKey));
List<JournalArticle> journalArticles = JournalArticleLocalServiceUtil.dynamicQuery(dynamicQuery);
}
There's no need to construct dynamic queries and fiddle with class loader, JournalArticleService can do that.
See JournalArticleLocalServiceUtil#getStructureArticles(groupId, dmStructureKey).
Related
I have written a helper function (I'm quite proud of this it - look what I can do!) that does what I need. Is there a built in way, though, to access a ContentItem's fields without having first to get the "main" ContentPart? The word "main" here means the ContentPart with the same name as the ContentType.
#functions
{
dynamic GetMainPartFromContentItem(ContentItem item)
{
var contentType = item.TypeDefinition.Name;
var parts = item.Parts as List<Orchard.ContentManagement.ContentPart>;
dynamic mainPart = parts.First(p => p.PartDefinition.Name.Equals(contentType));
return mainPart;
}
}
dynamic mainPart = GetMainPartFromContentItem(contentItem);
var shortTitle = mainPart.ShortTitle.Value; // access an InputField's value
If you have a ContentType called Page with a field called Topic you can do:
dynamic item = Model.ContentItem;
string topic = item.Page.Topic.Value;
Basically when you add fields directly to the content item, they are being added to a part on your content item called whatever your content type is, in this case Page
The situation is:
I've got subsite(SPWeb) htp://servername/subsitename/
and i need to use CrossListQueryInfo to find item in all lists but just in this subsite(SPWeb)
i do:
var query = new CrossListQueryInfo
{
Lists = "<Lists ServerTemplate=\"100\" />",
ViewFields = "...",
Webs = "<Webs Scope=\"Recursive\" />",
WebUrl = web.ServerRelativeUrl,
UseCache = true,
Query = "..."
};
var cache = new CrossListQueryCache(query);
var dataTable = cache.GetSiteData(web.Site, CrossListQueryCache.ContextUrl()))
but this search in whole sitecollection, what is rigth way to use it? what do i miss?
In order to retrieve items only for specific site, specify for Webs property empty value.
According to MSDN:
The Webs property specifies which Web sites to include in the query.
By default, the query considers only the Web site from which the
GetSiteData method was invoked.
You can broaden the scope of the query
by setting the Webs property to a string containing a Webs tag and a
Scope attribute. Possible values of the Scope attribute include
Recursive and SiteCollection.
<Webs Scope="Recursive" />
<Webs Scope="SiteCollection" />
When the Scope attribute is set to Recursive, the query considers the
current Web site and all subsites of the current Web site.
When the
Scope attribute is set to SiteCollection, the query considers all Web
sites that are in the same site collection as the current Web site. Of
the two attribute values, this is the more inclusive
So, the updated code:
var query = new CrossListQueryInfo
{
Lists = "<Lists ServerTemplate=\"100\" />",
ViewFields = "...",
Webs = string.Empty, // considers only the Web site from which the GetSiteData method was invoked
WebUrl = web.ServerRelativeUrl,
UseCache = true,
Query = "..."
};
var cache = new CrossListQueryCache(query);
var dataTable = cache.GetSiteData(web.Site, CrossListQueryCache.ContextUrl()))
The requirements is easy. Someone publish a JournalArticle with some Tags (TagA, TagB). On the other pages (Layouts) we have AssetPublisher portles that show all JournalArticles with those Tags (e.g. TagA or TagB). The question is, how to get this layouts programmaticaly?
I solve it with recursive DynamicQuery, enjoy:
public static Set<Layout> getLayoutsWithThisTags(SortedSet<String> tags) throws SystemException, PortalException {
Set<Layout> layouts = new HashSet<Layout>();
//build DynamicQuery that contains "assetTags" as "queryName0", see configuration of AssetPublisher
DynamicQuery query = DynamicQueryFactoryUtil.forClass(com.liferay.portal.model.PortletPreferences.class, PortalClassLoaderUtil.getClassLoader())
.add(PropertyFactoryUtil.forName("preferences").like("%<preference><name>queryName0</name><value>assetTags</value></preference>%"))
.add(getTagConditions(tags));
Set<PortletPreferences> preferences = new HashSet<PortletPreferences>(PortletPreferencesLocalServiceUtil.dynamicQuery(query));
for (PortletPreferences portletPreferences : preferences) {
long plid = portletPreferences.getPlid();
layouts.add(LayoutLocalServiceUtil.getLayout(plid));
}
return layouts;
}
private static Criterion getTagConditions(SortedSet<String> tags) {
//create recursive OR-Criterion that contains any of the tags
Criterion criterion = RestrictionsFactoryUtil.or(
PropertyFactoryUtil.forName("preferences").like("%<preference><name>queryValues0</name>%<value>" + tags.first() +"</value>%"),
(tags.size() > 2) ? getTagConditions(tail(tags)) :
PropertyFactoryUtil.forName("preferences").like("%<preference><name>queryValues0</name>%<value>" + tags.last() +"</value>%"));
return criterion;
}
private static SortedSet<String> tail(SortedSet<String> tags) {
tags.remove(tags.first());
return tags;
}
for Portal with 250 Pages (Layouts) this code need 12ms.
Suddenly this came to my mind :-)
List assetPublisherLayouts;
List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(groupId, privateLayout);
for (Layout layout : layouts)
{
if(layout.getTypeSettings().contains("101_INSTANCE")) {
assetPublisherLayouts.add(layout);
}
}
While 101 being the protlet ID for Asset publisher and it is instantiable..
I can think of two ways:
Using DynamicQuery to fetch Layouts that contain Asset Publisher portlets and then processing the Layout list retrieved for those specific layouts which have Asset Publisher with TagA & TagB.
The code might be something like this (disclaimer: it is just pseudo code :-)):
layoutDynamicQuery.add(RestrictionFactoryUtil.ilike("typeSettings","%101_INSTANCE%"));
List<Layout> layoutList = LayoutLocalServiceUtil.dynamicQuery(layoutDynamicQuery);
List<Layout> finalLayoutList = new ArrayList<Layout>();
for (Layout layout : layoutList) {
// 1) fetch portletIds for this layout
// 2) fetch relevant PortletPreferences for the instance-id for the AssetPublisher portlet, can use PortletPreferencesLocalServiceUtil
// 3) Check if the tags (TagA & TagB) are present in the preference retrieved.
// 4) if point-3 is true then: finalLayoutList.add(layout);
}
Using custom-sql to fetch the Layouts in a single complex sql query, by joining/subquerying required tables like AssetTags, Layout, PortletPreferences etc.
This is not a general requirement scenario in liferay, so it is obvious that there won't be a direct way of doing this.
Hope this proves to be of some help.
I am working on SharePoint 2010.I have an documentlibrary ID and document ID in that library with me.i don't have either web,site in which the document library is present.So now I have to get the Full URL of the document at runtime.How can I get it .
I have tried the following.
string filepath = currentList.DefaultViewUrl + "/" + sListItem.Url;
Please answer this.
Use the field "EncodedAbsUrl" on the SPListItem. Works for SPFile as well:
SPListItem item = ...;
string absUrl = (string) item[SPBuiltInFieldId.EncodedAbsUrl];
or for a SPFile
SPFile file = ...;
string absUrl = (string) file.Item[SPBuiltInFieldId.EncodedAbsUrl];
The built in field id is for sure the best way to go but it returns the Url as encoded which may or may not be what you want.
I think the best way is to add a little extension method to a utilities class somewhere:
public static string AbsoluteUrl(this SPFile File, bool Decode = true)
{
string EncodedUrl = File.Item[SPBuiltInFieldId.EncodedAbsUrl].ToString();
if (Decode)
return SPEncode.UrlDecodeAsUrl(EncodedUrl);
else
return EncodedUrl;
}
And then call as follows
Item.File.AbsoluteUrl();
if you want a decoded Url or
Item.File.AbsoluteUrl(false);
if you want the Url to remain encoded.
Note that the default parameter value for Decode will only be available in .Net4+ and therefore SP2013 only but you can easily create an overload method for SP2010. You'll also need a reference to Microsoft.SharePoint.Utilities namespace to access the SPEncode class.
Try this ,
using (SPSite ospSite = new SPSite("http://abcd:24931"))
{
using (SPWeb web = ospSite.OpenWeb("/subsite")
{
// Get document library collection here and fetch all the document urls
SPDocumentLibrary docLib = (SPDocumentLibrary)web.Lists["docu"];
//where docu is my document library
SPListItemCollection items = docLib.Items;
foreach (SPListItem item in items)
{
string url = item.Url;
}
}
}
Hope this shall get you going.
public string GetItemURL(SPListItem item)
{
string web = item.Web.Url;
string listID = item.ParentList.ID.ToString();
string contentType = item.ContentTypeId.ToString();
string itemID = item.ID.ToString();
string url = web+"/_layouts/listform.aspx?PageType=4&ListID={"+listID+"}&ID="+itemID+"&ContentTypeID="+contentType;
return url;
}
It's Working for me. Hope I help (List Item url)
If this is for the document library, try this one.
item.Web.Url+"/"+item.File.Url
Use below code to get absolute URL of file:
SPFile file;
string url = file.Item[SPBuiltInFieldId.EncodedAbsUrl] as string;
For what it's worth, accessing the item.Web property means you are actually instantiating the SPWeb object which means that this should be disposed otherwise you'll be causing memory leakage.
It's a lot of overhead when there are better and quicker ways already mentioned.
I would use the BuiltInFieldId.EncodedAbsUrl approach mentioned since this gives you the easiest access to what you want.
The answer is
string url = currentweb.url+"/"+ Listitem.url;
I tried searching on the net to programmatically insert a List as a webpart in a webpart page but was not lucky enough.
Any thoughts or ideas how i could Programmatically insert a List as a webpart in a webpart page
Many Thanks!
First add these using statements.
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
Then in your code
// First get the list
SPSite site = new SPSite("http://myserver");
SPWeb web = site.OpenWeb();
SPList list = web.Lists["MyCustomlist"];
// Create a webpart
ListViewWebPart wp = new ListViewWebPart();
wp.ZoneID = "Top"; // Replace this ith the correct zone on your page.
wp.ListName = list.ID.ToString("B").ToUpper();
wp.ViewGuid = list.DefaultView.ID.ToString("B").ToUpper();
// Get the web part collection
SPWebPartCollection coll =
web.GetWebPartCollection("default.aspx", // replace this with the correct page.
Storage.Shared);
// Add the web part
coll.Add(wp);
If you want to use a custom view, try playing with this:
SPView view = list.GetUncustomizedViewByBaseViewId(0);
wp.ListViewXml = view.HtmlSchemaXml;
Hope it helps,
W0ut
You need to perform two steps to add a web part to a page. First you have to create the list you want to show on the page. Therefore you can use the Add() method of the web site's list collection (SPListCollection).
To show the list on the web part page you have to add a ListViewWebPart to the web part page using the SPLimitedWebPartManager of the page.
To make this more re-usable as part of a feature receiver, you could pass in the splist and spview as part of a method:
static public void AddEventsListViewWebPart(PublishingPage page, string webPartZoneId, int zoneIndex, string webPartTitle, PartChromeType webPartChromeType, string listName, string viewname)
{
using (SPLimitedWebPartManager wpManager = page.ListItem.File.GetLimitedWebPartManager(PersonalizationScope.Shared))
{
SPWeb web = page.PublishingWeb.Web;
SPList myList = web.Lists.TryGetList(listName);
using (XsltListViewWebPart lvwp = new XsltListViewWebPart())
{
lvwp.ListName = myList.ID.ToString("B").ToUpperInvariant();
lvwp.Title = webPartTitle;
// Specify the view
SPView view = myList.Views[viewname];
lvwp.ViewGuid = view.ID.ToString("B").ToUpperInvariant();
lvwp.TitleUrl = view.Url;
lvwp.Toolbar = "None";
lvwp.ChromeType = webPartChromeType;
wpManager.AddWebPart(lvwp, webPartZoneId, zoneIndex);
}
}
}
And then call it during feature activation:
AddEventsListViewWebPart(welcomePage, "Right", 1, "Events", PartChromeType.TitleOnly, "Events", "Calendar");