Sitecore CMS and everything related RSS 2.0
 Friday, August 08, 2008

(For introduction to the new publishing architecture, read the part 1: New Publishing Pipelines and Events in Sitecore 6)

Today’s example is using the publish:itemProcessed event to publish related media items.

A little background first. Imagine a new item structure being created, and some content items have an image field that uses items from the media library. Neither the content items nor the media items have been published yet. Now if the editor publishes the content item in a “single-item” mode (i.e. selects the publish in the ribbon, and not the incremental, smart or full publishing), the item will get published to the web database, but the media items will not.

The event handler below listens to the publish:itemProcessed event, and if the content item had been published in the single-item mode and has links to media items, they get published too.

public class ItemProcessedHandler {
  public void ItemProcessed(object sender, EventArgs rawArgs) {
    var args = rawArgs as ItemProcessingEventArgs;
    Assert.IsNotNull(args, "args");

    var context = args.Context;
    
    // [1] publish mode check
    if (context.PublishOptions.Mode != PublishMode.SingleItem) {
      return;
    }

    var item = context.PublishHelper.GetSourceItem(context.ItemId);
    if (item == null) {
      return;
    }

    if (!item.Paths.IsContentItem) {
      return;
    }

    // [2] Triggering publishing of the related item by running the publishItem pipeline again
    var options = new PublishOptions(
      context.PublishOptions.SourceDatabase,
      context.PublishOptions.TargetDatabase,
      PublishMode.SingleItem,
      context.PublishOptions.Language,
      context.PublishOptions.PublishDate);

    var relatedMedia = GetRelatedMedia(item);

    foreach(var mediaItem in relatedMedia) {
      PublishItemPipeline.Run(mediaItem.ID, options);
    }
  }

  // [3] related media items are retrieved using the link database
  IList GetRelatedMedia(Item item) {
    var references = Globals.LinkDatabase.GetReferences(item);
    var result = new List();

    foreach(var reference in references) {
      if (reference.SourceDatabaseName != item.Database.Name) {
        continue;
      }

      var referenceItem = item.Database.GetItem(reference.TargetItemID);
      if (referenceItem == null) {
        continue;
      }

      if (referenceItem.Paths.IsMediaItem) {
        result.Add(referenceItem);
      }
    }

    return result;
  }
}

Notes:

  1. Check the publish mode – no need to intervene in the incremental or full publishes, Sitecore will publish everything needed by itself
  2. Programmatically running the publishItem pipeline for each media item. Higher level PublishManager API could have been used as well
  3. Link database is used to retrieve the related media items. Nothing new here.

To activate the event:

<event name="publish:itemProcessed">
  <handler type="Pipelines.Publishing.ItemProcessedHandler, Pipelines" method="ItemProcessed" />
</event>
Friday, August 08, 2008 8:44:30 AM (FLE Standard Time, UTC+02:00)  #    Comments [4] -
Sitecore | Crestone
 Wednesday, August 06, 2008

Sitecore 6 publishing architectureEven as the live mode is used more often, publishing remains one of the most important parts of the Sitecore world. If you look to the right, you’ll see my ugly drawing designed to contrast with the beauty of the new publishing architecture Ole implemented for Sitecore 6.

The entire publishing process is managed by the two pipelines: publish and publishItem. The publish pipeline runs once whenever a publish process is started from the user interface or programmatically. The pipeline collects all the items that need to be published, and runs the publishItem pipeline for each item separately.

PublishItem pipeline decides how to perform the actual publishing. It also raises two very useful events: publish:itemProcessing and publish:itemProcessed. Each event receives the full set of current publishing settings and the item being published.

When deciding between extending the publishItem pipeline and using the publishing events, I’d say use the events whenever reasonably possible. Publishing is still a low-level core process, so not having a chance to mess up the way the pipeline operates is good.

I’ll illustrate the new extensibility with two examples, one for each event.

Preventing an Item from Being Published

As the name suggests, publish:itemProcessing event fires before the publishing is performed, and can be used to cancel the process. In this example, the publishing of protected items is forbidden.

public class EventHandler {
  public void ItemProcessing(object sender, EventArgs rawArgs) {
    // [1] – retrieving the args.

var args = rawArgs as ItemProcessingEventArgs; Assert.IsNotNull(args, "args");

    // [2] – action check
    if (args.Context.Action == PublishAction.DeleteTargetItem) {
      return;
    }
    // [3] – retrieving the item being published
    var item = args.Context.PublishHelper.GetSourceItem(args.Context.ItemId);
    if (item == null) {
      return;
    }

    // [4] – cancel publishing if the item is protected
    if (item.Appearance.ReadOnly) {
      args.Cancel = true;
    }
  }
}

Things to note:

  1. The way arguments are passed to the event handler. This differs from the Event.ExtractParameter that had to be used for older events.
  2. The args.Context.Action check. The publishItem pipeline (and therefore the events) are run for each publishing operation, even if the publishing actually results in the item being removed from the target (web) database. In this example I don’t want to prevent item deletion, so the handler bails out.
  3. The use of args.Context.PublishHelper.GetSourceItem() method to retrieve the item being published.
  4. The operation is canceled in a traditional .NET way by setting the args.Cancel to true.

To activate the event:

<event name="publish:itemProcessing">
  <handler method="ItemProcessing" type="Pipelines.Publishing.EventHandler, Pipelines" />
</event>

In the next post I’ll show how to publish related media items using the publish:itemProcessed event.

Wednesday, August 06, 2008 11:09:07 AM (FLE Standard Time, UTC+02:00)  #    Comments [2] -
Sitecore | Crestone
 Monday, August 04, 2008

Sitecore 6 Content Editor Warning: "The item haven't been updated in a while"Sitecore 6 introduces a number of new pipelines. Some reflect new features added to the system, and some provide new customization opportunities for the previously existing features.

Today's topic is the getContentEditorWarnings pipeline.

Content Editor warnings are the yellow warning blocks that appear above sections and fields in the main Content Editor area. We have more than a dozen warnings supported out of the box, such as "the item is protected", "the item will not be published", etc.

These warnings are specific to Sitecore - we don't know anything about the business domain of the site. However it is easy to add new warnings using the getContentEditorPipeline.

As an example, I've created a warning that checks the updated date of the item, and warns if the item haven't been updated in 6 months or more:

public class GetContentEditorWarnings {
  public void Process(GetContentEditorWarningsArgs args) {
    if (DateTime.Now - args.Item.Statistics.Updated > TimeSpan.FromDays(180)) {
      var warning = args.Add();
      warning.Title = "This item haven't been updated in a while";
      warning.Text = "Consider revising the content.";
      
      warning.AddOption("Set a reminder", "item:reminderset(id={0})".FormatWith(args.Item.ID));
    }
  }
}

The steps here a simple: title and text provide warning description to the user, and AddOptions allows setting up quick fixes. In this example, a “set a reminder” dialog will popup if “Set a reminder” is clicked.

To enable the warning, just add the new processor to the getContentEditorWarnings pipeline either by modifying web.config or using auto-include files (recommended).

<getContentEditorWarnings>
  ..
  <processor type="Pipelines.ContentEditor.GetContentEditorWarnings, Pipelines" />
</getContentEditorWarnings>

A warning can also be exclusive or fullscreen. Exclusive warnings do not allow other warnings to appear. If no exclusive warning is displayed, multiple “normal” warnings can be shown. If fullscreen warning is shown, it hides the usual editing interface of the Content Editor – sections and fields are hidden. Both warning modes can be activated by setting relevant properties of the GetContentEditorWarningsArgs.

Sitecore 6 Content Editor Warning: "The item haven't been updated in a while"

Monday, August 04, 2008 12:16:08 PM (FLE Standard Time, UTC+02:00)  #    Comments [2] -
Sitecore | Crestone
 Friday, August 01, 2008

Sitecore search results grouped in a new "Draft state" category In part 2 I've shown how to customize grouping of existing search results.

Going one step further, it's also possible to inject additional search results. I don't suggest that you try to improve the way the items indexes and searched. Instead, you can increase usability by supporting special searches that are meaningful to your solution or module, or search external locations that are not indexed by Sitecore.

I'll use workflow state searcher as an example: whenever a search query matches the name of any workflow state in the system, the items in that workflow state are added to the search results.

How This Works

Client searches are handled by the <search> pipeline:

<search>
  <processor type="Sitecore.Pipelines.Search.IDResolver, Sitecore.Kernel" />
  <processor type="Sitecore.Pipelines.Search.PathResolver, Sitecore.Kernel" />
  <processor type="Sitecore.Pipelines.Search.UrlResolver, Sitecore.Kernel" />
  <processor type="Sitecore.Pipelines.Search.SecurityResolver, Sitecore.Kernel" />
  <processor type="Sitecore.Pipelines.Search.DatabaseResolver, Sitecore.Kernel" />
  <processor type="Sitecore.Pipelines.Search.SearchSystemIndex, Sitecore.Kernel" />
  <processor type="Sitecore.Pipelines.Search.CategorizeResults, Sitecore.Kernel" />
  <processor type="Sitecore.Pipelines.Search.AddInstantOptions, Sitecore.Kernel" />
</search>

You can see that special searches that Sitecore supports (see part 1) are implemented with separate processors. Adding a new processor in the pipeline will allow new search results to be added.

The Code

public class WorkflowSearchResolver
{
  public void Process(SearchArgs args)
  {
    foreach (var workflow in args.Database.WorkflowProvider.GetWorkflows())
    {
      foreach (var state in workflow.GetStates())
      {
        if (state.DisplayName.Equals(args.TextQuery, StringComparison.CurrentCultureIgnoreCase))
        {
          AddStateResults(args, workflow, state);
          return;
        }
      }
    }
  }

 
void AddStateResults(SearchArgs args, IWorkflow workflow, WorkflowState state)
  {
    foreach (var uri in workflow.GetItems(state.StateID))
    {
      var item = args.Database.GetItem(uri);
      if (item == null)
      {
        continue;
      }

     
args.Result.AddResultToCategory(SearchResult.FromItem(item), state.DisplayName + " state");
    }
  }
}

The logic flow is simple: iterate through all workflow states, and if the query (args.TextQuery) matches the state name, get the items in the workflow state and add them to a category named <state name> state.

All search processors must complete before the search results are displayed, so considering performance is a good idea. For production implementation, caching the workflow state names will make performance impact of the new search processor negligible.

Note that the searches only display a limited number of results (unless the standalone search application is used). Therefore consider limiting a number of search results you inject, so that other processors can also add theirs. In this example, sorting the results is also a good idea: updated date or the date of workflow state change can be used, so that the most recent items appear first. I skip both steps to make the example simpler.

The new search will work both in Content Editor and startbar (instant search) scenarios. However you can limit it to either one by checking the args.Type and aborting if needed.

Try It Out

Add a new processor to the search pipeline. A spot before the standard search system index would be a good place:

<processor type="SearchExtensions.WorkflowSearchResolver, SearchExtensions" />

Now either open the Content Editor and search any workflow state name (such as Draft), or press Ctrl-/ to focus the startbar search and type workflow state name there. You should see a result similar to the screenshot at the beginning of this post.

 

This post is a part of series about new client search introduced in Sitecore 6:

Part 1: Overview
Part 2: Categorization
Part 3: Custom Search Results

Friday, August 01, 2008 7:47:41 AM (FLE Standard Time, UTC+02:00)  #    Comments [0] -
Sitecore | Crestone
 Sunday, July 27, 2008

Sitecore 6 client search is built for extensibility and the most common scenario is to customize result categorization.

We ship with a number of default categories common for all Sitecore solutions - content items, media items (split into images and documents), layouts, system and user templates, workflows, etc.

Each solution or module, however, has its own inherent categories. Solutions benefit from content categories like news, customers and partners. Modules have distinct item types: RSS feeds, mailing lists.

All these categories can be setup in a declarative manner. There is a new section in web.config named search, which includes the categorizer definition:

<categorizer type="Sitecore.Pipelines.Search.CategorizeResults+Categorizer, Sitecore.Kernel">
<Categories hint="raw:AddCategory">
  <category path="/sitecore/content"/>
  <category displayName="Images">
    <templateID>{F1828A2C-7E5D-4BBD-98CA-320474871548}</templateID>
    <templateID>{DAF085E8-602E-43A6-8299-038FF171349F}</templateID>
    <templateID>{C97BA923-8009-4858-BDD5-D8BE5FCCECF7}</templateID>
    <templateID>{EB3FB96C-D56B-4AC9-97F8-F07B24BB9BF7}</templateID>
  </category>
  <category displayName="Documents">
    <templateID>{16692733-9A61-45E6-B0D4-4C0C06F8DD3C}</templateID>
    <templateID>{777F0C76-D712-46EA-9F40-371ACDA18A1C}</templateID>
    <templateID>{7BB0411F-50CD-4C21-AD8F-1FCDE7C3AFFE}</templateID>
    <templateID>{0603F166-35B8-469F-8123-E8D87BEDC171}</templateID>
    <templateID>{3DB3A3CA-A0A9-4228-994B-F70C8E99A1CE}</templateID>
    <templateID>{2A130D0C-A2A9-4443-B418-917F857BF6C9}</templateID>
    <templateID>{F57FB07D-332A-4934-AA67-0A629C5396E2}</templateID>
    <templateID>{CC80011D-8EAE-4BFC-84F1-67ECD0223E9E}</templateID>
  </category>
  <category path="/sitecore/media library"/>
  <category path="/sitecore/layout/devices"/>
  <category path="/sitecore/layout/layouts"/>
  <category path="/sitecore/layout/sublayouts"/>
  <category path="/sitecore/layout/renderings"/>
  <category path="/sitecore/layout"/>
  <category templateIDs="{455A3E98-A627-4B40-8035-E683A0331AC7}" displayName="Template Fields"/>
  <category templateIDs="{E269FBB5-3750-427A-9149-7AA950B49301}" displayName="Template Sections"/>
  <category path="/sitecore/templates/branches"/>
  <category path="/sitecore/templates/system" displayName="System Templates"/>
  <category path="/sitecore/templates"/>
  <category path="/sitecore/system/aliases"/>
  <category path="/sitecore/system/languages"/>
  <category path="/sitecore/system/workflows"/>
  <category path="/sitecore/system"/>
  <category path="/sitecore/content/applications/control panel" database="core"/>
  <category path="/sitecore/content/applications" database="core"/>
</Categories>
</categorizer>

The syntax is fairly self-explanatory. Declarative categories can be setup either using item path or template IDs. Whichever category matches first wins, so the more specific categories (Images and Documents) should go before the generic ones (Media Library).

It's important to understand that categories do not affect the indexes, but only how the results are grouped in the UI.

To setup a content category such as news: <category path="/sitecore/content/home/news" />. Make sure to add this line above the /sitecore/content category.

To setup a template category: <category templateIDs="{id-of-the-rss-feed-template}" displayName="RSS Feeds" />. Again, this category should go before the default ones.

 

This post is a part of series about new client search introduced in Sitecore 6:

Part 1: Overview
Part 2: Categorization
Part 3: Custom Search Results

Sunday, July 27, 2008 12:50:15 PM (FLE Standard Time, UTC+02:00)  #    Comments [0] -
Sitecore | Crestone
 Thursday, July 24, 2008

An amazing story by photographer Phillip Toledano: "Days With My Father".

This is a tech blog, so what I want to say is how the user interface really worked for me.

It's toned down, elegant and beautiful, being a perfect compliment for the story.

I love how text compliments the images, how they look and work together.

There's no slideshow - I love how it makes me flip the pages, adding just a bit of a physical feel but without the corny page-flip animation.

The interface is not perfect by the books. The table of contents and page flipping controls are not discoverable, you need to hover around just a little. But for story this beautiful - I say this works, putting in some effort only makes it better.

It's also interesting to see similarities with the new slide navigation UI the Mozilla is coming up with for the firefox mobile. Is this going to be a new trend?

Actually, I hate picking such a beautiful thing apart and analyzing it, but it comes with the job.

Thursday, July 24, 2008 1:09:21 PM (FLE Standard Time, UTC+02:00)  #    Comments [0] -
Personal | User Experience
 Thursday, July 17, 2008

Search-driven navigation is getting more and more popular as amount of data increases and it gets harder to organize and access it using the traditional structured approach. I'm also a big fan of the application launchers, having tried most of the tools on the Scott Hanselman's list and then some. In fact, if you're not on Vista and don't use any of those, I highly recommend trying a few.

In Sitecore 6 we took a step in that direction, enhancing the UI with two large-scale search options.

Content Editor Search

Content Editor search sits right on top of the content tree. The simplest mode is the basic search:

 Sitecore 6 Content Editor search

All search results are grouped into categories. Some categories are contextual (subitems), most are based on items paths and some use item templates (like Jpeg image). Clicking the result moves the Content Editor to the selected item.

The search input can also be expanded to allow field-level search:

Field search in Sitecore 6 Content Editor

The new search has a few special abilities, being able to recognize item IDs and paths:

ID:
Searching for the item ID in Sitecore 6

Item path (a few variations of paths are supported, you can omit /sitecore or /sitecore/content):
Searching for the item path in Sitecore 6

Startbar Search

The familiar startbar search has also been upgraded, now operating in the live search mode:

Sitecore 6 starbar search: search in progres

Sitecore 6 starbar search showing the search results

To enable keyboard-only searches, there is a new global shortcut: press Ctrl-/ and the startbar search will get focused so you can start typing immediately.

Both searches operate using a new "Quick Search" index. If you don't get any results - rebuild the index using the same Rebuild the Search Index control panel applet.

The startbar search has a few extra abilities compared to the Content Editor, being able to launch applications, provide shortcut to the user editor and database switcher.

Application launcher (supports both traditional applications and control panel applets):
Application search in Sitecore 6 starbar

Users (the user name has to be an exact match, clicking the result opens the Edit User dialog):
User search in Sitecore 6 starbar

Databases:
Database search in Sitecore 6 starbar

The application launcher makes the search really handy in the developer scenario. In the deployed website the ability to search through content is likely to provide more value to the editors.

The geek beauty of the new search architecture is that it allows shell developers to hook in and provide own categorization, additional search results and implement new actions. In the following parts, I'll get to that.

 

This post is a part of series about new client search introduced in Sitecore 6:

Part 1: Overview
Part 2: Categorization
Part 3: Custom Search Results

Thursday, July 17, 2008 2:01:29 PM (FLE Standard Time, UTC+02:00)  #    Comments [0] -
Sitecore | Crestone
 Monday, July 14, 2008

Validation fixes are left for dessert. It's entirely possible to build great validation implementation into a site and never use fixes, but they make a perfect finishing touch.

Show me the Fixes

The setup: the Title field has a max length validator. If the field value is longer than 40 symbols, the validator displays an error even before the item is saved (no refresh required)

 Sitecore 6 max length validator shows an error because the field value is longer than 40 symbols

Now right click the red square in the validator bar:

"Trim" option appears after the validation error is right-clicked in Sitecore 6

Click "Trim" and the field value gets cut back to 40 symbols, and again - save operation is not required, content editor doesn't refresh.

The field value is cut to 40 symbols and validation error no longer appears

How to Make One

Now back to our business requirement: we need to make sure no one spells Sitecore as "SiteCore". In part 3 we made a validator that checks for this situation, but it's also fairly easy to fix the spelling without human involvement.

Step 1. Back to the validator definition at /sitecore/system/settings/validation rules/field rules. Under the validator item, create a new item based on the menu item template (as often, its easier to duplicate an existing fix, for example the one under the max length validator). There are two important fields to fill: Display Name and Message.

Field setup for Sitecore's validator fix

Step 2. Register the validator:fixsitecore command. This should be familiar if you do any Sitecore client development. Open then /App_Config/commands.config file and add a new command:

<command name="validator:fixsitecore" type="Validators.Actions.FixSitecore, Validators"/>

Step 3. The code. Similar to other client commands, but inherit from Sitecore.Shell.Framework.Commands.ContentEditor.Validators.ValidatorCommand. Key points are noted in the comments:

  public class FixSitecore : ValidatorCommand {
    public override void Execute(CommandContext context) {
      // gets the validator. use it to access validator parameters, if needed.
      var validator = GetValidator(context);
      if (validator == null) {
        return;
      }

      // get the field web control that we want to interact this. This really
      // depends on the way the content editor field is implement. Remember
      // that we deal with a simple single-line text field in this example.
      var rawControl = GetControlToValidate(validator);
      if (rawControl == null) {
        return;
      }
      var control = rawControl as Sitecore.Web.UI.HtmlControls.Control;
      if (control == null) {
        return;
      }

      // The actual fix logic
      control.Value = control.Value.Replace("SiteCore", "Sitecore");

      // Re-run the validation, so that red light turns to green in the UI.
      Validate();
    }
  }

 

The hardest part is having to deal with asp.net control structure. We cannot provide the familiar Sitecore item and field API here because validator bar validation runs in real time before the item is saved. This means that the field value might not even exist in the database, and is only available on the UI level.

This means that most fixes are tied to the field implementation. Changing the text field value is fairly easy. To do the same for the rich-text field, a different approach is required: javascript is probably the way to go, because rich text field embeds editor in an iframe.

Step 4. The result:

'Fix capitalization' option appears if 'Sitecore' is capitalized in a wrong way

Summary

While not all validation fixes are straight-forward to implement, they can provide that finishing touch you need for a perfect validation system or a great demonstration.

This concludes the series of posts about new validation features implemented in Sitecore 6, hope you can put it to a good use soon.

Part 1: Introduction, configuration, validation types.
Part 2: Error levels, built-in validators.
Part 3: Making a custom validator.
Part 4: Making a validator fix action.

Monday, July 14, 2008 5:34:07 PM (FLE Standard Time, UTC+02:00)  #    Comments [0] -
Sitecore | Crestone
 Friday, July 04, 2008

Today we're building a custom field validator. The business requirement will be simple: a lot of people at Sitecore get upset when Sitecore is spelled as "SiteCore" (oh, the joy of rebranding). We'll be making a validator to detect the incorrect capitalization and make sure items containing such atrocity never get published.

The Code

Start with the code. Here's what you should keep in mind:

  1. The class should inherit from Sitecore.Data.Validators.StandardValidator.
  2. The validator should be serializable: notice the [Serializable] attribute and serialization-supporting constructor.
  3. Evaluate() method is responsible for the actual validation. The field value is available through the ControlValidationValue property. Return ValidationResult.Valid if no errors are found.
  4. If there are errors, use the Text property to set the human-readable error description, and GetFailedResult method to return the default error value. This will allow solution architects to override the error level later (I've covered this in part 2).
  5. Use the GetMaxValidatorResult method to return the maximum error level the validator can result in. Sitecore needs this to decide if your validator can potentially block a UI operation and therefore it must wait for validator to execute before the operation starts.

Now to the code:

  [Serializable]
  public class FieldValidator : StandardValidator {
    public override string Name {
      get {
        return "Sitecore capitalization validator";
      }
    }

    public FieldValidator() {}

    public FieldValidator(SerializationInfo info, StreamingContext context) : base(info, context) {}

    protected override ValidatorResult Evaluate() {
      var value = ControlValidationValue;

      if (string.IsNullOrEmpty(value)) {
        return ValidatorResult.Valid;
      }

      if (value.Contains("SiteCore")) {
        Text = "Invalid 'Sitecore' capitalization";
        return GetFailedResult(ValidatorResult.Error);
      }

      return ValidatorResult.Valid;
    }

    protected override ValidatorResult GetMaxValidatorResult() {
      return GetFailedResult(ValidatorResult.Error);
    }
  }

Registering the Validator in Sitecore

Once the validator is ready, the next step is to let Sitecore know about it. Open the /sitecore/system/settings/validation rules/field validators, create a new item using the Validation Rule template, and fill in the type field:

image

Now we need to setup when and where the validator should execute.

In this case we don't have to consider performance because the validation logic is simple, and we do want the validator to block workflows. So we'll enable this validator for all four scenarios for all single-line text and rich text fields in the system.

Open the /sitecore/system/settings/validation rules/field validators/field types and find the item named Rich Text.

The Rich Text will already have a number of rules set up - these are the default validations. Add the validator you've created to all of the four fields, that is the Quick Action Bar, Validate Button, Validator Bar and Workflow:

image

for single-line text fields (the new name for old text field) repeat the same, but you'll also need to create the Single-line text field under the field rules, because no global validators are setup for this field type by default. You can simply duplicate any existing item and remove all validators.

Action!

We're done, "SiteCore" no more:

image

Reusability

For a little extra reusability, this validator can easily be made configurable.

Step 1: go back to the validator definition (at /sitecore/system/settings/validation rules/field validators), and add the parameter specifying the word the validator should look for:

image

Step 2: update the code.

      var pattern = Parameters["Find"];
      if (value.Contains(pattern)) {
        Text = "Invalid capitalization";
        return GetFailedResult(ValidatorResult.Error);
      }

 

Notice the usage of Parameters dictionary instead of the hardcoded value. That's it.

Next

I promise, next part will be the last, and we'll build an action that fixes the errors automatically in the single-line text field.

 

This post is a part of series about new validation features introduced in Sitecore 6:

Part 1: Introduction, configuration, validation types.
Part 2: Error levels, built-in validators.
Part 3: Making a custom validator.
Part 4: Making a validator fix action.

Friday, July 04, 2008 3:40:40 PM (FLE Standard Time, UTC+02:00)  #    Comments [1] -
Sitecore | Crestone
 Thursday, July 03, 2008

Error Levels

So apart from lighting up the red lights in the user interface, how does the validation affect the content flow?

Each validator evaluates to one of the following error levels:

Unknown
Valid
Suggestion
Warning
Error
Critical Error
Fatal Error


Suggestion and Warning display colored hints in the UI but never prevent users from completing their tasks:
image

Error prevents the item from changing the workflow state (see part 1 of this article), but like a lot of other details, this is a default that can be changed. Error level also displays scarier red markers in the UI:
image


Critical Error displays a modal warning whenever an item is being saved in the Content Editor. However it's up to editor to decide if she wants to proceed:
image

Fatal Error displays a warning and prevents the item from being saved:

image

 

Overriding the Default Error Level

As a solution architect or administrator, it's up to you to decide the level of error each validator should return.

Crestone ships with a Url Characters validator that displays a warning if the item name will have to be encoded in the URL. However you might be taking your URLs really seriously, and you want the Url Characters validator to result in a Critial Error, to make sure that editors get an in-your-face warning and the item cannot get to the final state of the workflow.

Url Characters is an item-level validator, which means it's registered at /sitecore/system/settings/validation rules/item validators. To change the error level, add the Result=CriticalError parameter to the parameters field:

image

 

Some validators allow further configuration: maximum length validator defaults to 40 characters, but you can change that using the same parameters field.

Built-in Validators

Sitecore 6 ships with a number of item and field validators you can use:

Item validators
Broken Links – Checks the item for broken links.
Duplicate Name - Checks that the item name is unique among siblings.
Full Page XHtml – Renders the entire page and validates against local XHTML schema.
Media Size Too Big – Checks if media is too big to load in memory or store in the database.
Url Characters - Checks if an item name contains characters that must be escaped in URLs.

Field validators
Broken Links - Checks if a field contains broken links.
Is Email, Is Integer - Checks if a field contains an email address or an integer value.
Is XHtml – Validates field XHTML against a local schema.
Max Length 40 - Checks if a field contains a value of 40 or less characters (limit can be changed)
Rating 1 to 9 - Checks if a field contains a value between 1 and 9.
Required - Checks if a field contains a value.
Spellcheck - Checks spelling using the RAD Editor spell check validation, also used in the Rich Text editor.
W3C XHtml Validation - Validates the field HTML using the remote W3C validation service.

System field validators
Alt Required - Checks that the alt text is filled in on the media item.
Extension May Not Start with a Dot - Checks that the media file extension does not start with a dot.
Extern Link Target – Checks that external links open in a new window.
Image Has Alt Text - Checks the image field has alt text set.
Image Has Alt Text from Media Library - Checks if the media item has default alt text.
Image Size - Checks the size for the images referenced through image fields.
Rich Text Image Size - Checks the image dimensions for the images included in the rich text fields, i.e. if the image is too big to look good in the site design.

 

In part 3 I'll show how to build a validator of your own.

 

This post is a part of series about new validation features introduced in Sitecore 6:

Part 1: Introduction, configuration, validation types.
Part 2: Error levels, built-in validators.
Part 3: Making a custom validator.
Part 4: Making a validator fix action.

Thursday, July 03, 2008 11:29:57 AM (FLE Standard Time, UTC+02:00)  #    Comments [0] -
Sitecore | Crestone
Archive
<August 2008>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456
Blogroll
 Alex de Groot
Few words about SiteCore from Holland
 Alexander Shyba
Sitecore Support
 Anders Dreyer
Anders Dreyer on Sitecore Development
 Jakob Christensen
Sitecore Core Development
 Lars Fløe Nielsen
Lars's ramblings about development and business processes
 Ole Thrane
Sitecore API
 Runi Thomsen
Runi Thomsen Sitecore Toughts
 The Sitecore Experience
The Sitecore Experience
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008
Alexey Rusakov
Sign In
Statistics
Total Posts: 199
This Year: 49
This Month: 3
This Week: 0
Comments: 0
Themes
Pick a theme:
All Content © 2008, Alexey Rusakov
DasBlog theme 'Business' created by Christoph De Baene (delarou)