5

I'm looking for an option to compare programatically using SPE all the fields of an item that have changed from the latest version x the version prior to that and highlight what changed. Have anyone done anything like that?

1 Answer 1

11

I found some code from John West some time back and made that into a module on Github.

You could take the below snippet I converted to PowerShell and make it a report.

# Create a list of field names on the Standard Template. This will help us filter out extraneous fields.
$standardTemplate = Get-Item -Path "master:" -ID "{1930BBEB-7805-471A-A3BE-4858AC7CF696}"
$standardTemplateTemplateItem = [Sitecore.Data.Items.TemplateItem]$standardTemplate
$standardFields = $standardTemplateTemplateItem.OwnFields + $standardTemplateTemplateItem.Fields | Select-Object -ExpandProperty key -Unique

$itemTemplate = Get-Item -Path "master:" -ID "{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}"
$itemTemplateTemplateItem = [Sitecore.Data.Items.TemplateItem]$itemTemplate
$itemTemplateFields = $itemTemplateTemplateItem.OwnFields + $itemTemplateTemplateItem.Fields | Select-Object -ExpandProperty key -Unique

$filterFields = $itemTemplateFields | Where-Object { $standardFields -notcontains $_ } | Sort-Object

$item1 = Get-Item -Path "master:" -ID "{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}" -Version 1
$item2 = Get-Item -Path "master:" -ID "{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}" -Version 2

foreach($filterField in $filterFields) {
    $first = $item1.$filterField
    $second = $item2.$filterField

    if($first -eq $second) {
        Write-Host "$($filterField) : NoChange"
        continue
    }

    $engine = New-Object Sitecore.Text.Diff.DiffEngine
    $source = New-Object Sitecore.Text.Diff.DiffListHtml($first)
    $destination = New-Object Sitecore.Text.Diff.DiffListHtml($second)
    $engine.ProcessDiff($source, $destination, [Sitecore.Text.Diff.DiffEngineLevel]::SlowPerfect) > $null

    foreach($span in $engine.DiffReport()) {
        if($span -and $span.Status -ne "NoChange") {
            Write-Host "$($filterField) : $($span.Status)"
        }
    }
}

The $span.Status indicates the status of NoChange, Replace, DeleteSource, or AddDestination. I recommend you install the module while you test so you can make sure your report is accurate.

This is where the magic happens in the FieldDifferenceEvaluator.cs file. I'm creating html spans and injecting the styling.

public string GetDifferences(string first, string second)
{
    var engine = new DiffEngine();
    var source = new DiffListHtml(first);
    var destination = new DiffListHtml(second);

    engine.ProcessDiff(source, destination, DiffEngineLevel.SlowPerfect);
    var builder = new StringBuilder();

    foreach (DiffResultSpan span in engine.DiffReport())
    {
        if (span == null) continue;
        switch (span.Status)
        {
            case DiffResultSpanStatus.NoChange:
                Append(builder, first, span.SourceIndex, span.Length);
                break;
            case DiffResultSpanStatus.Replace:
                Append(builder, first, span.SourceIndex, span.Length, "green");
                Append(builder, second, span.DestIndex, span.Length, "red;text-decoration:line-through;font-weight:bold");
                break;
            case DiffResultSpanStatus.DeleteSource:
                Append(builder, first, span.SourceIndex, span.Length, "red;text-decoration:line-through;font-weight:bold");
                break;
            case DiffResultSpanStatus.AddDestination:
                Append(builder, second, span.DestIndex, span.Length, "blue;font-weight:bold");
                break;
        }
    }

    return builder.ToString();
}
0

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.