Sitecore Modal Dialogs Fix For Chrome 37+

In the newest release of Chrome (37), the showModalDialog function is disabled by default (Chromium Blog). This change will affect all Sitecore instances using version lower than 7.1.

Show Modal Dialog Is not Defined

Fortunately, there are options to workaround the issue.

The first approach is to enable the showModalDialog function via the EnableDeprecatedWebPlatformFeatures policy. For more information on how to set policies you can refer to one of these two articles depending on your organization – Set Chrome policies for devices or Set Chrome policies for users. Keep in mind that this fix needs to be applied on every device.

!!!UPDATE!!!

As it seems the javascript solution with window.open is not working as it is not blocking the execution. The window is actually opened, but the changes won`t be saved because they won`t be passed back to the caller. So the only solution is enabling the deprecated web platform features (or upgrading Sitecore to 7.1+). The big problem is that Mozilla currently deprecated the Window.showModalDialog(), so if they obsolete it in the near future the only option will remain to use IE or upgrade to 7.1+.

The second approach is to replace the showModalDialog function with window.open. This should be done in [Web_Root]\sitecore\shell\Controls\Gecko.js. There are two functions which should be modified.

scBrowser.prototype.prompt

Modify the following line (Line 231 in the JS file):

From

return showModalDialog(“/sitecore/shell/prompt.html”, arguments, features);

To

return window.open(“/sitecore/shell/prompt.html”, arguments, features);

scBrowser.prototype.showModalDialog

Modify the following line (The line number varies for different versions of Sitecore. For Sitecore 7.0 it is Line 350 and for Sitecore 6.6 Line 345):

From

showModalDialog(url, arguments, features);

To

window.open(url, arguments, features);

The big difference is that now the opened windows will not block the GUI, because they are opened in a new browser window and the fabulous dim effect is gone :).

Fixed Modal

Hope this will help you stick to your favorite browser !

Here are some useful links from other sources:

Main SDN Discussion Thread – PSA: showModalDialog disabled by default in Chrome 37

Blog Post By Dheer Rajpoot which covers the chrome policies approach in details – Sitecore Modal Pop-ups are not working in Chrome

Blog Post By Ben McCallum – Sitecore modals and problems in newer browsers

Blog Post By Kamruz Jaman using jQuery UI Dialog – Fix for Dialog Modals not working in Sitecore in Chrome 37+ browsers 

Sitecore KB – Sitecore does not work in Chrome 37 and later

Useful Sitecore Query String Parameters

At the end of the day Sitecore is a web based system and as such uses query string parameters to pass viable data. They are used to switch between display modes, sites, languages etc. I found out that remembering these parameters is a huge speed improvement especially in cases when dealing with multi-language, multi-device or page editor enabled solutions. Here is a list of the Sitecore query string parameters that I are most useful in my day-to-day job.

sc_mode – Used to change the display mode of the website. Can have the following values:

  • normal – normal display – the way the users see the site
  • edit – page editor mode
  • preview – preview mode

Example: http://yoursitename.com?sc_mode=preview

sc_lang – Used to change the website language. Can have any value that is defined under /sitecore/system/languages

Example: http://yoursitename.com?sc_lang=fr-FR

sc_itemid – Used to change the current item.

Example: http://yoursitename.com?sc_itemid={12345678-1234-1234-1234-123456789ABC}

sc_site – Used to change the current website.

Example: http://yoursitename.com?sc_site=mywebsite

sc_device – Used to change the device in which the website is displayed. Can be used with the device name or the device id.

Example: http://yoursitename.com?sc_device=mobile

Example: http://yoursitename.com?sc_device={12345678-1234-1234-1234-123456789ABC}

sc_database – Used to change the database from which the content is displayed.

Example: http://yoursitename.com?sc_database=master

 

And here are some of the debug specific query string parameters.

sc_debug – Used to start/stop the debug mode. Possible values are 0 and 1.

Example: http://yoursitename.com?sc_debug=1

sc_prof – Used to start/stop the Sitecore profiler. Possible values are 0 and 1.

Example: http://yoursitename.com?sc_debug=1&sc_prof=1

sc_trace – Used to start/stop the Sitecore trace. Possible values are 0 and 1.

Example: http://yoursitename.com?sc_debug=1&sc_trace=1

sc_ri – Used to show/hide the rendering information. Possible values are 0 and 1.

Example: http://yoursitename.com?sc_debug=1&sc_ri=1

The default debugger usually starts with all three enabled – http://yoursitename.com?sc_debug=1&sc_prof=1&sc_trace=1&sc_ri=1

 

These are the query string params that I usually use in my day-to-day job. There are probably many more of them in Sitecore that are sitting there, waiting for someone to find them 🙂 !

Sitecore Custom Field Validators

In many cases developers rely on the content editors to input valid content. In reality that never happens. The only way to protect ourselves from receiving invalid data from Sitecore is by using validators. Sitecore has pretty nice “out of the box” validation rules for common scenarios. But common scenarios are much like unicorns and the guys in Sitecore know that. Because of that there is a pretty nice way to add our own custom validators. It can be achieved in 3 easy steps.

The scenario described in this example is the following: There is a single line text field which should contain exactly 16 characters. The first 8 characters must be numbers and the other 8 characters must be English alphabet letters. (Please keep in mind this can be implemented via the built in Sitecore.Data.Validators.FieldValidators.RegexValidator).

Step 1 – Creating A Custom Validator

Create a Custom Validator that inherits from StandardValidator with the following code.

using Sitecore.Data.Validators;
using System.Text.RegularExpressions;

namespace Sandbox.Validators
{
    public class SandboxIDValidator : StandardValidator
    {
        private readonly Regex numbersRegex = new Regex(@"^\d+$");
        private readonly Regex lettersRegexnew = new Regex(@"^[A-Za-z]+$");

        protected override ValidatorResult Evaluate()
        {
            string value = base.GetControlValidationValue();

            if (!string.IsNullOrEmpty(value) && value.Length == 16)
            {
                string firstPart = value.Substring(0, 8);
                string secondPart = value.Substring(8, 8);

                if (numbersRegex.IsMatch(firstPart) && lettersRegexnew.IsMatch(secondPart))
                {
                    return ValidatorResult.Valid;
                }
            }

            base.Text = "Text is not a valid Sandbox ID";

            return base.GetFailedResult(ValidatorResult.Error);
        }

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

        public override string Name
        {
            get { return "Sandbox ID Validator"; }
        }
    }
}

To create a custom validator, the StandardValidator abstract class should be inerited (which inherits the BaseValidator abstract class). The Name property is self descriptive. The evaluate method gets called when the field needs validation. It determines if the value of the field is valid and and in case it is – it should return ValidatorResult.Valid. Otherwise it should return a validation error of some kind (it might be a suggestion or warning) and error message. GetMaxValidator result is best explained by decompiling the Sitecore.Kernel and looking at the remark:

GetMaxValidatorResult

 

Step 2 – Creating a Sitecore Validation Rule

After the code is ready the validator needs to be added as a Validation Rule in Sitecore. The field validators are located under “/sitecore/system/Settings/Validation Rules/Field Rules/”. The new validation rule for the custom validator should look like this.

Creating_a_custom_validator

Step 3 – Attaching the Validator to a Field

In order to use the validator it should be attached to a field. To attach it navigate to the Template Field in the Template. After that expand the Validation Rules section and add it under the appropriate sections where the validator should appear.AttachToItem

At the end the result should look like this:

ValidatedItem

Happy Validating !

 

Switch Sitecore 7.2 Speak UI Media Browser to the good old Sheer UI Media Browser

I am posting this article as a follow up to the following SDN Topic – Sitecore 7.2: Delete image in media picker in page editor.

After upgrading to Sitecore 7.2 the content editors might complain about the new Speak UI Media Browser, as they would not find it as intuitive as the old one (or maybe they will have a hard time getting used to it). Fortunately there is a way to disable the new Speak Media Browser and switch to the good old Sheer one.

It can be achieved by disabling Speak overrideXmlControls in the Sitecore.Speak.config.

Create a custom configuration with the following code.

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
	<sitecore>
		<overrideXmlControls>
			<override xmlControl="Sitecore.Shell.Applications.Media.MediaBrowser" with="/sitecore/client/applications/Dialogs/SelectMediaDialog">
				<patch:delete />
			</override>
		</overrideXmlControls>
	</sitecore>
</configuration>

Keep in mind that the configuration file needs to be bellow the Sitecore.Speak.config in the Include folder otherwise the configuration file won’t work because the original Sitecore.Speak.config overrides won`t be registered (a good name will be z_Sitecore.Speak.Overrides.config).

The effects can be seen on the screenshots bellow.

Before:

Speak UI Media Browser
After:

Sheer UI Media Browser

You can also notice that Sitecore.Speak.config is the configuration file in which the old Sheer UI Dialogs were overridden by the new Speak UI Dialogs (under the overrideDialogs node). If you want to switch to the old Sheer Dialogs this is the place to do it.

Playing with the Sitecore Item Saved Event

There are cases in which the data for an item should get automatically populated from a service or some kind of external database. In some cases the content editors want to decide on which items exactly should be pulled from the external service. One of the ways to achieve this is by attaching to the Sitecore Item Saved Event.

Attaching to the Item Saved Event can be achieved with two simple steps.

Step 1 – Creating a custom event handler


namespace Sandbox.Events
{
    using System;
    using Sitecore.Data;
    using Sitecore.Data.Items;
    using Sitecore.Events;
    using Sitecore.SecurityModel;

    public class ItemSavedHandler
    {
        public void OnItemSaved(object sender, EventArgs args)
        {
            // Extract the item from the event Arguments
            Item savedItem = Event.ExtractParameter(args, 0) as Item;

            // Allow only non null items and allow only items from the master database
            if (savedItem != null && savedItem.Database.Name.ToLower() == "master")
            {
                // Do some kind of template validation to limit only the items you actually want

                if (savedItem.TemplateID == ID.Parse("{00000000-0000-0000-0000-000000000000}"))
                {
                    // Get the data that you need to populate here

                    // Start Editing the Item

                    using (new SecurityDisabler())
                    {
                        savedItem.Editing.BeginEdit();

                        // Do your edits here

                        savedItem.Editing.EndEdit();
                    }
                }
            }
        }
    }
}

When inside the handler all the field values that were populated by the content editor can be accessed (for example the ID of the item in the external system).

Step 2 – Creating a custom configuration

The sample configuration can be found bellow


<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <events>
      <event name="item:saved">
        <handler type="Sandbox.Events.ItemSavedHandler, Sandbox" method="OnItemSaved">
        </handler>
      </event>
    </events>
  </sitecore>
</configuration>

The configuration is simple – it is attaching the custom code to the item:saved event.

And that`s it ! Now you are ready to attach to the item saved event and do your magic !

There are many other events in Sitecore which are a very powerful tools and allow the developers to intercept any stage of the item`s lifecyle, but they will be covered in different posts.

Sitecore Custom Tokens

Out of the box Sitecore comes with the following expand standard values tokens:

  • $name – Name of the item
  • $date – Current server date
  • $time – Current server time
  • $now – Current server date time
  • $id – Item ID
  • $parentid – Item’s Parent ID
  • $parentname – Item’s Parent Name

Sometimes the already existing tokens are not enough. There are cases in which the Content Editors won`t be able to access the value that needs to be populated (ex. – webservice call) or it will be hard for them to do it (ex. – the value of the item varies on many other items). In the current example the $next token will be implemented. It will automatically replace the token with the current siblings count plus one  – this token is usually used in cases where there is a requirement for auto incrementing sort order of items.

Implementing a custom token is fairly simple and can be achieved in 2 easy steps.

Step 1 – Creating a custom ExpandInitialFieldValueProcessor

Create a custom ExpandInitialFieldValueProcessor with the following code.


namespace Sandbox.Processors
{
    using Sitecore.Pipelines.ExpandInitialFieldValue;

    public class TokenNextProcessor : ExpandInitialFieldValueProcessor
    {
        public override void Process(ExpandInitialFieldValueArgs args)
        {
            if (args.SourceField.Value.Contains("$next"))
            {
                if (args.TargetItem != null && args.TargetItem.Parent != null && args.TargetItem.Children != null)
                {
                    args.Result = args.Result.Replace("$next", args.TargetItem.Parent.Children.Count.ToString());
                }
                else
                {
                    args.Result = args.Result.Replace("$next", "0");
                }
            }
        }
    }
}

The code is pretty straightforward. It checks if the value of the field contains the $next token. If it does it checks if the parent is not null and the parent has children. If the parent is not null and there are children the value is set to the children`s count (the processor is executed after the child is added so the index will be 1 based), otherwise it sets the value to 0.

Step 2 – Creating the custom configuration

The configuration is standard. It should register the processor under the expandInitialFieldValue pipeline.


<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <expandInitialFieldValue>
        <processor type="Sandbox.Processors.TokenNextProcessor , Sandbox" patch:after="processor[@type='type=Sitecore.Pipelines.ExpandInitialFieldValue.ReplaceVariables, Sitecore.Kernel']"/>
      </expandInitialFieldValue>
    </pipelines>
  </sitecore>
</configuration>

And here is an example of how it works.

Adding The Token to the standard values

The content tree

The result