3

I am using a Scriban template in Sitecore 9.3 with SXA and am attempting to render a link field. While the sc_link function reliably generates the URL, I cannot seem to find a way to access any other attributes of the Link Details such as Description, Alternate Text, Style class, Query string etc.

While I can use the sc_field function to pass in attributes to be rendered and it will render the values included in the Link Details fields, I cannot append to these values, just over-ride them (and only for the link's attributes).

Using these values from the link selector in Sitecore:

  • Description: Click Here
  • Target: New Browser
  • Alternate text: Alt Title
  • Style class: my-class
  • Query string: testing

With this code:

sc_field i_item 'CardLink' [['aria-label', (i_item.CardLink.Title.raw)], ['class', 'btn btn-orange'], ['role', 'button']]

Results in this markup:

<a href="/Company?testing" aria-label="Company" title="Alt Title" role="button" class="btn btn-orange" target="_blank">Click Here</a>

Good but there's no way for me to set the aria-label to the Alternate text value or include a Font Awesome icon inside the <a> tag.

Outputting the markup directly in the template solves the icon issue, but doesn't seem to give me access to the Link Details fields.

This code:

<a href="{{ sc_link i_item.CardLink.target }}" class="btn btn-orange" aria-label="{{ i_item.CardLink.Title.raw }}" role="button">
            <ul>
            <li>Description: {{i_item.CardLink.Description}}</li>
            <li>Title: {{i_item.CardLink.Title}}</li>
            <li>Text: {{i_item.CardLink.Text}}</li>
            <li>Class: {{i_item.CardLink.Class}}</li>
            <li>Target: {{i_item.CardLink.Target}}</li>
            <li>URL: {{i_item.CardLink.Url}}</li>
            </ul>
<i class="far fa-angle-double-right"></i></a>

Results in this markup:

<a href="/Company" class="btn btn-orange" aria-label="Company" role="button">
        <ul>
            <li>Description: </li>
            <li>Title: Company</li>
            <li>Text: </li>
            <li>Class: </li>
            <li>Target: /sitecore/content/[Tennant]/[Site]/Home/Company</li>
            <li>URL: /Company</li>
            </ul>  
<i class="far fa-angle-double-right"></i></a>

Proper URL and easily able to include the icon markup, but no access to the Link Details values.

Is there something I am missing?

3

The reason why you cannot access those properties is because they are not know in the Scriban context provided by the SXA extensions. If you have i_item.CardLink in your Scriban template, that will match a Field object. This object has some properties (eg Target), but not the properties from a LinkField. And those are the ones you are requesting.

There is a solution, but is it not ootb.. and actually there are 2 solutions. Both require custom coding.

Solution 1: using functions

You could create a custom function in Scriban for each property you need. Creating custom function is rather easy: https://ggullentops.blogspot.com/2019/11/custom-sxa-scriban-extensions.html

It's a quick solution, as the development is easy and you will have quick results. In the easiest form, you might write a function for each property you need but I think there is way to do it passing the required property as a parameter as well (you can pass parameters and you can call properties in C#..).

Solution2: using a custom object

Second solution is a bit harder - as you seem to be missing an object for the LinkField you can write that yourself. Adding an object to the Scriban context requires a bit more code: https://ggullentops.blogspot.com/2020/03/extending-sitecore-scriban-user-object.html.

Benefit of this solution though is that you give access to all the required properties of the LinkField in a proper way. You will still need one function that gets you the LinkField item though (as the ootb Scriban extensions will give you a Field).

| improve this answer | |
  • After posting this and reviewing the post referenced here, this seems fair. An object mapping to the LinkField makes the most sense. Thanks for the quick answer! – Sirius_B Apr 15 at 15:13
1

Try using an extension. See https://gist.github.com/auzick/c2e127ed4c6aef0f019eedc0ab738d2b.

using Scriban.Runtime;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.XA.Foundation.Abstractions;
using Sitecore.XA.Foundation.Scriban.Pipelines.GenerateScribanContext;
using System;

namespace Example.ScribanExtensions.Pipelines
{
    public class LinkExtensions : IGenerateScribanContextProcessor
    {
        protected readonly IPageMode PageMode;
        private readonly IContext context;
        private delegate LinkInfo LinkInfoDelegate(Item item, object linkFieldName);

        public LinkExtensions(IPageMode pageMode, IContext context)
        {
            PageMode = pageMode;
            this.context = context;
        }

        public void Process(GenerateScribanContextPipelineArgs args)
        {
            var linkInfo = new LinkInfoDelegate(GetLinkInfo);
            args.GlobalScriptObject.Import("sc_link_info", (Delegate)linkInfo);
        }

        public LinkInfo GetLinkInfo(Item item, object field)
        {
            if (item == null
                || String.IsNullOrWhiteSpace((string)field)
                || item.Fields[(string)field] == null
                )
            {
                return null;
            }

            LinkField lnkField = (LinkField)item.Fields[(string)field];
            if (lnkField == null)
            {
                return null;
            }

            return new LinkInfo(lnkField);
        }
    }

    public class LinkInfo
    {
        public string url { get; set; }
        public string text { get; set; }
        public string title { get; set; }
        public string anchor { get; set; }
        public string target { get; set; }

        public LinkInfo() { }

        public LinkInfo(LinkField item)
        {
            url = item.GetFriendlyUrl();
            text = item.Text;
            title = item.Title;
            anchor = item.Anchor;
            target = item.Target;
        }
    }

}

You wire this up in config like this:

<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 = "Example.ScribanExtensions.Pipelines.LinkExtensions, Example.ScribanExtensions" resolve="true" />
            </generateScribanContext>
        </pipelines>
    </sitecore>
</configuration>

Then, access the link properties like this:

{{- linkInfo = (sc_link_info i_item 'link') -}}
<ul>
    <li> URL: {{ linkInfo.url}}</li>
    <li> Text: {{ linkInfo.text}}</li>
    <li> Title: {{ linkInfo.title}}</li>
    <li> Anchor: {{ linkInfo.anchor}}</li>
    <li> Target: {{ linkInfo.target}}</li>
</ul>
| improve this answer | |

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.