Introduction
Le refinement dans le Search center permet de pouvoir facilement filtrer sur l'ensemble des enregistrements afin de rendre la recherche plus pertinente. Cette WebPart se trouve par défaut sur la gauche et affiche les filtres de manière textuelle.
Il y a possibilité de personnaliser le refinement, notamment, l'ordre des catégories ou les catégories à afficher (voir http://blog.xvanneste.com/Lists/Billets/Post.aspx?ID=27 )
Ici j'ai ajouté en haut les Body Parts qui sont des métadonnées extrait de mes documents (voir http://blog.xvanneste.com/Lists/Billets/Post.aspx?ID=28 )
Mais on peut aller beaucoup plus loin dans le refinement et on peut le customiser entièrement en développant notre propre WebPart de refinement.
RefinementManager
La premiére chose à étudier est le RefinementManager. Celui-ci permet de récupérer le XML de refinement et donc les différentes catégories qui seront utilisé par le Refinement Panel.
On utilisera donc la méthode GetRefinementXml pour récupérer le XML du refinement panel.
Voici ce qu'on peut s'attendre à récupérer (seul la partie ResultType est mise pour des raisons de quantité):
<?xml
version="1.0"
encoding="utf-8"?>
<FilterPanel>
<FilterCategory
Id="Microsoft_Office_Server_Search_WebControls_ManagedPropertyFilterGenerator__-357320691"
ConfigId="Microsoft_Office_Server_Search_WebControls_ManagedPropertyFilterGenerator__-357320691"
Type="Microsoft.Office.Server.Search.WebControls.ManagedPropertyFilterGenerator"
DisplayName="Result Type"
ManagedProperty="format"
ShowMoreLink="True"
FreeFormFilterHint=""
MoreLinkText="show more"
LessLinkText="show fewer"
ShowCounts="Count">
<Filters>
<Filter>
<Value>Any Result Type</Value>
<Tooltip>Any Result Type</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=</Url>
<Selection>Implied</Selection>
<Count></Count>
<Percentage></Percentage>
</Filter>
<Filter>
<Value>Rich Text</Value>
<Tooltip>Rich Text</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=format%3D%22AQlSaWNoIFRleHQGZm9ybWF0AQJeIgIiJA%3D%3D%22</Url>
<Selection>Deselected</Selection>
<Count>20</Count>
<Percentage>0.3174603</Percentage>
</Filter>
<Filter>
<Value>Adobe PDF</Value>
<Tooltip>Adobe PDF</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=format%3D%22AQlBZG9iZSBQREYGZm9ybWF0AQJeIgIiJA%3D%3D%22</Url>
<Selection>Deselected</Selection>
<Count>17</Count>
<Percentage>0.2698413</Percentage>
</Filter>
<Filter>
<Value>Microsoft Word</Value>
<Tooltip>Microsoft Word</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=format%3D%22AQ5NaWNyb3NvZnQgV29yZAZmb3JtYXQBAl4iAiIk%22</Url>
<Selection>Deselected</Selection>
<Count>15</Count>
<Percentage>0.2380952</Percentage>
</Filter>
<Filter>
<Value>Microsoft PowerPo…</Value>
<Tooltip>Microsoft PowerPoint</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=format%3D%22ARQBTWljcm9zb2Z0IFBvd2VyUG9pbnQGZm9ybWF0AQJeIgIiJA%3D%3D%22</Url>
<Selection>Deselected</Selection>
<Count>9</Count>
<Percentage>0.1428571</Percentage>
</Filter>
</Filters>
<MoreFilters>
<Filter>
<Value>Any Result Type</Value>
<Tooltip>Any Result Type</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=</Url>
<Selection>Implied</Selection>
<Count></Count>
<Percentage></Percentage>
</Filter>
<Filter>
<Value>Rich Text</Value>
<Tooltip>Rich Text</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=format%3D%22AQlSaWNoIFRleHQGZm9ybWF0AQJeIgIiJA%3D%3D%22</Url>
<Selection>Deselected</Selection>
<Count>20</Count>
<Percentage>0.3174603</Percentage>
</Filter>
<Filter>
<Value>Adobe PDF</Value>
<Tooltip>Adobe PDF</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=format%3D%22AQlBZG9iZSBQREYGZm9ybWF0AQJeIgIiJA%3D%3D%22</Url>
<Selection>Deselected</Selection>
<Count>17</Count>
<Percentage>0.2698413</Percentage>
</Filter>
<Filter>
<Value>Microsoft Word</Value>
<Tooltip>Microsoft Word</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=format%3D%22AQ5NaWNyb3NvZnQgV29yZAZmb3JtYXQBAl4iAiIk%22</Url>
<Selection>Deselected</Selection>
<Count>15</Count>
<Percentage>0.2380952</Percentage>
</Filter>
<Filter>
<Value>Microsoft PowerPo…</Value>
<Tooltip>Microsoft PowerPoint</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=format%3D%22ARQBTWljcm9zb2Z0IFBvd2VyUG9pbnQGZm9ybWF0AQJeIgIiJA%3D%3D%22</Url>
<Selection>Deselected</Selection>
<Count>9</Count>
<Percentage>0.1428571</Percentage>
</Filter>
<Filter>
<Value>Web Page</Value>
<Tooltip>Web Page</Tooltip>
<Url>/Search/Pages/results.aspx?k=anatomie&r=format%3D%22AQhXZWIgUGFnZQZmb3JtYXQBAl4iAiIk%22</Url>
<Selection>Deselected</Selection>
<Count>2</Count>
<Percentage>0.03174603</Percentage>
</Filter>
</MoreFilters>
</FilterCategory>
</FilterPanel>
Comme on peut le voir on a deux grosses parties, la première est Filters qui contient la collection de filtre. Cette collection de filtre est composée du nom, du Tooltip, de l'url de refinement, du nombre de document et du pourcentage par rapport au total.
La deuxième partie est le MoreFilters qui reprend le filtre mais correspond à l'ensemble des données. (Attention dans MoreFilters on a une redondance par rapport à Filters).
Commençons notre WebPart. La première chose à faire est d'hériter de RefinementWebPart afin de récuperer l'ensemble des caractéristiques de cette webpart.
[ToolboxItemAttribute(false)]
public
class
RefineWP : RefinementWebPart
{}
A partir de là, on peut personnaliser le comportement du web part.
Dans le CreateChildControl on va utiliser le GetRefinementXml pour récuperer le XML. Pour cela on utilisera la variable _RefinementManager qui est héritée de RefinementWebPart.
protected
override
void CreateChildControls()
{
XDocument xdoc = GetXDocFromXmlDoc(this._RefinementManager.GetRefinementXml());
var q = from c in xdoc.Descendants("FilterCategory") select
new
RefinementXmlPart((string)c.Attribute("DisplayName").Value, (string)c.Attribute("Id").Value, (XElement)c);
FillControlLst(q);
foreach (Control ctrl in lstControl)
{
this.Controls.Add(ctrl);
}
base.CreateChildControls();
}
Ici il manque quelque test, en effet _RefinementManager peut être nulle si le xml des filter categories est mal formaté, GetRefinementXml peut aussi retourner nulle. Mais ce code est pour la démo.
GetXPathNavigator
Si on prend notre code tel quel, il y aura un problème de redondance, en effet la webpart RefinementWebPart dont on hérite va créer son refinement textuel, nous on veut ajouter un refinement graphique pour le Format et pour BodyPart. On aura donc deux fois format et bodypart dans le panel refinement. On va surcharger GetXPathNavigator qui permet de modifier le XML utiliser.
protected
override
XPathNavigator GetXPathNavigator(string viewPath)
{
XPathNavigator xpath= base.GetXPathNavigator(viewPath);
if (xpath == null)
return xpath;
XmlDocument xmldoc = new
XmlDocument();
xmldoc.LoadXml(xpath.OuterXml);
XDocument xdoc = GetXDocFromXmlDoc(xmldoc);
var q = (from e in xdoc.Descendants("FilterCategory") where e.Attribute("ManagedProperty").Value == "format" || e.Attribute("ManagedProperty").Value == "bodyparts"
select e);
q.Remove();
return xdoc.CreateNavigator();
}
Ici on sélectionne tous les nœuds du fichier XML qui pointent sur format et sur bodyparts et on les enlève du XML retourné par XPathNavigator.
On aurait pu les retirer du Filter Categories definition mais le souci c'est que les informations sont importantes pour créer les aspects visuels de refinement.
Apres nettoyage, voici le refinement panel :
Résultat
Une fois le Filter Categorie Definition complété correctement et le code de création des Charts et de l'ImageMap body de compilé. Voici ce que l'on obtient :
Les images sont bien entendu réactives :

Et permettent en cliquant dessus de filtrer la recherche :
Le code se trouve sur http://xvanneste.codeplex.com Nom du projet XVRefinementWP.