How to add massive "find and replace text" functionality to your MCMS 2002 site

I was talking to a customer last week at PDC and we were discussing about the possibilities offered by Microsoft Content Management Server 2002 (MCMS 2002). Powered by Microsoft .NET–connected technology, MCMS 2002 enables companies to quickly and efficiently build, deploy, and maintain mission critical content-rich Web sites.

MCMS 2002 provides a managed object model that allows you to extend the functionality that ships with the product and manage content programmatically. You can create custom navigation controls, placeholder controls, and more. A common need for site managers is to find and replace text of a given set of web pages. Imagine that after a while of creating postings (web pages) inside your MCMS 2002 site, you suddenly realize that you need to replace the text "foo" with the text "bar." Now imagine that you have more than 10,000 postings! MCMS 2002 does not provide built-in functionality to find and replace text because there are multiple combinations of channels, postings, and different kinds of placeholders where you might need to find and replace text. However, you can add this functionality to your site thanks the managed object model that ships with MCMS 2002.

Suppose that given a root channel, you need to find and replace text inside all the HTMLPlaceholders of all postings and the same for each subchannel inside the root channel. The following source code provides a way to implement the functionality that I explained:

  1. Declare the following namespaces and add the corresponding references to your project.
    using System.Security.Principal;
    using System.Threading;
    using Microsoft.ContentManagement.Publishing;
    using Microsoft.ContentManagement.Common;
    using Microsoft.ContentManagement.Publishing.Extensions.Placeholders;

  2. Create a method that searches for text in all the postings and subchannels of a given channel.
    public string FindAndReplaceText(string channel, string findtext, string replacetext) {

        // Create CmsApplicationContext and authenticate
        CmsApplicationContext context = new CmsApplicationContext();
        WindowsIdentity ident = (WindowsIdentity)Thread.CurrentPrincipal.Identity;
        context.AuthenticateUsingUserHandle(ident.Token, PublishingMode.Update);

        // Define root channel based on context
        Channel root = null;
        root = (Channel) context.Searches.GetByPath(channel);

        // Search for findtext in all the channel's postings
        foreach(Posting ps in root.Postings){
            if (ps.State == "Published"){
                foreach(Placeholder pl in ps.Placeholders){
    SearchText(pl, ps, findtext, replacetext);
                }
    }
    }

        // Search for findtext in all the channel's subchannels
        if (root.Channels.Count>0){
            foreach(Channel ch in root.Channels){
                foreach(Posting ps in ch.Postings){
                    if (ps.State == "Published"){
                        foreach(Placeholder pl in ps.Placeholders){
    SearchText(pl, ps, findtext, replacetext);
                        }
    }
    }
    }
    }
    }

  3. Create a method that searches for text inside all the HtmlPlaceholders of a given posting
    public void SearchText(Placeholder pl, Posting ps, string findtext, string replacetext) {
        if (pl.GetType().ToString() == "Microsoft.ContentManagement.Publishing.Extensions.Placeholders.HtmlPlaceholder"){
    HtmlPlaceholder ph;
            ph = (HtmlPlaceholder)pl;
    if (ph != null) {
                int ptr = ph.Text.IndexOf(findtext);
    if (ptr != -1){
                    string content = ph.Datasource.RawContent;
                    ph.Datasource.RawContent = content.Replace(findtext,replacetext);
                    ph.Posting.Approve();
                    context.CommitAll();
                }
    }
    }
    }

So as you can see, you can play around with the MCMS 2002 managed object model and create cool enhancements for your Web sites.