Try our conversational search powered by Generative AI!

Jacob Khan
Mar 8, 2010
  5453
(1 votes)

Compare in Edit mode CMS 6

In CMS 6 a new editorial feature is available making it easier to compare versions in EPiServer. When listing versions there is a new tab showing three different compare options. Compare the old way, side by side, compare properties also side by side and merge using EPiDiff and highlight changes. We hope that these three options will make it easier for editors to be able to see changes in their documents and be able to track changes easier.

image

 

EPiDiff is the default comparer added by EPiServer through code. When doing comparison it is important to render correct html based on the premise that the html already given is correct. The first thing it does is fix html and make it xhtml friendly using the html parser is EPiServer.Core.Html.HTMLParser. This will give a XMLDocument and we use its XMLNodes. We also fix script tags so that //CDATA is correct. By this I mean that if script tags don’t have CDATA we add it, if they are commented out for earlier browser versions we remove the comments. If we do not do this we cannot render correct XML which is needed in order to traverse through the xhtml.

image

It starts comparing the nodes inside the body tag because we cannot show changes in Meta tags anyways so it seems unnecessary to compare them. It goes through each node and checks if their html is equal to each other. If they are equal the node is added to our final concatenated string. If they are not equal we recursively call ourselves with the selected child as parameter.

Most texts in the xml are considered as a whole and individual words will not be compared unless the html tag is added to our list AnalyzeTextBasedOnTheseBlocks. In the default provider it includes <span> and <p>.

If we encounter html tags that are in this list we automatically compare individual words and their relative position. This algorithm looks at individual words and sees if they can find the word later in the text. If the word can be found the words before it is considered inserted or deleted. In reality this function is more complex but this is the simple explanation of it. The summary is that the text based comparison handles moved words whilst the xml based comparison does not handle moved tags. Why is because moved html is tricky and in a composer environment this could easily render correct html by math but to an editor it looks odd and breaks design. We show changed information using <ins> and <del> tags.

Since this is a provider model most of this can be changed. The provider needs to inherit from the abstract class called “PageCamparerProviderBase” in the namespace “EPiServer.UI.Edit.PageCompare.Core”, and implement the abstract method called “GetDiffOfHtml”. The method takes two strings as argument. The strings contain the html from a page, and the method should return an html string showing the differences between the two pages.

public class PageCompareAlgorithm : PageComparerProviderBase
{
public override string GetDiffOfHtml(string html1, string html2)
{}}

EPiServers implementation is called “PageCompareAlgorithm” and can be found in the namespace “EPiServer. EPiServer.UI.Edit.PageCompare.Core.Providers”. This class inherits from “PageCamparerProviderBase”.

The PageCompareAlgorithm implementation has a lot of virtual methods that can be overridden. This makes it easy for developers to change small pieces of the default implementation.The example below makes it possible to change the <ins style=”background:…> to whatever color and you want to.

public class TestProvider : PageCompareAlgorithm
{
 public override string AddedBeginTag
{}
}

To add a provider through the configuration file, open web.config for the site and add the following section:

<configSections><section name="episerver.pageComaprer" type="EPiServer.UI.Edit.PageCompare.Configuration.PageCompareSection, EPiServer.UI" /></configSections>
<episerver.pageComaprer>
<pageComparer defaultProvider="DefaultPageComparer">
<providers>
<add name="MyProvider" description="" type="MyNamespace.MyClass, MyAssembly" AnalyzeTextBasedOnTheseBlocks="p; span" />
</providers>
</pageComparer>
</episerver.pageComaprer>

The section element must be placed inside the “configSections” element, and the “episerver.pageComparer” section must be placed inside the “configuration” element.

In the provider, we have an optional attribute called “AnalyzeTextBasedOnTheseBlocks” that can be added. This will be loaded into a property with the same name in the provider base when the provider gets initialized.

The default provider will set the “p” and the “span” element as analyze blocks if nothing else is configured in the configuration file. By adding the section in web.config and setting EPiServers provider as the default provider, it’s possible to change this property.

There is a possibility to use a custom provider without adding anything to the configuration file. It can be done by creating a “ProviderSettings” object with the type as parameter. It will not be possible to use the provider this way with the default plug-in, but it can be useful when making tests.

string providerName = "TestProvider";
 
ProviderSettings providerSettings = new ProviderSettings(providerName, "EPiServerUnitTest.EPiDiff.TestProviders.TestProvider, EPiServerUnitTest");
 
providerSettings.Parameters.Add("AnalyzeTextBasedOnTheseBlocks", "p; span; div");
 
DiffComparerProviderBase diffComparerProvider = DiffComparerProviderBase.CreateInstance(providerSettings);

We hope that this feature will be used and is appreciated by our editors. We are constantly trying to improve this algorithm and find new ways of showing changes made such as image changes and dynamic content changes.

/Jacob

Mar 08, 2010

Comments

Sep 21, 2010 10:33 AM

Hi Jacob,

cannot change the provider in 6.0.530.0...

Any changes to this specific version?

Thanks
Fabio
/ Fabio Fabrizio

Sep 21, 2010 10:33 AM

Sorry Jacob,

worked it out - a mispelling in the config tag.

Fabio
/ Fabio Fabrizio

stephane.lapointe@orckestra.com
stephane.lapointe@orckestra.com Sep 21, 2010 10:33 AM

Hi Jacob,

It works great, just a little error in your article about the configuration though:








Please login to comment.
Latest blogs
The A/A Test: What You Need to Know

Sure, we all know what an A/B test can do. But what is an A/A test? How is it different? With an A/B test, we know that we can take a webpage (our...

Lindsey Rogers | Apr 15, 2024

.Net Core Timezone ID's Windows vs Linux

Hey all, First post here and I would like to talk about Timezone ID's and How Windows and Linux systems use different IDs. We currently run a .NET...

sheider | Apr 15, 2024

What's new in Language Manager 5.3.0

In Language Manager (LM) version 5.2.0, we added an option in appsettings.json called TranslateOrCopyContentAreaChildrenBlockForTypes . It does...

Quoc Anh Nguyen | Apr 15, 2024

Optimizely Search & Navigation: Boosting in Unified Search

In the Optimizely Search & Navigation admin view, administrators can set a certain weight of different properties (title, content, summary, or...

Tung Tran | Apr 15, 2024

Optimizely CMS – Getting all content of a specific property with a simple SQL script

When you need to retrieve all content of a specific property from a Page/Block type, normally you will use the IContentLoader or IContentRepository...

Tung Tran | Apr 15, 2024

Join the Content Recommendations Work Smarter webinar May 8th 16.00-16.45 CET with expert Aidan Swain

Learn more about Content Recommendations, with Optimizely’s very own Senior Solutions consultant, Aidan Swain . He will discuss best practices and...

Karen McDougall | Apr 12, 2024