Programmatically Create Variation for a Publishing Page

Wow, have I ever spend time trying to figure this one out. There seems to be nothing, and I mean nothing out on the web that would explain how you would go about programmatically creating a page’s variation in SharePoint. The scenario I have is the following, we have users copying HTML pages from a legacy site into SharePoint using the Explorer View. An event receiver has been defined on the SharePoint Pages library that will go and read the file’s content, clean its HTML code, remove any PHP or Javascript code in it, and then convert it to a SharePoint Publishing Page (.aspx). Since we use a naming convention that uses a –e or –f at the end of a page’s name to determine if its content is English or French, it is very easy for me to determine where the variation page will be located.

 

Variations are created by a Timer job in SharePoint. This timer job uses a special king of JobDefinition called, the SPWorkItemJobDefinition. Think of it as a service ticket that is created and stored in the SharePoint content database, only to be picked up and processed by the timer job at a certain interval. All we need to do then, is to figure out a way to create such a Work Item and have it stored back in the content Database, but without interacting with the DB directly! Only by using the SharePoint Object Model. SPWorkItemJobDefinition is a generic class, and the only way to specify what type of work item we want to create, is by passing it a GUID. The type of work item that we are looking for in our scenario is named “CreateVariationPageJobDefinition” and has a GUID of 726dd8f-0e23-4c35-88b5-4fba39482515.

Work Item Name Work Item GUID
CreateVariationPageJobDefinition 726dd8f-0e23-4c35-88b5-4fba39482515

 

Work Items are added to the database by calling the SPSite.AddWorkItem() method on the Page’s parent Site Collection. Calling the following method will do exactly what we are looking for:

string textLoad = @”<WorkItem><PageTitle>Variation Page’s Title</PageTitle><Description>My Variation Page’s Description</Description><PageLayoutName>ArticleLeft.aspx</PageLayoutName>

<VariationLabel>fra</VariationLabel>

<DestPageName>variationpage.aspx</DestPageName><IsCopy>True</IsCopy>

<SourcePageUrl>http://mysite/Pages/mycurrentpage.aspx

</SourcePageUrl></WorkItem>”;

 

Guid webId = SPContext.Current.Web.ID; // Id of the current web in which the Publishing Page exists (not the variation web).

Guid rootWebId = SPContext.Current.Site.RootWeb.ID; // ID of the Site Collection’s root Web

int itemId = SPContext.Current.ListItem.ID; // Id of the publishing page itself. ID in this case is an autonumber representing the order in the list;

int userId = SPContext.Current.Web.CurrentUser.ID;

 

VariationHandler.AddWorkItem(properties.WebUrl, properties.Web.ID, properties.OpenSite().RootWeb.ID, properties.ListItem.ID, properties.Web.CurrentUser.ID, textLoad

 

SPSecurity.RunWithElevatedPrivileges(delegate()

{

using (SPSite site = new SPSite(siteUrl))

{

site.AddWorkItem(Guid.NewGuid(), System.DateTime.Now, new Guid(“726ddd8f-0e23-4c35-88b5-4fba39482515”), webId, rootWebId, itemId, true, Guid.Empty, Guid.Empty, userId, null, textLoad, Guid.Empty);

}

});

 

The Text Payload information is really what contains the magic. It tells the timer job what’s the name of the variation page, what its name is going to be in the variation site, what variation label to create it under, and adds a pointer to the current page to ensure proper linkage between the root label and the variations one. By default, the variation page timer job is set to execute every 2 minutes, so you’ll need to be patient if you’re trying to create a lot of pages at once.

Leave a Reply

Your email address will not be published. Required fields are marked *