18

I have a Sitecore 8.1 multisite environment and when I scan for broken links all items that are using tokens are falsely reported as having broken links.

For example:

A datasource of an item is:

$site/Components/Global/Header

$site resolves to the site the user is on.

Is there any way to prevent these from showing in the broken links report?

3
  • 3
    I retagged your question; as $site is not a token in OOTB Sitecore; it is introduced in the Habitat demo solution. Oct 13, 2017 at 10:13
  • Looked a little bit into your issue. It boils down to the ValidateLinks method on a field type (such as Sitecore.Data.Fields.RenderingDatasourceField). If there is a value the GetItem will try to fetch the item with $site/Components/Global/Header. Don't have a solution though
    – Koen Heye
    Nov 8, 2017 at 8:12
  • Not sure if it'll work, but try implementing the solution in this answer: sitecore.stackexchange.com/a/9174/490
    – TamerM
    Dec 27, 2017 at 11:19

1 Answer 1

2

It's not too easy to do for all fields at once, but I think you have a few options to choose from.

Option 1 - Extend and replace existing fields with custom link validation

The broken/not broken logic is handled on each separate field type, so you can extend one (or several) of them and override the ValidateLinks(LinkedsValidationResult) method. You then also need to patch the field type in the configuration using a config patch file. This will also work in the Content Editor and no longer warn you about broken links when saving.

Here is an example for the Rendering Datasource field type:

using System.Linq;
using Sitecore.Data.Fields;
using Sitecore.Links;

namespace YourNamespace.Fields
{
    public class CustomRenderingDatasourceField : RenderingDatasourceField
    {
        public CustomRenderingDatasourceField(Field innerField)
            : base(innerField)
        {
        }

        public CustomRenderingDatasourceField(Field innerField, string runtimeValue)
            : base(innerField, runtimeValue)
        {
        }

        public override void ValidateLinks(LinksValidationResult result)
        {
            // Skip completely if path contains "$site"
            if (Path?.Contains("$site") ?? false)
                return;

            base.ValidateLinks(result);
        }
    }
}

You could maybe also try to replace the $site token, but I'm not 100% sure about contexts etc. so you will have to do some experimentation with that yourself.

Config patch to make the field use your custom implementation:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
  <sitecore>
    <fieldTypes>
      <fieldType name="Rendering Datasource" set:type="YourNamespace.Fields.CustomRenderingDatasourceField, YourAssembly" />
    </fieldTypes>
  </sitecore>
</configuration>

Option 2 - A custom field with its own link validation

You could also create a new custom field. You would then need to change the field type in all the places where you might end up using the $site token.

Option 3 - Replace SqlServerLinkDatabase and filter broken links

This option is actually pretty simple, but also in a place I would prefer to not tinker with too much.

NOTE: I haven't actually tested this, but it should work.

Extend the class Sitecore.Data.SqlServer.SqlServerLinkDatabase and override the method ItemLink[] GetBrokenLinks(Database).

In there call the method of the base class and then filter out unwanted broken links - in the example below, all links containing $site.

using Sitecore.Data.SqlServer;
using Sitecore.Data;
using Sitecore.Links;

public class CustomSqlServerLinkDatabase : SqlServerLinkDatabase
{
    public CustomSqlServerLinkDatabase(string connectionString)
        : base(connectionString)
    {
    }

    public override ItemLink[] GetBrokenLinks(Database database)
    {
        var brokenLinks = base.GetBrokenLinks(database).Where(x => !x.TargetPath.Contains("$site"));
        return brokenLinks.ToArray();
    }
}

Then you just replace the LinkDatabase with a config patch:

<configuration xmlns:set="http://www.sitecore.net/xmlconfig/set/">
  <sitecore>
    <LinkDatabase set:type="Your.Namespace.CustomSqlServerLinkDatabase, Your.Assembly" />
  </sitecore>
</configuration>

This will not change anything in the Content Editor regarding warnings when saving items with "broken" links.

1
  • RenderingDatasourceField is having an internal access specifier, so we are unable to consume it in SC9.1. Do we have any other base class, can be used or any other solution? Mar 22, 2021 at 14:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.