Missing Content Types association with variations - an STSADM extension solution

I ran into an issue the other day where all content for most pages where missing when viewing a "target variation" (I define a variation as "target" when it's not the source variation).  After taking a closer look, we could see the titles and description, but any custom fields were missing unless the page was a System Page or an Article.

 

After more investigation, I went in the Pages Library Settings and could see that the associated Content Types were only with Page & Article.  Now, all custom types I create are based on Page so what was happening was that only the fields available in Page were showing since it's my base type.  I could simply, even in the GUI, add the associated content type to the library and the content was showing.

 

Basically, while the column's data are replicated to each variations, if the content type isn't associated to a library, the library won't show data from that content type at all even if a page references it.  Obviously, creating all of those by hands would be quite a feat and so I ended up working out an STSADM extension that was reading the source variation and updating the ContentTypes collection of each Pages library for each variation (based on the source available content types).

 

Update :

Here's a snippet of code to apply Content Types on a Pages library.  You will need a reference to the Site's content types (in snippet, variable name : _publishingSiteContentTypes) which you can get by having an SPWeb on the site collection (or root web) and reading its "ContentTypes" collection:

    1: private void ApplyPagesContentTypes(SPWeb spWeb, PagesContentTypes pagesContentTypes)
    2: {
    3:     _log.WriteLine(Environment.NewLine + String.Format("Applying {0} Pages Document Library Content Types", spWeb.Title));
    4:     _log.WriteLine(LogStepLineBreak);
    5:  
    6:     if (pagesContentTypes.Items != null)
    7:     {
    8:         SPList pages = spWeb.Lists["Pages"];
    9:  
   10:         SPContentType contentType = null;
   11:         string contentTypeName = null;
   12:  
   13:         for (int i = 0; i < pagesContentTypes.Items.Length; i++)
   14:         {
   15:             contentTypeName = ((ContentTypeName)pagesContentTypes.Items.GetValue(i)).Value as string;
   16:  
   17:             SPContentType pagesContentType = pages.ContentTypes[contentTypeName];
   18:             contentType = _publishingSiteContentTypes[contentTypeName];
   19:  
   20:             if (contentType != null && pagesContentType == null)
   21:             {
   22:                 pages.ContentTypes.Add(contentType);
   23:                 _log.WriteLine("\t" + contentType.Name + " assigned");
   24:             }
   25:             else if (contentType == null)
   26:             {
   27:                 _log.WriteLine("\tError: " + contentTypeName + " wasn't found in the available content types");
   28:             }
   29:         }
   30:  
   31:         spWeb.Update();
   32:     }
   33:  
   34:     _log.WriteLine(LogStepLineBreak);
   35: }

 

Maxime