Home > Lucene Search > Step 3: Create a Web Control to Display Related Items

Step 3: Create a Web Control to Display Related Items

Next create a Web control class to display search results on your Web site. In this solution there are three Web controls:

  • RelatedItems.cs
  • SearchResults.cs
  • Facet.cs

In this blog post we will only create the first control, RelatedItems.cs and provide the code used to create the facet control.

How to Create a Related Items Web Control

 

RelatedItems.cs

The purpose of the related items control is to trigger a query that fetches content from the search indexes. It uses the Searcher and the Query Runner classes to return a list of items and then formats the list and displays the results as related items in the side bar of the appropriate product pages.

To create a related items control:

1. Include the following namespaces:

namespace Starterkit.WebControls

{

using System;

using System.Web.UI;

using Sitecore.Data.Items;

using Sitecore.Links;

using System.Collections.Generic;

using System.Linq;

using Sitecore.Data;

using Sitecore.Data.Fields;

using Sitecore.Diagnostics;

using Sitecore.Training.Index;

2. Name this Web control RelatedItems.

public class RelatedItems : Sitecore.Web.UI.WebControl

3. When you create a class that inherits from a Web control you always need a DoRender method. Create a DoRender method to control the presentation of the related items list. The following code extract shows the entire method.

protected override void DoRender(HtmlTextWriter output)

{

var categories = from relatedItem in GetAllRelations()

group relatedItem by GetDisplayNameById(relatedItem.ParentID) into g

select new { CategoryName = g.Key, Items = g };

if (categories.Count() > 0)

{

//<div id="relatedItems">

output.AddAttribute(HtmlTextWriterAttribute.Id, "relatedItems");

output.RenderBeginTag(HtmlTextWriterTag.Div);

//<h2>

output.RenderBeginTag(HtmlTextWriterTag.H2);

output.Write("Related Categories");

//</h2>

output.RenderEndTag();

//<ul>

output.RenderBeginTag(HtmlTextWriterTag.Ul);

foreach (var category in categories)

{

//<li>

output.RenderBeginTag(HtmlTextWriterTag.Li);

output.Write(String.Format("{0} ({1}):", category.CategoryName,

category.Items.Count()));

//</li>

output.RenderEndTag();

//<ul>

output.RenderBeginTag(HtmlTextWriterTag.Ul);

foreach (var item in category.Items)

{

//<li>

output.RenderBeginTag(HtmlTextWriterTag.Li);

//<a href='/item.aspx'

output.AddAttribute(HtmlTextWriterAttribute.Href,

LinkManager.GetItemUrl(item));

output.RenderBeginTag(HtmlTextWriterTag.A);

output.Write(item.DisplayName);

//</a>

output.RenderEndTag();

//</li>

output.RenderEndTag();

}

//</ul>

output.RenderEndTag();

}

//</ul>

output.RenderEndTag();

//</div>

output.RenderEndTag();

}

}

Create a method called GetAllRelations.

protected IEnumerable<Item> GetAllRelations()

This method goes to the multi-list field on the item and fetches all items that are marked as related by reading the value of the multi-list field.

It then creates an instance of the Searcher and calls the Searcher GetRelatedItems byField method which triggers the Searcher and Query Runner.

4. In the GetAllRelations method, use comments to select a Searcher method. Add or remove comments so that only one method can be run at any one time:

//relatedItems.AddRange(searcher.GetItemsByFullTextQuery(ItemIds));

relatedItems.AddRange(searcher.GetRelatedItemsByField(ItemIds, fieldName, true));

//relatedItems.AddRange(searcher.GetRelatedItems(ItemIds));

This enables you to easily change the way the control interacts with the Searcher.

5. Create a method called GetDirectItemRelations(string fieldName)

protected List<Item> GetDirectItemRelations(string fieldName)
        {
            var directItemRelations = new List<Item>();

            foreach (var itemId in ItemIds.Split(new[] { "|" }, 

            StringSplitOptions.RemoveEmptyEntries))
            {
                var item = Sitecore.Context.Database.GetItem(itemId);

                if (item != null &&
                    item.Fields[fieldName] != null &&
                    (FieldTypeManager.GetField(item.Fields[fieldName]) is MultilistField))
                {
                    MultilistField relatedItemsField = item.Fields[fieldName];
                    directItemRelations.AddRange(relatedItemsField.GetItems());
                }
            }

            return directItemRelations;
        }

            return directItemRelations;
        }

Get all related items and return a list of GUIDS that are pipe separated. Sitecore uses pipe separated lists in the Related Items field to separate GUIDS. In the Content Editor View tab, if you select the raw values field, you can see the pipe separated GUIDS in the RelatedItems field.

pipe separated guids

6. Create a method called GetDisplayNameById(ID itemId).

This method gets the title or display name for the selected item from the title field and displays it in the control.

standard related items  Related Items Web control

7. Save and compile your new Web control.

Facet.cs

This control adds the refinements that display Category and Brand Name above the related items control.

The Facet Web control fetches items from the Content Editor, content tree and then gets the URLs of each item. Then it constructs a query in the address bar of the browser.

For example:

http://<your site>/en/Standard-Items/Search-Results.aspx?search=desk

desk in address bar

Code extract to show how the refinements query is constructed:

{

string url = LinkManager.GetItemUrl(Sitecore.Context.Item);

var queryStringDictionary = WebUtil.ParseQueryString(WebUtil.GetQueryString());

if(queryStringDictionary.ContainsKey(FieldName))

queryStringDictionary.Remove(FieldName);

return WebUtil.AddQueryString(url + "?" + WebUtil.BuildQueryString(queryStringDictionary, false), new[] { FieldName, FieldValue });

}

AppendFacetURL is called by the following code that controls the presentation of the refinements:

{

//<div id="relatedItems">

output.AddAttribute(HtmlTextWriterAttribute.Class, "facet");

output.RenderBeginTag(HtmlTextWriterTag.Div);

//<a href='/item.aspx'

output.AddAttribute(HtmlTextWriterAttribute.Href, AppendFacetUrl());

output.RenderBeginTag(HtmlTextWriterTag.A);

output.Write(Name);

//</a>

output.RenderEndTag();

//</div>

output.RenderEndTag();

}

search results control  Search Results control with facetted list control

Search Results.cs

The Search Results Web control uses the same classes as RelatedItems.cs to display related items and other refinements in the side bar. See the full solution source code to find out how this control has been adapted to display the same related items and facetted list in the side bar.

search results control related items  Search Results control with related items control

Next step: Testing the Solution

Advertisement
Categories: Lucene Search
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.