Unfortunately just specifying resource string for WebUrl
property of ContentByQueryWebPart web part is not enough since resource string could not be resolved dynamically (basically not supported) using SharePoint web parts infrastructure like in case of Url tokens (e.g. ~sitecollection
).
But, you could consider the following approach.
Solution
The solution demonstrates how to dynamically resolve resource string specified for WebUrl
property of CBQ web part, it consists of:
- a custom module (see
WebPartsResourceManager
class below) that
allows to substitute the resource key with actual value for web part property when the web part is initialized
- in order to register that module,the custom publishing page layout is
intended (see the
PublishingLayout
class below)
Module for to resolving web part property values from resource strings:
public class WebPartsResourceManager
{
static WebPartsResourceManager()
{
}
public static void Register(Page page)
{
page.PreRender += OnPagePreRender;
}
static void OnPagePreRender(object sender, EventArgs e)
{
using (new SPMonitoredScope("ResourceManagerWebPart.OnPreRender"))
{
try
{
var page = sender as Page;
var manager = WebPartManager.GetCurrentWebPartManager(page);
if (manager == null || manager.DisplayMode == WebPartManager.EditDisplayMode)
{
return;
}
ForEachWebPart<ContentByQueryWebPart>(manager, ResolveWebUrlProperty);
}
catch (Exception ex)
{
//Logging goes here..
}
}
}
private static void ResolveWebUrlProperty(ContentByQueryWebPart cbq)
{
var lcid = System.Threading.Thread.CurrentThread.CurrentUICulture.LCID;
cbq.WebUrl = SPUtility.GetLocalizedString("$Resources:Contoso.SharePoint,NewsSourceUrl;", "Contoso.SharePoint", (uint)lcid);
}
private static void ForEachWebPart<T>(WebPartManager manager, Action<T> action) where T : WebPart
{
var webParts = manager.WebParts.OfType<T>();
foreach (var webPart in webParts)
{
action(webPart);
}
}
}
Custom Publishing Layout Page that allows to resolve WebUrl
property from resource string:
public class PublishingLayout : PublishingLayoutPage
{
public PublishingLayout()
:base()
{
WebPartsResourceManager.Register(this);
}
}
Now, you could create your page layout that inherits from PublishingLayout
, for example:
<%@ Page Language="C#" Inherits="Contoso.Intranet.SharePoint.UI.ApplicationPages.PublishingLayout, Contoso.Intranet.SharePoint.UI, Version=1.0.0.0,Culture=neutral,PublicKeyToken=c5dbb8c5770bc890" %>
and specify WebUrl
property like this:
<property name="WebUrl" type="string">$Resources:Contoso.SharePoint,NewsSourceUrl;</property>
where NewsSourceUrl
is a key from resource file (Contoso.SharePoint.resx
)