The Admin UI of the site collection provides easy access to the variation settings. But the object model does not provide easy access to these settings. There are many scenarios where it would be (e.g.) very interesting to know which site is the root site of the variation.
The solution for this problem is Reflection. Using Reflection it is possible to access the VariationSettings object which provides easy access to this information.
Here is some sample code:
using System.Reflection;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
namespace StefanG.Tools
{
class DumpVariationSettings
{
static void Main(string[] args)
{
SPSite site = new SPSite(“http://url-to-site-collection/”);
// Get Assembly hosting the hidden VariationSettings class
Assembly a = typeof(PublishingWeb).Assembly;
Type[] types = a.GetTypes();
Type VariationSettingsType = null;
// Find VariationSettings type
foreach (Type t in types)
{
if (t.FullName == “Microsoft.SharePoint.Publishing.Internal.VariationSettings”)
{
VariationSettingsType = t;
break;
}
}
// Instantiate a VariationSettings object
ConstructorInfo ci = VariationSettingsType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance,
null, new Type[] { typeof(SPSite), typeof(bool) }, null);
object VariationSettings = ci.Invoke(new object[] { site, false });
// Retrieve the URL of the variation root
BindingFlags.NonPublic | BindingFlags.Instance );
string Url = pi.GetValue(VariationSettings, null) as string;
// Alternatively retrieve the PublishingWeb of the variation root
BindingFlags.NonPublic | BindingFlags.Instance);
PublishingWeb pubWeb = pi2.GetValue(VariationSettings, null) as PublishingWeb;
}
}
}
Permalink
Would it be easier to create a PublishingWeb with the static GetPublishingWeb() Method like this
PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(SPContext.Current.Web);
Permalink
Hi David,
you missed the point. I’m not trying to get the publishing web for the current web. The code above will give you the web which is configured as the rootweb of the variation in a give site collection.
Cheers,
Stefan
Permalink
Why not compare the ServerRelativeURLs?
SPSite site = SPContext.Current.Site;
SPWeb currentWeb = SPContext.Current.Web;
string strWebURL;
foreach (SPWeb web in site.RootWeb.Webs)
{
strWebURL = web.ServerRelativeUrl;
if (currentWeb.ServerRelativeUrl.StartsWith(strWebURL))
// this is the VariationRoot
SPWeb.Webs returns only the direct children Websites, so if your variation starts deeper, don’t use SPSite.RootWeb …
Permalink
Hi Markus,
that will not help you if you don’t know where the root is.
The code above will get the configured variation root without a need to have any background info at which level it might be.
So you can write code that works correct in various different site collections with different variation root sites.
Cheers,
Stefan
Permalink
Hi Stefan,
I have variation urls like http://server/sites/site1/variationrootsite/language1/subweb1/subweb11 and http://server/sites/site1/variationrootsite/language2/subweb1/subweb11. I am at subweb11 of language1. how i can get the variationroot url directly which about the help of above code?
Permalink
Hi Ashish,
not sure what you mean. The code above will return the variation root site in the "pubWeb" variable and the Url in the Url variable.
Cheers,
Stefan