I would like to ask if there is any Java API call in liferay which returns the web contents, which were uploaded by a specific user.
For example, I have one user who has upload some content and I want to show in a portlet this content, how can I do this via java?
If you are specifically talking about web-content which is displayed inside Web-content Display portlet, then you can use the JournalArticleService and JournalArticleLocalService API to fetch the content depending upon the User.
Prior to Liferay 6.0 Web-content was known as JournalArticle and hence the API name has not changed.
So for example:
You can use DynamicQuery API, as follows:
long userId = 10987L; // ofcourse you need to find this
DynamicQuery dynamicQuery = JournalArticleLocalServiceUtil.dynamicQuery();
dynamicQuery.add(RestrictionsFactoryUtil.eq("userId", userId));
int startOfList = 0;
int endOfList = 1000;
// if you want all the JournalArticle retrieved then use:
// int endOfList = QueryUtil.ALL_POS;
// this will retrieve the list of webcontents
List<JournalArticle> articles = (List<JournalArticle>) JournalArticleLocalServiceUtil.dynamicQuery(dynamicQuery, startOfList, endOfList);
The above code will retrieve all the JournalArticles so you would get all the versions of a single web-content since all these versions are stored in the same JournalArticle table. So for this you can add conditions to the dynamicQuery for the fields like version, id, resourcePrimKey, articleId, groupId, companyId etc.
Or if you have more complex needs than you can create a custom-sql-finder in liferay to fetch the desired data from any combination of Liferay DB tables.
If you are talking about contents as in Blogs, Wikis, Files, Webcontents etc then either use their respective *LocalServiceUtil or you can use AssetEntryLocalServiceUtil to fetch the assets for a particular User.
So with AssetEntryLocalServiceUtil also you can use the DynamicQuery API as shown above. The code may not be same but will be along the same lines.
You can know more about DynamicQuery API from this blog.
Related
When Kentico documents have images embedded in them, the image is inserted into the HTML as an <img> tag. I need to determine if this image is hosted by Kentico and if so, use the Kentico API to retrieve the database information for it.
So far I have parsed the File GUID out of the URL like this:
const string attachmentPrefix = "~/getattachment/";
if (imageElement.LinkAddress.StartsWith(attachmentPrefix))
{
var start = attachmentPrefix.Length;
var end = imageElement.LinkAddress.IndexOf("/", start);
var fileGuidString = imageElement.LinkAddress.Substring(start, end - start);
var fileGuid = new Guid(fileGuidString);
var info = AttachmentHistoryInfoProvider.GetInfoByGuid("-- what goes here --", fileGuid);
}
But I have not found any useful methods in the Kentico API that will retrieve information about the attachment from the GUID. The closest I found was AttachmentHistoryInfoProvider.GetInfoByGuid() but it takes an objectType parameter that I can't find any documentation for.
Does anyone know how to get information on attachments in Kentico 7 starting from a File GUID?
You mention that you're talking about images in the media library, but are trying to use the AttachmentHistoryInfoProvider in your code sample. I think it depends on what you are referring to when you say 'documents have media library images embedded in them'; in what way are you embedding them? Perhaps using the Editable image web part for example.
If you are using files from the media library, you should try using MediaFileInfoProvider.GetMediaFileInfo(Guid, string) which takes the Guid of the file and the site code name. This will return you a MediaFileInfo class. You can find it in the CMS.DataEngine assembly in Kentico 7. For a file from a media library, I'd expect to see a URL like /SampleSite/media/cats/nohandskitten.aspx to be rendered.
If you're not using images from the media library, but are inserting directly into content, then yes - this is an attachment. Rather than using AttachmentHistoryInfoProvider, you should use AttachmentInfoProvider. Calling AttachmentInfoProvider.GetAttachmentInfo(Guid, string) with the Guid of the file and the site code name will return the AttachmentInfoObject. I believe the AttachmentHistoryInfoProvider will only return things to you if you have object versioning enabled. For a file from an attachment, I'd expect to see a URL like /getattachment/75408145-0995-45dc-943a-d27296a45327/nohandskitten.jpg.aspx.
These InfoProviders do fundamentally different things, so long as you know what type of information you're looking for, you should be able to choose the correct one
If you don't have it already, the API reference for Kentico 7 may be helpful: https://devnet.kentico.com/docs/7_0/kenticocms_api.zip
I am xpages enabling an old Notes application which is using profile documents to store translated labels. The translated lables in the notes form are read from the profile document using #GetProfileField depending on which language the user have selected in their profile.
I have read that profile documents are not recommended to use with xpages so I need a better solution for my xpages users. but it is important that users using Notes client still use the "old" profile document solution.
How can I provide these translation lables to my xpages users?
Thanks
Thomas
In addition to Knut's answer there is also the option to "double" your translated labels via the way to prefer in XPages dev by using the localization options as described here: http://www-10.lotus.com/ldd/ddwiki.nsf/dx/UsingLocalizationOptions.htm
You need to split the task into two. First have a function that is called inside the XPage to get the label you are looking for, secondly have a way to provide that value inside the function.
Making a direct call to the profile isn't a good idea since it fixes the way you provide the data (besides potentially creating a memory leak if you don't recycle dilligently). I would see 4 potential solutions:
Define your profile document as additional data source and simply bind the labels to items in the document. Saves you most of the recycling work, but couples tight
Use a SsJS function: getLabel(name). It would check for a scope variable (a Map) and if not found load it - currently from your profile. If application scope is good enough, you touch the profile once only- speed. If you change the loader later on - you don't need to change anything in the XPage.
Use a managed bean. Same approach as #2, only now you can use el data binding. Your bean needs to implement Map
If the labels hardly change do a design time conversion and write the profile doc out into properties files (works nicely with ODP) and use XPages internal mechanism for internationalization
Let us know how it goes
You can use profile documents for this use case as the content gets changed only with new versions of your project probably. So, you can easily live with profile document's caching.
You get the label translation from a profile document with
var doc = database.getProfileDocument("LabelsEnglish", "");
var label = doc.getItemValueString("label1");
doc.recycle();
return label;
You could read all labels in an application scope variable Map too and do your own caching. This way profile documents would get read only once.
if (!applicationScope.labels) {
var map = new java.util.HashMap();
var doc = database.getProfileDocument("LabelsEnglish", "");
var allItems = doc.getItems();
for (var i = 0; i < allItems.size(); i++) {
var item = allItems.elementAt(i);
item.getName();
map.put(item.getName(), item.getValueString());
item.recycle();
}
doc.recycle();
applicationScope.labels = map;
}
Execute the SSJS code above in a custom control which is included in every XPage (e.g. application layout custom control) in before page load event so you can be sure application scope variable "labels" is initialized when you want to use it. You can access the labels easily with EL
applicationScope.labels.label1
I have started developing portlets with Liferay and I would like to show one (or more) Web-content article(s) with a specified structure.
For example, suppose I've a structure "A" so how can I get the last web-content article which is created using this structure?
This article explains how to get articles with a tag but not with a structure.
Thank you
The Liferay API Docs (this is for 6.1, as I don't know what version you're using) are your friend as is the Liferay source code.
In short you'll want to use one of the following API methods:
JournalArticleLocalServiceUtil.getStructureArticles(long groupId, String structureId);
JournalArticleLocalServiceUtil.getStructureArticles(long groupId, String structureId, int start, int end, OrderByComparator obc)
These rely on knowing the ID of the structure from which your content was generated, if you don't know what it is then you can use the following API method to get a list of all of them for your current Community:
JournalStructureLocalServiceUtil.getStructures(long groupId)
You can also use similar methods to find Journal Articles by the JournalTemplate that they use:
JournalTemplateLocalServiceUtil.getStructureTemplates(long groupId, String structureId);
JournalArticleLocalServiceUtil.getTemplateArticles(long groupId, String templateId);
JournalArticleLocalServiceUtil.getTemplateArticles(long groupId, String templateId, int start, int end, OrderByComparator obc)
Comment back if you have any questions, or if this answers your question please hit the "Accept answer" button tick! Thanks!
I was playing around with custom Search Indexing Handlers for SDL Tridion 2011 (GA). I got something working, using the very helpful information provided by Arjen, however I am not sure if my execution is the best option.
The requirement is to be able to search for pages in the CMS by url (eg www.example.com/news/index.html). In order to do this I have the created a class using the ISearchIndexingHandler interface (code below). I am indexing the url in the ContentText field of the item, however I am not sure if this would normally contain something else for a page (I think a page only has metadata so this should be OK). The advantage of using this over a custom field is that I can simply type the url in the search box without having to use <url> IN <fieldname> or something like that.
So my question is, is there any reason not to use ContentText for Pages, and is there any advantage in using a custom field? Also bonus marks go to anyone with good ideas on how to handle BluePrinting (if I create a page in a parent publication, I want the local urls also to be indexed in the child publications), and the case where a Structure group path is altered (I guess I can somehow trigger a re-index of child page items from within my indexing handler).
The code:
using System;
using Tridion.ContentManager.Search;
using Tridion.ContentManager.Search.Indexing.Handling;
using Tridion.ContentManager.Search.Indexing.Service;
using Tridion.ContentManager.Search.Indexing;
using Tridion.ContentManager.Search.Fields;
namespace ExampleSearchIndexHandler
{
public class PageUrlHandler : ISearchIndexingHandler
{
public void Configure(SearchIndexingHandlerSettings settings)
{
}
public void ExtractIndexFields(IdentifiableObjectData subjectData, Item item, CoreServiceProxy serviceProxy)
{
PageData data = subjectData as PageData;
if (data != null)
{
PublishLocationInfo info = data.LocationInfo as PublishLocationInfo;
string url = GetUrlPrefix(data) + info.PublishLocationUrl;
item.ContentText = url;
}
}
private string GetUrlPrefix(PageData page)
{
//hardcoded for now, but will be read from publication metadata
return "www.example.com";
}
}
}
You can store the url in the ContextText Property. Thies field is used to index Template content data.
Tridion does not index shared item(s) of child publication.
Indexing is triggered on Item modification(create, update, delete, localize and unlocalize).
Or you can use reindexing tool to reindex ur item. but there is no way to index shared items in child publication.
I don't think you can include the URL prefix in neither your search query as the indexed item. Because shared items are not indexed, you will probably index the Page from the Website Structure layer, which is never published.
When a Structure Group is moved you would have to make an event handler that triggers re-indexing all child pages using a protected method of the TOM.NET API. This method is not part of the public API, so posting the code for that solution would probably declare me a persona non grata with R&D :)
Before you re-index anything you should store the original publish location url of the Structure Group in the TcmEventArgs.ContextVariables property, so you can verify whether or not a re-indexing action is necessary.
Environment:
I have a windows network shared desktop application written in C# that leans against an MSSQL database. Windows sharepoint services 3.0 is installed (default installation, single processor, default sql express content database and so on) on the same Windows Server 2003 machine.
Scenario:
The application generates MS Word documents during processing (creating work orders) that need to be saved on sharepoint, and the result of the process must be linked to the corresponding document.
So, for each insert in dbo.WorkOrders (one work order), there is one MS Word document. I would need to save the document ID from the sharepoint library to my database so that later on, possible manual corrections can be made to the document related. When a work order is deleted, the sharepoint document would also have to be deleted.
Also, there is a dbo.Jobs table which is parent to dbo.WorkOrders and can have several work orders.
I was thinking about making a custom list on sharepoint, that would have two ID fields - one is the documents ID and the other AutoID of the document. I don't think this would be a good way performance-wise and it requires too much upkeep, therefore it's more error prone.
Another path I was contemplating is metadata. I could have an Identity field in dbo.WorkOrders that would be unique and auto incremented, and I could save that value as a file name (1.docx, 2.docx 3.docx ... n.docx where n would be the value in dbo.WorkOrder's identity field). In the metadata field of the Word document, I could save the job ID from dbo.Jobs.
I could also just increment the identity field in the WorkOrder (it would be a bigint), but then the file names would get ugly and maybe I'd overflow the ID range (since there could be a lot of documents).
There are other options also that I have considered and dismissed, since none of them satisfied the requirements (linked data sources, subfolder structures etc.). I'm not sure how to proceed. I'm new to sharepoint and it's still a bit of a mystery to me, as I don't understand all the inner workings of the system.
What do you suggest?
Edit:
I think I'll be using guid as file names and save those guids in my database after sending documents to sharepoint. What do you think of that?
All the documents in SharePoint under the same Content Database (SQL Database) are stored in the same table, that said, you have an unique ID for files no matter where they are in the sharepoint structure.
When retrieving files by their UniqueID The API only gives you the option to get them if you also know their SPWeb, so you could easily store, for each record you have in your external database (or your custom list, the SPFile GUID and the SPWeb GUID) retrieving them with:using(SPWeb subweb = (SPContext.Current.Site.OpenWeb(new Guid("{000...}")))
{
SPFile file = subweb.GetFile(new Guid("{111...}"));
// file logic
}
ps.: As Colin pointed out, url retrieval is possible but messy. I also changed the SPSite to the context since you are always under the same Site Collection in my example.
Like F.Aquino said, all items in sharepoint have a UniqueId field already (i.e. SPListItem.UniqueId and SPFile.UniqueId), which is a guid. Save that to your database, along with your web.'s guid. Then you can use the code provided by F.Aquino to get the file, or even the byte[] of the stream.
P.S. for F.Aquino, your code leaves the SPSite in memory, use this instead:
P.P.S this is just clarification, mark F.Aquino as the answer.
using(SPSite site = new SPSite("http://url"))
{
using(SPWeb subweb = site.OpenWeb(new Guid("{000...}"))
{
SPFile file = subweb.GetFile(new Guid("{111...}"));
// file logic
}
}