1

I have to list my upcoming events on the web page. I have created the data source item for holding all the events and each event has event date. I'm using Scriban to display all the events. My question is how should I ignore the passed day events and have to do the order by event date.

This is my Scriban Code snippet:

<div>
         {{ for i_child in i_datasource.children }}
             <div> 
               <h1><a href="{{ sc_link_url i_child 'CTA'}}"> {{ sc_field i_child 'Title'}}</a></h1>
             </div>     
       {{ end }}
    
</div>

Finally Done

As mentioned here How do you create a scriban function which implements the Content Search API? I have created the new search method for my requirements.

Created new class file

 public class GetSortOrder : IGenerateScribanContextProcessor
{
    protected ISearchService SearchService { get; }
    protected ISortingService SortingService { get; }
    protected ISiteInfoResolver SiteInfoResolver { get; }

    public GetSortOrder(ISearchService searchService, ISortingService sortingService)
    {
        SearchService =searchService;
        SortingService = sortingService;
    }
    private delegate IEnumerable<Item> SearchItemsDelegate(Item item, string s, string q = null, string o = null, int p = 10, int e = -1, string g = null, double r = -1);
  

   /// <summary>
    /// Search API
    /// </summary>
    /// <param name="s">ScopeID</param>
    /// <param name="p">NumberOfResults</param>
    /// <param name="o">Order</param>
    /// <param name="f">OrderBy FieldName</param>
    /// <returns>Result Items</returns>
    public IEnumerable<Item> SearchItemsImpl(string s, int p = 10, int o = 0, string f = null)
    {
        try
        {
            var scopesIDs = s?.Split(',', '|').Where(ID.IsID).Select(ID.Parse);

            var query = this.SearchService.GetQuery(new SearchQueryModel
            {
                ScopesIDs = scopesIDs,
            }, out var indexName);

            //if o=1 then ascending
            if (o == 1)
                query = query.OrderBy((ContentPage i) => i.get_Item<double>((string)f));
            else
                query = query.OrderByDescending((ContentPage i) => i.get_Item<double>((string)f));

            if (p > 0)
            {
                query = query.Take(p);
            }

            return query.Select(i => i.Uri).ToList()
                .Select(u => Factory.GetDatabase(u.DatabaseName)
                    .GetItem(u.ItemID, u.Language, u.Version));
        }
        catch (Exception ex)
        {
            Log.Info(string.Format("SearchItemsImpl-error-{0}stacktrace{1}", ex.Message.ToString(), ex.StackTrace.ToString()), ex);
        }
        return null;
    }


    public void Process(GenerateScribanContextPipelineArgs args)
    {
        args.GlobalScriptObject.Import("sc_searchitems", new SearchItemsDelegate(SearchItemsImpl));
    }
}

Added in Patch file

   <processor type="Foundation.ScribanExtensions.Pipelines.GetSortOrder, Foundation.ScribanExtensions" resolve="true" />

Updated scriban

{{ for i_searchitem in ( sc_searchitems i_datasource "{D7C469EF-8B47-4B19-810F-3ACA1354D979}" o: "EventDate,Descending" p: 50 q:"./*[@@templatename='Events'] " ) }}
  <li>{{ i_searchitem.Fields['Title'] }}</li>
{{ end }}

Here, I have mentioned my field EventDate, not working. I could see, it is working as expected with Title Field. So, something i have to add for Date field, s

10
  • Similar to this answer here sitecore.stackexchange.com/questions/28748/… you can consider writing a custom function to sort exactly how you want. Feb 8 at 16:09
  • @MichaelWest Thank you for your quick response. Do you have a GitHub URL for the code file? I am facing issue with the namespace, if I received it would helpful to me Feb 8 at 17:38
  • The example I provided is something you would incorporate into your solution. Feb 8 at 17:50
  • You should indeed create your own function for logic like this.
    – Gatogordo
    Feb 9 at 8:00
  • @MichaelWest the given code is working fine. Thank you. I am trying to do the sorting using the EventDate field, but it's not working. Do you have any suggestions? Feb 9 at 12:30

2 Answers 2

1

Answering question from the title of your question, there are built-in functions for array in scriban:

How you can use it in Sitecore? Something like that normally would do the trick if you want to order by item Name descending:

for i_child in i_datasource.children | array.sort "Name" | array.reverse

And then you can compare

if (i_child.Name > "b")

But I don't think there is an option to do the same with dates easily. If you try to compare

if (i_child.EventData > data.now)

I expect that you will get some error from scriban. Also, don't think that sorting would work for you with date field.

1
  • I just tried the first one. I am facing this issue for i_child in i_datasource.children | array.sort "Name" ------------- Failed to compare two elements in the array. Feb 8 at 17:52
0

I have resolved the issue and would like to post the

   public IEnumerable<Item> SearchItemsImpl(string s, int p = 10, int o = 0, string of = null, string f = null)
    {
        try
        {
            var scopesIDs = s?.Split(',', '|').Where(ID.IsID).Select(ID.Parse);

            var query = this.SearchService.GetQuery(new SearchQueryModel
            {
                ScopesIDs = scopesIDs,
            }, out var indexName);

            //if o=1 then ascending
            if (o == 1)
                query = query.OrderBy((ContentPage i) => i.get_Item<double>(of));
            else
                query = query.OrderByDescending((ContentPage i) => i.get_Item<double>(of));

            //filter by passed date
            if (!string.IsNullOrEmpty(f))
                query = query.Where((ContentPage i) => i.get_Item<DateTime>(f) >= DateTime.Now);

            if (p > 0)
            {
                query = query.Take(p);
            }

            return query.Select(i => i.Uri).AsEnumerable()
                .Select(u => Factory.GetDatabase(u.DatabaseName)
                    .GetItem(u.ItemID, u.Language, u.Version));
        }
        catch (Exception ex)
        {
            Log.Info(string.Format("SearchItemsImpl-error-{0}stacktrace{1}", ex.Message.ToString(), ex.StackTrace.ToString()), ex);
        }
        return new List<Item>();
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.