Skip to main content

Sitecore

Extending General Link for Experience Editor

Two programmers working together with lines of code superimposed over them

The content editor and experience editor modes may seem similar at first glance, but they operate with different controls. In simpler terms, even though they look alike, the tools and functions they use are not the same, which can be a source of confusion for those working with them. We have already seen the content editor part in the Extending General Link for Content Editor article. Hence, in this article, we are going to explore how we can use the process of extending the general link for experience editor mode in Sitecore 10.2.

In order to enable the “Telephone Link” feature in Experience Editor mode, we should follow the specified steps.

1. Navigate to General Link Field Type

Go to the core database and locate the “General Link” field type under the path “/sitecore/system/Field types/Link Types/General Link”.

2. Update Edit Link – WebEdit Buttons Click Control

  1. Choose the “General Link” field type and open it up for more options.
  2. You can locate the “WebEdit Buttons” folder and open it up to view additional options.
  3. Select the “Edit Link” WebEdit button and modify the “Click” control property to “webedit:editextendedlink”.

WebEdit Buttons Edit Link Click Control

Note: It was originally set as “webedit:editlink” and now we’re extending it by incorporating the necessary code for the “Telephone Link” That’s why we’ll be using the extended keywords.

3. Add EditExtendedLink.cs Class

Next, we need to create the “EditExtendedLink.cs” class, which will be used to load the customized design page where an additional “Telephone Link” control property is going to be added.

The “EditExtendedLink.cs” class is created by inheriting the existing “EditLink.cs” class file. In Sitecore 10.2, if you extract the “Sitecore.ExperienceEditor.dll” you’ll locate this particular class within the “Sitecore.Shell.Applications.WebEdit.Commands” namespace. Copy the entire code from the “EditLink.cs” class and paste it inside the “EditExtendedLink.cs” created class, and update the “Run” method with the following code.

protected static void Run(ClientPipelineArgs args)
{
   //Code snippet from the "EditLink.cs" class
   if (args.IsPostBack)
   {
      //Code snippet from the "EditLink.cs" class
   }
   else
   {
      UrlString urlString = new UrlString(Context.Site.XmlControlPage);
      //urlString["xmlcontrol"] = "GeneralLink"; //Original code in the "EditLink.cs" class
      urlString["xmlcontrol"] = "ExtendedGeneralLink";  //To make it compatible with the extended general link controls, you just have to modify this single line of code.

      new UrlHandle()
      {
         ["va"] = new XmlValue(args.Parameters["fieldValue"], "link").ToString()
      }.Add(urlString);
      string parameter2 = args.Parameters["language"];
      urlString.Append("la", parameter2);
      urlString.Append("ro", field.Source);
      Context.ClientPage.ClientResponse.ShowModalDialog(urlString.ToString(), "550", "650", string.Empty, true);
      args.WaitForPostBack();
   }
}

Click on the GitHub – EditExtendedLink.cs link to access the detailed code.

4. Add Configuration Patch File

In the “Extending General Link for Content Editor” article, we established a configuration patch file to configure and link the control source. Within this patch file, we have the option to include a “command” source for the “EditExtendedLink.cs” class.

Note : If you prefer, you have the option to generate a distinct patch file.

<?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>
      <commands>
         <command name="webedit:editextendedlink" type="Fieldtypes.ExtendedGeneralLink.EditExtendedLink, Fieldtypes" />
      </commands>
    </sitecore>
</configuration>

You can find the entire code for the configuration patch file on the GitHub -Fieldtypes.ExtendedGeneralLink.Patch.config link.

5. Add ExtendedGeneralLink.xml Design File

To generate the “ExtendedGeneralLink.xml” design file, we used the existing “GeneralLink.xml” design file as a base. Copy all the content from “GeneralLink.xml” and paste it to “ExtendedGeneralLink.xml”, make the necessary modifications to incorporate the “Telephone Link” feature in Experience Editor mode.

Path : “/sitecore/shell/Applications/Dialogs/GeneralLink/” original “GeneralLink.xml” file location.

To include the “ExtendedGeneralLink.xml” design file, follow the steps outlined below.

  1. Navigate to the “/sitecore/shell/Applications/Dialogs” path in your project solutions, if it exists. Otherwise, create the folder hierarchy.
  2. Create a folder named “ExtendedGeneralLink” within the previously mentioned folder hierarchy.
  3. Create a file named “ExtendedGeneralLink.xml” inside the “ExtendedGeneralLink” folder.
  4. Once you’ve included the “ExtendedGeneralLink.xml” file, the file path should be “/sitecore/shell/Applications/Dialogs/ExtendedGeneralLink/ExtendedGeneralLink.xml”.
  5. Click on the GitHub – ExtendedGeneralLink.xml link to access the detailed HTML structure needed for the “Telephone” dialog box in Content Editor mode.

Note: For best practice, duplicate the “GeneralLink.css & GeneralLink.js” files and rename them as “ExtendedGeneralLink.css & ExtendedGeneralLink.js”. Subsequently, position these duplicated files within the directory where the “ExtendedGeneralLink.xml” file is located.

Designfilestructure

6. Add ExtendedGeneralLinkForm.cs class

Create the “ExtendedGeneralLinkForm.cs” class, which serves as the code behind for the “ExtendedGeneralLink.xml” design file.

The “ExtendedGeneralLinkForm.cs” class is created by inheriting the existing “LinkForm.cs” class file. In Sitecore 10.2.0, if you extract the “Sitecore.Client.dll” you’ll locate this particular class within the “Sitecore.Shell.Applications.Dialogs” namespace. Here you will get a reference about how “LinkForm” is being used.

But, here we extended the feature of “General Link”, due to this reason, check the “GeneralLinkForm.cs” class present in the same “Sitecore.Client.dll and within the “Sitecore.Shell.Applications.Dialogs.GeneralLink” namespace.

Once, we copy and paste all the code from the “GeneralLinkForm.cs” class into the “ExtendedGeneralLinkForm.cs” class. Next, it’s necessary to include essential changes in the “ExtendedGeneralLinkForm.cs” file to implement the “Telephone” link feature in Sitecore’s Experience Editor mode.

namespace Fieldtypes.ExtendedGeneralLink
{
    public class ExtendedGeneralLinkForm : LinkForm
    {
        //Important code snippet from the "GeneralLinkForm.cs" class
        
        protected override void OnOK(object sender, EventArgs args)
        {
            //Code snippet from the "GeneralLinkForm.cs" class
            bool flag;
            switch (this.CurrentMode)
            {
                //Code snippet from the "GeneralLinkForm.cs" class
                case "tel":
                   flag = this.SetTelephoneLinkAttributes(packet);
                   break;
                //Code snippet from the "GeneralLinkForm.cs" class
            }
            //Code snippet from the "GeneralLinkForm.cs" class    
        }
    
        //Code snippet from the "GeneralLinkForm.cs" class
    
        private void SetTelephoneLinkControls()
        {
           if (this.LinkType == "tel" && string.IsNullOrEmpty(((Control)this.Url).Value))
           {
              ((Control)this.TelephoneToLink).Value = this.LinkAttributes["url"].Replace("tel:", "");
           }

           ShowContainingRow((Control)this.TelephoneToContainer);
           this.SectionHeader.Text = Translate.Text("Specify the Telephone, e.g. 9006662121");
        }
    
        //Code snippet from the "GeneralLinkForm.cs" class
    
        private bool SetTelephoneLinkAttributes(Packet packet)
        {
            Assert.ArgumentNotNull((object)packet, nameof(packet));
            var tel = GetTelephone();
            if (tel == "__Canceled")
            {
               SheerResponse.Alert("The telephone number is invalid.");
               return false;
            }

            SetAttribute(packet, "url", tel ?? string.Empty);
            SetAttribute(packet, "anchor", string.Empty);
            return true;
        }
    
        private string GetTelephone()
        {
            var value = ((Control)this.TelephoneToLink).Value;
            var str = value;
            if (str.Length > 0)
            {
                if (str.IndexOf(":", StringComparison.InvariantCulture) >= 0)
                {
                   str = str.Substring(str.IndexOf(":", StringComparison.InvariantCulture) + 1);
                }

                if (!new Regex(@"^(?:\(?)(?<AreaCode>\d{3})(?:[\).\s]?)(?<Prefix>\d{3})(?:[-\.\s]?)(?<Suffix>\d{4})(?!\d)", RegexOptions.IgnoreCase).IsMatch(str))
                {
                     return "__Canceled";
                }
            }

            if (value.Length > 0 && value.IndexOf(":", StringComparison.InvariantCulture) < 0)
            {
               value = string.Concat("tel:", value);
            }

            return value;
        }
        
        //Code snippet from the "GeneralLinkForm.cs" class
        
        private void SetModeSpecificControls()
        {
             //Code snippet from the "GeneralLinkForm.cs" class
             HideContainingRow((Control)this.TelephoneToContainer);
             //Code snippet from the "GeneralLinkForm.cs" class
             switch (this.CurrentMode)
             {
                 //Code snippet from the "GeneralLinkForm.cs" class
                 case "tel":
                     this.SetTelephoneLinkControls();
                     break;
                 //Code snippet from the "GeneralLinkForm.cs" class
             }

             //Code snippet from the "GeneralLinkForm.cs" class
        }
        
        private void UpdateMediaPreview(Item item)
        {
             //Code snippet from the "GeneralLinkForm.cs" class
             MediaUrlBuilderOptions thumbnailOptions = MediaUrlBuilderOptions.GetThumbnailOptions(GetMediaItem(item));
             //Code snippet from the "GeneralLinkForm.cs" class
             this.MediaPreview.InnerHtml = "<img src=\"" + MediaManager.GetMediaUrl(GetMediaItem(item), thumbnailOptions) + "\" width=\"96px\" height=\"96px\" border=\"0\" alt=\"\" />";
        }

        private MediaItem GetMediaItem(Item item)
        {
            return item;
        }
    }
}

Click on the “GitHub – ExtendedGeneralLinkForm.cs” link to access the detailed code logic needed for implementing the “ExtendedGeneralLinkForm.cs” class.

Once, all the changes have been added, don’t forget to clean and rebuild the solution.

7. Final Output – Experience Editor

When adding a component that utilizes the “General Link” field type, choose its “General Link” field through the experience editor mode.

Telephone Link Experience Editor

Click on the “Edit” button as mentioned in the below image.

Telephone Link Experience Editor Edit

Following that, the “Insert a link” dialog box will appear, where you can locate the option for adding a “Telephone” link along with its necessary properties.

Experience Editor Telephone Link

Conclusion

When extending the General Link field type in Sitecore, it’s crucial to consider both content and experience editor modes. By making specific changes to configuration patch files, design files, and code files, we can introduce new features, such as the “Telephone” link, ensuring a seamless experience for both content creators and users navigating the site in Experience Editor mode. These modifications empower us to enhance the functionality of the General Link field type and tailor it to our specific needs within the Sitecore platform.

Happy learning!

Thoughts on “Extending General Link for Experience Editor”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Saket Singh

Saket Singh is currently working with Perficient GDC Nagpur as a Senior Technical Consultant. He is a Sitecore developer who works on SXA and Sitecore Headless websites. He also has knowledge of ASP.NET, ASP.NET MVC, C#, Web API, MSSQL, and JavaScript. He enjoys discovering new technologies and understanding the architecture that supports them.

More from this Author

Follow Us