November Happy Hour will be moved to Thursday December 5th.

Jacob Khan
Mar 8, 2010
  5547
(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
Optimizely SaaS CMS + Coveo Search Page

Short on time but need a listing feature with filters, pagination, and sorting? Create a fully functional Coveo-powered search page driven by data...

Damian Smutek | Nov 21, 2024 | Syndicated blog

Optimizely SaaS CMS DAM Picker (Interim)

Simplify your Optimizely SaaS CMS workflow with the Interim DAM Picker Chrome extension. Seamlessly integrate your DAM system, streamlining asset...

Andy Blyth | Nov 21, 2024 | Syndicated blog

Optimizely CMS Roadmap

Explore Optimizely CMS's latest roadmap, packed with developer-focused updates. From SaaS speed to Visual Builder enhancements, developer tooling...

Andy Blyth | Nov 21, 2024 | Syndicated blog

Set Default Culture in Optimizely CMS 12

Take control over culture-specific operations like date and time formatting.

Tomas Hensrud Gulla | Nov 15, 2024 | Syndicated blog

I'm running Optimizely CMS on .NET 9!

It works 🎉

Tomas Hensrud Gulla | Nov 12, 2024 | Syndicated blog

Recraft's image generation with AI-Assistant for Optimizely

Recraft V3 model is outperforming all other models in the image generation space and we are happy to share: Recraft's new model is now available fo...

Luc Gosso (MVP) | Nov 8, 2024 | Syndicated blog