Jacob Khan
Mar 8, 2010
  5530
(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
Add your own tools to the Optimizely CMS 12 admin menu

The menus in Optimizely CMS can be extended using a MenuProvider, and using the path parameter you decide what menu you want to add additional menu...

Tomas Hensrud Gulla | Oct 3, 2024 | Syndicated blog

Integrating Optimizely DAM with Your Website

This article is the second in a series about integrating Optimizely DAM with websites. It discusses how to install the necessary package and code t...

Andrew Markham | Sep 28, 2024 | Syndicated blog

Opticon 2024 - highlights

I went to Opticon in Stockholm and here are my brief highlights based on the demos, presentations and roadmaps  Optimizely CMS SaaS will start to...

Daniel Ovaska | Sep 27, 2024

Required fields support in Optimizely Graph

It's been possible to have "required" properties (value must be entered) in the CMS for a long time. The required metadata haven't been reflected i...

Jonas Bergqvist | Sep 25, 2024