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

Advertisements

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.

Collaborating with Microsoft, is a phrase that reads rather like a pejorative. Clearly not what is intended but revealing nonetheless of Microsoft’s perception in the open source community.  This is a perception that Microsoft is clearly serious about changing and I have somehow become part of this (despite turning up for a meeting at MS HQ toting a Macbook and iPhone).

I am now part of a collaborative effort (with Microsoft at the fulcrum) to create some sexy open source packages for the Umbraco platform. Also on this team are:

This as far as I can tell is a fairly hands off Microsoft backed initiative, we build some packages, blog and vlog about it and Microsoft give us access to the relevant teams they have internally.

There is no censorship on what we say, if we think Silverlight is a solution in need of a problem we’re free to say so……… nope no MS swat team just bashed down my door, looks like I’m free to continue.

We’re working on a few different projects, but there is one biggie that will be the posterboy of this effort. Can’t say too much right now, it’s bad luck to discuss vapourware (rather like naming Macbeth in a theatre, only without the over theatrical swooning and hopping round in a circle three times, to break the hex).

So far I have been impressed with Microsoft’s willingness to help and most impressively it’s willingness to listen to open source developers. This from a company that only a few years ago described open source in distinctly disparaging terms.

I’m hoping this will mark the beginning of a fruitful relationship between Microsoft and not just the Umbraco community but the other open source communities that Microsoft is extending is offer of friendship to. (I suspect they are tired of jokes about Steve Ballmer throwing chairs through windows at the thought of it however).

So what’s been achieved so far? Well Warren has released his excellent auto translation package (well done Warren), initial planning of the “don’t mention it’s name” app is done and Darren has made some fantastic progress on getting a proof of concept up and running. Microsoft have set us a deadline (very sensible in my opinion, as I’m wont to talk at length about any subject, regaling my audience with anecdotes and tales of my past at the code face) so with a fair wind we should have exciting things to see by the end of this month.

Until my next update (when hopefully I will have actually written some code)

à bien tôt!

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).

Today I had occasion to try and add an Umbraco macro to a User Control (.ascx) file.

Here’s how it’s done:

Umbraco Macro’s are just like normal UserControls so can be added to an user control using the standard Controls.Add() method.

However passing macro parameters proved to be a whole different ball game. This is because Macro parameters needed to be specified in lower case, despite the ones I was adding being in camel case in the Umbraco backend and the alias property not being case sensitive.

Here’s an example of the code I used to load my macro in with:


int ProductFolderID = 1188;
umbraco.presentation.templateControls.Macro mcr = new umbraco.presentation.templateControls.Macro();
mcr.Alias="SiteDocumentULList";
mcr.MacroAttributes.Add("source",ProductFolderID);
mcr.MacroAttributes.Add("documenttypealias", "1079");
this.macroContainer.Controls.Add(mcr);

As you can see creating and adding a macro is very simple, but watch out for the all lower case macro parameters and also that in the code that parameters are referred to as attributes.

For those who like a bit more detail here’s what the code above is doing:

First we create a new Macro object and assign it to the mcr variable for later use.
Note: the Macro object you need to create is in the following namespace: umbraco.presentation.templateControls.

Next up we update the alias property of the macro object. This tells umbraco which macro to use.
Note: this is not case sensitive.

Next we add the parameters to the macro, we do this by adding an entry into the MacroAttributes property, which is just a Hashtable. In my example the first parameter I add takes a value from a variable I have declared. The second parameter is a string literal I am passing direct to the hashtable.

The final line uses the standard Add() method on a PlaceHolder I have created in my usercontrol to add the umbraco macro to the page.

 

Had a problem after upgrading to Umbraco 4.0.1 today.

I dutifully copied and merged all my files together from Umbraco 4.0.0 to 4.0.1 and everything appeared to work fine.

However when I tried to log into the backend I couldn’t. No error no indication of why my log-in now didn’t work.

Turns out that Umbraco is now set to Hash passwords by default in the web config and if you have users created before this change they no longer work (because their passwords are not hashed).

To solve the problem remove the passwordFormat=”Hashed” attribute from the UmbracoMembershipProvider and UsersMembershipProvider

The old logins will work correctly again now.

Had to upgrade a site to Umbraco 4.0.1 today and found it useful to have a proper list of the files that had been changed in Umbraco 4.0.1 from 4.0.0

So here it is:

http://www.thecogworks.co.uk/umbraco-files/umbraco4.0.0to4.0.1.htm

Thought it might come in handy for someone else.