Enable editors to hide pages from appearing in the search

Vote:
 

Hi there,

I would like to add the ability for our editors to be able to hide certain pages from appearing in the site-wide search.

What would be the best way to go about doing this?

Let's say I edit our model for SitePageData.cs from which all our pages inherit and add a boolean like so: public virtual bool HidePage { get; set; }

How could I access this boolean from the Search Query?

#254981
May 17, 2021 10:50
Vote:
 

Yes just add a new property to your SitePageData model that's a boolean and then adjust the Search & Navigation code to only search for pages where it's set to true using the Match() method https://world.episerver.com/documentation/Items/Developers-Guide/EPiServer-Find/11/DotNET-Client-API/Searching/Filtering/Boolean/ 

#254983
May 17, 2021 13:14
Vote:
 

Thanks Scott for your suggestion, so I have gone ahead and added a boolean to our SitePageData.cs model:

        [Display(
            GroupName = SystemTabNames.Settings,
            Order = 351)]
        public virtual bool ExcludeFromSearch { get; set; }

Then in FindSearchPageController.cs I attempted to adjust the search by adding a filter as suggested in the example you posted:

        private ITypeSearch<ISearchableContent> BuildQuery(FindSearchContentModel model, string language)
        {
            var searchQuery = searchClient.Search<ISearchableContent>()
                .For(model.Query)
                .InField(x => x.Name)
                .InAllField()
                .UsingAutoBoost(TimeSpan.FromDays(30))
                .Filter(sp => sp.IsDeleted.Match(false))
                .Filter(x => x.ExcludeFromSearch.Match(false))
                .FilterForVisitor()
                .Filter(x => x.SearchLanguage.Match(language) | x.SearchLanguage.Match(string.Empty))
                .TermsFacetFor(x => x.SearchSection())
                .FilterFacet("AllSections", x => x.SearchSection().Exists())
                .TermsFacetFor(x => x.SearchTags)
                .FilterFacet("AllTags", x => x.SearchTags.Exists())
                .TermsFacetFor(x => x.SearchCategory)
                .FilterFacet("AllCategories", x => x.SearchCategory.Exists());

            if (!string.IsNullOrWhiteSpace(model.SectionFilter))
            {
                searchQuery = searchQuery.Filter(x => x.SearchSection().Match(model.SectionFilter));
            }

            if (!string.IsNullOrWhiteSpace(model.FilterByTags))
            {
                searchQuery = searchQuery.Filter(x => x.SearchTags.Match(model.FilterByTags));
            }

            if (!string.IsNullOrWhiteSpace(model.Category))
            {
                searchQuery = searchQuery.Filter(x => x.SearchCategory.Match(model.Category));
            }

            searchQuery = Sort(searchQuery, model.SortBy)
                .Skip((model.PagingPage - 1) * model.CurrentPage.PageSize)
                .Take(model.CurrentPage.PageSize)
                .ApplyBestBets();

            var doNotTrackHeader = System.Web.HttpContext.Current.Request.Headers.Get("DNT");
            // Should not track when value equals 1
            if (doNotTrackHeader == null || doNotTrackHeader.Equals("0"))
            {
                searchQuery = searchQuery.Track();
            }

            return searchQuery;
        }

The error I get however is: "ISearchableContent does not contain a definition for ExcludeFromSearch and no accessible extension method ExcludeFromSearch accepting a first argument of type ISearchableContent could be found"

If I look in ISearchableContent I see:

using EPiServer.Core;
using System;
using System.Collections.Generic;

namespace ProjectDigital.Site.Models.Search
{
    public interface ISearchableContent : IContent
    {
        DateTime SearchPublishDate { get; }

        IEnumerable<string> SearchTags { get; }

        IEnumerable<string> SearchCategory { get; }

        string TeaserText { get; }

        ContentReference PageImage { get; }

        string SearchLanguage { get; }

        IEnumerable<string> SearchBreadcrumbs { get; }
    }
}

Apologies I am new to this all. Do you have any suggestion for me perhaps? 

#254989
May 17, 2021 16:44
Vote:
 

You need to add ExcludeFromSearch to the Interface.

using EPiServer.Core;
using System;
using System.Collections.Generic;

namespace ProjectDigital.Site.Models.Search
{
    public interface ISearchableContent : IContent
    {
        DateTime SearchPublishDate { get; }

        IEnumerable<string> SearchTags { get; }

        IEnumerable<string> SearchCategory { get; }

        string TeaserText { get; }

        ContentReference PageImage { get; }

        string SearchLanguage { get; }

        IEnumerable<string> SearchBreadcrumbs { get; }

       bool ExcludeFromSearch {get;}
    }
}
#254990
May 17, 2021 16:48
Vote:
 

Thank you so much for your help Scott, I assume I will have to rebuild the find index for this to work correct?

#254991
May 17, 2021 16:50
Scott Reed - May 17, 2021 16:52
Yes you'll need the content re-indexed to have the new field in the JSON document. You can use the admin interface for Find in the CMS to look at the content and check if it's indexed properly.
Vote:
 

Thanks so much Scott, working perfectly. 

#254993
May 17, 2021 17:21
Scott Reed - May 17, 2021 17:23
no worries :-)
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.