Sep 3, 2009
visibility 5424
star star star star star
(0 votes)

Adding glossary functionality in XHtml-property content

A customer wanted to be able to have explanation for the words in the site dictionary. The chosen solution for making this popup was to mark the text with a span around it.

<span rel="description">Word</span>

The replacement of this should only be displayed in view-mode. To make this I extended the xhtml-control to return a new control

[PageDefinitionTypePlugIn]
public class DictionaryXHTMLString : PropertyXhtmlString
{
    public override IPropertyControl CreatePropertyControl()
    {
        return new DictionaryXHTMLStringControl();
    }
}
public class DictionaryXHTMLStringControl : PropertyLongStringControl
{
    public override void CreateDefaultControls()
    {
        base.CreateDefaultControls();
        foreach (Control ctrl in Controls[0].Controls)
        {
            Literal lit = ctrl as Literal;
            if (lit != null)
            {
                lit.Text = GlossaryFilter.GetDictionaryMarkup(lit.Text);
            }
        }
    }
}

The PropertyLongStringControl populates the control tree with a panel and a list of Literals. If dynamic content is included it comes as a different class so we don’t have to worry about it.

The magic is performed by the glossary filter which adds the span tags by parsing the content with a small regex.

public static string GetDictionaryMarkup(string markup)
{
    try
    {
        GlossaryWordCollection gc = GlossaryWord.GetAllGlossaryWords(false);

        foreach (GlossaryWord word in gc)
        {
            if (!string.IsNullOrEmpty(word.ToolTip))
            {
                Regex ex = new Regex(string.Format(@"(>[^<]*?)(?<data>\b{0}\b)", word.Word), RegexOptions.IgnoreCase);
                string replaceString = string.Format("$1<span class=\"tooltip\" rel=\"{0}\">$2</span>",word.Description);
                string newmarkup = ex.Replace(markup, replaceString);
                markup = newmarkup;
            }
        }
        return markup;
    }
    catch //if whatever happens, return the original string.
    {
        return markup;
    }
}

This replaces the first occurrence of a word in the text after any tag. If all occurrences should be matched the regex could be changed or perhaps loop it for a while….

The attribute rel in the tag was chosen as to not have a tooltip when hovering the tag. The popup is then created with javascript, but that’s just a matter of choosing how to display it.

Sep 03, 2009

Comments

error Please login to comment.
Latest blogs
The Top 10 Things I'm Actually Using AI For

A while back I wrote about ReviewPR, an Azure Function that uses AI to review Azure DevOps pull requests. That was one specific use case, but over...

KennyG | Aug 5, 2026

Drag-and-Drop Reordering for Commerce Media Collection in Optimizely Commerce Connect

Optimizely Commerce Connect ships a polished asset editor for the CommerceMediaCollection  property on catalog entries. It lets editors add, remove...

Linh Doan Cuu | Aug 5, 2026

Order tabs with drag and drop V2

I earlier did a very simple Blazor version to be able to sort tabs with drag and drop. I wanted to update it a bit and also display how the tabs ar...

Per Nergård (MVP) | Aug 4, 2026

Optimizely : Missing Language Manager Gadget Fix in CMS 12 After Upgrading to .NET 10

Recently, while upgrading an Optimizely CMS solution to .NET 10, we came across an issue where the Language Manager gadget completely disappeared...

Madhu | Aug 2, 2026 |