Following on from the talk I gave at the UK Umbraco Festival about automated testing in Umbraco, using Slenium etc.

I’ve created an example folder structure with build files and also included some example cc.net config files as well. You can download it here.

As per the comment below, here’s the Visual Studio plugin we use for Mercurial: http://visualhg.codeplex.com/, also Tortoise HG http://tortoisehg.bitbucket.org/

Hopefully this will get you started.

T

Whilst working on my first big Umbraco 4.5 implementation I began noticing the new preview functionality didn’t behave as I expected.

To start off with I thought it was broken, but in fact there are some performance related decisions that have been made in the implementation that can confuse you when you first start using it.

First off how does Preview work:

The new Umbraco preview functionality generates a new XML cache of the Umbraco content when you press the preview button and uses this whilst you are browsing the site in preview mode.

However to aid performance Umbraco only generates preview data for the nodes including and below the one you are previewing. They do this for performance reasons. However this can lead to some unexpected behaviour if you are using recursive data in your macros etc (Data which is stored higher in the tree than the node you are previewing).

The solution to this is of course to preview your site starting from the homepage, then the full node tree is populated with preview data when you press preview (this could get slow in big sites).

Preview works perfectly with NodeFactory and with XSLT as long as you bear the above in mind.

The other quirk that had me stumped for ages and made me think preview was broken was Linq2Umbraco. Linq to Umbraco staunchly failed to show preview content. So I had a dig about in the 4.5 source and discovered that the default provider for Linq to Umbraco ONLY USES PUBLISHED DATA.

However the clever folk at Umbraco have given us a way to make this work (they just haven’t told us 😉 )

The answer is in the code below:

namespace Extensions.LinqToUmbraco
{
    using System;
    using System.Web;
    using umbraco.presentation;
    using umbraco.presentation.preview;
    using umbraco.Linq.Core.Node;

    /// <summary>
    /// Extension class which provides singleton like access to the UmbracoNodesDataContext
    /// It is not a true singleton pattern, but is ueful because it provides HttpContext
    /// level caching of Umbraco data, improving performance on requests
    /// </summary>
    public partial class UmbracoNodesDataContext
    {
        /// <summary>
        /// Instance property which creates a new instance of the UmbracoNodesDataContext class
        /// if the instance has already been created within the current HttpContext then it returns the cached version.
        /// However if the site is in preview mode then it returns the current preview content (this is not cached in the HttpContext)
        /// </summary>
        public static UmbracoNodesDataContext Instance
        {
            get
            {
                var context = HttpContext.Current.Items["UmbracoNodesDataContex"] as UmbracoNodesDataContext;

                if (UmbracoContext.Current.InPreviewMode)
                {
                    var previewContent = new PreviewContent(new Guid(umbraco.BusinessLogic.StateHelper.GetCookieValue("PreviewSet")));
                    var path = previewContent.PreviewsetPath;
                    context = new UmbracoNodesDataContext(new NodeDataProvider(path, true));
                }
                else
                {
                    if (context == null)
                    {
                        context = new UmbracoNodesDataContext();
                        HttpContext.Current.Items["UmbracoNodesDataContext"] = context;
                    }
                }

                return context;
            }
        }
    }
}
The above code is a partial calss which extends the DataContext which is auto generated by Linq2Umbraco. It needs to be in the same nasespace as your main DataContext class and have the same class name.
More info on partial classes here: http://msdn.microsoft.com/en-us/library/wa80x488(VS.80).aspx
It does 2 things, the first is to implement a singleton type pattern so your datacontext can be cached during the current HttpContext, which should give you a performance boost (as outlined in this video: http://vimeo.com/9790069)
It also checks to see if the site is in preview mode and if it is grabs the preview XML and passes that to the NodeDataProvider. This means that when in preview mode Linq2SQL will behave just like Nodefactory and XSLT and sow the preview content. I’m not caching the preview content in the current context BTW.
Till next time.

Deleting nodes from Umbraco is a simple task, but there appears is a lack of clear examples on the web. So here is a code snippet to help you get started.

if(doc.Published)
{
    doc.UnPublish();
    library.UnPublishSingleNode(doc.Id);
}

doc.delete();

So what’s going on here?

First of all we retrieve the document by instantiating the Document class with the node id. In this case 1234.

Now check to see if the document is published. If the document is published then call the UnPublishSingleNode method (passing the id of the document). This method removes the document from the runtime xml index (effectively removing it from the site).

Finally we call the delete method on the document. This moves the document into the trash (including all its children).

If you want to permanently delete the document then simply call the delete method again.  The document will then be entirely removed from Umbraco.

What about  umbraco.library.RefreshContent();

Some examples I found say that you need to call:

umbraco.library.RefreshContent();

In my example this is replaced with:

library.UnPublishSingleNode(doc.Id);

This is a more efficient method as RefreshContent() re-generates the entire runtime xml index, whereas UnPublushSingleNode() only affects the Document you are deleting (it also means you can check to see if the document is published first in order to prevent unnecessary work).

I had an odd problem today when I was working with an SMS gateway.

They asked for the SMS message I wanted to send to be URL Encoded.

No problems I said and simply added the URLEncode() method around where I was sending them the message:

string SMSToSend = HttpUtility.UrlEncode(message);

However, when the message string contained a £ sign my SMS got sent over as £.

So instead of £200 being sent £200 was sent instead.

First I thought it was a problem at their end, so I asked them. But they said they were receiving the  from me.

So with some further digging it transpires that URLEncode doesn’t like the default format of of C# string which is UTF-8. This means that when you URLEncode a string with characters such as £ in it you MUST specify the correct encoding, which is iso-8859-1

string SMSToSend = HttpUtility.UrlEncode(message, “iso-8859-1”);

This solved the problem and is one to watch out for in the future as it is not clear at first look that URLEncode() would cause this issue.