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: - The class should inherit from Sitecore.Data.Validators.StandardValidator.
- The validator should be serializable: notice the [Serializable] attribute and serialization-supporting constructor.
- 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.
- 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).
- 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:
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:
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:
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:
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.
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:
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:
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:
Fatal Error displays a warning and prevents the item from being saved:
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:
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.
Validation received a major upgrade in Crestone, going from regular expressions firing up when the item is saved, to a powerful setup of validator classes running at different stages and providing UI feedback through different means. Configuration Validators are configured in a new content tree location in the master database: /sitecore/system/settings/Validation Rules
Field Rules and Item Rules folders define available validators, and Field Types and Global rules configure the validators to be run for all items and fields of given field type. In addition to the global configuration, it's possible to add validators for individual items and fields. For items, there are four new fields in standard template, grouped in the new Validation section. As usual, the best practice is to only change these at template level and use standard values to propagate data to individual items. For fields, "template field" template also has four additional fields that allow validators to be added at field configuration level. So the formula is: Item validators = Global Rules + Validators defined on the item itself using new standard template fields Field validators = Field Types rules (matched by the field type) + rules defined on the template field. Whichever strategy you use to configure validation, you'll always have to deal with these four treelist fields: Validation Types So what are these? Quick Action Bar, Validate Button, Validator Bar and Workflow represent four distinct sets of validations you can define for each item and field: Validator Bar is the most powerful validation device. Notice the red marker to the left of the field - it indicates that the field contains an error. Hovering over the bar will display a tooltip with the error message returned by the validator. Validator bar to the right of the Content Editor duplicates this information, providing validation summary for the entire item and all of its fields. Important: Validators configured to run in the validator bar are updated in the real time. As soon as you stop editing the field, the validators will be run asynchronously in background, and the UI will be updated. Quick Action Bar (left) is another Content Editor upgrade that displays status for each item visible in the tree and allows quick actions, such as check in, to be performed. Validation is turned off by default, so to enable it, you need to right click the Quick Action Bar and make sure that "Validation Rules" menu item is checked. Validate Button represents a new Validation Results dialog, that displays the most detailed validation status for the current item:
Workflow defines the validators, which will be run when the item is moved from one workflow state to another. It's implemented with a new workflow action, which allows to define workflow states that should be guarded by the validation: Item with significant validation errors will not be allowed to the next state. I'll show how define which errors are "significant" and what other effects they have in the UI in the following parts. 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.
Sitecore 6 is out, phew. New features? See for yourself: What's new (PDF, 35 pages), Download, Product page. For me this sums up 10 months on the user interface side of development, and I'm looking forward to seeing people use and abuse, complain and praise what we have done.
I like drawing when designing user interfaces, but my drawings don't usually end up as famous (nor as pretty) as these did: see The Paper Web, UI design sketches of flickr, twitter, vimeo, youtube and others.
Fast Query is an exciting Crestone feature that is usually off the marketing radar. It is a subset of Sitecore Query that executes with SQL speed, meaning fast. While it's not as expressive as Sitecore Query, you can still retrieve items using item paths, IDs or names, field values and parent/child relationships, which is what people need 80% of the time. The performance gain is outstanding - think writing an SQL query instead of going through all the items using the Sitecore API. How to Use the Fast Query? Much like standard Sitecore Query before, you can use Fast Query either in field sources or in the API. To indicate that that your query must be executed in the "fast" mode, prefix it with "fast:" : The API way: Sitecore.Context.ContentDatabase.SelectItems("fast:/sitecore/content/home/*"); Note that relative queries starting from a specific item are not supported, you cannot use fast query in item.Axes.SelectItems. So What Queries are Supported? - Only child and descendant axes are supported. For example you cannot search for a parent of a specific item or following-sibling.
- The following special attributes are supported: @@id, @@name, @@templateid, @@masterid and @@parentid.
- String comparison is converted to SQL LIKE operator.
- Functions are not supported, contains() is replaced by string comparison which behaves like SQL LIKE.
- Subqueries are not supported. i.e. the following query won't work: //*[../@name='Home']
- It is not possible to query from a context item, only the whole database.
(More on query syntax in the original Crestone beta forum post by Dmitry Kostenko) How to Test? The XPath Builder works great with Fast Query. Open Developer Center, select Tools menu and then XPath Builder. Remember to prefix your queries with "fast:": Performance XPath Builder actually shows how much time it spent executing the query, so we can see the difference the fast query makes: Switch the XPath Builder to the core database (it's much bigger than the master in a clean Sitecore installation). fast://*[@@name = 'Home'] takes 1-2ms. //*[@@name = 'Home'] takes 350-500ms after the first couple of runs. New Usage Scenarios Fast Query enables scenarios that weren't possible before because of the query speed: In Sitecore 5 we have a shared source "My Locked Items" module that has to use caching and subsequently cache invalidation to get a list of items locked by the user with a decent performance. In Crestone we have a built-in Locked Items application, that does pretty much the same but was trivial to make, because all it has to do to get the list of items locked by the user is to run the following query: Database.SelectItems("fast://*[@__lock='%sitecore\\Admin%']" The Crestone version of the RSS module will also use the fast query to retrieve items while building the feed, which will hopefully make generating feeds per-demand more feasible. Summary It doesn't get much simpler: the new query is fast, use it to make your sites more responsive or to provide better features which you couldn't implement before. Update: As of June 14th, 2008, the fast query is considered an experimental feature in Sitecore 6.0. It's recommended that you test the results of the query first - in some situations it's possible that queries relying on parent-child relationships can return results that are slightly out of date. This is likely to be fixed in the following versions of Sitecore.
After the Carousel, Slider and Visual list field types, I've decided to take a pause to work on the quality and make an actual release. This includes all of the housekeeping well-behaved Sitecore fields should do, bugfixes (thanks for the feedback, really) and documentation. What's changed: - Carousel and Visual list can be used outside of the media library. They will default to using the content item icon, but it's also possible (and expected) to supply an image field name to take the image from. Same works for item titles. See the documentation for configuration examples
- All fields now properly indicate their changed state to Sitecore, which results in timely "Do you want to save the item" prompts
- All fields also support readonly state - if the item is protected, or the user does not have write permissions, the field will be rendered in readonly state ("grayed out")
- Carousel and Visual list fields support link checking
- Production and Items Only (development) packages and package projects are included.
It's time to call it a Beta - see the Field Types trac site for downloads. The goal is to apply more polish and make a quality release when the time Crestone ships, so that the fields can be used right away. Some tickets are already piling up for the next release. If you have ideas for new field types - send them in, or contribute.
RSS module trunk is shaped up to support Crestone. The module no longer requires web.config to be modified after the installation, packages are updated, and the project structure is changed to match rest of the modules more closely. After some surface testing the module appears to work fine on Crestone, the updated Crestone beta should do. Trunk development has moved to Crestone; Visual Studio 2008 is required to work with the project. Use Sitecore5 branch for the stable Sitecore 5.3.x version. From the feedback, accumulated during the module lifetime, these are the goals I see for the next version: - Update the module to work with Crestone (almost there, needs more testing)
- Simplify feed creation, configuration and troubleshooting - ease of use.
- Add more extensibility points, to allow partners to better fit the module to their needs without modifying the module itself.
What do you think? As always, packages, source code and updates are available at the trac site.
Another field type is up and running: introducing Visual List, allowing to maintain a list of images (or any items, in future) in a very simple and visual way. The field allows editors to select any number of images from a specified source, and supports drag-and-drop reordering. Good usage scenarios for this fields include maintaining a list of banners to rotate on the page, a list of product images, etc. An advantage over using a set of subitems to achieve the same functionality is editor experience: no not having to switch items saves a lot of editing time, and its easy to see all selected items at once.  The Outercore fieldtypes project, which now includes Carousel, Slider and Visuallist fields, has moved to Sitecore shared source repository, so no more download links in the blog. Use the project trac site to view or update the documentation, download the source, file tickets or watch the updates. I'll continue to post update summaries in the blog. Bug reports, new field type ideas are welcome. Contributors are most welcome, of course, mail me to become one.
The Crestone beta update was made available on Friday (requires beta forum access). Apart from numerous fixes and tweaks, it should be able to run both Carousel and Slider fields. Have fun, and let us know how it feels.
|