JSON: not just an object literal

For a while I’ve considered JSON to be the same as an object literal in JavaScript.

How wrong I’ve been.

JSON doesn’t support half of this stuff. The JSON format has been developed specifically for data exchange and supports only a subset of what an object literal does.

First of all, property names must be qualified by a double-quote. Single-quotes are not valid. That one had me confused for while as I tried to validate my code.

Secondly, values can only be one of the following: null, string, number, boolean, array, or another JSON object. Functions are definitely not gonna fly.

Generally you’ll be using some other library to generate JSON based on your objects (that’s what kept me so unelightened for so long).

However, for when you need to cut it by hand, there’s a nice little tool at jsonlint.com which you can use to validate your objects.

Tagged ,

Layout inheritance in Sitecore

I was recently tripped up by a publishing error in Sitecore that dragged me kicking and screaming into understanding the new inheritance logic that underpins layout settings. The error was the usual helpful Value cannot be null, directly after a Database.GetItem() call. OK thinks I, there must be a broken link somewhere. Two hours later of adding and removing sublayouts, publishing, re-publishing, staring at XML, commenting in, commenting out, copying and pasting, I had me an understanding of how the oh-so-important  __Renderings field now functions. Now I look forward to the fix that stops the following error occurring when I forget to publish my standard values item that contains half, yes half, of my presentation data.

So, what’s new?

I recently had a meeting with Sitecore Australia’s Steve Green, in which he mentioned in passing the upcoming changes to presentation. It “stores the delta between your standard values and the item”. This sounded interesting, we’ll save countless man hours usually spent updating settings on multiple items due to a tiny change in the UI. I left the meeting looking forward to the next version, 6.5. Unbeknownst to me, this functionality was already alive and kicking on our current implementation on version 6.4.1.

The Delta, you say?

You might be familiar with the XML structure that is used to store presentation. The following image shows the basics, an opening r element(for Renderings), one or more d elements (for Device) and a number of r elements (for Rendering.. or Sublayout as I’ll refer to them here). Each Device element will have a GUID that defines the Layout to be used for that Device, while each Sublayout element will have a GUID reference to the Sublayout, the placeholder it will be added to, the parameters containing settings and/or content .. plus a number of other attributes and settings that describe its functionality.

Usually you’d configure this using the Sitecore interface by editing the __Standard values item of your template. Any items based on this template will then use these presentation settings until the time you make a change to the item presentation – for example, by updating the RichTextContent parameter and adding a promotion to the content_right placeholder. Previously at this point, the entire XML would be updated and stored in the item’s __Renderings field, replacing the XML from the standard values item.

As of version 6.4 however, the layout XML on the item contains just the differences between the standard values and the item. The new layout info is distinguished by an attribute namespace, s. In our example, the majority of the configuration for the RichText Sublayout remains within the standard values item, and is now referenced by its uid attribute, with the updated RichTextContent value stored within s:par, signifying that it overrides the original par attribute from the standard values item. Likewise, the new promotion Sublayout is added with all attributes but with the s: attribute namespace.

Sitecore will now get the standard values information and merge it with the delta in the item, allowing you to change common info. For example, if we needed to move the RichText Sublayout into a new placeholder, or update caching options, this could be done on the standard values item and published with one simple change, rather than update every item that uses the template as we had to do in the past. Great stuff.

So that’s it, basically. Whatever you do, don’t forget to publish your template’s __Standard values item before the item, or you’ll get that nasty publishing error. The null reference error occurs because the uid attribute is the reference to the same rendering in the standard values. As of version 6.4.1, Sitecore won’t let you publish an item without the target uid existing.

Update: the publishing error was fixed in Sitecore CMS 6.4.1 rev.110928 (6.4.1 Update-4). Fear not the publish – fire at will.

Using Fiddler2 and jsbeautifier to debug minified javascript

You’ve deployed to production, everything is tested. You’re quietly confident your AM and the client will be hitting the publish button on the content, high-fiving with gusto and heading downtown for Martini’s while you trudge to the bus stop in the rain. But no. Ten minutes after you send the email, alarms start ringing – “the compact search isn’t displaying in IE!”. That’s the compact, front-and-centre most highly used feature of home page and gateway to the gazillions in sales we receive every hour, search. And that’s IE, the browser (still?!) with the highest god-damned user base. OK, time to investigate.

The compact search is an ajax-driven form that is displayed on page load, so you’re 99% sure the problem is JavaScript. Firing up IE, you hit F12 to launch the developer console, hit the script tab and start debugging. Refresh.

IE9 JavaScript Error - SCRIPT16385 Not implemented

Oh great. 3rd Party Library. Minified. It’ll be a breeze making sense of that code … <Insert more blasphemy here>.

JavaScript Error Code

But there is light in this tunnel.. just down aways.

Open up Fiddler, says Tony. I’ll show you a trick. Refresh the page. Woila, there’s all the files the browser requested for that page, include the culprit, Modernizr. Now, generally speaking there’s nothing special there – nothing that standard browser developer tools don’t give you. But look a little deeper, and we can do some fancy stuff.

  1. Here is our Modernizr include file
  2. Here is the file output – notice it is Gzipped and encoded, hit the button to convert this stuff: Gzipped code, into your actual minified JavaScript code.
  3. Next let’s look at AutoResponder, home of aforementioned fancy stuff. Hit that tab and let’s have a look.

Fiddler Output

So now that you’ve found your javascript file, decoded it and moved over to the AutoResponder tab, drag that file from the list over into the AutoResponder window. You’ll end up with something like this:

Fiddler AutoResponder 1

OK, so look at that… instead of loading the js file from the server now, Fiddler is going to intercept the request and serve this version of the file. Let’s just right-click that sucker and select Edit Response. That’ll give us this window:

Fiddler AutoResponder 2

OK, now we can edit this code to debug the problem. No need to touch anything on the production server. How about we copy the code from this window, head over to jsbeautifier.org and BANG, readable javascript code. Paste that back into the Fiddler AutoResponse, save it and refresh your page. Check your console now and you’ll have the real line where that error occurred. You now have some context.

JavaScript - CleanError Code

Let’s have a quick Google to see why Modernizr 1.6 is crashing in IE9… oh look at that: https://github.com/Modernizr/Modernizr/issues/224. Windows Server 2008 doesn’t deal with the video tag properly because HTML5 isn’t enabled without setting up “Desktop Experience” on the server. But wait a sec, this is happening on a desktop, not a server. Let’s look at that, oh Windows 7 Enterprise ‘N’ .. what the fuck is ‘N’?! More searching reveals this: http://www.techarp.com/showarticle.aspx?artno=619&pgno=3. So looks like ‘N’ is causing a similar issue because Windows didn’t have Media Player and IE set up properly from the start. Nuts.

Side note (rant)

But why does Windows come with this crazy ‘N’ version that has the messed up Html5 / media player features. Well let’s go back in time a bit kiddies, to when Microsoft was a great ogre, rolling over the top of their competition, selling Windows with the web browser already installed!!! Yes, that’s right, already installed! Netscape the other great browser maker of the time were losing market share rapido. All of Microsoft’s competitors freaked out and thought this giant was going to take over the entire world – all because Windows came with IE (and Windows Media Player) installed.

So up rose the mighty US government, pitchforks in hand, and headed to the courts, in both the US and Europe. George W Bush came along and gave the smack down to the case in the US, but Europe ruled that MS had to split the Windows from IE. Enter ‘N’ version of Windows causing me my headache today.

Ten years later, Internet Explorer is still the most widely used browser. But nobody really cares about whether browsers and operating systems and media players are integrated. In fact just look at what Apple do these days. Mac OS comes with everything you need, from Safari to iPhoto. Look at Google, they’re turning the browser into the OS. What’s going on there? Integration is the way of the future.

So why did we stop Microsoft doing this ten years ago?

Haters gotta hate.


Tagged

Sitecore Request Validation – or lack thereof

If you’re ever finding that ValidateRequest isn’t working in your Sitecore site and the dodgy script tag in your form gets posted anyway, this is why.

  • namespace Sitecore.Pipelines.PreprocessRequest
  • {
  •     public class SuppressFormValidation : PreprocessRequestProcessor
  •     {
  •         public override void Process(PreprocessRequestArgs args)
  •         {
  •             Assert.ArgumentNotNull(args, “args”);
  •             try
  •             {
  •                 NameValueCollection form = args.Context.Request.Form;
  •             }
  •             catch (HttpRequestValidationException exception)
  •             {
  •                 if (!args.Context.Request.RawUrl.StartsWith(“/sitecore/shell/”, StringComparison.InvariantCultureIgnoreCase))
  •                 {
  •                     Log.Error(exception.Message, exception, this);
  •                 }
  •             }
  •         }
  •     }
  • }

See what they did there?!

Initially I just removed the processor from the config, but then I added it back in. This is my “fix”.

  • namespace SC.Pipelines.PreprocessRequest
  • {
  •     public class SuppressFormValidation : PreprocessRequestProcessor
  •     {
  •         public override void Process(PreprocessRequestArgs args)
  •         {
  •             bool isShell = args.Context.Request.RawUrl.StartsWith(“/sitecore/shell/”, StringComparison.InvariantCultureIgnoreCase);
  •             if (isShell)
  •             {
  •                 Assert.ArgumentNotNull(args, “args”);
  •                 try
  •                 {
  •                     //requesting these objects for the first time will trigger ‘ValidateRequest’ to ensure no script is being posted                    
  •                     var form = args.Context.Request.Form;
  •                     var qs = args.Context.Request.QueryString;
  •                     var cookies = args.Context.Request.Cookies;
  •                 }
  •                 catch (HttpRequestValidationException) { }
  •             }
  •         }
  •     }
  • }