sort Ektron content types - asp.net

Ektron 801 SP1
I am using the following code to fetch some smart form content. Can I pre-sort (using OrderByField?) before I fetch 20 rows? I am sorting memberlist but that is after the fact and kinda useless. What am I missing?
Criteria<ContentProperty> criteria1 = new Criteria<ContentProperty>();
criteria1.AddFilter(ContentProperty.XmlConfigurationId, CriteriaFilterOperator.EqualTo, MEMBERS_ID);
criteria1.PagingInfo = new PagingInfo(20);
List<ContentType<member>> memberslist = contentTypeManager.GetList(criteria1);

I have good news and bad news for you.
First, the good news. You can sort by Content Properties with the Criteria object before you pull the 20 items. You'll want to use the OrderByField and OrderByDirection properties of the criteria.
criteria.OrderByField = ContentProperty.DateCreated;
criteria.OrderByDirection = EkEnumeration.OrderByDirection.Descending;
The bad news comes when trying to order items based on fields within the Smart Form. You might be able to do so using the IndexSearch API, but since Ektron 8.0* still relies on Microsoft's Indexing Service, I'm not a fan of that approach and don't have any code to share. If you choose to go that route, the premise is to use search to return the content IDs in the correct order, then use the criteria, as you are, to get items with those IDs.
What you can do with just the API is use Microsoft LINQ to sort the data after it's loaded, but in order to get the right results in the right order you have to load all items first (and ideally cache them to minimize performance impact). I'm using one of my content types as an example, but you should get the idea.
var membersList = new List<SlideBannerType>();
var sortedList = membersList.OrderBy(s => s.EnableAlternateText);
var firstpage = sortedList.Take(20);
var nextpage = sortedList.Skip(20).Take(20);
It's not ideal, but it does work very well for smaller (in the hundreds, perhaps thousands, but not tens of) data sets.
The second bit of good news, though, is that Ektron uses Microsoft Search Server for versions 8.5 and up. This has a much, much more robust API and performs fantastic (both in terms of speed and reliability). The premise would actually stay the same as that for the IndexSearch, use Search to get the IDs in the right order, and then ContentManager (or ContentTypeManager) to get the items. I've used this approach several times, albeit not with Smart Forms specifically. Your best result would come from upgrading to 8.6 and Microsoft Search Server and using the two APIs together to get each page of data. In doing so, it would actually be almost trivial at that point to mix in advanced search and filter options as well with the new search APIs.

Related

youtube channel new ID and iframe list user_uploads

It seems that youtube are now using ID's for their channels instead of names (part of the V3 api)
However it seems that the embedded iframe playlist player cannot handle these channel ID's
example channel https://www.youtube.com/channel/UCpAOGs57EWRvOPXQhnYHpow
then ID is UCpAOGs57EWRvOPXQhnYHpow
Now try to load this
http://www.youtube.com/embed/?listType=user_uploads&list=UCpAOGs57EWRvOPXQhnYHpow
Can anyone shine a light on this issue ? Or is there some hidden username ?
I also placed this question at the gdata-issues website http://code.google.com/p/gdata-issues/issues/detail?id=6463
The issue here is that a channel is not a playlist; channels can have multiple playlists, yet the listType parameter is designed to look for an actual playlist info object. The documented way around this is to use the data API and call the channel endpoint, looking at the contentDetails part:
GET https://www.googleapis.com/youtube/v3/channels?part=contentDetails&id=UCuo5NTU3pmtPejmlzjCgwdw&key={YOUR_API_KEY}
The result will give you all of the feeds associated with that channel that you can choose from:
"contentDetails": {
"relatedPlaylists": {
"uploads": "UUuo5NTU3pmtPejmlzjCgwdw"
}
}
If available (sometimes with oAuth), there could also be "watch later" lists, "likes" lists, etc.
This may seem like a lot of overhead. In the short term, though, it can be noted that the different feeds are programmatically named; so, for example, if my user channel begins with UC and then a long string, that UC stands for 'user channel' -- and the uploads feed would begin with 'UU' (user uploads) and then have the rest of the same long string. (you'd also have 'LL' for the likes list, 'WL' for the watch later list, 'HL' for the history list, 'FL' for the favorites list, etc. This is NOT documented, and so there's no guarantee that such a naming convention will perpetuate. But at least for now, you could change your ID string from beginning with UC to beginning with UU, like this:
http://www.youtube.com/embed/?listType=user_uploads&list=UUpAOGs57EWRvOPXQhnYHpow
And it embeds nicely.
Just to inform on current state of things -- the change suggested by jlmcdonald doesn't work anymore, but you can still get a proper embed link via videoseries (with the same UC to UU change). I.o.w. link like
http://www.youtube.com/embed/videoseries?list=UUpAOGs57EWRvOPXQhnYHpow
works as of at the moment of writing this.

Javascript and Wordpress

Two related questions:
Is there any good documentation on the Fusion Tables Javascript API? I've found a list of methods, but with little info on return values, semantics, or usage idioms.
Is there any guidance (or suggested plugins or idioms) for integrating the FT Javascript API into a locally hosted Wordpress site?
There is some documentation here:
https://developers.google.com/fusiontables/docs/v1/getting_started#JS
but I didn't find it very useful.
But this example, in the context of the Google Maps API I found very useful for the new API 1.0
https://googledrive.com/host/0B5KVZ6J1ohN_Q3ZqVkFGSGZ2cEE/custom%20markers%20code/customicons_viaApi.html
You'll need to view and save the source. Also if you search the FT tag for JSONP you will find many examples using the old pre 1.0 API but the concepts are the same, just the AJAX end point has changed and the need for an apiKey.
The basic idea is that any FT query will return a JSON object with both columns and rows members, very much like a CSV response.
As the example above shows:
function onDataFetched(data) {
var rows = data.rows;
var cols = data.cols;
...
}

How to retrieve only an ASP.NET MVC3 Collection's Count without element properties

I am using ASP.NET MVC 3 to track hits on a set of stored links. I run into problems when displaying the hits' counts. I think this is because since I am using lazy loading, whenever I call
link.Hits.Count
it loads all of each hit's data, including such things as agent and referrer information. (Hits is a Collection.) This is an issue when a link has over 9000 hits. Is there a way of just getting the Hits' Count without it pulling in the Hits' data?
If the Hits has been written like this, the Count will work:
Hits = repository.GetAll(....).Where(....);
But if like this, the Count will not work, because the ToList() has already loaded all the data:
Hits = repository.GetAll(....).Where(....).ToList();

Applying more than one sort on a Tridion broker query

I have a broker query where I need to sort by 2 different fields (using JSP and 2011 SP1)
The API has the method "addSorting" which I am applying.
It appears, however, that the second addSorting call is overwriting the first addSorting call - rather than adding the second sort:
// Sort by Date
CustomMetaKeyColumn customMetaKeyColumnDate = new CustomMetaKeyColumn("date", MetadataType.DATE);
query.addSorting(new SortParameter(customMetaKeyColumnDate, SortParameter.DESCENDING));
// Sort by Owner
CustomMetaKeyColumn customMetaKeyColumnOwner = new CustomMetaKeyColumn("owner", MetadataType.STRING);
query.addSorting(new SortParameter(customMetaKeyColumnOwner, SortParameter.ASCENDING));
They sorts work fine individually.
Is this expected? Is addSorting really a setSorting - where only 1 sort can be specified or am I missing a way to combine 2 sorts?
The addSorting method works just fine. However, it simply does not work for CustomMeta columns!!! There is already a confirmed defect regarding this subject with the following summary: "SortParameter does not work with two metadata fields". This is still an open defect for 2011SP1 and is scheduled to be fixed only for the next release.
Cheers,
Daniel.

Dynamics GP Web Service -- Returning list of sales order based on specific criteria

For a web application, I need to get a list or collection of all SalesOrders that meet the folowing criteria:
Have a WarehouseKey.ID equal to "test", "lucmo" or "Inno"
Have Lines that have a QuantityToBackorder greater than 0
Have Lines that have a RequestedShipDate greater than current day.
I've succesfully used these two methods to retrieve documents, but I can't figure out how return only the ones that meet above criteria.
http://msdn.microsoft.com/en-us/library/cc508527.aspx
http://msdn.microsoft.com/en-us/library/cc508537.aspx
Please help!
Short answer: your query isn't possible through the GP Web Services. Even your warehouse key isn't an accepted criteria for GetSalesOrderList. To do what you want, you'll need to drop to eConnect or direct table access. eConnect has come a long way in .Net if you use the Microsoft.Dynamics.GP.eConnect and Microsoft.Dynamics.GP.eConnect.Serialization libraries (which I highly recommend). Even in eConnect, you're stuck with querying based on the document header rather than line item values, though, so direct table access may be the only way you're going to make it work.
In eConnect, the key piece you'll need is generating a valid RQeConnectOutType. Note the "ForList = 1" part. That's important. Since I've done something similar, here's what it might start out as (you'd need to experiment with the capabilities of the WhereClause, I've never done more than a straightforward equal):
private RQeConnectOutType getRequest(string warehouseId)
{
eConnectOut outDoc = new eConnectOut()
{
DOCTYPE = "Sales_Transaction",
OUTPUTTYPE = 1,
FORLIST = 1,
INDEX1FROM = "A001",
INDEX1TO = "Z001",
WhereClause = string.Format("WarehouseId = '{0}'", warehouseId)
};
RQeConnectOutType outType = new RQeConnectOutType()
{
eConnectOut = outDoc
};
return outType;
}
If you have to drop to direct table access, I recommend going through one of the built-in views. In this case, it looks like ReqSOLineView has the fields you need (LOCNCODE for the warehouseIds, QTYBAOR for backordered quantity, and ReqShipDate for requested ship date). Pull the SOPNUMBE and use them in a call to GetSalesOrderByKey.
And yes, hybrid solutions kinda suck rocks, but I've found you really have to adapt if you're going to use GP Web Services for anything with any complexity to it. Personally, I isolate my libraries by access type and then use libraries specific to whatever process I'm using to coordinate them. So I have Integration.GPWebServices, Integration.eConnect, and Integration.Data libraries that I use practically everywhere and then my individual process libraries coordinate on top of those.

Resources