Programmatically Publish a List as a Catalog with Cross Site Publishing in SharePoint 2013
Publishing (or nominating) a list as a catalog for use with the cross site publishing feature in SharePoint 2013 is possible both through the UI and through API. If you need an overview of cross site publishing then you may want to look into my other post about Search Driven Publishing using Managed Navigation and Cross-Site Collection Publishing here. You will find a lot out about strictly XSP from that but the overall context touches on Managed Navigation in addition to ultimately cover a new publishing architecture. This post is based on Technical Preview of SharePoint 2013.
As a prerequisite to nominating the list you will need to have activated the site collection feature for Cross-Site Collection Publishing.*
Microsoft.SharePoint.Publishing.PublishingCatalogUtility is the type that will be used to actually publish, MSDN documentation is here.
PublishingCatalogUtility.PublishCatalog has a few overloads giving flexibility around some of the optional settings. A connecting site may choose not to use defaults provided from the catalog for Catalog Navigation and Primary Key and choose their own, one or the other, or neither based on how they want to integrate or choose to not integrate at all. One overload allows a simpler nomination without FURL fields and Catalog Navigation field defaults specified, the other two present a couple ways of nominating while specifing some default integration options.
I will give an example using the fuller PublishCatalog overload which adds the complexities in and not cover the other two since they are along the same lines except being somewhat simpler. I consider the one below because it introduces us to the CatalogTaxonomyFieldSettings type in addition to PublishingCatalogUtility.
Here's a link to documentation is the method in this example:
PublishingCatalogUtility.PublishCatalog(
SPWeb parentWeb,
SPList list,
Nullable<bool> allowAnonymousAccess,
IEnumerable<string> furlFields,
IEnumerable<CatalogTaxonomyFieldSettings> taxFields
)
The parentWeb parameter is not reflected in the UI but is inferred based on your context there; same applies for the list parameter. The list parameter is obviously the SPList object for the list you are publishing, and parentWeb is the site that list is in.
The allowAnonymousAccess parameter represents the "Allow anonymous search access" setting from the catalog settings page.
The furlFields parameter represents the "Primary key" setting.
The taxFields parameter represents the "Catalog Navigation" setting. When programmatically connecting to this catalog, having specified eligible single value tagging fields here allows easy consumption for the other site. The values here will be represented in the CatalogConnectionSettings objects returned from API calls like GetPublishingCatalogs in this same type. There is also means to retrieve information about available catalogs in Microsoft.SharePoint.Publishing.CatalogConnectionManager; the actual type used to connect to a published list. So there is more flexibility here than the UI, which just opts for you to make a single selection in the drop down. If you do not provide the details of other eligible single value tagging fields (if any) for this list with the argument provided to this parameter then the connection UI or settings retrieved directly through the purposed APIs, like GetPublishingCatalogs, will not directly offer up the other options available. When nominating through the UI you do not have an option to reduce the mentioned Catalog Navigation options that would appear. Specifying all the relevant fields here but having none of them with IsSelected true is the same as choosing "None" in the drop down for the field in the UI.
Microsoft.SharePoint.Publishing.CatalogTaxonomyFieldSettings is the means by which to specify the details of available Catalog Navigation fields for the connecting side to use while making the connection. It contains most notably the ids for the taxonomy element behind the tagging site column, and specifies what the managed property in search is or will be named. A taxonomy field crawled property will automatically be mapped to a new managed property and the naming convention is shown in the code sample.
To set up a full integration eligible scenario for nomination I have a site column and tagging term set added, the site column being Managed Metadata type and rooted in that term set; I won't detail how to get those here - if you're looking to do this in API and not UI I assume you've got that nailed along with the basics on XSP.
$parentWeb = Get-SPWeb WebUrl;
$list = $parentWeb.Lists["Pages"];
# get managed metadata info for populating details about Catalog Navigation
$taxSession = New-Object -TypeName Microsoft.SharePoint.Taxonomy.TaxonomySession @($parentWeb.Site);
$termStore = $taxSession.TermStores["Managed Metadata Service"];
$group = $termStore.Groups["Demo"];
$termSet = $group.TermSets["DemoTagging"];
# set up CatalogTaxonomyFieldSettings for the single value tagging field DemoTag1
$taxFieldSetting = New-Object -TypeName Microsoft.SharePoint.Publishing.CatalogTaxonomyFieldSettings;
$field = $list.Fields["DemoTag1"];
$taxFieldSetting.TermId = $field.AnchorId;
$taxFieldSetting.TermSetId = $termSet.Id;
$taxFieldSetting.TermStoreId = $termStore.Id;
$taxFieldSetting.FieldId = $field.Id;
$taxFieldSetting.FieldManagedPropertyName = "owstaxid" + $field.InternalName;
$taxFieldSetting.IsSelected = $True;
$taxFieldSetting.FieldDisplayName = $field.StaticName;
# there can be more than one single value tagging field to integrate on when connecting, so the parameter expects an IEnumerable
$taxFieldSettings = New-Object -TypeName System.Collections.Generic.List[Microsoft.SharePoint.Publishing.CatalogTaxonomyFieldSettings];
$taxFieldSettings.Add($taxFieldSetting);
# specify the Primary Key or FURL fields default as just /[Title]
$selectedIds = New-Object -TypeName System.Collections.Generic.List[System.String];
$selectedIds.Add("Title");
# publish the list as a catalog
[Microsoft.SharePoint.Publishing.PublishingCatalogUtility]::PublishCatalog($parentWeb, $list, $False, $selectedIds, $taxFieldSettings);
If you were at some point (before seeing the right hand side of the relevant line above) wondering what the TermId is for on the tax field setting that’s a great question! That is just the AnchorId for the taxonomy field in question. It’s used on the connection UI for Root Term of Hierarchy to ensure picking is done from the anchor if restricted. If the taxonomy field accepts any term from the term set then the taxonomy field AnchorId and the TermId property here are both the default System.Guid.
Of course, this works the same way with the Server OM in each language you might go about the process in for different reasons.
In my example I only utilize one field for Primary Key, and one site column that is eligible for Catalog Navigation integration. To specify more for either just continue to add to the collections in the same way.
I also nominate the Pages library of a publishing web, but you can nominate any list within a site collection that has the XSP feature active. *Technically, currently, you are able to publish a list as a catalog programmatically regardless of the feature activation but I recommend sticking to the flow the UI exhibits.
Enjoy!