Custom validator for Sitecore Rich Text field

The Rich Text Editor (RTE) stands out as the tool most frequently and extensively utilized by content authors. This is the interface extensively utilized for manipulating the HTML of the page/components.

As a result, developers must implement fundamental validations for Rich Text fields. Nevertheless, there are instances when basic validations are insufficient. In such cases, it becomes necessary to implement a custom validator.

In this blog, I will dig into a practical scenario where the implementation of a custom validator was imperative. This validator goes beyond merely validating HTML; it also performs instant corrections as needed.

Let me give you the background why we need to implement a custom validator for Rich Text. I would like to highlight here the Links to cross-origin destinations are unsafe SEO audit issue. Lighthouse tool flags unsafe links to cross-origin destinations, if it is not handled properly.

Linking to a page on another site with the target="_blank" attribute can expose your site to performance and security issues. For additional details, please refer to this link.

Actual Scenario - Whenever a content author adds or modifies content in the Rich Text field, it's essential to validate external page links within the Rich Text content, especially if the target is set to "_blank" without the rel="noopener noreferrer" attribute. 

Simultaneously, it is imperative to automatically correct this if the rel="noopener noreferrer" attribute is absent.

Implementing such a custom validator will yield the following outcomes:

  • This will alleviate the burden on Content Authors, as they won't need to explicitly add the attribute every time they include external links.
  • Additionally, this measure serves as a safeguard against phishing attacks.
  • Furthermore, incorporating this approach contributes to enhancing the SEO score.

Let's see this in action -

Creating a custom validator for Sitecore Rich Text fields involves several steps. The process may vary depending on your specific requirements and the version of Sitecore you are using.

Step 1: Create a Custom Validator Class in your solution.

Create a class that inherits from Sitecore.Data.Validators.StandardValidator. This class will contain the logic for your custom validation.

using Sitecore.Data.Validators;

[Serializable]
public class RichTextCustomValidator : StandardValidator
{
  public RichTextCustomValidator() : base(){}

  public RichTextCustomValidator(SerializationInfo info, StreamingContext context) : base(info, context){}

  protected override ValidatorResult Evaluate()
  {
      Field field = this.GetField();
      bool linkUpdated = false;

      if (!string.IsNullOrEmpty(field.Value.Trim()))
      {
         var htmlDoc = new HtmlDocument();
         htmlDoc.LoadHtml(field.Value);

         if (htmlDoc.DocumentNode != null && htmlDoc.DocumentNode.SelectNodes("//a[@target]") != null)
         {
             foreach (HtmlNode link in htmlDoc.DocumentNode.SelectNodes("//a[@target]"))
             {
                 // Get the value of the HREF attribute
                  string target = link.GetAttributeValue("target", string.Empty);
                  string rel = link.GetAttributeValue("rel", string.Empty);

              if (!string.IsNullOrEmpty(target) && target.Equals("_blank", StringComparison.OrdinalIgnoreCase) 
                  && string.IsNullOrEmpty(rel))
                  {
                      link.SetAttributeValue("rel", "noopener noreferrer");

                       if (!linkUpdated)
                           linkUpdated = true;
                   }
                }

                if (linkUpdated)
                {
                   var item = this.GetItem();

                    try
                    {
                       item.Editing.BeginEdit();
                        item[field.ID] = htmlDoc.DocumentNode.InnerHtml;
                        item.Editing.EndEdit();
                     }
                     catch (Exception)
                     {
                        //Revert the Changes
                         item.Editing.CancelEdit();
                     }
                   }

                }
            }

            return ValidatorResult.Valid;
        }

  protected override ValidatorResult GetMaxValidatorResult()
  {
      return ValidatorResult.Valid;
  }

   public override string Name
   {
      get { return "RichTextCustomValidator"; }
   }
}

Step 2: Register the Custom Validator

Create a patch file (e.g., CustomRichTextValidator.config) in the App_Config\Include folder. Add the following configuration:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <validators>
      <validator mode="on" type="YourNamespace.RichTextCustomValidator, YourAssembly" />
</validators> </sitecore> </configuration>
Ensure that your custom validator class and assembly are deployed to the appropriate locations in your Sitecore instance.

Step 3: Apply the Validator to Rich Text Fields

In Sitecore, navigate to the item path - /sitecore/system/Settings/Validation Rules/Field Rules/Text
  • Insert a new validation rule for RichTextCustomValidator.
  • Provide the custom validator class and assembly info as highlighted below.


Now, navigate to the item template that defines your Rich Text field and add your custom validator to the Validation Rules field of the template.


Step 4: Test Your Custom Validator

We're almost done. It's time to test the custom validator. Navigate to the item which is created form the template we just modified with the validation rules.

Try to add some external link in the Rich Text field with target "_blank" without the rel="noopener noreferrer" attribute and accept the change.

Now open the editor again and check for the expected result. You should see the rel="noopener noreferrer" attribute added.

Comments

Popular posts from this blog

Setup Sitecore XM Cloud Dev Environment using Docker

Sitecore Content Hub - Triggers, Actions and Scripts

All Blog Posts - 2023