New John West Sitecore Blog on Sitecore Community Hub

I’ve finally started the John West Sitecore Blog on the Sitecore Community hub. At the moment, the first and only post is just an introduction, but I will post more as time permits.

John West Sitecore Blog

Or for short:


Posted in Obsolete | 2 Comments

LearnSitecore Podcast: Ten Things You Didn’t Know about John West (Dreamcore 2010)

I am happy to announce that Ten Things You Didn’t Know about John West (Dreamcore 2010) is the first podcast to appear on LearnSitecore, a Web site devoted to educating Sitecore developers. At dreamcore 2010 Europe, the founders of the LearnSitecore, Jens Mikkelsen and Jimmi Lyhne Andersen, interviewed me for this podcast. Among other things, we talked about my responsibilities at Sitecore, what I do on a daily basis, trends in the Internet industry, and the topics from my presentation at dreamcore 2010.

Posted in Obsolete | 1 Comment

One More Reason to Own Your Web Analytics Data

Several months ago I blogged that I was leaving the Microsoft platform because it feels like abandonware that largely enables spam. Now Microsoft appears to have disabled my access to Web statistics for my site. While the browser-based statistics interface was terrible, I used these statistics to determine what search terms brought visitors to my blog, which I used to refine posts to address the most common issues. Previously, after I logged in, something like “Statistics” appeared on this Options menu:

I hope this is just a technical glitch and Microsoft will restore this functionality. Whether or not Microsoft intended to remove this feature, the experience demonstrates one reason you should always manage Web statistics data internally using a visitor experience analytics system such as Sitecore OMS rather than using an external service for Web analytics. Additionally, OMS provides features far beyond statistics.

Luckily, the Sitecore Community Hub is almost ready to host my blog.

Update 14.June.2010: I also see this more frequently now:

Posted in Obsolete | 2 Comments

Maximize Sitecore Content Editor Performance

Posted in Obsolete | Leave a comment

Free Ways to Make Your Computer Faster and More Stable: Disable Software

This post describes techniques that you can apply to improve the performance and stability of your computer by reducing the number of active programs.

You can use the Autoruns utility from Sysinternals to reduce the amount of software that runs when you boot or log in to Windows. You can download Autoruns individually or you can download the entire Sysinternals Suite of utilities, which includes Autoruns. These programs come as zip files with no installer. Installation instructions may be slightly different on editions of Windows other than 64-bit Windows 7, but for me:

  1. Create a subdirectory to contain the utilities, such as C:\Program Files (x86)\Sysinternals.
  2. Extract the Sysinternals zip file to that subdirectory.
  3. In that subdirectory, select autoruns.exe, and create a shortcut to that item on the desktop or the Windows Start menu. Name the shortcut Autoruns.

Consider creating another shortcut for Process Explorer (procexp.exe), which is an excellent replacement for Windows Task Manager.

Launch Autoruns, but think carefully before disabling any options. You might want to capture a screen shot of the default configuration so that you can see how things were and re-enable items you later determine some software to require. To capture a screen shot of the Autoruns window, press ALT-PRTSCN, paste that image into another application, and then save that file.

Most of the items that you should disable will appear towards the top of the Autoruns window under one of the following categories:

  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
  • HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
  • C:\Users\<profile>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup (or equivalent)
  • HKCU\Software\Microsoft\Windows\CurrentVersion\Run           

Many of these programs don’t seem to do anything significant, but consume resources, including space in the notification area, and introduce variables when you are trying to troubleshooting other issues. I like to disable anything that I don’t use every time I use the computer. It’s generally easy to start these applications when I need them:

  • The Windows Sidebar.
  • Citrix GoToMeeting.
  • Miicrosoft Gotomeeting, Groove, and OneNote.
  • Any instant messaging software.
  • Any software for hardware such as a fingerprint reader, camera, phone, scanner, printer, modem, or fax.
  • Adobe anything.
  • Google anything.
  • Roxio anything.
  • CyberLink anything.
  • Zune anything.
  • Skype anything,
  • Apple anything.

If you know you will never need a piece of software, you can use Autoruns to delete that entry. Otherwise just clear the checkbox. Here’s how Autoruns currently appears on my system:


If the name of the entry and its description don’t help you determine whether you can disable something, look at Publisher and Image Path. For example, I had no idea what EEventManager Application was, but the publisher SEIKO EPSON definitely makes printers, so I assumed I could disable it. You can also search the Internet for specific programs, such as eeventmanager.exe, to try to determine what they do and hence whether you can disable them. Be careful, as many search hits for process names will take you to Web sites that encourage you to download additional software that you don’t need.

If you see the following message when you select or clear a checkbox:

You can click Run as Administrator to close Autoruns and launch the program again with the administrative rights required to change these settings. Maybe this helps you avoid unintended changes, but I like to avoid the extra moment it takes for Autoruns to scan the system again. Next time you launch Autoruns, you can SHFT-CTRL-Click the Autoruns shortcut to run as administrator once, or you can:

  1. Right-click that shortcut and select Properties.
  2. On the Shortcut tab, click Advanced, and then select Run as administrator.

If you want, you can occasionally use Autoruns to enable software update managers, reboot, and then use Autoruns to disable them again. I think most programs that install their own updates check for updates when you launch the program anyway, so at least some of these are redundant.

This is a good time to remember to disable Internet Explorer plug-ins as well, and to hide any browser toolbars that you don’t use. To disable add-ons in Internet Explorer, click the Tools menu or press ALT-T, and then click Manage Add-Ons. I disable almost everything, leaving only HttpWatch. To hide browser toolbars, click the View menu or press ALT-V, then click Toolbars, and then disable individual toolbars. This reminds me that you might also want to hide the ESET NOD32 and Citrix GoToMeeting toolbars in Outlook. Click the View menu, then click Toolbars, and then disable individual toolbars.

You can disable specific Windows services as well, but you should be very careful not to disable important services. The next time I build a machine, I will try to list the services that I disable. I generally set services to Disabled instead of Manual, so that I can more easily identify services that I have disabled, and so that I find out when some software tries to use a service I disabled. To access services, type services.msc into the Start menu or the Run prompt. I seem to have disabled at least:

  • Internet Connection Sharing (ICS)
  • SQL Active Directory Helper Service
  • SQL Server Agent
  • Visual Studio Remote Debugger

It’s probably a good idea to review these issues at least a few times each year, and especially after you get a new machine or install Windows. Please add your suggestions for software to disable below, or reasons not to disable what I’ve suggested above.

Posted in Obsolete | 1 Comment

Publish Referenced Media When You Publish Sitecore Content

For the current edition of this blog post, see:

I developed a prototype for a workflow action for use with the Sitecore ASP.NET CMS to publish referenced medias as a content item passes through workflow. This prototype also publishes any ancestors of each media item that do not exist in the publishing target database. You can use this workflow action to automatically publish media items and media folders before publishing content that depends on those items.

You can replace the default Auto Publish workflow action with this action. Additionally, you can use this workflow action earlier in the workflow, from a non-final workflow state, to publish only the media and not the content item.

The Publish Media and Publish Content actions in the following workflow definition both use the solution described in this post.

From the Draft state, the user submits a content item to the Media Approval state. From the Media Approval state, the media reviewer chooses the Approve Media command, which contains the Publish Media action that publishes referenced media, and transitions to the Content Approval state. From the Content Approval state, the content reviewer (who may also be the media reviewer) chooses the Approve Content commend, which transitions to the Approved state. The Approved state contains the Publish Content action that publishes the item and its descendants. The Validation Action under the Approve Content command prevents the content reviewer from publishing invalid content. Content can be invalid for a number of reasons, such as if you Validate Media Publishing Status with Sitecore and the content reviewer added a new image after media approval.

In the Parameters field in the Data section of the Publish Media workflow action definition item, enter:


The IncludeSelf parameter instructs the action to publish the item in workflow. The Deep parameter instructs the action to perform deep publishing. The IncludeMedia parameter instructs the action to publish related media. Alternatively, you can create a data template that defines three Checkbox fields named after these three parameters, use that data template for the workflow action definition item, and use those fields instead of the Parameters field.

In the Parameters field in the Data section of the Publish Content workflow action definition item, enter:


The IncludeSelf and Deep parameters default to false.

I will post the code at the Workflow with Media Items thread on the Sitecore Developer Network forums.

The Sitecore.Sharedsource.Workflow.Actions.Publish class that you reference in the Type field of workflow action definition items represents the workflow action. You can use this action to replace the default Sitecore.Workflows.Simple.PublishAction. Most of the logic in this class simply retrieves parameters. The Process() method passes those parameters to the Publish() method of an instance of Sitecore.Publishing.PublishHelper.

For each publishing target, the Publish() method of Sitecore.Publishing.PublishHelper creates a publishing queue containing the media referenced by the item in workflow that do not exist or differ from their correspondents in the publishing target database and any of their ancestors missing from that publishing target, and then publishes that queue.

The Sitecore.Publishing.PublishingTarget class represents a publishing target.

Even accounting for publishing targets, publishing related media is relatively straightforward if media will not have publishing restrictions, you don’t version/workflow media, early publication of media and media folders is unlikely to have a negative impact, and media items don’t have descendants. While this solution addresses the complexity of publishing targets, it does not address versioning, translation, publishing restrictions, and other factors. Nor does it address errors that can occur during publication.

Publishing related content would be more challenging than publishing related media. Referenced content may have publishing restrictions at the item and/or language/version level, including workflow state. Referenced content may contains references to additional media and content, including circular references. Still, it might be possible to publish related content, presentation components, data template definition components, or other relevant items.

At some point I tried to address some of these concerns with the PublishingSpider Sitecore shared source project, but I think it got too complicated and I didn’t maintain it. Maybe that project has some ideas or even code that someone reading this blog post could use.

Posted in Obsolete | 1 Comment

Validate Media Publishing Status with Sitecore

For the current edition of this blog post, see:

You can can use the approach described in this document to validate whether the Sitecore ASP.NET CMS has published the media referenced by an item. You can use validation with workflow to require the user to publish related media before publishing an item that references that media.

You can use this validator in conjunction with a Content Editor Warning to Display Publishing Status.  You can get more information about validation from my post about how to Validate a Sitecore Checklist, Multilist, Treelist, or TreelistEx Field, which contains links to pages, posts, and threads containing much more information about validation, including the Client Configuration Cookbook.

Here is my prototype for the validator:

namespace Sitecore.Sharedsource.Data.Validators.ItemValidators
  using System;
  using System.Collections.Generic;
  using System.Runtime.Serialization;
  using Sitecore.Configuration;
  using Sitecore.Data;
  using Sitecore.Data.Items;
  using Sitecore.Data.Validators;
  using Sitecore.Diagnostics;
  using Sitecore.Links;

  public class MediaPublishingStatus : StandardValidator
    public MediaPublishingStatus() : base()

    public MediaPublishingStatus(SerializationInfo info, StreamingContext context) : base(info, context)

    public override string Name
        return this.GetType().ToString();

    public static bool IsPublished(Item item, Database targetDatbase)
      Assert.ArgumentNotNull(item, "item");
      Assert.ArgumentNotNull(targetDatbase, "targetDatbase");
      Item targetItem = targetDatbase.GetItem(item.ID, item.Language, item.Version);
      return targetItem != null
             && item.Version.Number == targetItem.Version.Number
             && item.Statistics.Revision == targetItem.Statistics.Revision;

    public static Database[] GetPublishingTargets(Item item)
      Assert.ArgumentNotNull(item, "item");
      Item pubTargets = item.Database.GetItem("/sitecore/system/publishing targets");
      Assert.IsNotNull(pubTargets, "publishing targets");
      List<Database> databases = new List<Database>();

      foreach (Item target in pubTargets.Children)
        if (PublishingTargetApplies(item, target.ID))
          string name = target[FieldIDs.PublishingTargetDatabase];
          Assert.IsNotNull(name, target.Paths.FullPath);
          Database db = Factory.GetDatabase(name);
          Assert.IsNotNull(db, name);

      return databases.ToArray();

    public static bool PublishingTargetApplies(Item item, ID publishingTarget)
      while (item != null)
        string restricted = item[FieldIDs.PublishingTargets];

        if (!(String.IsNullOrEmpty(restricted) || restricted.Contains(item.ID.ToString())))
          return false;

        item = item.Parent;

      return true;

    protected override ValidatorResult Evaluate()
      Item item = this.GetItem();
      Assert.IsNotNull(item, "GetItem");
      Database[] pubTargets = GetPublishingTargets(item);

      foreach (ItemLink link in item.Links.GetAllLinks())
        if (link.SourceFieldID == Sitecore.Data.ID.Null)

        Sitecore.Data.Fields.Field field = item.Fields[link.SourceFieldID];
        Assert.IsNotNull(field, link.SourceFieldID.ToString());
        Item media = link.GetTargetItem();

        if (String.IsNullOrEmpty(field.Value) || media == null || !media.Paths.IsMediaItem)

        if (field.Value.Contains(media.ID.ToString()) || field.Value.Contains(ShortID.Encode(media.ID)))
          foreach (Database db in pubTargets)
            if (!IsPublished(media, db))
              this.Text = String.Format(
                "The field {0} references the media item {1}, which is not current in the {2} database.",
              return GetFailedResult(ValidatorResult.Error);

      return ValidatorResult.Valid;

    protected override ValidatorResult GetMaxValidatorResult()
      return ValidatorResult.Error;

While iterating the publishing target databases, this validator iterates each link from the current item to any other item. If the link exists in the selected version of the item, and the publishing target database does not contain the referenced media item or contains a different version or revision of that media item, then the validator returns a warning.

You could use this approach to check references other than media, such as presentation components. You could even check the template definition to see if it contains a field definition or standard values change to publish.

To define the item validator:

  1. Add the class to the Visual Studio project and compile.
  2. In the Content Editor, navigate to the /Sitecore/System/Settings/Validation Rules/Item Rules item and insert an item named Media Publishing Status using the System/Validation/Validation Rule data template.
  3. In the Media Publishing Status item, set the value of the Type field in the data section to the type signature of the validator class, such as Sitecore.Sharedsource.Data.Validators.ItemValidators.MediaPublishingStatus,assembly
  4. In the /Sitecore/System/Settings/Validation Rules/Global Rules item, in all four fields in the Validation Rules section, add Media Publishing Status to the selection.

There is clearly some code to factor out into other classes, and as usual, this is not well tested. If I have time, I hope to perform some refactoring while (re)developing a solution to publish related media. Publishing targets, item publishing restrictions, languages versions including restrictions, workflow status, revision identifiers, and probably other factors complicate the challenge of developing generic solutions to automate publishing.

Posted in Obsolete | 2 Comments