<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Tim</title>
    <link>http://blogs.thesitedoctor.co.uk/tim/</link>
    <description>Footprints in the snow of a warped mind</description>
    <language>en-gb</language>
    <copyright>Tim Gaunt</copyright>
    <lastBuildDate>Sat, 12 May 2012 13:53:24 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.2.8279.16125</generator>
    <managingEditor>timgaunt@gmail.com</managingEditor>
    <webMaster>timgaunt@gmail.com</webMaster>
    <item>
      <trackback:ping>http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=7bb72a12-e3e3-45de-92e2-7f6f5537879c</trackback:ping>
      <pingback:server>http://blogs.thesitedoctor.co.uk/tim/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,7bb72a12-e3e3-45de-92e2-7f6f5537879c.aspx</pingback:target>
      <dc:creator>Tim</dc:creator>
      <wfw:comment>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,7bb72a12-e3e3-45de-92e2-7f6f5537879c.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.thesitedoctor.co.uk/tim/SyndicationService.asmx/GetEntryCommentsRss?guid=7bb72a12-e3e3-45de-92e2-7f6f5537879c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/uCommerce_BC98/CustomControlInUCommerce2.png">
            <img style="background-image: none; border-right-width: 0px; margin: 0px 0px 20px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="CustomControlInUCommerce2" border="0" alt="CustomControlInUCommerce2" align="right" src="http://blogs.thesitedoctor.co.uk/tim/images/uCommerce_BC98/CustomControlInUCommerce2_thumb.png" width="236" height="236" />
          </a>uCommerce
is a great e-commerce engine for Umbraco and high on our list of options when evaluating
new e-commerce projects at <a title="Herefordshire based web design and development" href="http://www.thesitedoctor.co.uk/" target="_blank">The
Site Doctor</a>. 
</p>
        <p>
One thing that has always bugged me however is the lack of extensibility on the admin
backend. This is something I've discussed with Søren in the past and I believe is
on the cards to be resolved in the upcoming v3 release but we wanted to see if there
was a way we could get it working in the current release. Thanks to <a href="http://twitter.com/danstuken" target="_blank">Dan's</a> digging
we've found it is (ish).
</p>
        <p>
          <a href="#cblddlundownload" target="_blank">Skip to the downloads</a>.
</p>
        <h2>A Little Background
</h2>
        <p>
Before I dive into the code and overview how you should get it all wired up, I think
it's worth understanding how uCommerce is structured out of the box:
</p>
        <ul>
          <li>
Each uCommerce section has it's own folder under the "umbraco/uCommerce" folder so
if you want to extend the functionality for the "Product Catalog" area then you will
need to look in the "Catalog" folder. 
</li>
          <li>
The ASPX files are the main containers (e.g. EditProduct.aspx) and don't generally
include any logic as they load up the various UserControls (the ASCX files) as tabs. 
</li>
          <li>
Adding custom tabs can be done through the uCommerce_AdminTab table but that's outside
the scope of this post but <a href="http://blog.lasseeskildsen.net/post/Extending-uCommerce-Admin.aspx" target="_blank">Lasse
has a good introduction on his blog</a>. 
</li>
        </ul>
        <p>
As we plan to alter the product details edit functionality, we'll need to make a few
changes to EditProductBaseProperties.ascx. It's worth taking a quick look around the
file if you've not before as we've re-ordered the boxes, added classes and hidden
the SKU field before, all of which is often useful. You'll notice at the end of the
file there's  a repeater "ProductPropertyRepeater" -this is where uCommerce outputs
the various custom properties you've setup.
</p>
        <h3>Why's it useful?
</h3>
        <p>
Have you ever felt limited by the options of Text/Boolean/Enum/Image/Number and RichText
and wished you could implement your own cool control like an image cropper or checkbox
list? What about driving that control with data from Umbraco or another data source?
If you have, this is the blog post for you as it handles all those scenarios.
</p>
        <h2>Getting Started
</h2>
        <p>
If you don't want to know how to do this yourself you can <a href="#cblddlundownload" target="_blank">click
here to skip to the downloads</a> and get started straight away.
</p>
        <p>
          <strong>Caution:</strong> If you want a CheckBoxList or your own custom control, you
need to be running v2.6 as it adds IWebControlAdapter. As of v2.6 I'm not convinced
IWebControlAdapter is fully implemented as it allows you to retrieve the value from
the control but we will need to override the UserControl which outputs the control
which feels hacky.
</p>
        <h3>Create a custom control
</h3>
        <p>
Unless you want a fairly standard control (TextBox, CheckBox, DropDownList or ContentPickerUCommerce)
you'll need to create a control which uses the IWebControlAdapter interface. This
will mean uCommerce is able to get the value from it. You will need to implement two
methods:
</p>
        <ul>
          <li>
            <strong>Adapts(Control)</strong> - allows you to specify whether it is a control you
will be managing. 
</li>
          <li>
            <strong>GetValue(Object)</strong> - allows you to specify what value the control contains
In it's entirety it could be pretty simple: 
</li>
        </ul>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:423f91a7-8429-4e15-82ad-5954d4e06e6f" class="wlWriterEditableSmartContent">
          <pre class="brush: c#;">namespace TheSiteDoctor.Web.uCommerce.Admin.UI
{
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Linq;

    using UCommerce.Presentation.Web.Controls;

    public class UCommerceUmbracoDrivenCheckboxList : CheckBoxList, IWebControlAdapter
    {
        public bool Adapts(Control control)
        {
            return control is UCommerceUmbracoDrivenCheckboxList;
        }

        public object GetValue(object control)
        {
            var li = (UCommerceUmbracoDrivenCheckboxList)control;
            var values = (from ListItem listitem in li.Items where listitem.Selected select listitem.Value).ToList();
            return string.Join(",", values);
        }
    }
}</pre>
        </div>
        <h3>Create your own DataTypeControlFactory
</h3>
        <p>
uCommerce uses DataTypeControlFactory to determine what control to render in the editor
so you'll need to override the default implementation because it doesn't look for
IWebControlAdapters at the moment. 
</p>
        <p>
This is simple enough, it needs to accept a Page (the page you'll be adding the control
to) and the work out what control it should output e.g.:
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:35c1fd1f-d634-468d-826b-a94d6c5d0fef" class="wlWriterEditableSmartContent">
          <pre class="brush: c#;">public class CustomDataTypeControlFactory : DataTypeControlFactory
{
    Page _page;

    public CustomDataTypeControlFactory(Page page)
        : base(page)
    {
        _page = page;
    }

    public Control CreateCustomControl(IProductProperty productProperty)
    {
        if (productProperty == null)
            throw new ArgumentNullException("productProperty");

        return CreateCustomControl(productProperty.ProductDefinitionField, productProperty.Value);
    }

    private Control CreateCustomControl(ProductDefinitionField productDefinitionField, string value)
    {
        var fieldType = productDefinitionField.DataType.TypeName;

        if (fieldType.StartsWith("Something"))
            return base.CreateControl(productDefinitionField, value);

        // Some logic to work out whether you should be creating the control
        return customControl;
    }
}
</pre>
        </div>
        <h3>Add a custom ProductPropertyEditor.ascx
</h3>
        <p>
Now you'll need to create your own ProductPropertyEditor.ascx which calls your new
DataTypeControlFactory:
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:be50a395-7734-4139-9cbf-d041c67f33a7" class="wlWriterEditableSmartContent">
          <pre class="brush: c#;">public partial class CustomUcommerceProductPropertyEditor : ProductPropertyEditor
{
    protected new void Page_Load(object sender, EventArgs e)
    {
        InitializeControl();
    }

    public override void DataBind()
    {
        base.DataBind();
    }

    private void InitializeControl()
    {
        Controls.Clear();
        Control child = CreateControlToRender();
        Controls.Add(child);
    }

    private Control CreateControlToRender()
    {
        if (ProductProperty == null)
        {
            throw new InvalidOperationException("Cannot create control, ProductProperty not set.");
        }

        var factory = new CustomDataTypeControlFactory(Page);
        return factory.CreateCustomControl(ProductProperty);
    }
}</pre>
        </div>
        <p>
You may notice that we're clearing the controls in the InitializeControl which is
called from Page_Load whereas uCommerce makes the same call from DataBind(); this
is intentional. I've not yet figured out why but if you don't do it from Page_Load,
uCommerce still outputs a TextBox.
</p>
        <h3>Wire it all up
</h3>
        <p>
To get this all outputting, you now need to replace the call to ProductPropertyEditor
in EditProductBaseProperties.ascx with a reference to your own ASCX file, you can
do this by updating this line:
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:57577c2e-35a6-4076-bc7f-e7b1a43541df" class="wlWriterEditableSmartContent">
          <pre class="brush: html;">&lt;%@ Register Src="~/Umbraco/UCommerce/Controls/ProductPropertyEditor.ascx" TagPrefix="commerce" TagName="ProductPropertyEditor" %&gt;</pre>
        </div>
        <h3>To:
</h3>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:479f04f3-4535-4b38-be8a-4ab5c60dcd16" class="wlWriterEditableSmartContent">
          <pre class="brush: html;">&lt;%@ Register Src="~/Umbraco/UCommerce/Controls/[YourFileNameHere].ascx" TagPrefix="commerce" TagName="ProductPropertyEditor" %&gt;</pre>
        </div>
        <h2>Edit your Presenters.config
</h2>
        <p>
At this point if you were to load up your uCommerce backend you'd find that it outputs
as intended but when you saved the file you'd either get an error or the value doesn't
save. The reason for this is although you've replaced the display aspect of the editor,
uCommerce is still looking at it's old "GetValue" implementation instead of your new
control.
</p>
        <p>
Open /umbraco/ucommerce/configuration/presenters.config and add a reference to your
control which implements the IWebControlAdapters interface:
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:3e8b5ed2-65d9-4bc3-a7f5-6cb6da3596db" class="wlWriterEditableSmartContent">
          <pre class="brush: xml;">&lt;component id="UCommerceUmbracoDrivenCheckboxList"
			service="UCommerce.Presentation.Web.Controls.IWebControlAdapter, UCommerce.Presentation"
			type="Your.Custom.uCommerce.Namespace.ControlName, Your.Custom.uCommerce.AssemblyName" 
			lifestyle="PerWebRequest"/&gt;
</pre>
        </div>
        <p>
That's it, you're done, you can now add your own controls to the backend of uCommerce.
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/uCommerce_BC98/CustomControlInUCommerce.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="CustomControlInUCommerce" border="0" alt="CustomControlInUCommerce" src="http://blogs.thesitedoctor.co.uk/tim/images/uCommerce_BC98/CustomControlInUCommerce_thumb.png" width="356" height="397" />
          </a>
        </p>
        <h2 id="cblddlundownload">Download
</h2>
        <p>
To make life easier I've packaged the files up into an Umbraco package and have also
added the source:
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/files/TSD-Custom-UCommerce-Controls-Source-v1.0.zip" target="_blank">Download
the source code with references (C#) - 800KB</a>
        </p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/files/TSD-Custom-UCommerce-Controls-Package-v1.0.zip" target="_blank">Download
the Umbraco Package - 12KB</a>
        </p>
        <h2>Instructions on using the package
</h2>
        <p>
If you download the source code you may have noticed we're doing some funky things
with the DataTypeName. The idea behind the control is that it allows us to output
a DropDownList or CheckBoxList containing values based on a Document Type and start
node purely from the name of the DataType.
</p>
        <p>
I can go into more detail about how we're doing this if it's of interest, just leave
me a comment below but to start using it straight away you will need to use the following
naming convention for your DataType's name:
</p>
        <ol>
          <li>
TSD_: This is the prefix we use to identify whether it's a control we should be handling 
</li>
          <li>
Control Type: Currently this can either be "ddl" for a DropDownList or "chkl" for
a CheckBoxList 
</li>
          <li>
Start Node Id: This should be the id of the Umbraco parent node. You can cheat and
use the root node but it's best to use the parent 
</li>
          <li>
Document Type: This is the Document Type's alias to use 
</li>
        </ol>
        <p>
          <strong>Example:</strong> if you wanted a list of checkboxes for ShapeType (as above)
then your name would be: TSD_chkl_1234_ShapeType and a DropDownList would be: TSD_ddl_1234_ShapeType
</p>
        <h2>What next?
</h2>
        <p>
This is something we're using more and more in uCommerce these days as it allows us
to use the power of Umbraco to power uCommerce which is allowing us to do some really
interesting things. Although we'll only be developing it as we need it at the moment
we do have plans to add support for:
</p>
        <ul>
          <li>
Radio Button Lists 
</li>
          <li>
Image Cropper 
</li>
          <li>
Adding nesting to the list of items (to offer better support for hierarchical data) 
</li>
          <li>
Powering it by the members and media sections 
</li>
        </ul>
        <img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=7bb72a12-e3e3-45de-92e2-7f6f5537879c" />
      </body>
      <title>Umbraco powered CheckBoxList or DropdownList nodes in uCommerce admin area</title>
      <guid isPermaLink="false">http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,7bb72a12-e3e3-45de-92e2-7f6f5537879c.aspx</guid>
      <link>http://blogs.thesitedoctor.co.uk/tim/2012/05/12/Umbraco+Powered+CheckBoxList+Or+DropdownList+Nodes+In+UCommerce+Admin+Area.aspx</link>
      <pubDate>Sat, 12 May 2012 13:53:24 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/uCommerce_BC98/CustomControlInUCommerce2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 20px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="CustomControlInUCommerce2" border="0" alt="CustomControlInUCommerce2" align="right" src="http://blogs.thesitedoctor.co.uk/tim/images/uCommerce_BC98/CustomControlInUCommerce2_thumb.png" width="236" height="236" /&gt;&lt;/a&gt;uCommerce
is a great e-commerce engine for Umbraco and high on our list of options when evaluating
new e-commerce projects at &lt;a title="Herefordshire based web design and development" href="http://www.thesitedoctor.co.uk/" target="_blank"&gt;The
Site Doctor&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
One thing that has always bugged me however is the lack of extensibility on the admin
backend. This is something I've discussed with Søren in the past and I believe is
on the cards to be resolved in the upcoming v3 release but we wanted to see if there
was a way we could get it working in the current release. Thanks to &lt;a href="http://twitter.com/danstuken" target="_blank"&gt;Dan's&lt;/a&gt; digging
we've found it is (ish).
&lt;/p&gt;
&lt;p&gt;
&lt;a href="#cblddlundownload" target="_blank"&gt;Skip to the downloads&lt;/a&gt;.
&lt;/p&gt;
&lt;h2&gt;A Little Background
&lt;/h2&gt;
&lt;p&gt;
Before I dive into the code and overview how you should get it all wired up, I think
it's worth understanding how uCommerce is structured out of the box:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Each uCommerce section has it's own folder under the "umbraco/uCommerce" folder so
if you want to extend the functionality for the "Product Catalog" area then you will
need to look in the "Catalog" folder. 
&lt;/li&gt;
&lt;li&gt;
The ASPX files are the main containers (e.g. EditProduct.aspx) and don't generally
include any logic as they load up the various UserControls (the ASCX files) as tabs. 
&lt;/li&gt;
&lt;li&gt;
Adding custom tabs can be done through the uCommerce_AdminTab table but that's outside
the scope of this post but &lt;a href="http://blog.lasseeskildsen.net/post/Extending-uCommerce-Admin.aspx" target="_blank"&gt;Lasse
has a good introduction on his blog&lt;/a&gt;. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As we plan to alter the product details edit functionality, we'll need to make a few
changes to EditProductBaseProperties.ascx. It's worth taking a quick look around the
file if you've not before as we've re-ordered the boxes, added classes and hidden
the SKU field before, all of which is often useful. You'll notice at the end of the
file there's&amp;#160; a repeater "ProductPropertyRepeater" -this is where uCommerce outputs
the various custom properties you've setup.
&lt;/p&gt;
&lt;h3&gt;Why's it useful?
&lt;/h3&gt;
&lt;p&gt;
Have you ever felt limited by the options of Text/Boolean/Enum/Image/Number and RichText
and wished you could implement your own cool control like an image cropper or checkbox
list? What about driving that control with data from Umbraco or another data source?
If you have, this is the blog post for you as it handles all those scenarios.
&lt;/p&gt;
&lt;h2&gt;Getting Started
&lt;/h2&gt;
&lt;p&gt;
If you don't want to know how to do this yourself you can &lt;a href="#cblddlundownload" target="_blank"&gt;click
here to skip to the downloads&lt;/a&gt; and get started straight away.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Caution:&lt;/strong&gt; If you want a CheckBoxList or your own custom control, you
need to be running v2.6 as it adds IWebControlAdapter. As of v2.6 I'm not convinced
IWebControlAdapter is fully implemented as it allows you to retrieve the value from
the control but we will need to override the UserControl which outputs the control
which feels hacky.
&lt;/p&gt;
&lt;h3&gt;Create a custom control
&lt;/h3&gt;
&lt;p&gt;
Unless you want a fairly standard control (TextBox, CheckBox, DropDownList or ContentPickerUCommerce)
you'll need to create a control which uses the IWebControlAdapter interface. This
will mean uCommerce is able to get the value from it. You will need to implement two
methods:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Adapts(Control)&lt;/strong&gt; - allows you to specify whether it is a control you
will be managing. 
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GetValue(Object)&lt;/strong&gt; - allows you to specify what value the control contains
In it's entirety it could be pretty simple: 
&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:423f91a7-8429-4e15-82ad-5954d4e06e6f" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;namespace TheSiteDoctor.Web.uCommerce.Admin.UI
{
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Linq;

    using UCommerce.Presentation.Web.Controls;

    public class UCommerceUmbracoDrivenCheckboxList : CheckBoxList, IWebControlAdapter
    {
        public bool Adapts(Control control)
        {
            return control is UCommerceUmbracoDrivenCheckboxList;
        }

        public object GetValue(object control)
        {
            var li = (UCommerceUmbracoDrivenCheckboxList)control;
            var values = (from ListItem listitem in li.Items where listitem.Selected select listitem.Value).ToList();
            return string.Join(",", values);
        }
    }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Create your own DataTypeControlFactory
&lt;/h3&gt;
&lt;p&gt;
uCommerce uses DataTypeControlFactory to determine what control to render in the editor
so you'll need to override the default implementation because it doesn't look for
IWebControlAdapters at the moment. 
&lt;/p&gt;
&lt;p&gt;
This is simple enough, it needs to accept a Page (the page you'll be adding the control
to) and the work out what control it should output e.g.:
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:35c1fd1f-d634-468d-826b-a94d6c5d0fef" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public class CustomDataTypeControlFactory : DataTypeControlFactory
{
    Page _page;

    public CustomDataTypeControlFactory(Page page)
        : base(page)
    {
        _page = page;
    }

    public Control CreateCustomControl(IProductProperty productProperty)
    {
        if (productProperty == null)
            throw new ArgumentNullException("productProperty");

        return CreateCustomControl(productProperty.ProductDefinitionField, productProperty.Value);
    }

    private Control CreateCustomControl(ProductDefinitionField productDefinitionField, string value)
    {
        var fieldType = productDefinitionField.DataType.TypeName;

        if (fieldType.StartsWith("Something"))
            return base.CreateControl(productDefinitionField, value);

        // Some logic to work out whether you should be creating the control
        return customControl;
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Add a custom ProductPropertyEditor.ascx
&lt;/h3&gt;
&lt;p&gt;
Now you'll need to create your own ProductPropertyEditor.ascx which calls your new
DataTypeControlFactory:
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:be50a395-7734-4139-9cbf-d041c67f33a7" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public partial class CustomUcommerceProductPropertyEditor : ProductPropertyEditor
{
    protected new void Page_Load(object sender, EventArgs e)
    {
        InitializeControl();
    }

    public override void DataBind()
    {
        base.DataBind();
    }

    private void InitializeControl()
    {
        Controls.Clear();
        Control child = CreateControlToRender();
        Controls.Add(child);
    }

    private Control CreateControlToRender()
    {
        if (ProductProperty == null)
        {
            throw new InvalidOperationException("Cannot create control, ProductProperty not set.");
        }

        var factory = new CustomDataTypeControlFactory(Page);
        return factory.CreateCustomControl(ProductProperty);
    }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
You may notice that we're clearing the controls in the InitializeControl which is
called from Page_Load whereas uCommerce makes the same call from DataBind(); this
is intentional. I've not yet figured out why but if you don't do it from Page_Load,
uCommerce still outputs a TextBox.
&lt;/p&gt;
&lt;h3&gt;Wire it all up
&lt;/h3&gt;
&lt;p&gt;
To get this all outputting, you now need to replace the call to ProductPropertyEditor
in EditProductBaseProperties.ascx with a reference to your own ASCX file, you can
do this by updating this line:
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:57577c2e-35a6-4076-bc7f-e7b1a43541df" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: html;"&gt;&amp;lt;%@ Register Src="~/Umbraco/UCommerce/Controls/ProductPropertyEditor.ascx" TagPrefix="commerce" TagName="ProductPropertyEditor" %&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;To:
&lt;/h3&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:479f04f3-4535-4b38-be8a-4ab5c60dcd16" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: html;"&gt;&amp;lt;%@ Register Src="~/Umbraco/UCommerce/Controls/[YourFileNameHere].ascx" TagPrefix="commerce" TagName="ProductPropertyEditor" %&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;Edit your Presenters.config
&lt;/h2&gt;
&lt;p&gt;
At this point if you were to load up your uCommerce backend you'd find that it outputs
as intended but when you saved the file you'd either get an error or the value doesn't
save. The reason for this is although you've replaced the display aspect of the editor,
uCommerce is still looking at it's old "GetValue" implementation instead of your new
control.
&lt;/p&gt;
&lt;p&gt;
Open /umbraco/ucommerce/configuration/presenters.config and add a reference to your
control which implements the IWebControlAdapters interface:
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:3e8b5ed2-65d9-4bc3-a7f5-6cb6da3596db" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;component id="UCommerceUmbracoDrivenCheckboxList"
			service="UCommerce.Presentation.Web.Controls.IWebControlAdapter, UCommerce.Presentation"
			type="Your.Custom.uCommerce.Namespace.ControlName, Your.Custom.uCommerce.AssemblyName" 
			lifestyle="PerWebRequest"/&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
That's it, you're done, you can now add your own controls to the backend of uCommerce.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/uCommerce_BC98/CustomControlInUCommerce.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="CustomControlInUCommerce" border="0" alt="CustomControlInUCommerce" src="http://blogs.thesitedoctor.co.uk/tim/images/uCommerce_BC98/CustomControlInUCommerce_thumb.png" width="356" height="397" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h2 id="cblddlundownload"&gt;Download
&lt;/h2&gt;
&lt;p&gt;
To make life easier I've packaged the files up into an Umbraco package and have also
added the source:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/files/TSD-Custom-UCommerce-Controls-Source-v1.0.zip" target="_blank"&gt;Download
the source code with references (C#) - 800KB&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/files/TSD-Custom-UCommerce-Controls-Package-v1.0.zip" target="_blank"&gt;Download
the Umbraco Package - 12KB&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;Instructions on using the package
&lt;/h2&gt;
&lt;p&gt;
If you download the source code you may have noticed we're doing some funky things
with the DataTypeName. The idea behind the control is that it allows us to output
a DropDownList or CheckBoxList containing values based on a Document Type and start
node purely from the name of the DataType.
&lt;/p&gt;
&lt;p&gt;
I can go into more detail about how we're doing this if it's of interest, just leave
me a comment below but to start using it straight away you will need to use the following
naming convention for your DataType's name:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
TSD_: This is the prefix we use to identify whether it's a control we should be handling 
&lt;/li&gt;
&lt;li&gt;
Control Type: Currently this can either be "ddl" for a DropDownList or "chkl" for
a CheckBoxList 
&lt;/li&gt;
&lt;li&gt;
Start Node Id: This should be the id of the Umbraco parent node. You can cheat and
use the root node but it's best to use the parent 
&lt;/li&gt;
&lt;li&gt;
Document Type: This is the Document Type's alias to use 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;strong&gt;Example:&lt;/strong&gt; if you wanted a list of checkboxes for ShapeType (as above)
then your name would be: TSD_chkl_1234_ShapeType and a DropDownList would be: TSD_ddl_1234_ShapeType
&lt;/p&gt;
&lt;h2&gt;What next?
&lt;/h2&gt;
&lt;p&gt;
This is something we're using more and more in uCommerce these days as it allows us
to use the power of Umbraco to power uCommerce which is allowing us to do some really
interesting things. Although we'll only be developing it as we need it at the moment
we do have plans to add support for:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Radio Button Lists 
&lt;/li&gt;
&lt;li&gt;
Image Cropper 
&lt;/li&gt;
&lt;li&gt;
Adding nesting to the list of items (to offer better support for hierarchical data) 
&lt;/li&gt;
&lt;li&gt;
Powering it by the members and media sections 
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=7bb72a12-e3e3-45de-92e2-7f6f5537879c" /&gt;</description>
      <comments>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,7bb72a12-e3e3-45de-92e2-7f6f5537879c.aspx</comments>
      <category>ASP.Net</category>
      <category>C#</category>
      <category>Development</category>
      <category>eCommerce</category>
      <category>Hacking</category>
      <category>The Site Doctor</category>
      <category>uCommerce</category>
      <category>Umbraco</category>
      <category>Web Development</category>
    </item>
    <item>
      <trackback:ping>http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=db4afc01-468c-4e5b-90c3-f20e1230ab60</trackback:ping>
      <pingback:server>http://blogs.thesitedoctor.co.uk/tim/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,db4afc01-468c-4e5b-90c3-f20e1230ab60.aspx</pingback:target>
      <dc:creator>Tim</dc:creator>
      <wfw:comment>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,db4afc01-468c-4e5b-90c3-f20e1230ab60.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.thesitedoctor.co.uk/tim/SyndicationService.asmx/GetEntryCommentsRss?guid=db4afc01-468c-4e5b-90c3-f20e1230ab60</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="sublime-text-2" border="0" alt="sublime-text-2" align="right" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/sublime-text-2.jpg" width="260" height="260" />This
is one of those really simple little gems that helps productivity ten-fold. Firstly,
regardless of whether you're running a PC, Mac or Linux, if you've not already come
across <a href="http://www.sublimetext.com/2" target="_blank">Sublime Text 2</a> you
should <a href="http://www.sublimetext.com/2" target="_blank">go download it right
now</a>.
</p>
        <p>
There are a ton of amazing features in Sublime (enough to warrant an <a href="http://www.nxtgenug.net/ViewEvent.aspx?EventID=463" target="_blank">talk
by Dan Kendall</a> no less), some of them are available in Visual Studio but none
are quite as rich. Things like the <a href="http://www.screencast-o-matic.com/watch/cXj0Fr3TV" target="_blank">multi-selection/multi-cursor</a> feature
are just awesome for quickly making the same changes in multiple places, not to mention
the "select this word throughout the document" shortcut which has saved me hours already.
</p>
        <h2>So what's my quick tip?
</h2>
        <p>
Rather than copying/pasting the path in the open dialog each time you want to edit
the file, Dan pointed out to me the other day that you can easily wire it up as an
external tool and then add a shortcut so you can open the current file in a flash.
</p>
        <p>
Here's a step-by-step guide:
</p>
        <p>
          <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="7B3A4FE1-C8AB-43AC-96D3-353B3A6753AE" border="0" alt="7B3A4FE1-C8AB-43AC-96D3-353B3A6753AE" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/7B3A4FE1-C8AB-43AC-96D3-353B3A6753AE.png" width="484" height="765" />
        </p>
        <p>
          <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DCE35C2C-D18D-4498-BA4A-B76B1F8299E9" border="0" alt="DCE35C2C-D18D-4498-BA4A-B76B1F8299E9" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/DCE35C2C-D18D-4498-BA4A-B76B1F8299E9.png" width="769" height="629" />
        </p>
        <h2>Optional Additional Enhancement
</h2>
        <p>
You can wire up a keyboard shortcut for extra speed, again under the "Tools" menu,
go to "Options" and then "Keyboard" (under "Environment"):
</p>
        <p>
          <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ED2789BC-6B50-4AFA-A477-3C27AEDD576D" border="0" alt="ED2789BC-6B50-4AFA-A477-3C27AEDD576D" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/ED2789BC-6B50-4AFA-A477-3C27AEDD576D.png" width="1286" height="599" />
        </p>
        <p>
          <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ED2789BC-6B50-4AFA-A477-3C27AEDD576D-sm" border="0" alt="ED2789BC-6B50-4AFA-A477-3C27AEDD576D-sm" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/ED2789BC-6B50-4AFA-A477-3C27AEDD576D-sm.png" width="820" height="386" />
        </p>
        <p>
          <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2DEAB140-EA74-4FA9-BD80-21970F22CAF5" border="0" alt="2DEAB140-EA74-4FA9-BD80-21970F22CAF5" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/2DEAB140-EA74-4FA9-BD80-21970F22CAF5.png" width="709" height="271" />
        </p>
        <p>
Thanks Dan for the heads up on this one.
</p>
        <img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=db4afc01-468c-4e5b-90c3-f20e1230ab60" />
      </body>
      <title>Quick pro tip - Open File in Sublime from Visual Studio</title>
      <guid isPermaLink="false">http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,db4afc01-468c-4e5b-90c3-f20e1230ab60.aspx</guid>
      <link>http://blogs.thesitedoctor.co.uk/tim/2012/04/17/Quick+Pro+Tip+Open+File+In+Sublime+From+Visual+Studio.aspx</link>
      <pubDate>Tue, 17 Apr 2012 15:58:45 GMT</pubDate>
      <description>&lt;p&gt;
&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="sublime-text-2" border="0" alt="sublime-text-2" align="right" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/sublime-text-2.jpg" width="260" height="260" /&gt;This
is one of those really simple little gems that helps productivity ten-fold. Firstly,
regardless of whether you're running a PC, Mac or Linux, if you've not already come
across &lt;a href="http://www.sublimetext.com/2" target="_blank"&gt;Sublime Text 2&lt;/a&gt; you
should &lt;a href="http://www.sublimetext.com/2" target="_blank"&gt;go download it right
now&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
There are a ton of amazing features in Sublime (enough to warrant an &lt;a href="http://www.nxtgenug.net/ViewEvent.aspx?EventID=463" target="_blank"&gt;talk
by Dan Kendall&lt;/a&gt; no less), some of them are available in Visual Studio but none
are quite as rich. Things like the &lt;a href="http://www.screencast-o-matic.com/watch/cXj0Fr3TV" target="_blank"&gt;multi-selection/multi-cursor&lt;/a&gt; feature
are just awesome for quickly making the same changes in multiple places, not to mention
the "select this word throughout the document" shortcut which has saved me hours already.
&lt;/p&gt;
&lt;h2&gt;So what's my quick tip?
&lt;/h2&gt;
&lt;p&gt;
Rather than copying/pasting the path in the open dialog each time you want to edit
the file, Dan pointed out to me the other day that you can easily wire it up as an
external tool and then add a shortcut so you can open the current file in a flash.
&lt;/p&gt;
&lt;p&gt;
Here's a step-by-step guide:
&lt;/p&gt;
&lt;p&gt;
&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="7B3A4FE1-C8AB-43AC-96D3-353B3A6753AE" border="0" alt="7B3A4FE1-C8AB-43AC-96D3-353B3A6753AE" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/7B3A4FE1-C8AB-43AC-96D3-353B3A6753AE.png" width="484" height="765" /&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DCE35C2C-D18D-4498-BA4A-B76B1F8299E9" border="0" alt="DCE35C2C-D18D-4498-BA4A-B76B1F8299E9" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/DCE35C2C-D18D-4498-BA4A-B76B1F8299E9.png" width="769" height="629" /&gt;
&lt;/p&gt;
&lt;h2&gt;Optional Additional Enhancement
&lt;/h2&gt;
&lt;p&gt;
You can wire up a keyboard shortcut for extra speed, again under the "Tools" menu,
go to "Options" and then "Keyboard" (under "Environment"):
&lt;/p&gt;
&lt;p&gt;
&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ED2789BC-6B50-4AFA-A477-3C27AEDD576D" border="0" alt="ED2789BC-6B50-4AFA-A477-3C27AEDD576D" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/ED2789BC-6B50-4AFA-A477-3C27AEDD576D.png" width="1286" height="599" /&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ED2789BC-6B50-4AFA-A477-3C27AEDD576D-sm" border="0" alt="ED2789BC-6B50-4AFA-A477-3C27AEDD576D-sm" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/ED2789BC-6B50-4AFA-A477-3C27AEDD576D-sm.png" width="820" height="386" /&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2DEAB140-EA74-4FA9-BD80-21970F22CAF5" border="0" alt="2DEAB140-EA74-4FA9-BD80-21970F22CAF5" src="http://blogs.thesitedoctor.co.uk/tim/images/Quick-pro-tip--_8F3D/2DEAB140-EA74-4FA9-BD80-21970F22CAF5.png" width="709" height="271" /&gt;
&lt;/p&gt;
&lt;p&gt;
Thanks Dan for the heads up on this one.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=db4afc01-468c-4e5b-90c3-f20e1230ab60" /&gt;</description>
      <comments>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,db4afc01-468c-4e5b-90c3-f20e1230ab60.aspx</comments>
      <category>Development</category>
      <category>Productivity</category>
      <category>Software/Visual Studio</category>
      <category>Sublime Text 2</category>
      <category>The Site Doctor</category>
    </item>
    <item>
      <trackback:ping>http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=e9b3bf17-0f36-46b5-81c3-1d93f580ce5f</trackback:ping>
      <pingback:server>http://blogs.thesitedoctor.co.uk/tim/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,e9b3bf17-0f36-46b5-81c3-1d93f580ce5f.aspx</pingback:target>
      <dc:creator>Tim</dc:creator>
      <wfw:comment>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,e9b3bf17-0f36-46b5-81c3-1d93f580ce5f.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.thesitedoctor.co.uk/tim/SyndicationService.asmx/GetEntryCommentsRss?guid=e9b3bf17-0f36-46b5-81c3-1d93f580ce5f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've had a couple of people ask how they can create customer purchase cohorts from
their <a title="e-commerce package for Umbraco" href="http://www.ucommerce.dk" target="_blank">uCommerce</a> data
since my last post so here's a quick script.
</p>
        <p>
Depending on how you've setup your <a title="e-commerce package for Umbraco" href="http://www.ucommerce.dk" target="_blank">uCommerce</a> store,
the customer ids might be different so instead of using customer id. I would use the
email address of the customer personally as the identifier as this means you'll be
able to analyse those customers who have chosen to check out anonymously <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.thesitedoctor.co.uk/tim/images/How-to-generate-customer-purchase-cohort_C59E/wlEmoticon-smile.png" /></p>
        <p>
Here's the SQL to output the data in a format suitable for <a href="http://www.quickcohort.com">www.quickcohort.com</a>.
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:2810d194-e672-4099-a7f1-4128a30c88f4" class="wlWriterEditableSmartContent">
          <pre class="brush: sql;">WITH Actions (FirstAction, LastAction, UniqueId)
AS (
	SELECT min(dateadd(dd, datediff(dd, 0, o.CompletedDate), 0))
		 , max(dateadd(dd, datediff(dd, 0, o.CompletedDate), 0))
		 , ltrim(rtrim(LOWER(cc.EmailAddress)))
	FROM [uCommerce_PurchaseOrder] o LEFT JOIN uCommerce_Customer cc ON cc.CustomerId = o.CustomerId
	GROUP BY ltrim(rtrim(LOWER(cc.EmailAddress)))
)
SELECT a.[FirstAction]
	 , a.[LastAction]
	 , count(a.[UniqueId]) AS [CountOfCustomers]
FROM
	Actions a
GROUP BY a.[FirstAction]
	   , a.[LastAction]
HAVING 
	min(dateadd(dd, datediff(dd, 0, a.[FirstAction]), 0)) IS NOT NULL
ORDER BY a.[FirstAction]
	   , a.[LastAction]

GO</pre>
        </div>
        <p>
 
</p>
        <p>
Not using <a title="e-commerce package for Umbraco" href="http://www.ucommerce.dk" target="_blank">uCommerce</a> as
your e-commerce provider? Let me know and I'll knock up a script for you.
</p>
        <img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=e9b3bf17-0f36-46b5-81c3-1d93f580ce5f" />
      </body>
      <title>How to generate customer purchase cohorts from uCommerce data</title>
      <guid isPermaLink="false">http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,e9b3bf17-0f36-46b5-81c3-1d93f580ce5f.aspx</guid>
      <link>http://blogs.thesitedoctor.co.uk/tim/2012/04/06/How+To+Generate+Customer+Purchase+Cohorts+From+UCommerce+Data.aspx</link>
      <pubDate>Fri, 06 Apr 2012 09:02:29 GMT</pubDate>
      <description>&lt;p&gt;
I've had a couple of people ask how they can create customer purchase cohorts from
their &lt;a title="e-commerce package for Umbraco" href="http://www.ucommerce.dk" target="_blank"&gt;uCommerce&lt;/a&gt; data
since my last post so here's a quick script.
&lt;/p&gt;
&lt;p&gt;
Depending on how you've setup your &lt;a title="e-commerce package for Umbraco" href="http://www.ucommerce.dk" target="_blank"&gt;uCommerce&lt;/a&gt; store,
the customer ids might be different so instead of using customer id. I would use the
email address of the customer personally as the identifier as this means you'll be
able to analyse those customers who have chosen to check out anonymously &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.thesitedoctor.co.uk/tim/images/How-to-generate-customer-purchase-cohort_C59E/wlEmoticon-smile.png" /&gt;
&lt;/p&gt;
&lt;p&gt;
Here's the SQL to output the data in a format suitable for &lt;a href="http://www.quickcohort.com"&gt;www.quickcohort.com&lt;/a&gt;.
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:2810d194-e672-4099-a7f1-4128a30c88f4" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: sql;"&gt;WITH Actions (FirstAction, LastAction, UniqueId)
AS (
	SELECT min(dateadd(dd, datediff(dd, 0, o.CompletedDate), 0))
		 , max(dateadd(dd, datediff(dd, 0, o.CompletedDate), 0))
		 , ltrim(rtrim(LOWER(cc.EmailAddress)))
	FROM [uCommerce_PurchaseOrder] o LEFT JOIN uCommerce_Customer cc ON cc.CustomerId = o.CustomerId
	GROUP BY ltrim(rtrim(LOWER(cc.EmailAddress)))
)
SELECT a.[FirstAction]
	 , a.[LastAction]
	 , count(a.[UniqueId]) AS [CountOfCustomers]
FROM
	Actions a
GROUP BY a.[FirstAction]
	   , a.[LastAction]
HAVING 
	min(dateadd(dd, datediff(dd, 0, a.[FirstAction]), 0)) IS NOT NULL
ORDER BY a.[FirstAction]
	   , a.[LastAction]

GO&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
Not using &lt;a title="e-commerce package for Umbraco" href="http://www.ucommerce.dk" target="_blank"&gt;uCommerce&lt;/a&gt; as
your e-commerce provider? Let me know and I'll knock up a script for you.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=e9b3bf17-0f36-46b5-81c3-1d93f580ce5f" /&gt;</description>
      <comments>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,e9b3bf17-0f36-46b5-81c3-1d93f580ce5f.aspx</comments>
      <category>ASP.Net</category>
      <category>Cohorts</category>
      <category>eCommerce</category>
      <category>uCommerce</category>
    </item>
    <item>
      <trackback:ping>http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=ff5c038d-2b65-4971-8d80-c87f69f6120f</trackback:ping>
      <pingback:server>http://blogs.thesitedoctor.co.uk/tim/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,ff5c038d-2b65-4971-8d80-c87f69f6120f.aspx</pingback:target>
      <dc:creator>Tim</dc:creator>
      <wfw:comment>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,ff5c038d-2b65-4971-8d80-c87f69f6120f.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.thesitedoctor.co.uk/tim/SyndicationService.asmx/GetEntryCommentsRss?guid=ff5c038d-2b65-4971-8d80-c87f69f6120f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://twitter.com/seanronan" target="_blank">Sean Ronan</a> pointed out <a href="https://twitter.com/seanronan/status/171938616212340736" target="_blank">on
twitter</a> that "what" the columns on <a href="http://www.quickcohort.com">www.quickcohort.com</a> are
which is a good point so I thought I would fill in the gaps a little. The data for
a cohort is fairly simple and can be as granular as you decide but the columns needed
are:
</p>
        <ol>
          <li>
First Action Date/Time 
</li>
          <li>
Most Recent Action Date/Time 
</li>
          <li>
Count of customers which have this First/Most Recent Action Date/Times 
</li>
        </ol>
        <p>
Most of the time you can strip the time part from the date/time (especially if you're
looking at the data on a month basis) but the tricky part is getting the count of
users within each date grouping. You can't just select min/max dates as you need the
data grouped by your unique customer identifier. If you're running SQL Server 2005+
then you've got the benefit of Common Table Expressions.
</p>
        <p>
For this example, I've assumed a simple order table structure which contains a Customer
Reference (CustomerId) and an Order Date (OrderDate). You could however use any date
and identifier which groups actions together e.g. ProfileId and LastLoginDate.
</p>
        <h2>SQL 2005 or later
</h2>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:6fbab808-cfd9-4c3b-9890-7667c81cba50" class="wlWriterEditableSmartContent">
          <pre class="brush: sql;">WITH Actions (FirstAction, LastAction, UniqueId)
AS (
	SELECT min(dateadd(dd, datediff(dd, 0, o.[OrderDate]), 0))
		 , max(dateadd(dd, datediff(dd, 0, o.[OrderDate]), 0))
		 , o.[CustomerId]
	FROM Orders o
	GROUP BY CustomerId
)
SELECT a.[FirstAction]
	 , a.[LastAction]
	 , count(a.[UniqueId]) AS [CountOfCustomers]
FROM
	Actions a
GROUP BY a.[FirstAction]
	   , a.[LastAction]
ORDER BY a.[FirstAction]
	   , a.[LastAction]</pre>
        </div>
        <p>
Otherwise, I think you'll need to write something using temporary tables e.g.:
</p>
        <h2>Pre SQL 2005
</h2>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:854959aa-46bf-47ce-b369-ceb4df1f4b2f" class="wlWriterEditableSmartContent">
          <pre class="brush: sql;">CREATE TABLE #Actions(
	FirstAction SMALLDATETIME, 
	LastAction SMALLDATETIME, 
	UniqueId INT
)
INSERT INTO #Actions
(
  FirstAction
 ,LastAction
 ,UniqueId
)
SELECT min(dateadd(dd, datediff(dd, 0, o.[OrderDate]), 0))
	 , max(dateadd(dd, datediff(dd, 0, o.[OrderDate]), 0))
	 , o.[CustomerId]
FROM #Orders o
GROUP BY CustomerId

SELECT a.[FirstAction]
	 , a.[LastAction]
	 , count(a.[UniqueId]) AS [CountOfCustomers]
FROM
	#Actions a
GROUP BY a.[FirstAction]
	   , a.[LastAction]
ORDER BY a.[FirstAction]
	   , a.[LastAction]

DROP TABLE #Actions
</pre>
        </div>
        <p>
This should then generate some data that looks like this:
</p>
        <table>
          <tbody>
            <tr>
              <th>
FirstAction</th>
              <th>
LastAction</th>
              <th>
CountOfCustomers</th>
            </tr>
            <tr>
              <td>
2011-03-01</td>
              <td>
2011-03-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2011-03-01</td>
              <td>
2011-04-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2011-04-01</td>
              <td>
2011-06-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2011-05-01</td>
              <td>
2011-10-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2011-06-01</td>
              <td>
2011-11-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2011-07-01</td>
              <td>
2011-08-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2011-08-01</td>
              <td>
2011-08-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2011-09-01</td>
              <td>
2011-12-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2011-10-01</td>
              <td>
2012-02-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2011-11-01</td>
              <td>
2012-02-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2011-12-01</td>
              <td>
2012-02-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2012-01-01</td>
              <td>
2012-01-01</td>
              <td>
1</td>
            </tr>
            <tr>
              <td>
2012-02-01</td>
              <td>
2012-02-01</td>
              <td>
2</td>
            </tr>
          </tbody>
        </table>
        <p>
Which you should just be able to drop into <a href="http://www.quickcohort.com/" target="_blank">www.quickcohort.com</a>.
I've not written a version for MySQL as I suspect someone far better at MySQL will
be able to pop something together but the pre SQL 2005 script should work.
</p>
        <img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=ff5c038d-2b65-4971-8d80-c87f69f6120f" />
      </body>
      <title>How to generate the data needed for a cohort chart- cohort analysis Part 3</title>
      <guid isPermaLink="false">http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,ff5c038d-2b65-4971-8d80-c87f69f6120f.aspx</guid>
      <link>http://blogs.thesitedoctor.co.uk/tim/2012/02/22/How+To+Generate+The+Data+Needed+For+A+Cohort+Chart+Cohort+Analysis+Part+3.aspx</link>
      <pubDate>Wed, 22 Feb 2012 13:15:53 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://twitter.com/seanronan" target="_blank"&gt;Sean Ronan&lt;/a&gt; pointed out &lt;a href="https://twitter.com/seanronan/status/171938616212340736" target="_blank"&gt;on
twitter&lt;/a&gt; that "what" the columns on &lt;a href="http://www.quickcohort.com"&gt;www.quickcohort.com&lt;/a&gt; are
which is a good point so I thought I would fill in the gaps a little. The data for
a cohort is fairly simple and can be as granular as you decide but the columns needed
are:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
First Action Date/Time 
&lt;/li&gt;
&lt;li&gt;
Most Recent Action Date/Time 
&lt;/li&gt;
&lt;li&gt;
Count of customers which have this First/Most Recent Action Date/Times 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Most of the time you can strip the time part from the date/time (especially if you're
looking at the data on a month basis) but the tricky part is getting the count of
users within each date grouping. You can't just select min/max dates as you need the
data grouped by your unique customer identifier. If you're running SQL Server 2005+
then you've got the benefit of Common Table Expressions.
&lt;/p&gt;
&lt;p&gt;
For this example, I've assumed a simple order table structure which contains a Customer
Reference (CustomerId) and an Order Date (OrderDate). You could however use any date
and identifier which groups actions together e.g. ProfileId and LastLoginDate.
&lt;/p&gt;
&lt;h2&gt;SQL 2005 or later
&lt;/h2&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:6fbab808-cfd9-4c3b-9890-7667c81cba50" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: sql;"&gt;WITH Actions (FirstAction, LastAction, UniqueId)
AS (
	SELECT min(dateadd(dd, datediff(dd, 0, o.[OrderDate]), 0))
		 , max(dateadd(dd, datediff(dd, 0, o.[OrderDate]), 0))
		 , o.[CustomerId]
	FROM Orders o
	GROUP BY CustomerId
)
SELECT a.[FirstAction]
	 , a.[LastAction]
	 , count(a.[UniqueId]) AS [CountOfCustomers]
FROM
	Actions a
GROUP BY a.[FirstAction]
	   , a.[LastAction]
ORDER BY a.[FirstAction]
	   , a.[LastAction]&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Otherwise, I think you'll need to write something using temporary tables e.g.:
&lt;/p&gt;
&lt;h2&gt;Pre SQL 2005
&lt;/h2&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:854959aa-46bf-47ce-b369-ceb4df1f4b2f" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: sql;"&gt;CREATE TABLE #Actions(
	FirstAction SMALLDATETIME, 
	LastAction SMALLDATETIME, 
	UniqueId INT
)
INSERT INTO #Actions
(
  FirstAction
 ,LastAction
 ,UniqueId
)
SELECT min(dateadd(dd, datediff(dd, 0, o.[OrderDate]), 0))
	 , max(dateadd(dd, datediff(dd, 0, o.[OrderDate]), 0))
	 , o.[CustomerId]
FROM #Orders o
GROUP BY CustomerId

SELECT a.[FirstAction]
	 , a.[LastAction]
	 , count(a.[UniqueId]) AS [CountOfCustomers]
FROM
	#Actions a
GROUP BY a.[FirstAction]
	   , a.[LastAction]
ORDER BY a.[FirstAction]
	   , a.[LastAction]

DROP TABLE #Actions
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
This should then generate some data that looks like this:
&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;
FirstAction&lt;/th&gt;
&lt;th&gt;
LastAction&lt;/th&gt;
&lt;th&gt;
CountOfCustomers&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-03-01&lt;/td&gt;
&lt;td&gt;
2011-03-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-03-01&lt;/td&gt;
&lt;td&gt;
2011-04-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-04-01&lt;/td&gt;
&lt;td&gt;
2011-06-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-05-01&lt;/td&gt;
&lt;td&gt;
2011-10-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-06-01&lt;/td&gt;
&lt;td&gt;
2011-11-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-07-01&lt;/td&gt;
&lt;td&gt;
2011-08-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-08-01&lt;/td&gt;
&lt;td&gt;
2011-08-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-09-01&lt;/td&gt;
&lt;td&gt;
2011-12-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-10-01&lt;/td&gt;
&lt;td&gt;
2012-02-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-11-01&lt;/td&gt;
&lt;td&gt;
2012-02-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2011-12-01&lt;/td&gt;
&lt;td&gt;
2012-02-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2012-01-01&lt;/td&gt;
&lt;td&gt;
2012-01-01&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
2012-02-01&lt;/td&gt;
&lt;td&gt;
2012-02-01&lt;/td&gt;
&lt;td&gt;
2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
Which you should just be able to drop into &lt;a href="http://www.quickcohort.com/" target="_blank"&gt;www.quickcohort.com&lt;/a&gt;.
I've not written a version for MySQL as I suspect someone far better at MySQL will
be able to pop something together but the pre SQL 2005 script should work.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=ff5c038d-2b65-4971-8d80-c87f69f6120f" /&gt;</description>
      <comments>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,ff5c038d-2b65-4971-8d80-c87f69f6120f.aspx</comments>
      <category>Analysis</category>
      <category>Business</category>
      <category>Business/Business Start-up Advice</category>
      <category>Business/Client</category>
      <category>Cohorts</category>
      <category>The Site Doctor</category>
    </item>
    <item>
      <trackback:ping>http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=d8d11102-05a1-440f-83fa-f473e98825a2</trackback:ping>
      <pingback:server>http://blogs.thesitedoctor.co.uk/tim/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,d8d11102-05a1-440f-83fa-f473e98825a2.aspx</pingback:target>
      <dc:creator>Tim</dc:creator>
      <wfw:comment>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,d8d11102-05a1-440f-83fa-f473e98825a2.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.thesitedoctor.co.uk/tim/SyndicationService.asmx/GetEntryCommentsRss?guid=d8d11102-05a1-440f-83fa-f473e98825a2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my <a href="http://blogs.thesitedoctor.co.uk/tim/2011/12/12/Startups+Golden+Triangle+Of+Customer+Loyalty+Cohort+Analysis+Part+1.aspx" target="_blank">last
post about Cohort analysis</a> I briefly introduced what a cohort graph is, in this
one I'm going to go into a little more detail about how you can use it. I'm planning
on releasing some code so you can add it to your reporting suite in another post but
if you can't wait until then, I've thrown up a quick online cohort generator at: <a href="http://www.quickcohort.com">www.quickcohort.com</a> -just
dump your data into it and click graph.
</p>
        <h2>What can the cohort chart tell us?
</h2>
        <p>
A cohort chart can give you an idea of customer loyalty -and- an indication of potential
problems in their lifecycle.
</p>
        <p>
The key metric it gives us is <strong>customer loyalty</strong>. This is also one
of the most frequently ignored metrics in every company (mostly because people aren't
clear on how to measure it) yet it's probably one of the most important at the same
time. 
</p>
        <h2>What is Customer Loyalty?
</h2>
        <p>
That depends very much on your business and as a result the graphs will likely look
very different. It's probably easiest to compare what a couple of business types -a
retailer and an online magazine- might consider loyalty.
</p>
        <table border="0" cellspacing="0" cellpadding="2" width="100%">
          <tbody>
            <tr>
              <th valign="top" width="250">
Retailer 
</th>
              <th valign="top" width="250">
Magazine 
</th>
            </tr>
            <tr>
              <td valign="top" width="50%">
                <ul>
                  <li>
Repeat sales 
</li>
                  <li>
Visits to the store 
</li>
                  <li>
Engagement with the store e.g. email opens 
</li>
                </ul>
              </td>
              <td valign="top" width="50%">
                <ul>
                  <li>
Multiple Logins 
</li>
                  <li>
Subscription 
</li>
                  <li>
Number of comments on an article 
</li>
                </ul>
              </td>
            </tr>
          </tbody>
        </table>
        <p>
As you can see, although there may be some cross overs (Visits to the store and Logins
are probably quantified by a similar metric) the "what" depends very much on your
business but the longer the duration between the first and last engagement in all
scenarios above is how you can demonstrate loyalty.
</p>
        <h2>How should I read a cohort chart?
</h2>
        <p>
Unlike most tables which you read left to right (a row at a time), you'll probably
get more value out of a cohort chart from reading it by a column at a time. This will
enable you to spot possible problems in the user's lifecycle. 
</p>
        <p>
Problem points in the user's lifecycle can often be spotted where the colours change
in the same column. The greater the difference between the shades of colour, the bigger
difference is between the two months. In a perfect world, 100% of the customers from
Month 0 will still be using your site in Month 12 but life is rarely like that.
</p>
        <p>
Looking at the chart below of user logins over time, the eager should spot that there
are three months which appear to have issues: Month 3, Month 5 and Month 9:
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/How-to-read-and-interpret-a-Cohort-Trian_FC17/Cohort-Created-To-Signup-Problem.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Cohort-Created-To-Signup-Problem" border="0" alt="Cohort-Created-To-Signup-Problem" src="http://blogs.thesitedoctor.co.uk/tim/images/How-to-read-and-interpret-a-Cohort-Trian_FC17/Cohort-Created-To-Signup-Problem_thumb.png" width="579" height="429" />
          </a>
        </p>
        <p>
If you're not sure on what you're looking for, you're spotting those columns which
have a similarly shaded background which then lightens in the next month (or in the
case of Month 9 is completely unshaded.
</p>
        <h3>What does this mean?
</h3>
        <p>
As the chart above was logins over time, a quick glance over this cohort chart this
would suggest the following to me:
</p>
        <ul>
          <li>
Overall there is a pretty good retention for the users (the percentage of customers
going from month to month are pretty high) 
</li>
          <li>
The majority of users only remain engaged up to month 3, at which point a lot of users
lose interest in the site 
</li>
          <li>
There is a clear drop off in customer retention after month 9 
</li>
          <li>
The eldest customers had the best retention rates (despite the drop off in Month 9,
30-40% of visitors were still coming back until then) 
</li>
        </ul>
        <p>
When reading a cohort chart, you can generally discount the last cell of each cohort
as it's the current month.
</p>
        <h2>What might the cohort chart look like?
</h2>
        <h3>Repeat Sales
</h3>
        <p>
Logically, to be a repeat customer, you have to make at least two purchase from the
retailer so the duration we're interested in (the month) is the period between the
first purchase and most recent purchase.
</p>
        <p>
          <strong>First Date (Month 0):</strong> First Purchase 
<br /><strong>Last Date (Month x):</strong> Most Recent Purchase
</p>
        <p>
Check out the cohort chart below and see what you can interpret.
</p>
        <p>
          <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Cohort-Created-To-First-Purchse[3]" border="0" alt="Cohort-Created-To-First-Purchse[3]" src="http://blogs.thesitedoctor.co.uk/tim/images/How-to-read-and-interpret-a-Cohort-Trian_FC17/Cohort-Created-To-First-Purchse3_thumb.png" width="545" height="431" />
        </p>
        <p>
Remember, Month 0 represents the first purchase -all customers appear in this column.
Looking over the cohort chart, of the 69 customers the retailer had in October 2010,
39% (27 customers) were still around in November 2010 (month 1), 21% (15 customers)
were still around in December 2010 and so on.
</p>
        <p>
None of the 69 customers who made their first purchase in October 2010 are still a
customer 12 months later (although if your customers tend to make a purchase near
the end of the month, the customer who made a purchase in September 2011 may still
make a purchase).
</p>
        <p>
So looking at that chart, 30-40% of customers would make a second purchase 2 months
after their first purchase. Of the older customers (those which first purchased before
March 2011) 10% would make another purchase 5-6 months later.
</p>
        <h3>What else can we gleam? 
</h3>
        <p>
There are a few interesting things with the chart above, another is the sudden drop
off in month 3 for those customers who first purchased in May/Jun 2011, similarly,
the customers who signed up in Mar/Apr 2011 also stumbled in the same month, that
could indicate some form of seasonal trend or change in marketing.
</p>
        <p>
With a little background you will be able to get a much better insight into the meaning
behind some of the numbers. If for instance you had changed your marketing routine
around Jun 2011 this might explain the difference in numbers. It might be that your
business is very seasonal (in which as you'd be better to look at a 24 month chart
rather than 12 month).
</p>
        <p>
Keeping a record of what you were doing around the different months is important,
for instance you might start a pay-per-click campaign. Everyone's happy because you
notice an increase in sales (so an increase in Month 0) but are they a valuable customer
(a repeat purchaser) or a one-off? Cohort chart analysis will quickly highlight this
to you as the increase in Month 0 will be reflected in Month 1.
</p>
        <p>
Although time will tell, it would appear that a lot of customers make another purchase
about 2 months after their first. This could be co-incidence or it might be that you're
selling a product with a small sample accessory (e.g. a free pack of chalk with each
chalkboard) and that sample pack runs out after a couple of months. Alternatively
it could be a fault in the product e.g. you sell hinges and the oil runs out after
a couple of months so they're buying more grease. By adding a little context to the
data you'll likely get even more interesting stats out (we certainly have in the past).
</p>
        <h2>Visits to the store or customer engagement
</h2>
        <p>
Things start to get really interesting when you start comparing two cohort charts
for the same customer base and period against each other. 
</p>
        <p>
          <strong>First Date (Month 0):</strong> First Purchase 
<br /><strong>Last Date (Month x):</strong> Most Recent Login
</p>
        <p>
What's interesting when you compare the two charts is most of the customers who have
made a purchase are still returning to the site (over 30% are still logging in in
Month 11). This would suggest there's not as greater a problem with customer retention
as there is with sales.
</p>
        <p>
This could be because your store sells seasonal products but you keep customers engaged,
it might just be a co-incidence but it should drive investigation.
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/How-to-read-and-interpret-a-Cohort-Trian_FC17/Cohort-Created-To-Last-Purchse3.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Cohort-Created-To-Last-Purchse[3]" border="0" alt="Cohort-Created-To-Last-Purchse[3]" src="http://blogs.thesitedoctor.co.uk/tim/images/How-to-read-and-interpret-a-Cohort-Trian_FC17/Cohort-Created-To-Last-Purchse3_thumb.png" width="604" height="437" />
          </a>
        </p>
        <h2>What Can I do with this information?
</h2>
        <p>
In isolation it's helpful but only really gives you a top level view on a customer's
lifetime with you, it's when you're able to combine this data with knowledge of your
business, sales statistics, marketing strategy and information such as a customer's
LTV (Lifetime Value) that it gets really interesting and useful.
</p>
        <p>
Using a cohort chart and average sale value, you can use it as part of your sales
forecasting and predict what your company's sales will be going forwards e.g.: if
the Average Order Value is £10 and your average first 5 months looked like this:
</p>
        <table border="1" cellspacing="0" cellpadding="2" width="400">
          <tbody>
            <tr>
              <th valign="top" width="166">
Month:</th>
              <th valign="top" width="66">
0</th>
              <th valign="top" width="66">
1</th>
              <th valign="top" width="66">
2</th>
              <th valign="top" width="66">
3</th>
              <th valign="top" width="66">
4</th>
            </tr>
            <tr>
              <td valign="top" width="166">
Customer Trend</td>
              <td valign="top" width="66">
1,000</td>
              <td valign="top" width="66">
500</td>
              <td valign="top" width="66">
200</td>
              <td valign="top" width="66">
100</td>
              <td valign="top" width="66">
10</td>
            </tr>
          </tbody>
        </table>
        <p>
You'll then know that of the 1,000 or so customers which sign up in the current month
your revenue is likely to look something like this:
</p>
        <table border="1" cellspacing="0" cellpadding="2" width="400">
          <tbody>
            <tr>
              <th valign="top" width="166">
Month:</th>
              <th valign="top" width="66">
0</th>
              <th valign="top" width="66">
1</th>
              <th valign="top" width="66">
2</th>
              <th valign="top" width="66">
3</th>
              <th valign="top" width="66">
4</th>
            </tr>
            <tr>
              <td valign="top" width="166">
Expected Sales</td>
              <td valign="top" width="66">
£10,000</td>
              <td valign="top" width="66">
£3,000</td>
              <td valign="top" width="66">
£1,000</td>
              <td valign="top" width="66">
£900</td>
              <td valign="top" width="66">
£100</td>
            </tr>
          </tbody>
        </table>
        <p>
How have I got to those numbers? Well, of the 1,000 customers that purchase this month,
50% will make another purchase on or after month 1 and 20% will make a purchase on
or after month 2. With this in mind, of the 1,000 customers from Month 0, 30% will
make a purchase in Month 1 so the calculation is as follows:
</p>
        <p>
([Number of customers] * [Percentage Returning in Month]) * [Average Order Value]
= [Expected Sales]
</p>
        <p>
(1,000 * 30%) * £10 = £3,000
</p>
        <p>
There are a few assumptions with doing it like this -for instance, customers who purchase
monthly will only be counted once etc but this is still a good start.
</p>
        <p>
Using a cohort chart with sales data becomes very powerful as you're able to get a
really good insight into whether campaigns are generating worthwhile leads or just
generating traffic to the sites. If you're interested in reading more about that I'll
overview it in another post as that gets pretty heavy on number crunching.
</p>
        <p>
If you find that customers tend to drop off after a set number of months then it might
be worth setting up some form of customer engagement which is triggered just before
this point e.g. an email upselling a product that complements theirs or asking them
to get in touch with feedback.
</p>
        <img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=d8d11102-05a1-440f-83fa-f473e98825a2" />
      </body>
      <title>How to read and interpret a cohort chart - cohort analysis Part 2</title>
      <guid isPermaLink="false">http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,d8d11102-05a1-440f-83fa-f473e98825a2.aspx</guid>
      <link>http://blogs.thesitedoctor.co.uk/tim/2012/02/20/How+To+Read+And+Interpret+A+Cohort+Chart+Cohort+Analysis+Part+2.aspx</link>
      <pubDate>Mon, 20 Feb 2012 14:31:06 GMT</pubDate>
      <description>&lt;p&gt;
In my &lt;a href="http://blogs.thesitedoctor.co.uk/tim/2011/12/12/Startups+Golden+Triangle+Of+Customer+Loyalty+Cohort+Analysis+Part+1.aspx" target="_blank"&gt;last
post about Cohort analysis&lt;/a&gt; I briefly introduced what a cohort graph is, in this
one I'm going to go into a little more detail about how you can use it. I'm planning
on releasing some code so you can add it to your reporting suite in another post but
if you can't wait until then, I've thrown up a quick online cohort generator at: &lt;a href="http://www.quickcohort.com"&gt;www.quickcohort.com&lt;/a&gt; -just
dump your data into it and click graph.
&lt;/p&gt;
&lt;h2&gt;What can the cohort chart tell us?
&lt;/h2&gt;
&lt;p&gt;
A cohort chart can give you an idea of customer loyalty -and- an indication of potential
problems in their lifecycle.
&lt;/p&gt;
&lt;p&gt;
The key metric it gives us is &lt;strong&gt;customer loyalty&lt;/strong&gt;. This is also one
of the most frequently ignored metrics in every company (mostly because people aren't
clear on how to measure it) yet it's probably one of the most important at the same
time. 
&lt;/p&gt;
&lt;h2&gt;What is Customer Loyalty?
&lt;/h2&gt;
&lt;p&gt;
That depends very much on your business and as a result the graphs will likely look
very different. It's probably easiest to compare what a couple of business types -a
retailer and an online magazine- might consider loyalty.
&lt;/p&gt;
&lt;table border="0" cellspacing="0" cellpadding="2" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th valign="top" width="250"&gt;
Retailer 
&lt;/th&gt;
&lt;th valign="top" width="250"&gt;
Magazine 
&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="50%"&gt;
&lt;ul&gt;
&lt;li&gt;
Repeat sales 
&lt;/li&gt;
&lt;li&gt;
Visits to the store 
&lt;/li&gt;
&lt;li&gt;
Engagement with the store e.g. email opens 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td valign="top" width="50%"&gt;
&lt;ul&gt;
&lt;li&gt;
Multiple Logins 
&lt;/li&gt;
&lt;li&gt;
Subscription 
&lt;/li&gt;
&lt;li&gt;
Number of comments on an article 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
As you can see, although there may be some cross overs (Visits to the store and Logins
are probably quantified by a similar metric) the "what" depends very much on your
business but the longer the duration between the first and last engagement in all
scenarios above is how you can demonstrate loyalty.
&lt;/p&gt;
&lt;h2&gt;How should I read a cohort chart?
&lt;/h2&gt;
&lt;p&gt;
Unlike most tables which you read left to right (a row at a time), you'll probably
get more value out of a cohort chart from reading it by a column at a time. This will
enable you to spot possible problems in the user's lifecycle. 
&lt;/p&gt;
&lt;p&gt;
Problem points in the user's lifecycle can often be spotted where the colours change
in the same column. The greater the difference between the shades of colour, the bigger
difference is between the two months. In a perfect world, 100% of the customers from
Month 0 will still be using your site in Month 12 but life is rarely like that.
&lt;/p&gt;
&lt;p&gt;
Looking at the chart below of user logins over time, the eager should spot that there
are three months which appear to have issues: Month 3, Month 5 and Month 9:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/How-to-read-and-interpret-a-Cohort-Trian_FC17/Cohort-Created-To-Signup-Problem.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Cohort-Created-To-Signup-Problem" border="0" alt="Cohort-Created-To-Signup-Problem" src="http://blogs.thesitedoctor.co.uk/tim/images/How-to-read-and-interpret-a-Cohort-Trian_FC17/Cohort-Created-To-Signup-Problem_thumb.png" width="579" height="429" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
If you're not sure on what you're looking for, you're spotting those columns which
have a similarly shaded background which then lightens in the next month (or in the
case of Month 9 is completely unshaded.
&lt;/p&gt;
&lt;h3&gt;What does this mean?
&lt;/h3&gt;
&lt;p&gt;
As the chart above was logins over time, a quick glance over this cohort chart this
would suggest the following to me:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Overall there is a pretty good retention for the users (the percentage of customers
going from month to month are pretty high) 
&lt;/li&gt;
&lt;li&gt;
The majority of users only remain engaged up to month 3, at which point a lot of users
lose interest in the site 
&lt;/li&gt;
&lt;li&gt;
There is a clear drop off in customer retention after month 9 
&lt;/li&gt;
&lt;li&gt;
The eldest customers had the best retention rates (despite the drop off in Month 9,
30-40% of visitors were still coming back until then) 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
When reading a cohort chart, you can generally discount the last cell of each cohort
as it's the current month.
&lt;/p&gt;
&lt;h2&gt;What might the cohort chart look like?
&lt;/h2&gt;
&lt;h3&gt;Repeat Sales
&lt;/h3&gt;
&lt;p&gt;
Logically, to be a repeat customer, you have to make at least two purchase from the
retailer so the duration we're interested in (the month) is the period between the
first purchase and most recent purchase.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;First Date (Month 0):&lt;/strong&gt; First Purchase 
&lt;br /&gt;
&lt;strong&gt;Last Date (Month x):&lt;/strong&gt; Most Recent Purchase
&lt;/p&gt;
&lt;p&gt;
Check out the cohort chart below and see what you can interpret.
&lt;/p&gt;
&lt;p&gt;
&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Cohort-Created-To-First-Purchse[3]" border="0" alt="Cohort-Created-To-First-Purchse[3]" src="http://blogs.thesitedoctor.co.uk/tim/images/How-to-read-and-interpret-a-Cohort-Trian_FC17/Cohort-Created-To-First-Purchse3_thumb.png" width="545" height="431" /&gt; 
&lt;/p&gt;
&lt;p&gt;
Remember, Month 0 represents the first purchase -all customers appear in this column.
Looking over the cohort chart, of the 69 customers the retailer had in October 2010,
39% (27 customers) were still around in November 2010 (month 1), 21% (15 customers)
were still around in December 2010 and so on.
&lt;/p&gt;
&lt;p&gt;
None of the 69 customers who made their first purchase in October 2010 are still a
customer 12 months later (although if your customers tend to make a purchase near
the end of the month, the customer who made a purchase in September 2011 may still
make a purchase).
&lt;/p&gt;
&lt;p&gt;
So looking at that chart, 30-40% of customers would make a second purchase 2 months
after their first purchase. Of the older customers (those which first purchased before
March 2011) 10% would make another purchase 5-6 months later.
&lt;/p&gt;
&lt;h3&gt;What else can we gleam? 
&lt;/h3&gt;
&lt;p&gt;
There are a few interesting things with the chart above, another is the sudden drop
off in month 3 for those customers who first purchased in May/Jun 2011, similarly,
the customers who signed up in Mar/Apr 2011 also stumbled in the same month, that
could indicate some form of seasonal trend or change in marketing.
&lt;/p&gt;
&lt;p&gt;
With a little background you will be able to get a much better insight into the meaning
behind some of the numbers. If for instance you had changed your marketing routine
around Jun 2011 this might explain the difference in numbers. It might be that your
business is very seasonal (in which as you'd be better to look at a 24 month chart
rather than 12 month).
&lt;/p&gt;
&lt;p&gt;
Keeping a record of what you were doing around the different months is important,
for instance you might start a pay-per-click campaign. Everyone's happy because you
notice an increase in sales (so an increase in Month 0) but are they a valuable customer
(a repeat purchaser) or a one-off? Cohort chart analysis will quickly highlight this
to you as the increase in Month 0 will be reflected in Month 1.
&lt;/p&gt;
&lt;p&gt;
Although time will tell, it would appear that a lot of customers make another purchase
about 2 months after their first. This could be co-incidence or it might be that you're
selling a product with a small sample accessory (e.g. a free pack of chalk with each
chalkboard) and that sample pack runs out after a couple of months. Alternatively
it could be a fault in the product e.g. you sell hinges and the oil runs out after
a couple of months so they're buying more grease. By adding a little context to the
data you'll likely get even more interesting stats out (we certainly have in the past).
&lt;/p&gt;
&lt;h2&gt;Visits to the store or customer engagement
&lt;/h2&gt;
&lt;p&gt;
Things start to get really interesting when you start comparing two cohort charts
for the same customer base and period against each other. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;First Date (Month 0):&lt;/strong&gt; First Purchase 
&lt;br /&gt;
&lt;strong&gt;Last Date (Month x):&lt;/strong&gt; Most Recent Login
&lt;/p&gt;
&lt;p&gt;
What's interesting when you compare the two charts is most of the customers who have
made a purchase are still returning to the site (over 30% are still logging in in
Month 11). This would suggest there's not as greater a problem with customer retention
as there is with sales.
&lt;/p&gt;
&lt;p&gt;
This could be because your store sells seasonal products but you keep customers engaged,
it might just be a co-incidence but it should drive investigation.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/How-to-read-and-interpret-a-Cohort-Trian_FC17/Cohort-Created-To-Last-Purchse3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Cohort-Created-To-Last-Purchse[3]" border="0" alt="Cohort-Created-To-Last-Purchse[3]" src="http://blogs.thesitedoctor.co.uk/tim/images/How-to-read-and-interpret-a-Cohort-Trian_FC17/Cohort-Created-To-Last-Purchse3_thumb.png" width="604" height="437" /&gt;&lt;/a&gt;&gt;&gt;
&lt;/p&gt;
&lt;h2&gt;What Can I do with this information?
&lt;/h2&gt;
&lt;p&gt;
In isolation it's helpful but only really gives you a top level view on a customer's
lifetime with you, it's when you're able to combine this data with knowledge of your
business, sales statistics, marketing strategy and information such as a customer's
LTV (Lifetime Value) that it gets really interesting and useful.
&lt;/p&gt;
&lt;p&gt;
Using a cohort chart and average sale value, you can use it as part of your sales
forecasting and predict what your company's sales will be going forwards e.g.: if
the Average Order Value is £10 and your average first 5 months looked like this:
&lt;/p&gt;
&lt;table border="1" cellspacing="0" cellpadding="2" width="400"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th valign="top" width="166"&gt;
Month:&lt;/th&gt;
&lt;th valign="top" width="66"&gt;
0&lt;/th&gt;
&lt;th valign="top" width="66"&gt;
1&lt;/th&gt;
&lt;th valign="top" width="66"&gt;
2&lt;/th&gt;
&lt;th valign="top" width="66"&gt;
3&lt;/th&gt;
&lt;th valign="top" width="66"&gt;
4&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="166"&gt;
Customer Trend&lt;/td&gt;
&lt;td valign="top" width="66"&gt;
1,000&lt;/td&gt;
&lt;td valign="top" width="66"&gt;
500&lt;/td&gt;
&lt;td valign="top" width="66"&gt;
200&lt;/td&gt;
&lt;td valign="top" width="66"&gt;
100&lt;/td&gt;
&lt;td valign="top" width="66"&gt;
10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
You'll then know that of the 1,000 or so customers which sign up in the current month
your revenue is likely to look something like this:
&lt;/p&gt;
&lt;table border="1" cellspacing="0" cellpadding="2" width="400"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th valign="top" width="166"&gt;
Month:&lt;/th&gt;
&lt;th valign="top" width="66"&gt;
0&lt;/th&gt;
&lt;th valign="top" width="66"&gt;
1&lt;/th&gt;
&lt;th valign="top" width="66"&gt;
2&lt;/th&gt;
&lt;th valign="top" width="66"&gt;
3&lt;/th&gt;
&lt;th valign="top" width="66"&gt;
4&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="166"&gt;
Expected Sales&lt;/td&gt;
&lt;td valign="top" width="66"&gt;
£10,000&lt;/td&gt;
&lt;td valign="top" width="66"&gt;
£3,000&lt;/td&gt;
&lt;td valign="top" width="66"&gt;
£1,000&lt;/td&gt;
&lt;td valign="top" width="66"&gt;
£900&lt;/td&gt;
&lt;td valign="top" width="66"&gt;
£100&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
How have I got to those numbers? Well, of the 1,000 customers that purchase this month,
50% will make another purchase on or after month 1 and 20% will make a purchase on
or after month 2. With this in mind, of the 1,000 customers from Month 0, 30% will
make a purchase in Month 1 so the calculation is as follows:
&lt;/p&gt;
&lt;p&gt;
([Number of customers] * [Percentage Returning in Month]) * [Average Order Value]
= [Expected Sales]
&lt;/p&gt;
&lt;p&gt;
(1,000 * 30%) * £10 = £3,000
&lt;/p&gt;
&lt;p&gt;
There are a few assumptions with doing it like this -for instance, customers who purchase
monthly will only be counted once etc but this is still a good start.
&lt;/p&gt;
&lt;p&gt;
Using a cohort chart with sales data becomes very powerful as you're able to get a
really good insight into whether campaigns are generating worthwhile leads or just
generating traffic to the sites. If you're interested in reading more about that I'll
overview it in another post as that gets pretty heavy on number crunching.
&lt;/p&gt;
&lt;p&gt;
If you find that customers tend to drop off after a set number of months then it might
be worth setting up some form of customer engagement which is triggered just before
this point e.g. an email upselling a product that complements theirs or asking them
to get in touch with feedback.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=d8d11102-05a1-440f-83fa-f473e98825a2" /&gt;</description>
      <comments>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,d8d11102-05a1-440f-83fa-f473e98825a2.aspx</comments>
      <category>Analysis</category>
      <category>Business</category>
      <category>Business/Business Start-up Advice</category>
      <category>Business/Expanding Your Business</category>
      <category>Cohorts</category>
      <category>Statistics</category>
    </item>
    <item>
      <trackback:ping>http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=7988f7bc-947c-4134-ab52-af22770b639c</trackback:ping>
      <pingback:server>http://blogs.thesitedoctor.co.uk/tim/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,7988f7bc-947c-4134-ab52-af22770b639c.aspx</pingback:target>
      <dc:creator>Tim</dc:creator>
      <wfw:comment>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,7988f7bc-947c-4134-ab52-af22770b639c.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.thesitedoctor.co.uk/tim/SyndicationService.asmx/GetEntryCommentsRss?guid=7988f7bc-947c-4134-ab52-af22770b639c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you've been using web.config transformations or a nuget package with transformations
in at all you'll no doubt have come across the runtime configuration error of "Unrecognized
attribute 'xmlns:xdt'. Note that attribute names are case-sensitive" pointing at the
start of the &lt;configuration&gt; node (if not see below). This one has been bugging
me for a while so I thought I'd work a way around it. 
</p>
        <h3>Server Error in '/' Application. 
<hr size="1" width="100%" /></h3>
        <h4>
          <i>Configuration Error</i>
        </h4>
        <b>Description: </b>An error occurred during the processing of a configuration file
required to service this request. Please review the specific error details below and
modify your configuration file appropriately. 
<br /><b>Parser Error Message: </b>Unrecognized attribute 'xmlns:xdt'. Note that attribute
names are case-sensitive. 
<br /><b>Source Error:</b><p><code></code></p><pre>Line 1:  &lt;?xml version="1.0" encoding="utf-8"?&gt;
Line 2:  &lt;configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"&gt;
Line 3:    &lt;configSections&gt;
Line 4:      &lt;section name="Exceptioneer" type="Something, Assembly" requirePermission="true" /&gt;</pre><p><b>Source File: </b>c:\domain.com\web.config<b>    Line: </b>2
</p><hr size="1" width="100%" /><b>Version Information:</b> Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272 
<p>
 
</p><h2>The Solution
</h2><p>
To work around this, I've assumed you're running some form of custom build already
(or have access to add a pre-deploy build step).
</p><ol><li>
Download and install the <a href="http://msbuildtasks.tigris.org/" target="_blank">MSBuild
Community Tasks</a></li><li>
Add the new FileUpdate build step below which looks at your config file (you'll need
to run this against each one). You'll also need to have a space in the ReplacementText
as you can't currently replace with String.Empty.</li><li>
You're done 
</li></ol><ol>
Simple but effective I think 
</ol><img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.thesitedoctor.co.uk/tim/images/876d6b03d4c8_8451/wlEmoticon-smile.png" /><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:e77320b2-9198-46dc-b9a8-1f9572dacc11" class="wlWriterEditableSmartContent"><pre class="brush: xml;">&lt;ItemGroup&gt;
    &lt;FileUpdateFiles Include="**\*.config" /&gt;
&lt;/ItemGroup&gt;
&lt;FileUpdate 
    Files="@(FileUpdateFiles)" 
    Regex=" xmlns\:xdt\=&amp;quot;http\://schemas\.microsoft\.com/XML-Document-Transform&amp;quot;"
    ReplacementText=" " /&gt;</pre></div><p>
If you've got a better (automated) solution, please let me know, it's been bugging
me for ages!
</p><img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=7988f7bc-947c-4134-ab52-af22770b639c" /></body>
      <title>Avoid Unrecognized attribute 'xmlns:xdt' configuration error</title>
      <guid isPermaLink="false">http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,7988f7bc-947c-4134-ab52-af22770b639c.aspx</guid>
      <link>http://blogs.thesitedoctor.co.uk/tim/2012/02/10/Avoid+Unrecognized+Attribute+Xmlnsxdt+Configuration+Error.aspx</link>
      <pubDate>Fri, 10 Feb 2012 13:21:02 GMT</pubDate>
      <description>&lt;p&gt;
If you've been using web.config transformations or a nuget package with transformations
in at all you'll no doubt have come across the runtime configuration error of "Unrecognized
attribute 'xmlns:xdt'. Note that attribute names are case-sensitive" pointing at the
start of the &amp;lt;configuration&amp;gt; node (if not see below). This one has been bugging
me for a while so I thought I'd work a way around it. 
&lt;/p&gt;
&lt;h3&gt;Server Error in '/' Application. 
&lt;hr size="1" width="100%" /&gt;
&lt;/h3&gt;
&lt;h4&gt;&lt;i&gt;Configuration Error&lt;/i&gt;
&lt;/h4&gt;
&lt;b&gt;Description: &lt;/b&gt;An error occurred during the processing of a configuration file
required to service this request. Please review the specific error details below and
modify your configuration file appropriately. 
&lt;br /&gt;
&lt;b&gt;Parser Error Message: &lt;/b&gt;Unrecognized attribute 'xmlns:xdt'. Note that attribute
names are case-sensitive. 
&lt;br /&gt;
&lt;b&gt;Source Error:&lt;/b&gt; 
&lt;p&gt;
&lt;code&gt;&lt;/code&gt;
&lt;/p&gt;
&lt;pre&gt;Line 1:  &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
Line 2:  &amp;lt;configuration xmlns:xdt=&amp;quot;http://schemas.microsoft.com/XML-Document-Transform&amp;quot;&amp;gt;
Line 3:    &amp;lt;configSections&amp;gt;
Line 4:      &amp;lt;section name=&amp;quot;Exceptioneer&amp;quot; type=&amp;quot;Something, Assembly&amp;quot; requirePermission=&amp;quot;true&amp;quot; /&amp;gt;&lt;/pre&gt;
&lt;p&gt;
&lt;b&gt;Source File: &lt;/b&gt;c:\domain.com\web.config&lt;b&gt;&amp;#160;&amp;#160;&amp;#160; Line: &lt;/b&gt;2
&lt;/p&gt;
&lt;hr size="1" width="100%" /&gt;
&lt;b&gt;Version Information:&lt;/b&gt; Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272 
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;h2&gt;The Solution
&lt;/h2&gt;
&lt;p&gt;
To work around this, I've assumed you're running some form of custom build already
(or have access to add a pre-deploy build step).
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Download and install the &lt;a href="http://msbuildtasks.tigris.org/" target="_blank"&gt;MSBuild
Community Tasks&lt;/a&gt; 
&lt;/li&gt;
&lt;li&gt;
Add the new FileUpdate build step below which looks at your config file (you'll need
to run this against each one). You'll also need to have a space in the ReplacementText
as you can't currently replace with String.Empty.&lt;/li&gt;
&lt;li&gt;
You're done 
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol&gt;
Simple but effective I think &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.thesitedoctor.co.uk/tim/images/876d6b03d4c8_8451/wlEmoticon-smile.png" /&gt;&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:e77320b2-9198-46dc-b9a8-1f9572dacc11" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;ItemGroup&amp;gt;
    &amp;lt;FileUpdateFiles Include="**\*.config" /&amp;gt;
&amp;lt;/ItemGroup&amp;gt;
&amp;lt;FileUpdate 
    Files="@(FileUpdateFiles)" 
    Regex=" xmlns\:xdt\=&amp;amp;quot;http\://schemas\.microsoft\.com/XML-Document-Transform&amp;amp;quot;"
    ReplacementText=" " /&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
If you've got a better (automated) solution, please let me know, it's been bugging
me for ages!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=7988f7bc-947c-4134-ab52-af22770b639c" /&gt;</description>
      <comments>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,7988f7bc-947c-4134-ab52-af22770b639c.aspx</comments>
      <category>ASP.Net</category>
      <category>Development</category>
    </item>
    <item>
      <trackback:ping>http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=07550372-9fac-4b67-9139-fef1bb5d507b</trackback:ping>
      <pingback:server>http://blogs.thesitedoctor.co.uk/tim/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,07550372-9fac-4b67-9139-fef1bb5d507b.aspx</pingback:target>
      <dc:creator>Tim</dc:creator>
      <wfw:comment>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,07550372-9fac-4b67-9139-fef1bb5d507b.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.thesitedoctor.co.uk/tim/SyndicationService.asmx/GetEntryCommentsRss?guid=07550372-9fac-4b67-9139-fef1bb5d507b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="Holiday-Time-Caravan-Clock-p[1]" border="0" alt="Holiday-Time-Caravan-Clock-p[1]" align="right" src="http://blogs.thesitedoctor.co.uk/tim/images/Theres-never-a-right-time_102F9/Holiday-Time-Caravan-Clock-p1.jpg" width="260" height="260" />I'm
about to go on holiday (yay me!), but have you ever worried beforehand because there's
not enough time to complete everything you need to get done before you go? 
</p>
        <p>
Lets face it:-
</p>
        <p>
          <strong>There's rarely enough time to do everything in the average week when you've
got a full week; without meetings or interruptions -let alone when you've got a deadline
like a holiday!</strong>
        </p>
        <p>
So relax; make the deadline work for you. Use it as a way to get things done with
a little more focus and clarity. Identify what <strong><em>needs</em></strong> to
be done before you go and what can wait for your return and then prioritise what <strong><em>needs</em></strong> to
be done. If you get it all done -great. If not, I suspect that it can wait for your
return so enjoy yourself knowing that you'll get stuck in on your return.
</p>
        <p>
Down time is important for everyone, if your clients worry about you going away, you
can reassure them that when you get back you'll be raring to go.
</p>
        <p>
 
</p>
        <p>
 
</p>
        <p>
 
</p>
        <p>
Shameless plug - if you are thinking about going on holiday -but worried about supporting
your clients, you should check out <a title="Crisis Cover - solving the &quot;what happens if you get hit by a bus&quot; problem" href="http://www.crisiscover.co.uk" target="_blank">Crisis
Cover</a>. <a title="Crisis Cover - solving the &quot;what happens if you get hit by a bus&quot; problem" href="http://www.crisiscover.co.uk" target="_blank">Crisis
Cover</a> allows you to store important information such as usernames and passwords
and give on-demand (and audited) access to anyone supporting your clients in your
absence. 
</p>
        <p>
          <a href="http://www.crisiscover.com/signup/" target="_blank">You can sign up as an
supplier here</a>
        </p>
        <img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=07550372-9fac-4b67-9139-fef1bb5d507b" />
      </body>
      <title>There’s never a right time</title>
      <guid isPermaLink="false">http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,07550372-9fac-4b67-9139-fef1bb5d507b.aspx</guid>
      <link>http://blogs.thesitedoctor.co.uk/tim/2012/01/27/Theres+Never+A+Right+Time.aspx</link>
      <pubDate>Fri, 27 Jan 2012 08:12:00 GMT</pubDate>
      <description>&lt;p&gt;
&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="Holiday-Time-Caravan-Clock-p[1]" border="0" alt="Holiday-Time-Caravan-Clock-p[1]" align="right" src="http://blogs.thesitedoctor.co.uk/tim/images/Theres-never-a-right-time_102F9/Holiday-Time-Caravan-Clock-p1.jpg" width="260" height="260" /&gt;I'm
about to go on holiday (yay me!), but have you ever worried beforehand because there's
not enough time to complete everything you need to get done before you go? 
&lt;/p&gt;
&lt;p&gt;
Lets face it:-
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;There's rarely enough time to do everything in the average week when you've
got a full week; without meetings or interruptions -let alone when you've got a deadline
like a holiday!&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
So relax; make the deadline work for you. Use it as a way to get things done with
a little more focus and clarity. Identify what &lt;strong&gt;&lt;em&gt;needs&lt;/em&gt;&lt;/strong&gt; to
be done before you go and what can wait for your return and then prioritise what &lt;strong&gt;&lt;em&gt;needs&lt;/em&gt;&lt;/strong&gt; to
be done. If you get it all done -great. If not, I suspect that it can wait for your
return so enjoy yourself knowing that you'll get stuck in on your return.
&lt;/p&gt;
&lt;p&gt;
Down time is important for everyone, if your clients worry about you going away, you
can reassure them that when you get back you'll be raring to go.
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
Shameless plug - if you are thinking about going on holiday -but worried about supporting
your clients, you should check out &lt;a title="Crisis Cover - solving the &amp;quot;what happens if you get hit by a bus&amp;quot; problem" href="http://www.crisiscover.co.uk" target="_blank"&gt;Crisis
Cover&lt;/a&gt;. &lt;a title="Crisis Cover - solving the &amp;quot;what happens if you get hit by a bus&amp;quot; problem" href="http://www.crisiscover.co.uk" target="_blank"&gt;Crisis
Cover&lt;/a&gt; allows you to store important information such as usernames and passwords
and give on-demand (and audited) access to anyone supporting your clients in your
absence. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.crisiscover.com/signup/" target="_blank"&gt;You can sign up as an
supplier here&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=07550372-9fac-4b67-9139-fef1bb5d507b" /&gt;</description>
      <comments>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,07550372-9fac-4b67-9139-fef1bb5d507b.aspx</comments>
      <category>Business</category>
      <category>Random Thought</category>
      <category>The Site Doctor</category>
    </item>
    <item>
      <trackback:ping>http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=18b12292-8c2f-4ebc-9ea7-93bbe0433e5c</trackback:ping>
      <pingback:server>http://blogs.thesitedoctor.co.uk/tim/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,18b12292-8c2f-4ebc-9ea7-93bbe0433e5c.aspx</pingback:target>
      <dc:creator>Tim</dc:creator>
      <wfw:comment>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,18b12292-8c2f-4ebc-9ea7-93bbe0433e5c.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.thesitedoctor.co.uk/tim/SyndicationService.asmx/GetEntryCommentsRss?guid=18b12292-8c2f-4ebc-9ea7-93bbe0433e5c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you're from a financial or medical background you'll probably already be familiar
with cohort analysis but more recently it's become a very popular way of measuring
customer loyalty among your consumers. I've been playing with it with our customers
for a while now and I think many more businesses can benefit from it's insights.
</p>
        <p>
Once you've worked out the customer's lifetime value (often referred to as LTV), average
order spend and time until first purchase, your analysis often end there. LTV is better
than nothing however you may be missing some major issues in their journey. Lets for
example say you sell a widget. Your widget lasts 12 months but needs to be oiled every
3 months. Your gut tells you that this is the case but proving this is difficult without
analysing each client individually.
</p>
        <p>
Individually you can't gain a great insight into your customer as each is slightly
different. Cohort analysis works around the granularity and groups customers together
into cohorts. Each cohort is based on a fixed point in the customer's timeline with
you -for instance the date/time they signed up or their first order. We can then use
this fixed point to compare other customers who have gone past the same period in
their lifetime (or not as the case may be) to spot trends.
</p>
        <p>
The easiest way to understand you group the users is to imagine the following timeline
of customer signups, we have three customers (Green, Blue and Red) and they all signup
up at different times throughout a 6 month period:
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/Start-ups-golden-triangle_100C9/20111212-Cohorts-Timeline.jpg">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="20111212-Cohorts-Timeline" border="0" alt="20111212-Cohorts-Timeline" src="http://blogs.thesitedoctor.co.uk/tim/images/Start-ups-golden-triangle_100C9/20111212-Cohorts-Timeline_thumb.jpg" width="504" height="139" />
          </a>
        </p>
        <p>
Spotting trends in these customers is less than obvious however all customers have
passed through a number of similar points in their lifecycle (in this example month
1, month 2 and month 3) so looking at the data from this perspective will help you
spot the trends:
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/Start-ups-golden-triangle_100C9/20111212-Cohorts-Lifecycle.jpg">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="20111212-Cohorts-Lifecycle" border="0" alt="20111212-Cohorts-Lifecycle" src="http://blogs.thesitedoctor.co.uk/tim/images/Start-ups-golden-triangle_100C9/20111212-Cohorts-Lifecycle_thumb.jpg" width="504" height="139" />
          </a>
        </p>
        <p>
Most cohort analysis groups customers into monthly groups however the size of each
group will depend on the number of signups/orders you have e.g. a system like Twitter
will have enough data to produce cohorts on a minute or even second basis. By grouping
customers together in this way you can then spot seasonal trends and retention (the
length of time you keep a customer).
</p>
        <h2>What does a cohort chart look like?
</h2>
        <p>
A cohort chart looks like this:
</p>
        <p>
          <strong>
            <font color="#ff0000">
              <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Cohort-Created-To-Last-Login" border="0" alt="Cohort-Created-To-Last-Login" src="http://blogs.thesitedoctor.co.uk/tim/images/Start-ups-golden-triangle_100C9/Cohort-Created-To-Last-Login.png" width="602" height="446" />
            </font>
          </strong>
        </p>
        <p>
You get this very distinctive triangle because the users on the first row are your
eldest users and will have been with you for the longest time (which is also why they
have the longest row). The users on the last row have just joined in the current month
so have the shortest row.
</p>
        <p>
The chart above is rather encouraging; it's from one of our e-commerce clients and
it shows really a rather dedicated customer base -a year after signing up 41% of the
customers are still logging into the system! 
</p>
        <p>
You may also notice an interesting dip in retention for those customers who signed
up in Dec 2010/Jan 2011. Although additional investigation is required, the type of
customer base they have is very busy during these months so they've probably forgotten
about signing up. This does however leave a prime opportunity for them to be contacted
directly and encouraged back.
</p>
In my next cohort analysis blog post I'll overview how you can read and interpret
the chart in more detail and use it to spot trends. <img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=18b12292-8c2f-4ebc-9ea7-93bbe0433e5c" /></body>
      <title>Start-up's golden triangle of customer loyalty - cohort analysis Part 1</title>
      <guid isPermaLink="false">http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,18b12292-8c2f-4ebc-9ea7-93bbe0433e5c.aspx</guid>
      <link>http://blogs.thesitedoctor.co.uk/tim/2011/12/12/Startups+Golden+Triangle+Of+Customer+Loyalty+Cohort+Analysis+Part+1.aspx</link>
      <pubDate>Mon, 12 Dec 2011 17:13:12 GMT</pubDate>
      <description>&lt;p&gt;
If you're from a financial or medical background you'll probably already be familiar
with cohort analysis but more recently it's become a very popular way of measuring
customer loyalty among your consumers. I've been playing with it with our customers
for a while now and I think many more businesses can benefit from it's insights.
&lt;/p&gt;
&lt;p&gt;
Once you've worked out the customer's lifetime value (often referred to as LTV), average
order spend and time until first purchase, your analysis often end there. LTV is better
than nothing however you may be missing some major issues in their journey. Lets for
example say you sell a widget. Your widget lasts 12 months but needs to be oiled every
3 months. Your gut tells you that this is the case but proving this is difficult without
analysing each client individually.
&lt;/p&gt;
&lt;p&gt;
Individually you can't gain a great insight into your customer as each is slightly
different. Cohort analysis works around the granularity and groups customers together
into cohorts. Each cohort is based on a fixed point in the customer's timeline with
you -for instance the date/time they signed up or their first order. We can then use
this fixed point to compare other customers who have gone past the same period in
their lifetime (or not as the case may be) to spot trends.
&lt;/p&gt;
&lt;p&gt;
The easiest way to understand you group the users is to imagine the following timeline
of customer signups, we have three customers (Green, Blue and Red) and they all signup
up at different times throughout a 6 month period:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/Start-ups-golden-triangle_100C9/20111212-Cohorts-Timeline.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="20111212-Cohorts-Timeline" border="0" alt="20111212-Cohorts-Timeline" src="http://blogs.thesitedoctor.co.uk/tim/images/Start-ups-golden-triangle_100C9/20111212-Cohorts-Timeline_thumb.jpg" width="504" height="139" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Spotting trends in these customers is less than obvious however all customers have
passed through a number of similar points in their lifecycle (in this example month
1, month 2 and month 3) so looking at the data from this perspective will help you
spot the trends:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/Start-ups-golden-triangle_100C9/20111212-Cohorts-Lifecycle.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="20111212-Cohorts-Lifecycle" border="0" alt="20111212-Cohorts-Lifecycle" src="http://blogs.thesitedoctor.co.uk/tim/images/Start-ups-golden-triangle_100C9/20111212-Cohorts-Lifecycle_thumb.jpg" width="504" height="139" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Most cohort analysis groups customers into monthly groups however the size of each
group will depend on the number of signups/orders you have e.g. a system like Twitter
will have enough data to produce cohorts on a minute or even second basis. By grouping
customers together in this way you can then spot seasonal trends and retention (the
length of time you keep a customer).
&lt;/p&gt;
&lt;h2&gt;What does a cohort chart look like?
&lt;/h2&gt;
&lt;p&gt;
A cohort chart looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font color="#ff0000"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Cohort-Created-To-Last-Login" border="0" alt="Cohort-Created-To-Last-Login" src="http://blogs.thesitedoctor.co.uk/tim/images/Start-ups-golden-triangle_100C9/Cohort-Created-To-Last-Login.png" width="602" height="446" /&gt;&lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
You get this very distinctive triangle because the users on the first row are your
eldest users and will have been with you for the longest time (which is also why they
have the longest row). The users on the last row have just joined in the current month
so have the shortest row.
&lt;/p&gt;
&lt;p&gt;
The chart above is rather encouraging; it's from one of our e-commerce clients and
it shows really a rather dedicated customer base -a year after signing up 41% of the
customers are still logging into the system! 
&lt;/p&gt;
&lt;p&gt;
You may also notice an interesting dip in retention for those customers who signed
up in Dec 2010/Jan 2011. Although additional investigation is required, the type of
customer base they have is very busy during these months so they've probably forgotten
about signing up. This does however leave a prime opportunity for them to be contacted
directly and encouraged back.
&lt;/p&gt;
In my next cohort analysis blog post I'll overview how you can read and interpret
the chart in more detail and use it to spot trends. &lt;img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=18b12292-8c2f-4ebc-9ea7-93bbe0433e5c" /&gt;</description>
      <comments>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,18b12292-8c2f-4ebc-9ea7-93bbe0433e5c.aspx</comments>
      <category>Analysis</category>
      <category>Business</category>
      <category>Business/Business Start-up Advice</category>
      <category>Business/Expanding Your Business</category>
      <category>Cohorts</category>
      <category>Statistics</category>
    </item>
    <item>
      <trackback:ping>http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=756a4d25-577c-4b6a-95cf-2e9c923539bd</trackback:ping>
      <pingback:server>http://blogs.thesitedoctor.co.uk/tim/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,756a4d25-577c-4b6a-95cf-2e9c923539bd.aspx</pingback:target>
      <dc:creator>Tim</dc:creator>
      <wfw:comment>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,756a4d25-577c-4b6a-95cf-2e9c923539bd.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.thesitedoctor.co.uk/tim/SyndicationService.asmx/GetEntryCommentsRss?guid=756a4d25-577c-4b6a-95cf-2e9c923539bd</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently I've noticed a growing number of Umbraco developers forgetting to disable
the Umbraco debug settings before going live. We all fall foul of this from time to
time but it is a security loophole that you can patch incredibly easily.
</p>
        <p>
If you're not familiar with the helpful debugging querystring parameters of umbDebug
and umbDebugShowTrace they basically show you the ASP.Net trace output and highlight
the various macros used on the page -there's also a <a href="http://www.cpalm.dk/blog/2008/01/umbraco-debugging-made-easy/" target="_blank">useful
toggle debugging in Umbraco bookmarklet on cpalm.dk</a>.
</p>
        <h2>Why you should disable trace
</h2>
        <p>
If you try it out on your site which has debugging enabled you'll get all sorts of
helpful information output to the page including where your website is installed -all
very helpful and interesting to hackers. It also identifies your site as an Umbraco
site very quickly -again something you would want to avoid if at all possible.
</p>
        <h2>How to disable the debug settings via the web.config
</h2>
        <p>
Umbraco helpfully has a built in flag in the web.config appSettings section which
allows you to effortlessly toggle the debuging features on/off. To turn it off, search
for "umbracoDebugMode" in your web.config and if it's set to "true", change it to
false.
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:6a47ccb6-0bdb-4f82-b1e4-0699fa03119f" class="wlWriterEditableSmartContent">
          <pre class="brush: xml;">&lt;add key="umbracoDebugMode" value="true" /&gt;</pre>
        </div>
        <p>
Should be:
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:e7bb9358-1d35-4487-b10b-021369203b71" class="wlWriterEditableSmartContent">
          <pre class="brush: xml;">&lt;add key="umbracoDebugMode" value="false" /&gt;</pre>
        </div>
        <p>
For good measure you should also change ASP.Net's built in debug flag:
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:422febdc-5b6c-48ff-97f9-697dcbbe990b" class="wlWriterEditableSmartContent">
          <pre class="brush: xml;">&lt;compilation defaultLanguage="c#" debug="true" batch="false" targetFramework="4.0"&gt;</pre>
        </div>
        <p>
Should be:
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:9a0b2f27-a853-4b5b-91ae-a124b1d753ae" class="wlWriterEditableSmartContent">
          <pre class="brush: xml;">&lt;compilation defaultLanguage="c#" debug="false" batch="false" targetFramework="4.0"&gt;</pre>
        </div>
        <h2>Disable it using UrlRewriting.config
</h2>
        <p>
If you prefer the belts and braces method, you can add a rule to your UrlRewriting.config
to redirect the user everytime the url includes something that looks suspicious. To
do this, just add the following rewrites to your UrlRewriting.config (or replace it
completely if you don't have any rules):
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:1081aa92-4baf-4225-90d6-6b8c38c57521" class="wlWriterEditableSmartContent">
          <pre class="brush: xml;">&lt;urlrewritingnet xmlns="http://www.urlrewriting.net/schemas/config/2006/07"&gt; 
          &lt;rewrites&gt; 
                    &lt;add name="nodebugaspx" 
                        virtualUrl="(.*).aspx.*umbDebug.*" 
                        rewriteUrlParameter="IncludeQueryStringForRewrite" 
                        redirect="Application" 
                        destinationUrl="~$1.aspx" 
                        ignoreCase="true" /&gt;

                    &lt;add name="nodebug" 
                        virtualUrl="(.*).*umbDebug.*" 
                        rewriteUrlParameter="IncludeQueryStringForRewrite" 
                        redirect="Application" 
                        destinationUrl="~$1" 
                        ignoreCase="true" /&gt; 
          &lt;/rewrites&gt; 
&lt;/urlrewritingnet&gt; 
</pre>
        </div>
        <img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=756a4d25-577c-4b6a-95cf-2e9c923539bd" />
      </body>
      <title>Umbraco developers - remember to disable the umbDebug settings when you go live</title>
      <guid isPermaLink="false">http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,756a4d25-577c-4b6a-95cf-2e9c923539bd.aspx</guid>
      <link>http://blogs.thesitedoctor.co.uk/tim/2011/10/28/Umbraco+Developers+Remember+To+Disable+The+UmbDebug+Settings+When+You+Go+Live.aspx</link>
      <pubDate>Fri, 28 Oct 2011 11:05:41 GMT</pubDate>
      <description>&lt;p&gt;
Recently I've noticed a growing number of Umbraco developers forgetting to disable
the Umbraco debug settings before going live. We all fall foul of this from time to
time but it is a security loophole that you can patch incredibly easily.
&lt;/p&gt;
&lt;p&gt;
If you're not familiar with the helpful debugging querystring parameters of umbDebug
and umbDebugShowTrace they basically show you the ASP.Net trace output and highlight
the various macros used on the page -there's also a &lt;a href="http://www.cpalm.dk/blog/2008/01/umbraco-debugging-made-easy/" target="_blank"&gt;useful
toggle debugging in Umbraco bookmarklet on cpalm.dk&lt;/a&gt;.
&lt;/p&gt;
&lt;h2&gt;Why you should disable trace
&lt;/h2&gt;
&lt;p&gt;
If you try it out on your site which has debugging enabled you'll get all sorts of
helpful information output to the page including where your website is installed -all
very helpful and interesting to hackers. It also identifies your site as an Umbraco
site very quickly -again something you would want to avoid if at all possible.
&lt;/p&gt;
&lt;h2&gt;How to disable the debug settings via the web.config
&lt;/h2&gt;
&lt;p&gt;
Umbraco helpfully has a built in flag in the web.config appSettings section which
allows you to effortlessly toggle the debuging features on/off. To turn it off, search
for "umbracoDebugMode" in your web.config and if it's set to "true", change it to
false.
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:6a47ccb6-0bdb-4f82-b1e4-0699fa03119f" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;add key="umbracoDebugMode" value="true" /&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Should be:
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:e7bb9358-1d35-4487-b10b-021369203b71" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;add key="umbracoDebugMode" value="false" /&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
For good measure you should also change ASP.Net's built in debug flag:
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:422febdc-5b6c-48ff-97f9-697dcbbe990b" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;compilation defaultLanguage="c#" debug="true" batch="false" targetFramework="4.0"&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Should be:
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:9a0b2f27-a853-4b5b-91ae-a124b1d753ae" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;compilation defaultLanguage="c#" debug="false" batch="false" targetFramework="4.0"&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;Disable it using UrlRewriting.config
&lt;/h2&gt;
&lt;p&gt;
If you prefer the belts and braces method, you can add a rule to your UrlRewriting.config
to redirect the user everytime the url includes something that looks suspicious. To
do this, just add the following rewrites to your UrlRewriting.config (or replace it
completely if you don't have any rules):
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:1081aa92-4baf-4225-90d6-6b8c38c57521" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;urlrewritingnet xmlns="http://www.urlrewriting.net/schemas/config/2006/07"&amp;gt; 
          &amp;lt;rewrites&amp;gt; 
                    &amp;lt;add name="nodebugaspx" 
                        virtualUrl="(.*).aspx.*umbDebug.*" 
                        rewriteUrlParameter="IncludeQueryStringForRewrite" 
                        redirect="Application" 
                        destinationUrl="~$1.aspx" 
                        ignoreCase="true" /&amp;gt;

                    &amp;lt;add name="nodebug" 
                        virtualUrl="(.*).*umbDebug.*" 
                        rewriteUrlParameter="IncludeQueryStringForRewrite" 
                        redirect="Application" 
                        destinationUrl="~$1" 
                        ignoreCase="true" /&amp;gt; 
          &amp;lt;/rewrites&amp;gt; 
&amp;lt;/urlrewritingnet&amp;gt; 
&lt;/pre&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=756a4d25-577c-4b6a-95cf-2e9c923539bd" /&gt;</description>
      <comments>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,756a4d25-577c-4b6a-95cf-2e9c923539bd.aspx</comments>
      <category>ASP.Net</category>
      <category>Development</category>
      <category>The Site Doctor</category>
      <category>Umbraco</category>
      <category>Web Development</category>
    </item>
    <item>
      <trackback:ping>http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=d2ecac89-d89d-46fc-bd3c-f4ee53f661be</trackback:ping>
      <pingback:server>http://blogs.thesitedoctor.co.uk/tim/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,d2ecac89-d89d-46fc-bd3c-f4ee53f661be.aspx</pingback:target>
      <dc:creator>Tim</dc:creator>
      <wfw:comment>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,d2ecac89-d89d-46fc-bd3c-f4ee53f661be.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.thesitedoctor.co.uk/tim/SyndicationService.asmx/GetEntryCommentsRss?guid=d2ecac89-d89d-46fc-bd3c-f4ee53f661be</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Frustrated" border="0" alt="Frustrated" align="right" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/Frustrated.jpg" width="244" height="244" />Ignoring
the aspects of design, SEO duplicate content, underlying code and tone of language,
as a content editor you really should give consideration to your user and what they're
looking for. I generally steer clear of critiquing -or even commenting on work that
isn't our own (or when being asked by the creator) but sadly there still seems to
be a real misunderstanding from clients on what makes a usable website.
</p>
        <p>
We recently launched a website for local award winning pie makers - <a title="Award wining pie makers based in Newport" href="http://elmtreefoods.com/" target="_blank">Elm
Tree Foods</a> and as a result we've spent a lot of time dealing with other local
providers websites/council websites and I'm left stunned by the horrific experience
they're offering their users. What riles me more about this though is the fact that
most of their users are the sort that need to be helped through the process as they
aren't often familiar with the internet (somewhat of an over generalising I realise).
</p>
        <p>
A good example I came across today is Herefordshire's main tourism website: <a href="http://www.visitherefordshire.co.uk">www.visitherefordshire.co.uk</a>.
It's well ranked for the search term of "<a href="http://www.google.co.uk/search?q=Flavours+of+Herefordshire">Flavours
of Herefordshire</a>" (a good start) but it's then down hill from there. I was trying
to find out where the <a title="Award wining pie makers based in Newport" href="http://elmtreefoods.com/" target="_blank">Elm
Tree Foods</a> stall would be and when the festival was. We've seen signs locally
saying it's at the Hereford Race Course (there's some debate over whether it really
is) but we weren't sure that was the case for <a title="Award wining pie makers based in Newport" href="http://elmtreefoods.com/" target="_blank">Elm
Tree Foods</a>.
</p>
        <p>
You can try this yourself, see how long it takes you to find out where and when the
Flavours of Herefordshire food festival is purely be using <a href="http://www.visitherefordshire.co.uk">www.visitherefordshire.co.uk</a>.
Ideally you want all the information on one page.
</p>
        <h2>Step 1: The Landing Page - Homepage
</h2>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/HomepageFull.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="HomepageFull" border="0" alt="HomepageFull" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/HomepageFull_thumb.png" width="454" height="452" />
          </a>
        </p>
        <p>
Message on the homepage - good start. Or is it? Take a closer look and you may find
that although you've got the dates (and if you continue reading a time) there's still
no indication of where the festival is:
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/Homepage.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Homepage" border="0" alt="Homepage" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/Homepage_thumb.png" width="545" height="245" />
          </a>
        </p>
        <h2>Step 2: This week's events in Herefordshire
</h2>
        <p>
Clicking the only apparent link on the homepage (I didn't want details on the other
events -rather the Flavours of Herefordshire event) takes you through to the listing
page which has the Date, location, contact details but no time (which was on the homepage
if you remember?). 
</p>
        <h1>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/EventList.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="EventList" border="0" alt="EventList" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/EventList_thumb.png" width="454" height="135" />
          </a>
        </h1>
        <p>
So we're set? We have the location and the date/time, what more is there? 
</p>
        <h2>Step 3: The Flavours of Hereford event landing page (version 1)
</h2>
        <p>
Well, not knowing Hereford that well, I don't know where 1 King Street is so need
to find that out. Logically I click through onto the event's page and I'm taken to:
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/FlavoursOfHerefordshireEventPage.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FlavoursOfHerefordshireEventPage" border="0" alt="FlavoursOfHerefordshireEventPage" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/FlavoursOfHerefordshireEventPage_thumb.png" width="454" height="522" />
          </a>
        </p>
        <p>
Putting to one side the MASSIVE white space on the top right, again there is no mention
of when this glorious event will take place.  Presumably they were going to put
all the clear location/date/time information in that large white space at the top
of the column -but were overwhelmed with their workload forgot.
</p>
        <p>
Another point with this page is that the content talks a lot in the past tense which
is very confusing, was this page meant to be released after the event?
</p>
        <p>
I still don't have a single page with all the information on so lets pop back to the
homepage to see if that offers anything else.
</p>
        <h2>Step 4: Back to the homepage
</h2>
        <p>
Back in the homepage for another look and it turns out the title, although not completely
clear, is also a link.
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/Homepage_3.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Homepage" border="0" alt="Homepage" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/Homepage_thumb_3.png" width="545" height="245" />
          </a>
        </p>
        <h2>Step 4: The Flavours of Hereford event landing page (version 2)
</h2>
        <p>
Clicking the title, I'm taken to this page:
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/FlavoursOfHerefordshireLandingPage.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FlavoursOfHerefordshireLandingPage" border="0" alt="FlavoursOfHerefordshireLandingPage" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/FlavoursOfHerefordshireLandingPage_thumb.png" width="454" height="482" />
          </a>
        </p>
        <p>
Ok good, I've got loads of helpful information here: "<em>Hereford Race Course for
the weekend of Saturday, 22nd October and Sunday 23rd October, 2011 - 10.00am to 4.30pm
each day</em>" -exactly what I was after (even though it's hidden away in a paragraph
of unnecessary fluff)! 
</p>
        <p>
But hang on, I thought it was at "Discover Herefordshire Centre, 1 King Street, Hereford,
Herefordshire"? What's this about the Hereford Race Course? Also, the other page didn't
mention anything about tickets or prices, does that mean I have to pay now? I'm now
confused.
</p>
        <p>
Imagine if you didn't know it wasn't at the race course (as I previously did), you'd
now be going to the Hereford race course, paying £7.00 to get in and left disappointed
at not getting to try <a title="Award wining pie makers based in Newport" href="http://elmtreefoods.com/" target="_blank">Elm
Tree Foods</a>' award winning pies. Bad times. To be clear, I won't know until this
weekend whether it is at the Race Course or not (or indeed what will be at 1 King
Street) so if you're interested, <a href="http://twitter.com/timgaunt" target="_blank">follow
me on Twitter</a> to find out first.
</p>
        <h1>"But it's complicated because we have so much content"
</h1>
        <p>
We've all heard it from larger organisations when getting them onto the web. It's
not hard to confuse the user -and it's also not difficult to help guide the user either;
regardless of how much content you have, you just need to give consideration to the
user's journey and what the important messages are at each step.
</p>
        <p>
Although it is still having work done to it, here for comparison is the <a title="Award wining pie makers based in Newport" href="http://elmtreefoods.com/" target="_blank">Elm
Tree Foods</a> homepage and event details page. Even when resized, the important information
is largely available:
</p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/ElmTreeFoodsHomepage.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ElmTreeFoodsHomepage" border="0" alt="ElmTreeFoodsHomepage" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/ElmTreeFoodsHomepage_thumb.png" width="454" height="231" />
          </a>
        </p>
        <p>
          <a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/ElmTreeFoods.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ElmTreeFoods" border="0" alt="ElmTreeFoods" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/ElmTreeFoods_thumb.png" width="454" height="328" />
          </a>
        </p>
        <h1>But good design costs too much
</h1>
        <p>
I don't know how much <a href="http://www.visitherefordshire.co.uk">www.visitherefordshire.co.uk</a> cost
to design and develop however, one thing I'm almost certain of is that the user could
have been offered a much better user experience than they are currently receiving. 
</p>
        <p>
If after reading this you're concerned about your user's experience, contact <a title="Herefordshire based web design and development" href="http://www.thesitedoctor.co.uk/" target="_blank">The
Site Doctor</a> for a website check up.
</p>
        <img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=d2ecac89-d89d-46fc-bd3c-f4ee53f661be" />
      </body>
      <title>Think about your users when writing your content</title>
      <guid isPermaLink="false">http://blogs.thesitedoctor.co.uk/tim/PermaLink,guid,d2ecac89-d89d-46fc-bd3c-f4ee53f661be.aspx</guid>
      <link>http://blogs.thesitedoctor.co.uk/tim/2011/10/20/Think+About+Your+Users+When+Writing+Your+Content.aspx</link>
      <pubDate>Thu, 20 Oct 2011 13:20:06 GMT</pubDate>
      <description>&lt;p&gt;
&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Frustrated" border="0" alt="Frustrated" align="right" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/Frustrated.jpg" width="244" height="244" /&gt;Ignoring
the aspects of design, SEO duplicate content, underlying code and tone of language,
as a content editor you really should give consideration to your user and what they're
looking for. I generally steer clear of critiquing -or even commenting on work that
isn't our own (or when being asked by the creator) but sadly there still seems to
be a real misunderstanding from clients on what makes a usable website.
&lt;/p&gt;
&lt;p&gt;
We recently launched a website for local award winning pie makers - &lt;a title="Award wining pie makers based in Newport" href="http://elmtreefoods.com/" target="_blank"&gt;Elm
Tree Foods&lt;/a&gt; and as a result we've spent a lot of time dealing with other local
providers websites/council websites and I'm left stunned by the horrific experience
they're offering their users. What riles me more about this though is the fact that
most of their users are the sort that need to be helped through the process as they
aren't often familiar with the internet (somewhat of an over generalising I realise).
&lt;/p&gt;
&lt;p&gt;
A good example I came across today is Herefordshire's main tourism website: &lt;a href="http://www.visitherefordshire.co.uk"&gt;www.visitherefordshire.co.uk&lt;/a&gt;.
It's well ranked for the search term of "&lt;a href="http://www.google.co.uk/search?q=Flavours+of+Herefordshire"&gt;Flavours
of Herefordshire&lt;/a&gt;" (a good start) but it's then down hill from there. I was trying
to find out where the &lt;a title="Award wining pie makers based in Newport" href="http://elmtreefoods.com/" target="_blank"&gt;Elm
Tree Foods&lt;/a&gt; stall would be and when the festival was. We've seen signs locally
saying it's at the Hereford Race Course (there's some debate over whether it really
is) but we weren't sure that was the case for &lt;a title="Award wining pie makers based in Newport" href="http://elmtreefoods.com/" target="_blank"&gt;Elm
Tree Foods&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
You can try this yourself, see how long it takes you to find out where and when the
Flavours of Herefordshire food festival is purely be using &lt;a href="http://www.visitherefordshire.co.uk"&gt;www.visitherefordshire.co.uk&lt;/a&gt;.
Ideally you want all the information on one page.
&lt;/p&gt;
&lt;h2&gt;Step 1: The Landing Page - Homepage
&lt;/h2&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/HomepageFull.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="HomepageFull" border="0" alt="HomepageFull" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/HomepageFull_thumb.png" width="454" height="452" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Message on the homepage - good start. Or is it? Take a closer look and you may find
that although you've got the dates (and if you continue reading a time) there's still
no indication of where the festival is:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/Homepage.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Homepage" border="0" alt="Homepage" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/Homepage_thumb.png" width="545" height="245" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;Step 2: This week's events in Herefordshire
&lt;/h2&gt;
&lt;p&gt;
Clicking the only apparent link on the homepage (I didn't want details on the other
events -rather the Flavours of Herefordshire event) takes you through to the listing
page which has the Date, location, contact details but no time (which was on the homepage
if you remember?). 
&lt;/p&gt;
&lt;h1&gt;&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/EventList.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="EventList" border="0" alt="EventList" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/EventList_thumb.png" width="454" height="135" /&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;
So we're set? We have the location and the date/time, what more is there? 
&lt;/p&gt;
&lt;h2&gt;Step 3: The Flavours of Hereford event landing page (version 1)
&lt;/h2&gt;
&lt;p&gt;
Well, not knowing Hereford that well, I don't know where 1 King Street is so need
to find that out. Logically I click through onto the event's page and I'm taken to:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/FlavoursOfHerefordshireEventPage.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FlavoursOfHerefordshireEventPage" border="0" alt="FlavoursOfHerefordshireEventPage" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/FlavoursOfHerefordshireEventPage_thumb.png" width="454" height="522" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Putting to one side the MASSIVE white space on the top right, again there is no mention
of when this glorious event will take place.&amp;#160; Presumably they were going to put
all the clear location/date/time information in that large white space at the top
of the column -but were overwhelmed with their workload forgot.
&lt;/p&gt;
&lt;p&gt;
Another point with this page is that the content talks a lot in the past tense which
is very confusing, was this page meant to be released after the event?
&lt;/p&gt;
&lt;p&gt;
I still don't have a single page with all the information on so lets pop back to the
homepage to see if that offers anything else.
&lt;/p&gt;
&lt;h2&gt;Step 4: Back to the homepage
&lt;/h2&gt;
&lt;p&gt;
Back in the homepage for another look and it turns out the title, although not completely
clear, is also a link.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/Homepage_3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Homepage" border="0" alt="Homepage" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/Homepage_thumb_3.png" width="545" height="245" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;Step 4: The Flavours of Hereford event landing page (version 2)
&lt;/h2&gt;
&lt;p&gt;
Clicking the title, I'm taken to this page:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/FlavoursOfHerefordshireLandingPage.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FlavoursOfHerefordshireLandingPage" border="0" alt="FlavoursOfHerefordshireLandingPage" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/FlavoursOfHerefordshireLandingPage_thumb.png" width="454" height="482" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Ok good, I've got loads of helpful information here: "&lt;em&gt;Hereford Race Course for
the weekend of Saturday, 22nd October and Sunday 23rd October, 2011 - 10.00am to 4.30pm
each day&lt;/em&gt;" -exactly what I was after (even though it's hidden away in a paragraph
of unnecessary fluff)! 
&lt;/p&gt;
&lt;p&gt;
But hang on, I thought it was at "Discover Herefordshire Centre, 1 King Street, Hereford,
Herefordshire"? What's this about the Hereford Race Course? Also, the other page didn't
mention anything about tickets or prices, does that mean I have to pay now? I'm now
confused.
&lt;/p&gt;
&lt;p&gt;
Imagine if you didn't know it wasn't at the race course (as I previously did), you'd
now be going to the Hereford race course, paying £7.00 to get in and left disappointed
at not getting to try &lt;a title="Award wining pie makers based in Newport" href="http://elmtreefoods.com/" target="_blank"&gt;Elm
Tree Foods&lt;/a&gt;' award winning pies. Bad times. To be clear, I won't know until this
weekend whether it is at the Race Course or not (or indeed what will be at 1 King
Street) so if you're interested, &lt;a href="http://twitter.com/timgaunt" target="_blank"&gt;follow
me on Twitter&lt;/a&gt; to find out first.
&lt;/p&gt;
&lt;h1&gt;"But it's complicated because we have so much content"
&lt;/h1&gt;
&lt;p&gt;
We've all heard it from larger organisations when getting them onto the web. It's
not hard to confuse the user -and it's also not difficult to help guide the user either;
regardless of how much content you have, you just need to give consideration to the
user's journey and what the important messages are at each step.
&lt;/p&gt;
&lt;p&gt;
Although it is still having work done to it, here for comparison is the &lt;a title="Award wining pie makers based in Newport" href="http://elmtreefoods.com/" target="_blank"&gt;Elm
Tree Foods&lt;/a&gt; homepage and event details page. Even when resized, the important information
is largely available:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/ElmTreeFoodsHomepage.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ElmTreeFoodsHomepage" border="0" alt="ElmTreeFoodsHomepage" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/ElmTreeFoodsHomepage_thumb.png" width="454" height="231" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/ElmTreeFoods.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ElmTreeFoods" border="0" alt="ElmTreeFoods" src="http://blogs.thesitedoctor.co.uk/tim/images/Usability--how-bad-can-it-really-be_B091/ElmTreeFoods_thumb.png" width="454" height="328" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h1&gt;But good design costs too much
&lt;/h1&gt;
&lt;p&gt;
I don't know how much &lt;a href="http://www.visitherefordshire.co.uk"&gt;www.visitherefordshire.co.uk&lt;/a&gt; cost
to design and develop however, one thing I'm almost certain of is that the user could
have been offered a much better user experience than they are currently receiving. 
&lt;/p&gt;
&lt;p&gt;
If after reading this you're concerned about your user's experience, contact &lt;a title="Herefordshire based web design and development" href="http://www.thesitedoctor.co.uk/" target="_blank"&gt;The
Site Doctor&lt;/a&gt; for a website check up.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.thesitedoctor.co.uk/tim/aggbug.ashx?id=d2ecac89-d89d-46fc-bd3c-f4ee53f661be" /&gt;</description>
      <comments>http://blogs.thesitedoctor.co.uk/tim/CommentView,guid,d2ecac89-d89d-46fc-bd3c-f4ee53f661be.aspx</comments>
      <category>CMS</category>
      <category>Content</category>
      <category>Content Management</category>
      <category>Content Management System</category>
      <category>Design</category>
      <category>Marketing</category>
      <category>The Site Doctor</category>
      <category>Web Development</category>
    </item>
  </channel>
</rss>
