4

We are using SXA Rendering Variants with Scriban for our websites. In order to format the value of Sitecore field type DateTime in Scriban I am using

`{{ sc_field i_item 'Date' [ [ 'format', 'd\nM,\nyyyy' ] ] }}` . 

This works fine if the value is between the tags like below

<module-headline block="text-content">
                    {{ sc_field i_item 'EventDate' [ [ 'format', 'd\nM,\nyyyy' ] ] }}
                  </module-headline>

<!-- OR display: block -->
                  
                  <module-subline>{{ sc_field i_item 'EventDate' [ [ 'format', 'd\nM,\nyyyy' ] ] }}</module-subline>

But if I try to use this in one of the properties of the tags or with in JSON object in Scriban it does not work.

<sticky-detail-module

                    date="{{ sc_field i_item 'EventDate' [ [ 'format', 'd\nM,\nyyyy' ] ] }}"
                    place="{{ chosenevent.EventLocationLong.raw }}"
                    button-url="{{ sc_linktargeturl chosenevent 'Button1' }}"
                    button-text="{{ chosenevent.Button1Text.raw }}"
                  >
                  </sticky-detail-module>

OR WITH

 <events-teaser
                    :events="[
                    {
                      'place':'Barcelona',
                      'date':'{{ sc_field i_item 'EventDate' [ [ 'format', 'd\nM,\nyyyy' ] ] }}',
                      'title':'Headline',
                      'summary':'120 letters description – Lorem ipsum dolor sit amet, consetetur sadipscing elitr.',
                      'image':'../1920x1080.png',
                      'alt':'main events image',
                      'button2Text':'More information',
                      'button1Text':'Buy tickets',
                      'button2Url':'https://www.google.com/',
                      'button1Url':'https://www.google.com/'
                    },
                    {
                      'place':'Barcelona',
                      'date':'{{ sc_field i_item 'EventDate' [ [ 'format', 'd\nM,\nyyyy' ] ] }}',
                      'title':'Headline',
                      'summary':'120 letters description – Lorem ipsum dolor sit amet, consetetur sadipscing elitr.',
                      'image':'../1920x1080.png',
                      'alt':'main events image',
                      'button2Text':'Text 2',
                      'button1Text':'Text 1',
                      'button2Url':'https://www.google.com/',
                      'button1Url':'https://www.google.com/'
                    },
                  ]">
                 </events-teaser>

Is there a way to parse Sitecore DateTime field type value in a particular Date or Time format directly in Scriban for the tag properties as well? Is custom Embedded functions the only way to achieve this formatting?

0

Scriban has some nice date functions built in so you can use those. Unfortunately, Sitecore stores the raw value as yyyMMddThhmmssZ - so 20210709T102600Z for example. This is not a valid format for C#'s DateTime.Parse function, (which is what Scriban uses under the hood). So we need to get a bit sneaky with string parsing.

There are 2 options:

Option 1: No custom functions, Just scriban

Instead of using the field renderer, I would start with the raw value of the date field. Because of the non-standard date format, we need to be inventive in pulling the date out of Sitecore to allow the parsing to happen

eventDateString = (i_item.EventDate.raw | string.slice 0 4) + '-' + (i_item.EventDate.raw | string.slice 4 2) + '-' + (i_item.EventDate.raw | string.slice 6 2)

This will get us a string that looks like: yyyy-MM-dd. Now we can parse that into an actual date object:

eventDate = date.parse eventDateString

Now you can use the .to_string function in scriban to format the date:

formattedDate = eventDate.to_string '%d %m, %Y'

This can be even more simplified to

eventDate = date.parse eventDateString | date.to_string '%d %m, %Y'

The pipe works in a similar way to SPE where the value of the pipe is passed as the first argument in the next call.

Now you can use that variable in your json:

 <events-teaser
    :events="[
        {
          'place':'Barcelona',
          'date':'{{ eventDate }}',
          'title':'Headline',
          'summary':'120 letters description – Lorem ipsum dolor sit amet, consetetur sadipscing elitr.',
          'image':'../1920x1080.png',
          'alt':'main events image',
          'button2Text':'More information',
          'button1Text':'Buy tickets',
          'button2Url':'https://www.google.com/',
          'button1Url':'https://www.google.com/'
        },
    ]">
</events-teaser>

Option 2: Just write an embedded function, its cleaner

Having said all that, its a bit ugly to have to write that in Scriban. Its not reusable and hard to maintain. An embedded function would be simpler. This is one that I commonly have in my projects:

public class GetDateFieldShortDate : IGenerateScribanContextProcessor
{
    private readonly IContext context;
    private delegate string Delegate(Item item, string fieldName);

    public GetDateFieldShortDate(IContext context)
    {
        this.context = context;
    }

    public void Process(GenerateScribanContextPipelineArgs args)
    {
        args.GlobalScriptObject.Import("sc_date_short", new Delegate(GetShortDate));
    }

    public static string GetShortDate(Item item, string fieldName)
    {
        if (item?.Fields[fieldName] == null)
        {
            return string.Empty;
        }

        DateField field = item.Fields[fieldName];
        return field.DateTime.ToShortDateString(); 
    }
}

Is returns the Sitecore formatted date as a ShortDateString which the scriban date.parse function is able to use.

Your scriban now becomes:

eventDate = sc_date_short i_item 'EventDate' | date.parse | date.to_string '%d %m, %Y'

Much much simpler :)

references: If the date format strings look funny... they are, scriban seems to have its own set of format strings for some reason. Details are here: https://github.com/scriban/scriban/blob/486ae53003f3e9775d25a856f80cb28ca3b55e84/src/Scriban/Functions/DateTimeFunctions.cs#L287

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .