Even
though there is a Query Builder option provided in the edit mode of the
webpart, sometimes it is necessary to set the "QueryText" attribute
of the Content Search Web Part Programmatically.
In
a CSWP we can limit the search results to take from current site (This site) or
from site collection (This site collection). But there is no way to specify another
URL or relative URL without hardcoding the server name. In my case I wanted to
read data from variation top sites as all of my language dependent SPLists were
residing in <site_collection>/en and <site_collection>/fr level.
Therefore
I had to extend OOB CSWP and create a custom CSWP for my use. My plan was to override
the QueryText from the backend.
In
order to override the QueryText attribute, I had to override the BeforeSerializeToClient
event. So what I’m doing is;
- In the “Build Your Query” screen, in the
Query Text field, add the path attribute and set my own value called “CurrentVariationLabel”,
in addition to the other filters.
- Then in the “BeforeSerializeToClient” event, replace “CurrentVariationLabel”
text with current variation label.
- I have written a private method called “GetCurrentVariationLabel” to get the current
variation label.
protected override void OnLoad(EventArgs e)
{
if (this.AppManager != null)
{
if (this.AppManager.QueryGroups.ContainsKey(this.QueryGroupName) &&
this.AppManager.QueryGroups[this.QueryGroupName].DataProvider
!= null)
{ this.AppManager.QueryGroups[this.QueryGroupName].DataProvider.BeforeSerializeToClient +=
new BeforeSerializeToClientEventHandler(UpdateQueryText);
}
}
base.OnLoad(e);
}
private void UpdateQueryText(object sender, BeforeSerializeToClientEventArgs e)
{
DataProviderScriptWebPart
dataProvider = sender as DataProviderScriptWebPart;
dataProvider.QueryTemplate =
dataProvider.QueryTemplate.Replace("CurrentVariationLabel", "\"" + GetCurrentVariationLabel() +"\"");
}
private static string GetCurrentVariationLabel()
{
VariationLabel currentVL = null;
if (SPContext.Current != null)
{
string currentUrl = SPContext.Current.Web.Url;
ReadOnlyCollection<VariationLabel> variationLabels = null;
if (Variations.Current != null)
{
variationLabels
= Variations.Current.UserAccessibleLabels;
}
if (!String.IsNullOrEmpty(currentUrl) && variationLabels != null)
{
foreach (VariationLabel vl in variationLabels)
{
if (currentUrl.StartsWith(vl.TopWebUrl, StringComparison.CurrentCultureIgnoreCase))
{
currentVL = vl;
}
}
}
}
if (currentVL != null)
{
return currentVL.TopWebUrl;
}
}
With
the same approach, by changing GetCurrentVariationLabel() method, I can use my
custom CSWP to limit results from any other sub-site as well.