1-888-365-2779
+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / Custom Search Results

Custom Search Results

11 posts, 0 answered
  1. Steve Ditmer
    Steve Ditmer avatar
    6 posts
    Registered:
    05 Jan 2010
    16 Apr 2010
    Link to this post
    In our project we have multiple search indexes built and we need to return results for all three indexes.  I've searched the knowledge base and forums and haven't come up with anything quite like our needs.

    We would like to create a custom user control for results that would query all our indexes and where we could format the results and pagination our own way.  The built-in searchresults control does not give us the flexibility that we need.

    Can someone point us in the right direction?  Are there any code examples or documentation on retrieving search results?

    Thanks in advance for your help.
  2. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    16 Apr 2010
    Link to this post
    Hi Steve Ditmer,

    Thank you for using our services.

    The easiest approach is to create one consolidated search index, in one index you can add many page indexes, blog indexes, etc. as in attached image. Then you can have your other three indexes separately if you need them for something else. The other option is to extend the search to search in multiple indexes at once. This is discussed in those two threads:
    How to search for mutliple search indexes?
    Multiple search result controls

    Sincerely yours,
    Radoslav Georgiev
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  3. Steve Ditmer
    Steve Ditmer avatar
    6 posts
    Registered:
    05 Jan 2010
    16 Apr 2010
    Link to this post
    Hello Radoslav,

    Thank you for the quick response to my question.  Before posting I had looked at both of those posts as well as a few others.  In our situation we have the standard PageIndex.  We also have built a custom PDFIndex and are in the process of creating another custom index.  When combining these sources into one index we end up with an error regarding a missing .cfs file (as referenced in several other posts).  It is our understanding that we must create separate indexes due to this issue.  If there's another way, let us know!

    If there is a work-around or explanation to the missing .cfs file issue, please let me know.  I can provide more details if needed.  One thing I've noted is that the file it says is missing WAS there during the index process but has been deleted by the time indexing completes.

    Assuming we must use multiple indexes, I'll try to work with the information provided in the How to search for mutliple search indexes?  thread.

    Again, thank you!
  4. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    16 Apr 2010
    Link to this post
    Hi Steve Ditmer,

    Thank you for clarifying your situation.

    In this case I am afraid that you will have to use the methods in the forum threads linked in my previous reply. Unfortunately we have not been able to resolve the issue of the custom index being combined with other indexes.

    Greetings,
    Radoslav Georgiev
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  5. Steve Ditmer
    Steve Ditmer avatar
    6 posts
    Registered:
    05 Jan 2010
    20 Apr 2010
    Link to this post
    Hello Radoslov,

    I am having difficulty getting a custom SearchResults to work.  In addition to the link you provided, I've been following the greater detail in the Custom Search Results thread.  I've followed mcpdinkansas's steps which have been most helpful.  However, I am getting a message in the custom results page that "The resource object with key 'PreviousPage' was not found."  I'm sure this is because I'm missing something terribly simple.  Following are is the code from my project:

    SearchResultsControl.cs
    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
      
    namespace Lib.ui.WebControls
    {
        using Telerik.Framework.Web.Design;
        using Telerik.Cms.Web.UI;
        using Telerik.Search.WebControls;
        using Telerik.Search.Common;
        using System.IO;
        using System.Collections.Generic;
        using Telerik.Search.Engine;
        using Telerik.Utilities;
      
        public class SearchResultsControl : SearchResult
        {
            private Container container;
     
            protected override void CreateChildControls()
            {
     
                this.Controls.Clear();
     
                // Load the ASCX template assocated with this SearchResults
                string path = "~/UserControls/HTControls/searchresults.ascx";
                ITemplate itemTemplate = this.Page.LoadTemplate(path);
     
                string CatalogName = "Catalog_index";
     
                base.CreateChildControls();
     
                this.container = new Container(this);
     
                this.container.ResultsList.ItemDataBound += new RepeaterItemEventHandler(ResultsList_ItemDataBound);
                this.container.ResultsList.DataBind();
     
                itemTemplate.InstantiateIn(container);
     
                if (!string.IsNullOrEmpty(Query))
                {
                    string vPath = PathUtil.GetIndexPhysicalPath(this.IndexCatalogue);
                    string nPath = PathUtil.GetIndexPhysicalPath(CatalogName);
                    if (Directory.Exists(vPath) && Directory.Exists(nPath))
                    {
                        // check if query string is supplied to select the current page
                        if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString[PageKey]))
                        {
                            this.CurrentPage = Convert.ToInt32(
                                HttpContext.Current.Request.QueryString[PageKey]);
                        }
     
                        string searchQuery = Query;
                        string message = string.Empty;
     
                        bool isValid = this.EscapeSpecialChars ? this.EscapeSpecialChars : ValidateQuery(ref searchQuery, out message);
     
                        if (isValid)
                        {
                            int totalItems = 0;
                            int totalItems2 = 0;
                            int startIndex = (this.CurrentPage - 1) * this.PostsPerPage;
     
                            try
                            {
     
                                IList<ResultItem> DataSource = SearchManager.Search(
                                       searchQuery,
                                       CatalogName,
                                       startIndex,
                                       this.PostsPerPage,
                                       this.WordsMode,
                                       this.EscapeSpecialChars,
                                       out totalItems2);
     
                                foreach (ResultItem customItem in DataSource)
                                {
                                    if (customItem.Url.Contains(""))
                                    {
                                        string test = "";
                                    }
                                }
     
                                totalItems = totalItems + totalItems2;
     
                                int numberOfPages = (this.PostsPerPage == 0) ? 1 : (int)Math.Ceiling((double)totalItems / (double)this.PostsPerPage);
     
                                if (numberOfPages == 0 && totalItems > 0)
                                    numberOfPages = 1;
     
                                string qeryTest = this.Query.Trim('\"');
                                ((SearchResultsControlBase)this.layoutCnt.ResultsStats).EnableViewState = false;
                                this.container.ResultsStats.Text = string.Format(this.container.ResultsStats.Text, totalItems, qeryTest);
     
                                if (this.AllowPaging)
                                {
                                    this.container.Pager1.SelectedPageChanged += new EventHandler<EventArgs>(Pager_SelectedPageChanged);
                                    this.container.Pager1.PageCount = numberOfPages;
                                    this.container.Pager1.SelectedPage = this.CurrentPage;
                                }
                                this.container.ResultsList.DataSource = DataSource;
     
                            }
                            catch (Telerik.Lucene.Net.QueryParsers.ParseException ex)
                            {
                                this.container.ResultsStats.Text = "strange chars";
                                Log.Exception(ex);
                            }
                        }
                        else
                        {
                            this.container.ResultsStats.Text = message;
                        }
                    }
                    else
                    {
                        this.container.ResultsStats.Text = String.Format("InvalidIndex", this.IndexCatalogue);
                    }
                }
                else
                {
                    this.container.ResultsStats.Text = String.Empty;
                }
     
                this.container.ResultsList.ItemDataBound += new RepeaterItemEventHandler(ResultsList_ItemDataBound);
                this.container.ResultsList.SkinID = this.SkinID;
     
                this.Controls.Add(this.container);
                this.container.ResultsList.DataBind();
     
            }
     
            void ResultsList_ItemDataBound(object sender, RepeaterItemEventArgs e)
            {
                if (e.Item.ItemType == ListItemType.Footer)
                {
                    if (!this.AllowPaging)
                    {
                        e.Item.Controls.Clear();
                        return;
                    }
                }
            }
     
            void Pager_SelectedPageChanged(object sender, EventArgs e)
            {
                this.CurrentPage = ((Pager)sender).SelectedPage;
                this.ChildControlsCreated = false;
            }
     
     
    }
    SearchResultsToolboxItem.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace Lib.ui.WebControls
    {
        public class SearchResultsControlToolboxItem : System.Drawing.Design.ToolboxItem
        {
            /// <summary>
            /// Initializes the toolbox item with the proper type
            /// </summary>
            /// <remarks>
            /// The section under which the control is initially placed is determined by the
            /// [assembly: AssemblyCompany("Telerik")] attribute.
            /// Of course, it can later be changed to something else throuh web.config
            /// </remarks>
            public SearchResultsControlToolboxItem()
                : base(typeof(SearchResultsControl))
            {
                base.DisplayName = "Page Group Search Results";
                base.Description = "Displays search results for individual Page Groups";
            }
        }
    }
    SearchResultsControlBase.cs
    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
     
    namespace Lib.ui.WebControls
    {
        public class SearchResultsControlBase : UserControl
        {
            string test = "";
        }
    }
    searchresults.ascx
    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="searchresults.ascx.cs" Inherits="UserControls_HTControls_searchresults" %>
    <%@ Register Assembly="Telerik.Cms.Web.UI" Namespace="Telerik.Cms.Web.UI" TagPrefix="sfWeb" %>
     
    <div class="article">
    <h1><asp:Literal ID="ResultsStats" runat="server">Found {0} pages for "{1}" </asp:Literal></h1>
     
    <asp:Repeater ID="rptResults" runat="server">
        <HeaderTemplate>
            <dl class="searchResults">
        </HeaderTemplate>
        
        <ItemTemplate>
            
            <dt><strong><a href='<%#DataBinder.Eval(Container.DataItem, "Url")%>'><%#DataBinder.Eval(Container.DataItem, "Title")%></a></strong></dt
            <dd><%#DataBinder.Eval(Container.DataItem, "Snippet")%></dd>
     
        </ItemTemplate>
        <FooterTemplate>
            </dl>
        </FooterTemplate>
    </asp:Repeater>
     
    <sfWeb:Pager ID="Pager1" runat="server">
        <LayoutTemplate>
             <asp:Repeater ID="PageRepeaterLinkButton" runat="server">
                <HeaderTemplate>
                    <ol class="ht_pager">
                    <li><asp:LinkButton ID="PreviousPage" runat="server" Text="<%$Resources:PreviousPage %>"></asp:LinkButton></li>
                </HeaderTemplate>
                <ItemTemplate>
                    <li>
                        <asp:LinkButton ID="SingleItem" runat="server" />
                    </li>
                </ItemTemplate>
                <FooterTemplate>
                    <li><asp:LinkButton ID="NextPage" runat="server" Text="<%$Resources:NextPage %>"></asp:LinkButton></li>
                    </ol>
                </FooterTemplate>
            </asp:Repeater>
            <asp:Repeater ID="PageRepeaterHyperLink" runat="server">
                <HeaderTemplate>
                    <ol class="ht_pager">
                    <li><asp:HyperLink ID="PreviousPage" runat="server" Text="<%$Resources:PreviousPage %>"></asp:HyperLink></li>
                </HeaderTemplate>
                <ItemTemplate>
                    <li>
                        <asp:HyperLink ID="SingleItem" runat="server" />
                    </li>
                </ItemTemplate>
                <FooterTemplate>
                    <li><asp:HyperLink ID="NextPage" runat="server" Text="<%$Resources:NextPage %>"></asp:HyperLink></li>
                    </ol>
                </FooterTemplate>
            </asp:Repeater>
        </LayoutTemplate>
    </sfWeb:Pager>
     
    </div>
    searchresults.ascx.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.IO;
    using Lib.ui.WebControls;
     
    public partial class UserControls_HTControls_searchresults : SearchResultsControlBase
    {
        protected void Page_Load(object sender, EventArgs e)
        {
     
        }
     
    }
    I entered the following line in web.config
    <add name="CustomSearchControl" section="HTControls" type="Lib.ui.WebControls.SearchResultsControl, App_Code"/>

    I would appreciate any advice you can offer.
    Thank you,
    Steve

  6. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    20 Apr 2010
    Link to this post
    Hello Steve Ditmer,

    Have you added the resx files for the pager control that is in SearchResults template?

    Best wishes,
    Ivan Dimitrov
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  7. Steve Ditmer
    Steve Ditmer avatar
    6 posts
    Registered:
    05 Jan 2010
    20 Apr 2010
    Link to this post
    Hi Ivan,

    Thank you - I totally missed that.  I've fixed the resource problem and am now able to debug :)

    I've added a breakpoint to the CreateChildControls function but this function doesn't appear to be called.  How do I specify that this function is called when my searchresults.aspx is called?
  8. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    20 Apr 2010
    Link to this post
    Hello Steve Ditmer,

    You should set SearchResultsControlToolboxItem for the SearchResultsControl

    Greetings,
    Ivan Dimitrov
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  9. Steve Ditmer
    Steve Ditmer avatar
    6 posts
    Registered:
    05 Jan 2010
    20 Apr 2010
    Link to this post
    Ivan, I don't understand where I should set SearchResultsControlToolboxItem for the SearchResultsControl.  Can you be more specific? 

    Thank you,
    Steve

  10. Steve Ditmer
    Steve Ditmer avatar
    6 posts
    Registered:
    05 Jan 2010
    20 Apr 2010
    Link to this post
    Ivan, just to follow up, I think that in your previous message you may have been referring to the following class:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Telerik.Web;
     
    namespace Lib.ui.WebControls
    {
        public class SearchResultsControlToolboxItem: ToolboxItem
        {
            /// <summary>
            /// Initializes the toolbox item with the proper type
            /// </summary>
            /// <remarks>
            /// The section under which the control is initially placed is determined by the
            /// [assembly: AssemblyCompany("Telerik")] attribute.
            /// Of course, it can later be changed to something else throuh web.config
            /// </remarks>
            public SearchResultsControlToolboxItem() : base(typeof(SearchResultsControl))
            {
                base.DisplayName = "Page Group Search Results";
                base.Description = "Displays search results for individual Page Groups";
            }
        }
    }
    I do have this set as I believe you suggested.

    When adding this control to a page, I see that it is necessary to edit the control once placed, and change LayoutTemplatePath on the Appearance tab to point to my custom results page.  Even doing so, I find that I must still include an IndexCatalogue as part of the querystring - and that only results from that index are displayed.  Of course, the breakpoint that I have set in my custom SearchResultsControl.CreateChildControls() function is never hit.

    I know I'm getting close, but still need your advice in getting the page to use the correct function.  Please point me in the right direction.

    Thanks,
    Steve
  11. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    21 Apr 2010
    Link to this post
    Hi Steve Ditmer,

    You have the toolbox, but it is not referenced in  SearchResultsControl. In this case SearchResultsControl loads the default toolbox item and your control never gets called.

    [ToolboxItem ( typeof ( SearchResultsControlToolboxItem ) )]
    public class SearchResultsControl : SearchResult
    {
     
     // other logic goes here
     
    }


    Best wishes,
    Ivan Dimitrov
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
Register for webinar
11 posts, 0 answered