2

How to get random 3 data from a list of data source items using the Scriban template below query, I can get all data and show accordingly but I need random 3 data from a list of data sources.

<div style="margin-top:10px"
    <section class="regular slider carousel-documents slick-slider">

        {{ for i_child_res in i_datasource.children }}
        {{}}
        {{counter=0}}
        {{counter=for.index}}
        {{ if counter < 4 }}
        <div class="slide">
            <div class="field-slideimage">
                {{i_child_res.ResourceImage}}
            </div>
            <div class="slide-info">
                <div class="field-slidetext">
                    <div class="quantum-cta_tag-share">
                        <h4 class="quantum-cta-sub__title">{{i_child_res.ResourceCategory}}</h4>
                    </div>
                    <h1>{{i_child_res.ResourceTitle}}</h1>
                    <p class="campaign-cta-content">{{i_child_res.ResourceDescription}}</p>
                    <div class="tags-group">
                        {{ for i_child_rest in (sc_followmany i_item "ResourceTags") }}
                        <span class="tags">{{i_child_rest.dataName}}</span>
                        {{ end }}
                    </div>
                </div>
            </div>
        </div>
        {{ end }}
        {{end}}
    </section>
</div>
2
  • 1
    I would suggest you try the - math.random <minValue> <maxValue> -github.com/scriban/scriban/blob/master/doc/… You can run the loop three times and get the random value from your list by passing 1 as minValue and list length as maxValue. I didn't try it but I think this can be an option. Commented Jul 30 at 6:06
  • @MahendraShekhawat You should add it as an answer. It seems like an easiest implementation of all answers. Commented Aug 1 at 7:41

2 Answers 2

1

You can use the Scriban Custom Embedded function for the same. If you have not heard of custom embedded functions, please refer : https://blogs.perficient.com/2020/08/03/sxa-scriban-creating-custom-embedded-function-in-scriban/

I have provided details on how you can use the embedded function to get the required functionality. Here I have used datasourceItems as List. You can modify it accordingly.

using System;
using System.Collections.Generic;
using System.Linq;
using Scriban.Runtime;
using Sitecore.Data.Items;
using Sitecore.XA.Foundation.Scriban.Pipelines.GenerateScribanContext;
namespace MyProject.Pipelines.GenerateScribanContext
{
    public class AddRandomItemsFunction : IGenerateScribanContextProcessor
    {
          public AddRandomItemsFunction()
          {

          }

          private delegate List<Item> GetRandomItemsDelegate(List<Item> dataSourceItems);

          public void Process(GenerateScribanContextPipelineArgs args)
          {
               args.GlobalScriptObject.Import("sc_getrandomItems", new GetRandomItemsDelegate(GetRandomItems));
          }

          public List<Item> GetRandomItems(List<Item> dataSourceItems)
          {
              var random = new Random();
              var numbers = new HashSet<int>();
              List<Item> updatedDatasourceItems = new List<Item>();

              while (numbers.Count == 3)
              {
                  int randomNumber = random.Next(0, dataSourceItems.Count);
                  if (!numbers.Contains(randomNumber))
                      numbers.Add(randomNumber);
              }

              updatedDatasourceItems.AddRange(numbers.Select(x => dataSourceItems[x]).ToList());

              return updatedDatasourceItems;
          }
      }
}

Now you can call the embedded function like

updated_datasource_children = sc_getrandomItems i_datasource.children

And use the updated_datasource_children in the for loop.

Note : Have not verified this. But you can modify the logic accordingly.

Hope this helps !!!

1

You can use Scriban extension as below to fetch random list of children from datasource item.

  1. Create the Scriban Extension as below, to generate the random list that take list of items and the number of items to be returned as a parameter.
using Scriban.Runtime;
using Sitecore.Collections;
using Sitecore.Data.Items;
using Sitecore.XA.Foundation.Scriban.Pipelines.GenerateScribanContext;
using System;
using System.Collections.Generic;
using System.Linq;

public class GetRandomItemsFunction : IGenerateScribanContextProcessor
{
  private delegate List<Item> RandomItemDelegate(ChildList item, int randomElementsListSize);
  public void Process(GenerateScribanContextPipelineArgs args)
  {
     var randomItemsDelegate = new RandomItemDelegate(GetRandomItems);
     args.GlobalScriptObject.Import("sc_random_items", (Delegate)randomItemsDelegate);
  }
  public List<Item> GetRandomItems(ChildList items, int randomElementsListSize)
  {
     if (items != null)
     {
        return items.OrderBy(x => Guid.NewGuid()).Take(randomElementsListSize).ToList();
     }
     return null;
   }
}
  1. Thereafter, register the above Scriban Extension through below configuration patch:
<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
    <sitecore>
       <pipelines>
          <generateScribanContext>
                <processor type="SitecoreCustomExtensions.ScribanExtensions.GetRandomItemsFunction,SitecoreCustomExtensions" resolve="true"/>
          </generateScribanContext>
       </pipelines>
    </sitecore>
</configuration>
  1. Finally inside the Scriban, call the above Scriban Extension as below, with the datasource children and size i.e 3 as an argument to that extension.
{{randomList = sc_random_items i_datasource.children 3}}
{{if randomList}}
  {{ for i_child_res in randomList  }}
    <p>{{i_child_res.Title.raw}}</p>
  {{ end}}
{{ end}}

Using above changes, you can randomly fetch N number of items from the list.

Hope this helps!!! Let me know in case you face any issues.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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