SharePoint Automation Gary Lapointe – Founding Partner, Aptillon, Inc.

8Apr/0846

Fun with Variations

I've recently done a lot of work with my current client to get SharePoint variations working and as a result I've learned that you need to be very patient and persistent and keep a full bottle of Excedrin nearby.  Though this post is not directly related to stsadm extensions the results of my efforts on this project produced a couple of new commands which I'll touch upon here and detail in a follow-up post.  Before you begin working on a multilingual site using variations I highly suggest that you read the Building Multilingual Solutions Using 2007 SharePoint Products and Technologies white paper.

imageVariations in, a nutshell, allow you to present the same pages using different views of the page.  Though variations are typically used for multilingual sites they can also be used for other things such as media specific views.  For this post I'm going to create multilingual variation with the source variation being English and a single target variation using Korean.  The first thing we need to do is make sure that the operating system is ready for our language packs to be installed.  If you're using an East Asian language, such as Korean, then you will need to prep the OS, otherwise the OS should already be capable of handling the language pack.  To install the East Asian languages on the OS go to Start -> Control Panel -> Regional and Language Options.  On the "Languages" tab select the appropriate options and click OK.  This will install the necessary language files which will require a reboot when complete.

Now that the OS is prepared you are ready to install the language packs.  The install is real straightforward so I won't detail it here.  If you don't already have a web application created to host your variation sites you'll want to do that now.  Once you've identified your target web application you are ready to create your site collection.  It's important to note that the variations publishing feature is scoped at the site collection level - this means that you cannot have a source variation in one site collection and a target variation in another.  Also, the variation features are installed with the publishing feature so you must pick a publishing template when creating your initial site collection or activate the publishing features.  For your root site collection make sure you pick the language template that your administrators are going to be able to work with as your end-users will never see the root site collection stuff.

imageTo create your variation hierarchy you must first enable variations.  This is done by going to the root of the site collection and selecting "Site Actions -> Site Settings -> Modify All Settings -> Variations".  You first need to establish the variation root site - typically you'll just put a "/" which will make the root of site collection the variation root but you can make the variation root be a sub-site of the site collection.  The other options are fairly straightforward but the "Update Target Web Parts" and "Resources" options may need some clarification.  If you choose to update web parts with changes from the source be aware that any translations or changes that you may have made in the target variations will be overwritten with that of the source.  So if you're using a content editor web part and translating that content on the target sites then those translations will be overwritten when the page is propagated.  This may or may not be what you intend to happen.

One other thing that may require some additional clarification is the Resources option.  If you leave the option set to reference existing resources then there's essentially no change to the content - it will simply references images, for example, on the source site.  The copy option, however, will copy images to the target variations.  Note that if the image in question does not exist in the variations PublishingImages library then it won't be copied.  I've not had to deal with other resource types so I can't say what the limitations are for anything other than images.

imageOnce you've established that the site collection is to use variations you now need to create your variation labels.  When you initially create your labels you are not actually creating any instances of a site - you are just telling SharePoint how you want your sites to be created.  The sites are actually created later when you choose to create the variation hierarchy.  The first label you want to create is your source label.  It's important to note that once you've established your source you cannot change it later.  If you would a custom site template to be available here make sure that the FilterCategories property of your site template is set to PublishingSiteTemplate (you can find information about how to create your own publishing site templates here).  The "Label Name" field is what will appear in your URL - so if you specify "en-us" as the label name your url for the variation will look like "http://demo/en-us/".  For the "Hierarchy Creation" option you need to specify what you want copied when the label hierarchy is created.  The other options on this screen are very straightforward - you just need to specify the language template to use and the local and a name.

For this demo I've setup a source variation with a label name of "EN", "English" as the language template, "English (United States)" as the locale, "US-English" as the name, and "Publishing Site with Workflow" as the site template.  I've also chosen to copy the publishing site and all pages during hierarchy creation.

imageOnce your source variation is setup you can set up all of your target variations.  Note that you don't have to set the target variations up right away - you can create your hierarchy now and have it just create your source variation, get it looking/working the way you want and then add target variations as you are ready to handle them.  I would recommend though that you at least create one target variation so that you can work out the various issues that you're likely to encounter (see below) before you roll out your source variation.

For the purposes of this demonstration I'm going to create one target variation label which I'll name "KO".  The language template and locale will be set to "Korean".

imageOnce you've established your labels you are ready to create your variation hierarchy.  You do this by clicking the "Create Hierarchies" link on the "Variation Labels" page.

Now that you've got your variations created you can go to the site.  Notice that if you go to the root of the site collection (in my case "http://demo/" you will be automatically redirected to the variation whose locale matches that of your browser.  If SharePoint is unable to find a locale match then it will redirect you to the source variation.  The redirect is happening because SharePoint has replaced the welcome page of the root site collection with a new page called "VariationRoot.aspx".  It's important to note that the default.aspx page is still present and if a user navigates to that page they will see it so I recommend either deleting this page or adding a redirect web part or something similar to redirect users to the VariationRoot.aspx file so that it can do its thing.

Okay, so you've got your variations set up, now what?  Now it's time to create some content (realistically though you're going to want to work on branding and custom page layouts first but as there are tons of posts on how to do this I'm going to assume you've got that covered and are ready for creating content).  Editing the page in your source variation is no different than editing any publishing page.  However, once you publish the page the changes that you have made will be automatically copied to the variations.  Note that the act of copying the page is the result of an event receiver that is hooked up to the Pages library.  The event receiver will inspect the page and determine what needs to occur and then trigger a timer job to handle the actual copying of the page from the source library to all target libraries.  This timer job uses the Deployment API to copy the pages and if you've read any of my earlier posts you know that this imagedeployment API has numerous limitations (I'll touch upon a couple of problems below).  Because a timer job is used you won't see the pages propagated immediately - it could take several seconds to several minutes (I've even see it take several hours to show up).  If you'd like the page to be copied immediately then you can trigger it by selecting the "Update Variations" option from the "Tools" menu on the page editing toolbar.  If the page doesn't already exist in a variation you can use the "Submit a Variation..." link to submit the page to all variations.  If the page already exists in all variations then the "Submit a Variation..." link will effectively just work like the Create Page action.  Note that you can also use content deployment jobs to handle the translation of content by external agencies.  The XML that results from a content deployment job is a nightmare to work with but it wouldn't take much to provide a custom interface to that could be provided to your translators to work with the content.

image Now that you've got your changes made and you've created the variation, how do you get to that other pages?  One option is to simply edit the URL but you're users aren't going to know how to do that.  Fortunately there's a built in user control that we can enable called the Variation Label Control.  The control works via a SharePoint delegate control which is added to the master page of all publishing sites.  To enable the control you simply have to un-comment the server control tag in the "12\template\controltemplates\VariationsLabelMenu.ascx" file.  Once this has been enabled by un-commenting the server control tag then a drop down menu will appear at the top of the site allowing the user to jump to matching pages in other variations. 

It's important to understand how SharePoint relates the various pages to each other because in certain situations this relationship can get corrupted.  At the root of the site collection you can find a hidden list called "Relationships List".  This list contains entries which map the relationship between the various pages.  The behavior of the Variation Label Menu control is driven by this list so if the menu is not listing all pages then most likely it is because the Relationships List became corrupted (for example, an administrator on the Korean side decided to prevent changes from being propagated by deleting the page in the Korean Pages library and recreating it with new translated content).

imageLet's take a look at this hidden list - in our demo site we'll navigate to "http://demo/Relationships%20List/AllItems.aspx".  Once here we immediately see a few items with the title set to nothing (the first thing I usually do is create a new view showing at least the following columns: GroupID, ObjectID, and Deleted.  There will always be at least one entry in this list corresponding to the variation home which we set up earlier and defined as "/".  This entry, which will be the first item in the list, will always have "F68A02C8-2DCC-4894-B67D-BBAED5A066F9" as it's GroupID and whatever was set as the home path as it's ObjectID.  ParentAreaID has been empty in every example I've ever seen and does not appear to be used.  The GroupID field is used to group related elements.  So each variation label in the hierarchy will have the same GroupID and each page will have the same GroupID as its copied page in each variation.  The ObjectID is always the server relative url of the element (so the path to the variation label or page).

It's important to understand though that this is not the only place in which we find this information.  SharePoint will also store the GroupID and a backward link to an item in this list within two hidden fields on the page: PublishingVariationGroupID and Publishing VariationRelationshipLinkFieldID, respectively.  This information is also replicated in the MetaInfo property bag.  If we run my custom gl-exportlistitem2 command we can see what these values are for the default.aspx page:

C:\>stsadm -o gl-exportlistitem2 -url http://demo/en/pages/forms/allitems.aspx -path c:\exportdata\pages_en

The following is a snippet of the Manifest.xml file which results from running the above command (note that I've pulled some elements that were not relevant):

<Items SiteUrl="http://demo" WebUrl="/en">
  <Item IsPublishingPage="True" ContentTypeId="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D400040A230B8F679045ADE877C7A560A0E7" PageLayout="WelcomeLinks.aspx" File="c:\exportdata\pages_en\Data\default.aspx" CreatedDate="4/3/2008 4:27:48 PM" LeafName="default.aspx" FolderUrl="">
    <Fields>
      <Field Name="Title">Home</Field>
      <Field Name="PublishingVariationGroupID">41ad5bd3-a882-4d50-a2ac-db5de6eb872c</Field>
      <Field Name="PublishingVariationRelationshipLinkFieldID">http://demo/Relationships List/4_.000, /Relationships List/4_.000</Field>
      <Field Name="MetaInfo">PublishingPageContent:SW|Test
vti_parserversion:SR|12.0.0.6219
vti_charset:SR|utf-8
vti_author:SR|
vti_setuppath:SX|SiteTemplates\\BLANKINTERNET\\default.aspx
vti_cachedneedsrewrite:BR|false
PublishingPageImage:SW|
SummaryLinks:SW|&lt;div title="_schemaversion" id="_3"&gt;\r\n  &lt;div title="_view"&gt;\r\n    &lt;span title="_columns"&gt;1&lt;/span&gt;\r\n    &lt;span title="_linkstyle"&gt;&lt;/span&gt;\r\n    &lt;span title="_groupstyle"&gt;&lt;/span&gt;\r\n  &lt;/div&gt;\r\n&lt;/div&gt;
vti_modifiedby:SR|SPDEV\\spadmin
vti_cachedhastheme:BR|false
PublishingVariationGroupID:SW|41ad5bd3-a882-4d50-a2ac-db5de6eb872c
SummaryLinks2:SW|&lt;div title="_schemaversion" id="_3"&gt;\r\n  &lt;div title="_view"&gt;\r\n    &lt;span title="_columns"&gt;1&lt;/span&gt;\r\n    &lt;span title="_linkstyle"&gt;&lt;/span&gt;\r\n    &lt;span title="_groupstyle"&gt;&lt;/span&gt;\r\n  &lt;/div&gt;\r\n&lt;/div&gt;
vti_cachedcustomprops:VX|PublishingPageImage PublishingPageContent SummaryLinks PublishingVariationGroupID SummaryLinks2 ContentType PublishingVariationRelationshipLinkFieldID vti_title PublishingPageLayout
ContentTypeId:SW|0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D400040A230B8F679045ADE877C7A560A0E7
PublishingVariationRelationshipLinkFieldID:SW|http://demo/Relationships List/4_.000, /Relationships List/4_.000
vti_cachedtitle:SR|Home
vti_title:SR|Home
ContentType:SW|Welcome Page
PublishingPageLayout:SW|/_catalogs/masterpage/WelcomeLinks.aspx, /_catalogs/masterpage/WelcomeLinks.aspx
</Field>
    </Fields>
  </Item>
</Items>

Knowing that this information is stored in two places like this becomes extremely important if you are trying to troubleshoot issues with the variation propagation process.  If the data in the Relationships List does not match up with the data in the page or if the related pages do not share the same GroupID then the variation propagation will fail.


Things that can go wrong (and they will)

Now that you hopefully have at least a basic understanding of what variations are and how they work we can begin to discuss where things fall apart (and if your deployment is anything more than demoware then you most likely will run into one or all of these issues).  The following issues are what I've personally encountered:

  1. The Relationships List can get "confused" and have either missing or invalid entries
  2. The page fields linking the page to the Relationships List can become invalid
  3. Web parts must inherit from Microsoft.SharePoint.WebPartPages.WebPart or the variation propagation will fail causing the application pool to crash (there is a hotfix for this: http://support.microsoft.com/kb/948947)
  4. Your pages must have a valid contact or no contact or you will not be able to get into the page settings for the page (this is more of a content deployment problem and not a variation problem)
  5. Your pages must have a valid page layout URL or the variation propagation will fail causing the application pool to crash (among other things)
  6. Content types for pages must match
  7. The variation label menu will only work with variation pages and not system pages (such as a list view page)
  8. The variation label menu will not preserve querystring values
  9. If you're working with large sites (several thousand pages and multiple variations) expect propagation times in terms of days (I've not personally dealt with this one but in my small environment with only a few pages it takes close to an hour for the pages to propagate so it's easy to extrapolate out)
  10. Navigation structure is not preserved from one variation to another
  11. Root site pages and other content is still available if I know how to get to it
  12. Custom list definitions and site definitions will need to be localized (use resource files) - definitions reverse engineered using Solution Generator will not be localized by default
  13. Values in localized choice columns will lose localization settings on propagation
  14. Only pages in the "Pages" library will be propagated - list items will have to be handled using custom event receivers or workflows
  15. Page field values are overwritten when a page is propagated

In the following sections I will try to cover each of the above issues and what I did to work around the issue.

1,2 - Relationships List Gets "Confused" and/or Page Fields are Invalid or Missing

There are times when the items in the Relationships List can get out of sync with the pages they are supposed to correspond to or vice-a-versa (either entries could be missing or IDs can be incorrect or mismatched).  When this happens you will run into issues with the propagation of page changes to variations.  For example, you may receive errors stating that a page already exists when you go to propagate changes to a page.  The most common way for this list to get corrupted is when pages are imported from other environments.  To fix the data in the Relationships List and the page fields I created a new stsadm command called "gl-fixvariationrelationships".  The command essentially loops through all the pages in a variation and tries to find the page with the matching name in the other variations and then rebuilds the data in the Relationships List and the page fields based on its findings.  Here's an example of how to run this command:

c:\>stsadm -o gl-fixvariationrelationships -url http://portal -verbose

Update 4/14/2008: I've just finished documenting this command here.

Update 9/2/2008: Tim Dobrinski has a great tool that he's put together for fixing many issues with the relationships list (including addressing sub-sites which I'm not currently dealing with).  You can find details about the tool here: http://www.thesug.org/blogs/lsuslinky/Lists/Posts/Post.aspx?List=ee6ea231%2D5770%2D4c2d%2Da99c%2Dc7c6e5fec1a7&ID=21

3 - Web Parts Must Inherit From Microsoft.SharePoint.WebPartPages.WebPart

I consider this particular issue to be a bug with the product because it could have been easily solved.  To demonstrate this I created a simple HelloWorld web part which just output some text and inherited from System.Web.UI.WebControls.WebPart.  I added this web part to my default.aspx page and published the page.  The result is that an InvalidCastException is thrown and the application pool crashes!  You can see the error details below - note that you'll see three errors in the event log all saying essentially the same thing.

image

If I change my web part code to inherit from Microsoft.SharePoint.WebPartPages.WebPart then the variation propagation works just fine.  So for your custom web parts the solution is real easy - just inherit from the SharePoint WebPart base class.  For third party web parts (the Dundas Chart web parts are a good example of this) you will need to wrap them in a custom web part.  The interesting thing to note is that even though the propagation seemed to fail and the application pool crashed I found that in most cases the web part was in fact successfully propagated.  The reason for this is because the failure happens in the PublishingPage object's FixWebPartUrlsForVariation method.  When this method is called the page and web parts have already been propagated and now the API is simply repairing some URLs within the web parts on the page - so in many cases repairs won't be necessary so everything will work just fine.  Microsoft could avoid this bug by simply doing a type check in the FixWebPartUrlsForVariation method before doing the cast.

Note that the only web parts out-of-the-box that are affected by the FixWebPartUrlsForVariation method are those that inherit from IWebPartVariationUpdate which at present only include the ContentByQueryWebPart and the TableOfContentsWebPart.

Update 4/21/2008: There is a hotfix for this issue - http://support.microsoft.com/kb/948947 - thanks to djeeg for adding the comment about this!

4 - Pages Must Have a Valid Contact

There are many ways in which the contact for a page can become invalid.  The most common is when a contact is deleted from the site collection.  Another way is when a page is imported from one environment to another.  Having an invalid contact "shouldn't" prevent the page variation propagation from occurring, so as far as variations are concerned this shouldn't be an issue.  However, many shops will choose to have a separate authoring environment and will import the pages into their public environment.  In this scenario you are very likely to end up with invalid contacts on your pages.  The issue comes when you choose to view the "Page Settings and Schedules" page.  If your page has an invalid contact associated with it you will receive a user not found error.  Of course the real problem here is that this is the page that allows you to fix the contact so your essentially stuck with no way of fixing the contact.  This seems like an obvious bug - the settings page should be able to handle the case of a contact being deleted so that you can assign a valid contact.

To work around these issues I've created another new custom stsadm command which I called "gl-fixpagecontact".  This command will identify all pages with an invalid contact and will either attempt to locate a valid contact, assign the current user as the contact, or assign a passed in user as the contact.  The contact field for the page is stored as a string in the format of "id;#name".  Often times when a page is imported from another environment the name will match but the ID will be different.  In this case the command will attempt to locate a principle with a matching name.

Here's an example of how to run this command:

C:\>stsadm -o gl-fixpagecontact -scope site -url http://demo -verbose

5 - Pages Must Have a Valid Page Layout URL

This particular issue can come up in a variety of situations and isn't necessarily limited to variations.  There are two ways in which this problem typically manifests itself - the first is when a page is migrated from another site (the entire site may have also been migrated) and the second is when you assign a page layout that exists in your source variation but not in your target variation.  To demonstrate the problem I created a new page layout which was just a copy of the WelcomeLinks.aspx page and stored it in the master page gallery located at http://demo/en/_catalogs/masterpage/forms/allitems.aspx - I then changed the /en/default.aspx page to use this new page layout.  After approving the page I clicked the "Update Variations" menu item to propagate my page.  The result is that 3 error events were logged in the event log and the application pool crashed!

To resolve these issues make sure that you either use only site collection level page layouts or that for every page layout you have in your variation sites you make sure that there is a layout with the same name in every other variation site (the contents can be different - they just need to be named the same).  In some cases (particularly when you import the content from another source) you won't be able to reset the page layout using the browser (going to the "Page Settings and Schedules" page will throw a FileNotFoundException).  To help fix this problem you can use a command I created a while ago called "gl-fixpublishingpagespagelayouturl".  This command has a variety of different options but here's a command of how to explicitly set the layout for a specific page:

C:\>stsadm -o gl-fixpublishingpagespagelayouturl -url http://demo/en -pagename default.aspx -pagelayout "http://demo/_catalogs/masterpage/WelcomeLinks.aspx, http://demo/_catalogs/masterpage/WelcomeLinks.aspx" -verbose -scope page

6 - Page Content Types Must Match

I've not experienced this particular issue but I thought it was worth mentioning here for completeness.  Jeremy Jameson gives a great explanation of the problem in his 3 part posts "Dumping MOSS 2007 Variations" so I won't bother re-iterating it here (the gist of it though - use SP1 with custom site definitions if you need to use page content types).

7 - Variations Label Menu Only Works with Publishing Pages

This is rather minor limitation but its one you should be aware of before you decided to use it.  If you don't allow any access to system or list pages (/_layouts/viewlsts.aspx or /Documents/Forms/AllItems.aspx for example) then you don't need to worry about this.  If you do and you have matching pages/lists throughout all your variations then you'll need to create a custom data source or your own menu if you want the ability to jump between variations.

8 - Variation Label Menu Does Not Preserve Querystring Values

I consider this to be a minor issue as well.  If you have a page which, for example, uses a page field filter which takes in values from the querystring and you then use the variation label menu to jump between variations those querystring values will not be preserved.  The reason I consider this minor is because I personally consider this menu to be nothing but a waste.  If you're asked to use it you really should ask yourself why?  Is it for the end users so that they can read the same content in different languages (who does that?)? Or is it for your testers so that they can jump between the various variations easily?  I think you'll find that this is a feature that, under most circumstances, will never be used by your end users - so why deploy it?

9 - Long Running Propagation Jobs with Large Sites

This is another one that I don't have personal experience with but Jeremy Jameson explains the problem real well in his previously mentioned post "Dumping MOSS 2007 Variations".

10 - Navigation Structure Doesn't Propagate Between Variations

This isn't actually a bug - it's by design and I completely understand the reasoning behind it.  You may have very different navigation needs between different languages and there's no easy way for the Microsoft to anticipate all needs.  However, most will want the structure of their global and current navigation to match across all variations.  This just another one of those things that you need to anticipate and plan for as you plan out your multilingual sites.  One thing that I've used to help keep things in sync is my "gl-enumnavigation" command to export the navigation from the source variation and then let the translators translate the resultant XML and then use my "gl-setnavigationnodes" command to set the navigation for the target variations (at least for an initial site propagation - after that I've just made the changes manually).

11 - Root default.aspx and Other Root Pages Are Still Available

One thing I found that needs some clarification in the Building Multilingual Solutions Using 2007 SharePoint Products and Technologies white paper is its description of the VariationRoot.aspx file:

"After a variation hierarchy is created, the Variations feature replaces the default page of the variation’s home site with a special page called VariationRoot.aspx"

To be more precise - the feature changes the Welcome Page settings so that VariationRoot.aspx is now the welcome page of the site - so if I type in "http://demo/" I'll be taken to the variation that's appropriate based on my browser settings.  However, if I type in "http://demo/pages/default.aspx" I'll be taken to the root site collections default.aspx page, not the variation site.  The same goes for any other content, lists, and sites that exist at the root site (assuming I have access).  The solution here is pretty simple - if you don't want them getting to it either delete it (if it's not needed) or lock it down so they can't get access to it.  In the case of the default.aspx page you may want to keep it there and keep the access open and then just add a redirection web part or some simple javascript to handle redirecting to the VariationRoot.aspx page.

12 - Custom List Definitions Should be Localized

If you're creating custom list definitions then you should plan on making sure those list definitions are localized - set display names, choice values, query parameters, etc., to resource strings.  One thing to be aware of is that if you use Solution Generator (part of the Visual Studio Extensions for WSS) to reverse engineer your lists you'll have to set all the fields to use localized strings which could add some time to your development/QA cycle.

13 - Localized Choice Columns Fail on Propagation

If you use any localized list definitions, as mentioned above, be aware that a side effect is that choice column values will be stored using the actual values, not the resource strings.  Sjoert Ebben discusses this issue in his post "5 reasons why you should not use variations".  Sjoert recommends a couple of solutions, one of which is to create a custom field type which will store the resource string and not the actual value.

14 - Only Pages in the Pages Library will be Propagated to Variations

To some this may seem like a pretty obvious point but I found that many I spoke to about using variations initially were rather surprised that they couldn't enable this functionality for any list.  In order to get list values (such as announcements and such) propagated between variations I enabled moderation on the desired lists and created a custom event receiver which, upon approval, copies the list item to the lists with the same name in all variations.  You could also use a custom workflow to do the same - it really just depends on how complex your needs are.  You'll find that handling modifications to data will require careful consideration.  I'm hoping to provide a sample of my event receiver in a follow-up post so be on the lookout for that.

15 - Page Field Values Are Overwritten Upon Propagation

So here's the dilemma - best practice with publishing pages is to use page fields for all content because web part changes are not stored with the history of the page - unfortunately though, when you are using a page field and you approve your page in the source variation the page will propagate to all target variations and all page field values will be overwritten.  One solution to this is to add a custom page field where the editor can indicate whether the content change is a minor modification or a new version and then create a custom workflow which will delete the draft in the variation if the page is a minor modification.  Some solutions will decide to simply put all content in web parts and just turn off the web part propagation - I still don't recommend this as you will not be able to roll back to a previous version of the page (again, web part changes are stored separately from page data and cannot be rolled back!).

Conclusion

Variations can be a very cool feature that, for simple sites, could give you exactly what you need to get you up and running with a multilingual site.  The key with variations, as with just about any SharePoint feature, is careful planning.  Make sure you give yourself plenty of time to prototype your solution and, most importantly, get your translators involved early on as you will find that many things will work just fine when everything is in English but as soon as you start translating your content and resource files you will encounter issues.  Sometimes these issues can be addressed with simple planning and change control policies but in most cases you'll be looking at custom code and/or workflows and/or site and/or list definitions.

So, if you're going to be working with variations make sure you've got lots of coffee, plenty of headache drugs, a good punching bag, and lots of time to switch to a backup plan ;)

Comments (46) Trackbacks (0)
  1. Hey Gary, great write up, I have just finished a project that used variations too and I feel your pain, lots of fun indeed.

    Just in regard to your point 3, the class cast issue; I believe that it has been fixed by this hotfix.
    http://support.microsoft.com/kb/948947, you’ll need to get in contact with support for the download though.

  2. Hey Gary. Thanks for the post. I learned a lot from it.

    I have a situation that I don’t think falls into one of your error categories. I have an existing site that I want to convert to a multi-lingual site. I created an English source variation and then ran the Create Hierarchies to create an English variation folder. Next I used the Manage Content and Structure web interface to Move my sub-sites into the English source variation folder. Finally, I create another variation (French) and ran the Create Hierarchies again. All the sites and pages were created, but all my content is missing in the French site.

    I tried another experiment. I deleted all the variations and variation folders and created the same scenario except that I created the folders from scratch under the English source variation folder. Same result. The sub-sites and pages were created, but with no content.

    Thanks,
    John

    Can you give me any clues on what is happening?

  3. John – did you check your settings on the Variation Settings page? Specifically the Update Target Page Web Parts setting?

  4. Gary,
    I checked the setting and it is set to “Update Web Part changes…”

    However, I don’t think that this is relavent because all my pages are based on custom content types that use field controls, not web parts. Am I mistaken?

    Thanks,
    John

  5. John – I guess I should have clarified first – I’m assuming that you mean the content of the publishing page and not content such as list items and what not. I did find that the hierarchy creation will create the pages but you need to manually trigger the propagation by going to Tools->Update Variations on the pages editing tool bar (it may do the update automatically with time but I didn’t have time to see if there was a timer job that was going to run on it’s own – I suspect not though). And I’m sure you also know that only publishing sites will be propagated and not other sites. Also – you are right that the setting I mentioned won’t make a difference if you are using page fields for everything (just note that every time you propagate changes your variations will be overwritten with the field values).

  6. Hi Gary

    I am stuck way behind at the point of the hierarchy creation, where I get the following error:

    “An error was encountered performing this operation. You may re-try the operation, and you may need to clean up the half-created data first before re-trying. If the problem persists, please contact your system administrator.”

    My SP installation is in Portuguese and I have the English package installed as well. I created the labels according to instructions (over and over) and at the end when I try and do the hierarchy I always get the same error message. I’ve tried to create it after creating each label, and only after having the labels done. After this when I go back to the labels list, the Portuguese label has ‘Yes’ on the hierarchy created column but the English is always as ‘No’.
    I’ve tried also this, although it didn’t make me much sense:
    http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=2039978&SiteID=17
    and still no improvements.
    Any help at all is very welcome…I am at this earlier point compared to other problems and already having issues, reading all these posts about further bugs is certainly not the most motivating to try and use variations…
    Thanx in advanced

  7. I remember seeing that error at one point during my trials and tribulations but unfortunately I can’t remember what I did to resolve it – if you don’t have anything you need to keep then I’d try just deleting the site collection and starting over – sorry that I don’t have anything more helpful.

  8. This is a great post, In response to Tania:

    I have seen this error and the reason I was getting it was because it had a web part that wasn’t inheritting from the SharePoint.WebPart class. Changing my web part resolved this problem.

    As an addition to add my bit I have untold problems with Variation most of which were really inconsistent and frustating. I have 6 variation and sometimes the changes are propagated sometimes not. Sometimes to one or a number of my variations, then other times to others. This may be cause by me not being patient enough if the timings are an issue.

    The length of time I have taken created prototypes I would have been better writing some translation web part and a list of full of translation content.

    It would have been so much smoother, as it would seem that variations is just down right unfinished. Thanks Microsoft.

  9. Hi All

    Thanx for the comments sent, still no improvments so far.
    We are using a couple of custom webparts indeed, but they all do inherit from Microsoft.SharePoint.WebPartPages.WebPart.
    The variations are to be used in a new project that will is starting soon, so we were on experimenting in advanced the localization ‘feature’ since it is to be a multilingual internet site.
    The error I sent above was translated, as our sharepoint is in ‘Portuguese’ and so the installation. I have heard about several bugs withs Sharepoint translated products, so I am now considering to use an english installation and use the portuguese language package instead of the reverse (which is currently what I have). Also I am suspecting of the correct package installation, so I am looking to reinstall it first and go to conclusions afterwards.

    Thanx anyways for the effort.
    If I do get to figure out whats wrong I’ll come back and post about it.

  10. Great post.

    I have a variation site that has 6 published language variations and will have 20 when we get all our content translated. And after dealing with the quirks of variations, I wish I never used them. Propagation is turned off as everytime the root site is updated the variation pages (which are almost all not in English) are updated with the English content. So not only do my translators have to figure out what changed in between versions of the English site, but they have to re-translate the content or figure out how to get rid of the new draft version. This is not a good solution. So propagation is now done by hand and through manual email.

    But my problems go deep with vatriations. Our variation site – which is internet facing – is heavily customized. So much so that the Microsoft support rep on the MOSS team said “this is a SharePoint site?”. To “fix” my variations problem, their only recommendation was to “roll back my customizations”. Unreal. Microsoft support for MOSS is, for the most part, useless.

    Next, if you have custom page layouts on your welcome page and that page is named default.aspx, that page is overwritten by a new page with the default Page layout. So I’ve had to have all my welcome pages be named index.aspx and just change the welcome page on each varitaion. This is not only annoying but unacceptable for a product like this.

    Finally, if you have images in yuor Page Content section, the variation for that page will not create. I’ve had to put most images in a _layouts subfolder to get the variations to work.

    So I agree with an earlier poster that said variations was “unfinished”. While I agree with this, i also say that it is a gross understatement. Variations is near useless.

  11. Can I ask did you get the above list of problems after having installed Service Pack 1?

    Microsoft informed me that the problem with lost or broken variations may have been resolved in Service Pack 1 but given this post is quite recent I wondered if SP1 was still demonstrating the same behaviour?

  12. Paul – everything demonstrated here was post SP1 – note that there were (effectively) no fixes for variations and content deployment in SP1 but there were over 60 fixes in the recent content deployment rollup that just released a couple of weeks ago – I have not tested any of this with that rollup but supposedly many of these issues have been resolved.

  13. Nice article, one quick question, on the variation settings page if you select the copy resource option images and documents get copied when used in the page. I was wondering how I could replicate this for other items? Meaning I created a custom field control and allow users to select a media file. I would like that media file to be copied. I’ve tried a number of things but nothing seems to work.

    Suggestions?

  14. Where are you actually storing the media file?

  15. I created another document library within the source variation. I know (or I believe I know) that I need to create that library in the child variations.
    I was hoping that I could take advantage of the replication process that occurs when the image or a link to a document is entered into the OOTB content fields in the page layout.
    I guess I would like to know more about how the resource replication works, I’ve not dug to deep into it, but would like to be able to have the resources referenced in my custom field controls copied the same way as the image and page content field controls.

  16. Try storing your images in the PublishingImages library – it’s the only library that is affected by the copy resources option when setting up the variations. If you need to use a different library then you’ll need to create your own event receiver to handle copying items between the variations.

  17. Gary,

    This is a followup to one of my previous comments. Turns out the reason the content wasn’t displaying when creating variations wasn’t a variation problem at all. It was also occurring when I copied a page from one subsite to another. The cause was that when the new folder was created, the reference to the content type (we are using custom content types instead of the OOTB content types) wasn’t being created. The fix was to upgrade to SP1.

    Thanks for your help,
    John

  18. Gary,

    I ran into another variation issue with MOSS 2007 SP1 when I copied a WSS_Content database from my test sql server to my production sql server. It is similar to the problem that is fixed by your gl-fixpublishingpagespagelayouturl command. I had run this command and was checking a page file to make sure the reference had been updated (which it had) when I noticed another reference on the page that was still pointing to my test server. The field was <mso:PublishingVariationRelationshipLinkFieldID msdt:dt=”string”>http://rmcspcsdev1:2095/Relationships List/1382_.000, /Relationships List/1382_.000</mso:PublishingVariationRelationshipLinkFieldID>

    I ran your gl-fixvariationrealtionships command, but it seems to be addressing something else.

    What problems will this issue cause? Will changing the reference fix it? Do you have an STSADM command to address this?

    Thanks,
    John

  19. John – thanks for the follow-up – glad you got it all worked out!

  20. John – I’m not sure why the gl-fixvariationrelationships command didn’t work for you as that particular field is one that should be getting addressed by the command. As far as issues that you could see if it stays like this – most likely the pages just won’t propagate – SharePoint uses this field to figure out what the related pages are so that it can update them. You may also have issues with the variation label menu if you are using it.

  21. As for 14 – Only Pages in the Pages Library will be Propagated to Variations

    I’ve written a feature that deploys Document Library items to equivalent Doc Libs in Target Variations. It’s triggered by an Event Handler or manually through an item drop down menu option.

    I’d be interested to know how it compares with the solution your article mentions you have written.

    I’ve posted the basic code here;

    http://www.the-north.com/sharepoint/post/Propagating-Document-Library-Items-In-MOSS-Variations-(in-the-same-way-as-Pages).aspx

  22. Jamie – nice article and thanks for the link love :)

    The solution I came up with was similar to yours but slightly more involved. I used the meta data property bag to store the relationships between each variant within each variant so that from any of the variations I could tell what the source variation was and trigger a propagation from any of the variations (so in effect any variation could “become” the source variation). I also propagated all properties (fields) and supported document libraries and list items. And finally, whenever an item was propagated I created a task entry to translate the item (we decided to enable moderation for every list involved so that the propagated data was left in a pending state and thus not available to all users until it had been translated and approved – once approved the task item was automatically closed out). Oh, and I also handled deletions making sure to call SPListItem.Recycle instead of Delete :) . I didn’t thnk to add the menu item to the item drop down though – I like that idea and should have done that.

  23. Gary, I am running into a strange situation with my variation site and am hoping you can help. Here’s my story: I have created a new site collection using the publishing site template. I set the varaitions at the root of the site. Next I create a variation label for english as the default then I create a variation label for german. When I create the hierarchy the english variation gets created but the german variation does not. When I view the site content and structure I can see that the top level site and the english site are variation sites (based on the icon) but the german site has the sharepoint site icon. This is on an OOTB sharepoint publishing site.

    I have multiple development boxes called moss-dev and moss-dev1, and so on. The variation works on moss-dev but does not work on moss-dev1 or our live server. Are there some settings to enable variations that I have missed?

  24. Smitty – sorry for not responding earlier – honestly I’m not sure why it isn’t working – setting up the variations is pretty simple and you basically described the core of it. I’d check your ULS logs and event log to see if there’s any indicators in there.

  25. Slinky

    Ok. Just now responding. My variations problems are app pre-SP1. My server admins and myself have read enough horror stories about SP1 that we are a bit timid about installing it. So it’s still on SP1.

    One thing I am looking to do is start working to manually repair the variations by hand. I have tried Gary’s STSADM commands but I think that my problems are more than the command will fix.

    On that note, one question: I can get the PublishingVariationGroupID and PublishingVariationRelationshipLinkFieldID fields for pages, but do SPWebs also have this association? They are in the Relationships List, but I cannot get them via code. Thoughts?

    Tim

  26. Tim – to be honest I’m not sure if there is anything stored for the SPWeb objects. The work I was doing on variations didn’t necessitate any sub-sites so I didn’t have a need to look into it. I imagine the info would be stored in the objects properties bag though, if at all. Use stsadm to export the site and use nofilecompression and then take a look at the manifest.xml file – if it’s stored anywhere you’ll find it in there and then you can trace that back to a property or object that you can use.

  27. Thanks, Gary… you got me pointed in the right direction… turns out, though, that it wasn’t in the Properties PropertyBag but the AllProperties Hashtable. The key string is “Variation Group Id”.

    I’m working on a console app (for starters) to fix the associations in variations. I’ll let you know if I get it working.

  28. Hey Gary,
    I deleted the source variation (i.e en-us)and all the relationships is gone.I created a new variation label with the same name as en-us.I am able to create the label but when i try to create the Hierarchy, i get this following error: “A site already exists at the source label target location. Either rename the site or the label, and retry Hierarchy Creation.”

    Any inputs on how to retain the same source variation to english or en-us.

  29. Arun – deleting the source, not a very good idea :)

    There’s no way out of the box to recreate that source but you should be able to restore from a backup.

  30. Hey,
    Nice post about the Variation Pain!
    I wonder if there is a relation between the pages as well?

    So default.aspx (english – source) default.aspx (german).

    How to find out whats a created page by the system and which is created in german.
    Thanks in advance
    Timmey

  31. Gary,

    I appreciate the mention of my app in points 1,2. For what it’s worth, I’ve released the 2.0 version of the app. This one not only adds in the user-requested functionlity desired in the first version but now allows for the importing and exporting of content between non-Source nodes in Variations.

    thanks again for the shout out.

    - Tim

    http://www.thesug.org/blogs/lsuslinky/Lists/Posts/ViewPost.aspx?ID=25

  32. Hello Gary,

    You obviously are an expert on Variations. Would you know what is missing in a site collection if I get the following error when I type the URL of the site collection:

    “The Site Welcome Page is set to VariationsRoot but there are no Variation Sites. Site Administrator can reset the Site Welcome Page if necessary.”

    (I must point out that I took a site collection with Variations, and programmatically tried to copy its sub-sites and their lists to a new site collection.)

  33. The Labels are missing – so a label is a sub-site with some meta-data (sounds like you’ve got the sub-site but now you need the meta-data). Take a look at the relationships list and see if there’s anything in it. There’s a few posts floating around the web that explain how to remap labels.

  34. This indeed was the problem.
    Thank you!

  35. Yow Gary,

    Nice article. I’m trying to use variations for a simple multi-lang site. Just dutch to english.

    I did one test-setup that worked fine (not that you get announcement webparts working in variations, but you learn to live with that kind of stuff in MOSS).

    Then I deleted the site, created a new one, created the label and now the hierachy creation fails without an error (it just tells me it failed). I’m thinking on maybe just skipping the variations and use individual sites for dutch and english (seeing the problems everybody is running into).

    I agree with people that the variations/MOSS isn’t a fully finished product. Weird error’s like this aren’t supposed to happen in a application that costs a lot of money.

    On the other hand the fact that MOSS has to be customized so much means that thousands of companies and people earn money with it, making it a strategic choice for MS not to implement things like a decent wiki, or photoupload. At least that’s my feeling.

    You might want to check this out:
    http://www.codeplex.com/VariationsEditor

    I didnt use it yet, but it might be practical for variatons trouble shooting!

  36. Gary,

    You said at the end of the
    “14 – Only Pages in the Pages Library will be Propagated to Variations” section
    that you might follow-up on your event receiver code. I have seen Jamie’s attempt, but i like the sound of your all-encompassing effort. Any chance you could share this in a post?

    I’d be interested in which logic you use for finding custom lists and dealing with content-types etc.

    Cheers, Lewis.

  37. Gary,
    Thanks for the nice article. I have a question .I created a spanish variation and everything is created and in the variation label i am able to see both the variations english and spanish.Hierarchies are also created.English variation is source.My problem is when i am opening the default page of English variation there is no navigation link to go to spanish variation while other links are there like home,contact us at the top of the page.So how can get the navigation link only on the default page of english variation and navigation link for english variation on spanish variation default page.

  38. Hi

    I learnt about localization of custom wep-parts using resource file.

    But now the wuestion is how the dynamic contents ( contents from

    web services/SQL Databases /Sharepoint lists etc) can be localised on run-

    time depending on the language selected.

    Please do let me know any inputs in this regard.

    Thanks in Advance

    Prathibha

  39. Very helpful page!!! Thanks a lot.

    I was going crazy with a problem with a variation in which user had changed the site name.

  40. Hi Gary!

    Thanks a lot for this great article.

    I’ve actually a big problem using variations and as you seem to have much experience in this particular domain, perhaps you’ll have a solution for me :-) .

    How can I be notified when a new page is created in my variations sites? I tried the “traditional” way, adding an EventReceiver but this one is not working for propagated pages (for me it’s a bug…but hey I have to find a solution!). I’m actually trying to launch a Workflow when a page is created/modified, but it don’t seem to be very constant/stable…

    Thanks for you help.
    Bastien

    • What event are you specifically capturing? Is it the Adding or Added event? If memory serves me correctly only the Added event will fire but I could be wrong (it’s been a while since I’ve looked at this). Internally the variations propagation stuff is just using the content deployment API (which is riddled with issues); so workflows won’t come over but if you’re triggering a workflow via the event receiver then, assuming the event fires, you should be okay.

  41. Hi Garry,

    I am trying to apply variation on our site on our testing server. when I click on “create hierarchies” link after creating a label for en-GB, i can see in variation logs, that it has started creating variation site but some how it struck in between & doesn’t create variation sites for all the sites and sub sites.

    I have fixed all group id & page layout issues using sharepoint variation editor, but still facing same issue. Can you please suggest what should I check to ensure, variation is created for all the sites.

    thanks a lot for your support
    Deepak

  42. Gary,
    I am trying to get Variations work in SP2010 for a couple of different languages (fr, es).
    I have a top-level site-collection “Site A” with two sub-sites “Site B” and “Site C”.
    The [Create Hierarchy] works fine and creates the target site for “Site A” in fr and es.
    But I donot see a variation created for “Site B” and “Site C”.
    I have verified that A, B and C are all Publishing sites with Publishing feature turned on. In fact, I have no customizations done on B and C.
    Any pointers here.
    Thanks.

    • You’ll need to start digging through the ULS logs to see if there’s an error thrown which is preventing the site hierarchy creation. Also, how did you create the sub-sites? Make sure there’s an entry for them in the hidden relationships list (if you created via powershell or the object model they won’t be there).

  43. We have a SharePoint 2010 site with English site as a variation root and three different language variations. There’s a problem that has happened a couple of times now; site variation propagation fails for some of the variation sites, but succeeds for some.

    There’s an error in the Variation logs:

    •The Variations Propagate Site job failed for the source site http://site/variationroot/web/subweb1/subweb2 with the following error message: 0x80070002There is no Web named “/variationroot/web/subweb1″..
    Please help here : hclpankaj@gmail.com


Leave a comment

CAPTCHA Image

*

No trackbacks yet.