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.