1

I would like to add a custom data attribute for each link filed in Sitecore. This custom attribute should be configurable for Content Authors.

For Example <a href="#" class = "test" data-customattribute = '{testdata}'>.

How should I go about achieving this scenario?

1 Answer 1

1

You need to extend General Link field in Sitecore that way you can provide the ability to authors so that they can configure custom data attribute values.

follow the steps to add extending general link field.

1. Edit External link in Core DB

In the Core DB, go to the external link item by tracking the path /Sitecore/system/Field Types/Link Types/ General Link/Menu/External Link and perform the below changes:

  • The message field’s default value(contentlink:externallink(id=$Target) needs to be substituted with a custom value (contentlink:externallinkextend(id=$Target)).
  • Go to General Link (parent item of Menu), as shown in the above image, and update the Control field with the value content:ExtendLinks.

2. Custom code to create a new message handler.

  • Create custom control:
using Sitecore;
using Sitecore.DependencyInjection;
using Sitecore.Diagnostics;
using Sitecore.Shell.Applications.Dialogs.ExternalLink;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Web.UI.Sheer;
using Sitecore.Xml;
using System;
using System.Collections.Specialized;
using System.Xml;

namespace Foundation.Universal.Extensions
{
    public class ExternalLinkExtendForm: ExternalLinkForm
    {
        protected Edit FeatureName;
        protected Edit FeaturePosition;
        protected Edit FeatureOption;
        private ILinkExtendForm _linkExtendForm;
        public ExternalLinkExtendForm()
        {
            _linkExtendForm = (ILinkExtendForm)ServiceLocator.ServiceProvider.GetService(typeof(ILinkExtendForm));
            
        }

        private NameValueCollection customLinkAttributes;
        protected NameValueCollection CustomLinkAttributes
        {
            get
            {
                if (customLinkAttributes == null)
                {
                    customLinkAttributes = new NameValueCollection();
                    ParseLinkAttributes(GetLink());
                }

                return customLinkAttributes;
            }
        }

        protected override void ParseLink(string link)
        {
            base.ParseLink(link);
            ParseLinkAttributes(link);
        }

        protected virtual void ParseLinkAttributes(string link)
        {
            Assert.ArgumentNotNull(link, "link");
            XmlDocument xmlDocument = XmlUtil.LoadXml(link);
            if (xmlDocument == null)
            {
                return;
            }

            XmlNode node = xmlDocument.SelectSingleNode("/link");
            if (node == null)
            {
                return;
            }

            CustomLinkAttributes["FeatureNameAttributeName"] = XmlUtil.GetAttribute("FeatureNameAttributeName", node);
        }

        protected override void OnLoad(EventArgs e)
        {
            Assert.ArgumentNotNull(e, "e");
            base.OnLoad(e);
            if (Context.ClientPage.IsEvent)
            {
                return;
            }

            _linkExtendForm.LoadControls(CustomLinkAttributes,ref FeatureName);
        }

        protected override void OnOK(object sender, EventArgs args)
        {
            Assert.ArgumentNotNull(sender, "sender");
            Assert.ArgumentNotNull(args, "args");
            string path = GetPath();
            string attributeFromValue = GetLinkTargetAttributeFromValue(Target.Value, CustomTarget.Value);
            Packet packet = new Packet("link", new string[0]);
            SetAttribute(packet, "text",Text);
            SetAttribute(packet, "linktype", "external");
            SetAttribute(packet, "url", path);
            SetAttribute(packet, "anchor", string.Empty);
            SetAttribute(packet, "title", Title);
            SetAttribute(packet, "class", Class);
            SetAttribute(packet, "target", attributeFromValue);

            SetAttribute(packet, "FeatureNameAttributeName", FeatureName);
          
            SheerResponse.SetDialogValue(packet.OuterXml);
            SheerResponse.CloseWindow();
        }
        private string GetPath()
        {
            string url = this.Url.Value;
            if (url.Length > 0 && url.IndexOf("://", StringComparison.InvariantCulture) < 0 && !url.StartsWith("/", StringComparison.InvariantCulture))
            {
                url = string.Concat("http://", url);
            }

            return url;
        }
    }
}
  • Create a new message handler:
using Sitecore;
using Sitecore.Diagnostics;
using Sitecore.Shell.Applications.ContentEditor;
using Sitecore.Text;
using Sitecore.Web.UI.Sheer;

namespace Foundation.Universal.Extensions
{
    public class ExtendLinks : Link
    {
        public override void HandleMessage(Message message)
        {
            Assert.ArgumentNotNull((object)message, nameof(message));
            base.HandleMessage(message);
            if (message["id"] != this.ID)
                return;
            string name = message.Name;

            switch (name)
            {
                case "contentlink:externallinkextend":
                    {
                        string uri = UIUtil.GetUri("control:ExternalLinkExtendForm");
                        UrlString urlString = new UrlString(uri);
                        string strUrlString = urlString.ToString();
                        this.Insert(strUrlString);
                        break;
                    }
            }
        }
    }
}

3. Register control source

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <controlSources>
        <source assembly="Foundation.Universal" namespace="Foundation.Universal.Extensions" mode="on" prefix="content"/>
    </controlSources>
  </sitecore>
</configuration>
  • Go to the path sitecore\shell\Applications\Dialogs in file explorer and create a duplicate folder named ExternalLinkExtend from the folder ExternalLink
  • Open the folder ExternalLinkExtend and rename the file ExternalLink.xml to ExternalLinkExtend.xml
  • Add the FeatureName attribute in the newly created file(ExternalLinkExtend.xml), just below the Alternate Text field. The exact is depicted below:
<Label for="CustomTag" GridPanel.NoWrap="true"><Literal Text="Custom tag text:"/></Label>
        <Edit ID="CustomTag" Width="100%" />

4. Publish the code and Verify. After deploying, go to any General Link field and click on the external link option. The new custom field is visible. Once the text box is available, enter any value and check the raw value to see if everything works as expected.

Please refer below link for step-by-step implementation.

  1. Add a Custom Attribute to the General Link Field in Sitecore
  2. Extending General Link field in Sitecore

Hope it helps!

3
  • I am looking for way to achieve without extending the field. Also by default one custom property is there for link field, can it be enabled ?
    – karan
    Jun 28, 2023 at 9:19
  • You can try it out if that works, I don't think the other way around without extending the filed. Jun 28, 2023 at 9:20
  • This is a link only answer: meta.stackoverflow.com/tags/link-only-answers/…. - please provide detail in the answer and make it relevant and we can restore it.
    – Richard Seal
    Jun 28, 2023 at 15:28

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.