# Wednesday, 10 August 2011

imageWhen working with an e-commerce transaction system in an online store typically the information stored on the orders and order lines will come from the products themselves in the catalog system.

However, in some cases you might want to add custom information such as a personalized message, an indication whether gift wrapping is required, serial numbers, measurements, or something else entirely.

Enter Dynamic Order Properties

For this specific scenario uCommerce supports dynamic order properties, which is a way to add information to basket, orders, and individual order lines.

You can add as many as you want and you don’t have to stick with the same number of properties or even the same names across orders.

Using Dynamic Order Properties in Razor and .NET

// Grab the basket of the current customer
Basket basket = SiteContext.Current.OrderContext.GetBasket();
PurchaseOrder order = basket.PurchaseOrder;
//Add dynamic order property to the order
order["gift_message"] = "Happy birthday!";
// Grab the basket of the current customer
Basket basket = SiteContext.Current.OrderContext.GetBasket();
PurchaseOrder order = basket.PurchaseOrder;
//Add dynamic order property to an order line
OrderLine orderLine = order.OrderLines.First();
orderLine["serial_number"] = "ZX456-123";
PurchaseOrder purchaseOrder = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder;
// Reading the properties back is just as simple
string giftMessage = purchaseOrder["gift_message"];
string serialNumber = purchaseOrder.OrderLines.First()["serial_number"];

Using Dynamic Order Properties in XSLT

For convenience you can also work with dynamic order properties in XSLT courtesy the Commerce Library.

For order level properties you go:

<xsl:variable name="result" select="CommerceLibrary:SetOrderProperty('gift_message', 'Happy birthday!')"/>

For individual order lines you’ll refer to the index of the order line to target a specific one. That the first parameter. The index values will be part of the order XML produced by CommerceLibrary:GetBasket().

<xsl:variable name="basket" select="CommerceLibrary:GetBasket()"/>
<!-- Grab the index of the first line item -->
<xsl:variable name="firstLineItemIndex" select="$cart/purchaseOrder/lineItems/*[1]/@index"/>
<!-- Now set a dynamic order property on the line item with that index -->
<xsl:variable name="result" select="CommerceLibrary:SetOrderProperty(@firstLineItemIndex, 'serial_number', 'ZX456-123')"/>

Once set the dynamic order property will be outputted as part of the XML produced by GetBasket() or GetPurchaseOrder() in the orderProperties element under the order itself or under individual order lines.

<purchaseOrder index="0" orderNumber="WEB-20" orderGuid="62093368-877a-42d8-94c7-332f6f0031f1" status="New order" createdDate="8/10/2011 8:24:14 AM" completedDate="8/10/2011 8:25:10 AM" note="" vat="479.00" orderTotal="2874.00" discount="0.00" discountTotal="100.00" shippingTotal="0.00" paymentTotal="0.00" taxTotal="" subTotal="2395.00" lineItemCount="1" billingCurrency="EUR" productCount="1">
    <customer index="0" id="69" firstName="Søren" lastName="Spelling Lund" emailAddress="soren.spelling.lund@ucommerce.dk" phoneNumber="4540385659" mobilePhoneNumber="4540385659" umbracoMemberId="">
        <addresses />
    <discounts />
        <orderProperty key="gift_message" value="Happy birthday!" />
        <lineItem index="0" sku="100-000-001" variantSku="003" productName="uCommerce 1.0 RTM Go-Live" price="2495.00" quantity="1" discount="100.00" unitDiscount="100.00" vat="479.00" vatRate="0.20" total="2874.00">
                <orderProperty key="serial_number" value="ZX456-123" />
                <discount index="0" campaignName="Default Campaign" campaignItemName="Discounted unit price" description="" amountOff="100.00" />
        <shipment index="0" shipmentId="17" name="Download" createdDate="8/10/2011 8:25:06 AM" shippingMethodId="8" deliveryNote="Download" trackAndTrace="" price="0.00" taxRate="0.20" tax="0.00" shipmentTotal="0.00">
            <address addressId="76" addressName="Shipment" index="0" firstName="Søren" lastName="Spelling Lund" emailAddress="" phoneNumber="" mobilePhoneNumber="" company="uCommerce ApS" line1="Ny Banegårdsgade 55" line2="" postalCode="8000" city="Aarhus C" state="" country="Denmark" attention="" />
        <payment id="27" index="0" transactionId="33c6e85e-05f5-41d1-b32e-8b57212883a2" name="Account" dateCreated="8/10/2011 8:25:08 AM" fee="0.00" feeTotal="0.00" feePercentage="0.0000" amount="2874.00" statusId="1" paymentMethodId="6" />
    <addresses />
        <address addressId="75" addressName="Billing" index="0" firstName="Søren" lastName="Spelling Lund" emailAddress="soren.spelling.lund@ucommerce.dk" phoneNumber="+4561799997" mobilePhoneNumber="" company="uCommerce ApS" line1="Ny Banegårdsgade 55" line2="" postalCode="8000" city="Aarhus C" state="" country="Denmark" attention="" />


Dynamic order properties will be displayed in uCommerce Admin as part of the order overview.



Dynamic order properties is a great way to add custom information to orders during checkout or indeed later in the order process if required. It can be used to capture customer choice for later use such as custom messages, newsletter sign up flags, and more.

Because they are automatically picked up by the order management interface in the backend they are useful for information store managers need to know during the order management process.

posted on Wednesday, 10 August 2011 08:40:08 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Wednesday, 03 August 2011

imageMore often than not you will leverage uCommerce in a web context either via the Commerce Library XSLT extensions or through .NET directly.

In some cases though you might need to leverage the API outside a web context for automated integration between systems, for custom web services, or integration of uCommerce functionality directly in other custom applications such as point of sale- or kiosk apps.

This article outlines the steps required to get the API going.

Reference uCommerce Assemblies

First you need to reference the uCommerce assemblies and their dependencies in your project.

You’ll need to add references to:

  • UCommerce.dll
  • UCommerce.Infrastructure.dll
  • UCommerce.Umbraco.dll
  • businesslogic.dll (Umbraco)
  • Castle.Core.dll
  • Castle.Windsor.dll
  • FluentNhibernate.dll
  • NHibernate.dll
  • Nhibernate.ByteCode.Castle.dll

Modify App.Config

uCommerce needs some configuration to run. You’ll find examples of the relevant groups in web.config in your Umbraco installation. You’ll want to copy the commerce sectionGroup, connectionStrings, and commerce sections.

Add configSection Element

    <sectionGroup name="commerce" type="System.Configuration.ConfigurationSectionGroup">
        <section name="runtimeConfiguration" type="UCommerce.Infrastructure.Configuration.RuntimeConfigurationSection, UCommerce.Infrastructure" />

Add connectionStrings Element
    <add name="ucommerce" connectionString="Data Source=(local);Initial Catalog=Umbraco;integrated security=SSPI;" providerName="System.Data.SqlClient"/>

Add commerce Element

    <runtimeConfiguration componentsConfigurationFile="Components.config" enableCache="false" cacheProvider="" />

With all that in place your App.config file should look like this

        <sectionGroup name="commerce" type="System.Configuration.ConfigurationSectionGroup">
            <section name="runtimeConfiguration" type="UCommerce.Infrastructure.Configuration.RuntimeConfigurationSection, UCommerce.Infrastructure" />
        <add name="ucommerce" connectionString="Data Source=(local);Initial Catalog=Umbraco;integrated security=SSPI;" providerName="System.Data.SqlClient"/>
        <runtimeConfiguration componentsConfigurationFile="Components.config" enableCache="false" cacheProvider="" />

Add Configs to Application Folder

Components.config holds information about all the various subsystems in uCommerce. Copy Components.config and Marketing.config from the website folder you installed Umbraco and uCommerce in, e.g. c:\inetpub\Umbraco\uCommerce\Configuration and copy them to your app folder.

Modify Components.config to Work Outside Web Context

The configuration files assume a web context so we’ll have to update them to work in a non web environment. Open up Components.config in your favorite editor and modify any life cycle with a value of “PerWebRequest” to “Thread”.

This tells uCommerce to create an instance of the object once per thread as opposed to once per request, which oviously doesn’t make sense for what we’re trying to do.

Do the same for Marketing.config if you intend to use that in your application.

Remove Includes in Components.config

Be sure to remove includes in components.config, which refer to Presenters.config and XmlRenderings.config.


Leveraging uCommerce outside a web site makes for some interesting use cases. Foremost is automated integration with other systems, but you could use this method to establish an offline Point of Sale or Kiosk-type system with a completely different frontend done in Windows Presentation Foundation for a rich in store experience.

posted on Wednesday, 03 August 2011 14:05:37 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Tuesday, 07 June 2011

FoundationWhen we first conceived of uCommerce years ago there was no uCommerce HQ and no real plan for what uCommerce should become. When time came to choose a data access layer we went the RAD route and chose Subsonic for its productivity benefits. Since then Subsonic has been a blessing and a course.

A blessing because it got us off the ground rapidly as intended and it introduced some pretty cool concepts to the uCommerce API such as LINQ based Active Record.

What really hurt was the complete lack of options for tuning queries for optimum performance. Subsonic is great for throwing together custom queries, but is rather lacking in projecting the needed result into an existing model. Basically this means lots of lots of lazy loading, which hurts performance badly due to the many tiny SQL queries being issued to the database.

Thus we decided to switch to a more full featured ORM and the natural choice at the time was NHibernate.

NHibernate has been present in uCommerce since the very early days. In fact it was introduced in uCommerce 1.0.2 to improve performance when querying the catalog via the XSLT API. We’ve slowly migrated bits and pieces of uCommerce to NHibernate where it made sense over the years.

uCommerce 2.0

During the past two years we’ve kept uCommerce backwards compatible with previous versions to make it simple to upgrade to new versions of uCommerce. With version 2.0 we didn’t really have that option anymore as we reached the end of what was possible to achieve internally so we decided to migrate the final uCommerce .NET APIs to EntitiesV2 and NHibernate.

What this means for you and existing code written against UCommerce.Entities, UCommerce.Runtime, and  UCommerce.Pipelines will have to be migrated to UCommerce.EntitiesV2.

The following article describes changes required to make your code run against the new API. Completing the migration will give you several benefits:

  • A clearer API to work with
  • Less code to write
  • Better performance
  • Caching support
  • Single programming model for everything

Ids vs Entities

One of the common patterns you see in Subsonic is the use of id properties to tie object together. This is not possible in NHibernate, which has a more entity focused approach.

NHibernate moves the responsibility of handling the association to the “aggregate root” or in other words to the more logical owner of the child object, e.g. the order handles order line.


var purchaseOrder = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder();
var orderLine = new OrderLine();
orderLine.OrderId = purchaseOrder.OrderId;


var purchaseOrder = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder;
var orderLine = new OrderLine();
// Notice that the purchase order is responsible for handling the operation

Three things are worth nothing here:

  1. We’re not setting any ids. It’s all handled behind the scenes by NHibernate.
  2. The order line is added via the AddOrderLine() method, which is a very common pattern in EntitiesV2.
  3. The purchase order is responsible for saving both the order itself and the order line.

Simple Deletes

More often than not you don’t want to delete an entire aggregate, but just a portion of it. Subsonic and NHibernate deal with this is different ways.


var orderLine = OrderLine.All().Single(x => x.OrderLineId == orderLineId);


var orderLine = OrderLine.All().Single(x => x.OrderLineId == myOrderLineId);
var purchaseOrder = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder;
// Notice the RemoveOrderLine patterns. Use it whenever you can to delete.

As you can see the order is still responsible for handling the delete of the order line. You simply remove the order line from the order with the RemoveOrderLine() method and it will get deleted automatically when the order is saved. Because the operations are not actually carried out until the Save is issued you get the benefit of bulk operations because they will be batched together once you save.

If you don’t use the method, but go the orderLine.Delete() route instead, you’ll often see the following error message, “deleted object would be re-saved by cascade (remove deleted object from associations)[UCommerce.EntitiesV2.OrderLine#2] ==> RemoveEntity”. This happens because the loaded order has a reference to the object and would re-save it to the database.

Deep Deletes

In Subsonic the pattern for deleting an object is very straightforward: You simply go order.Delete(). The issue with Subsonic is that it has no knowledge of relationships between objects so in many cases simply deleting an order would cause a SQL error because other data would be related to the order like order lines, properties, customer, shipments, addresses, etc.. So you have to know about these related objects and the order in which to delete them. Not very user friendly.


var purchaseOrder = PurchaseOrder.All().Single(x => x.OrderId == myPurchaseOrderId);
OrderAddress.Delete(x => x.OrderId == myPurchaseOrderId);
Shipment.Delete(x => x.OrderId == myPurchaseOrderId);
OrderProperty.Delete(x => x.OrderId == myPurchaseOrderId);
OrderLine.Delete(x => x.OrderId == myPurchaseOrderId);
// etc.


var purchaseOrder = PurchaseOrder.All().Single(x => x.PurchaseOrderId == myPurchaseOrderId);
// simple, no? :)

NHibernate is smart enough to know about the relationships between objects, so it’ll go ahead and delete related objects where it makes sense so you don’t have to think about it. These are called cascades and it’s the same mechanism, which ensured that our order line got saved in the previous example.

One to One Relationships

An interesting design decision with Subsonic is that it doesn’t expression one to one relationships, e.g. PurchaseOrder has one Customer. Instead Subsonic will treat all relationships as many to many, e.g. PurchaseOrder has many Customers, which makes sense from an ORM implementation point of view, but is very confusing for a developer trying to use an API built on this approach.

Of course NHibernate lets us map data exactly the way we want, which makes the API so much cleaner and simple to understand.


var purchaseOrder = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder;
// You have to know that there's only a single customer in the database explicitly.
var customer = purchaseOrder.Customers.Single();


var purchaseOrder = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder;
// With NHibernate the customer is mapped properly
var customer = purchaseOrder.Customer;

Many to Many Relationships

While Subsonic defines everything as a one to many relation it’s not so great a handling many to many relations. Typically these are implemented with a relation table to go between object A and B, like in the case of a category and product relationship where the same product might be present in multiple categories. Subsonic will map the go-between and require more code to handle the relationship.


// Grab a random product and category
var product = Product.All().First();
var category = Category.All().First();
// Create the relationship
var categoryProductRelation = new CategoryProductRelation();
categoryProductRelation.ProductId = product.ProductId;
categoryProductRelation.CategoryId = category.CategoryId;


// Grab a random category and product
var category = Category.All().First();
var product = Product.All().First();
// Simply add the product to the category and you're done

As you can see NHibernate completely eliminates the requirement to create the relation object yourself. It will handle the intricacies of the relationship behind the scenes for you.

LINQ to uCommerce

With the switch to NHibernate LINQ to uCommerce will gain new options as well. The most obvious change is that you can get away with writing less code than today when doing joins. In many cases you can even get rid of the join altogether.


var query = from product in Product.All()
            join categoryRelation in CategoryProductRelation.All() on product.ProductId equals categoryRelation.ProductId
            join category in Category.All() on categoryRelation.CategoryId equals category.CategoryId
            where category.Name = "My Category"
            select product;


var query = from category in Category.All()
            join categoryRelation in CategoryRelation.All() on category equals categoryRelation.Category
            join product in Product.All() on categoryRelation.Product equals product
            select product;
// Notice that ids are omitted from the query


As you can see there are significant changes between the Entities and EntitiesV2 APIs, but rest assured that migrating to the newer API is very straightforward. uCommerce Admin, which is a pretty significant codebase written entirely against the Entities API was migrated to EntitiesV2 in three days straight including testing. The benefits we’ve seen from the migration are significant. UIs are more responsive, code required to do a certain operation is clearer, and more often than not there’s less of it.

posted on Tuesday, 07 June 2011 11:38:33 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Wednesday, 18 May 2011

Baskets, carts, bags, whatever you want to call them, people have very different expectations of how they should work given the business they’re in. By default uCommerce uses cookies to find the basket for a given customer, which is handy because the basket automatically carries over if the customer logs in. No need to migrate it from an anonymous context to a customer context.

But what if you have scenario where multiple people use the same computer to shop from? Effectively they’d share the same basket because it’s effectively tied to the computer, not the customer.

Fortunately the uCommerce Foundation API makes it simple to override this behavior. So lets take a look at what’s required to change the default basket behavior.


uCommerce uses the IOrderContext interface to determine the basket of the current customer, specifically the GetBasket() and GetBasket(Boolean) methods are used. Let’s take a look at what the IOrderContext interface contains.


To make things are little easier we’re not going to implement IOrderContext from scratch, rather we’ll modify the default implementation, which comes with uCommerce called OrderContext.


As mentioned we’re looking to change the behavior of loading a basket for a customer and OrderContext has two methods for this purpose: GetBasket() and GetBasket(Boolean). Basically what we’re going to do is use the default behavior when a customer is not logged in and use our custom behavior whenever a customer is logged in.

Overriding GetBasket(Boolean)

First we need a new class to inherit the existing OrderContext and second override the two GetBasket methods.

using System;
using System.Linq;
using UCommerce.Entities;
using UCommerce.Runtime;
using umbraco.cms.businesslogic.member;
namespace MyUCommerceApp.Library
    public class MyOrderContext : OrderContext
        protected ICatalogContext CatalogContext { get; set; }
        public MyOrderContext(ICatalogContext catalogContext) : base(catalogContext)
            CatalogContext = catalogContext;
        public override Basket GetBasket(bool create) {}
        public override Basket GetBasket()
            return GetBasket(false);

So right now it doesn’t do much, so lets make it behave like the existing OrderContext when a customer is not logged in. We’re going to use the Umbraco Member API to determine whether a customer is logged in.

using System;
using System.Linq;
using UCommerce.Entities;
using UCommerce.Runtime;
using umbraco.cms.businesslogic.member;
namespace MyUCommerceApp.Library
    public class MyOrderContext : OrderContext
        protected ICatalogContext CatalogContext { get; set; }
        public MyOrderContext(ICatalogContext catalogContext) : base(catalogContext)
            CatalogContext = catalogContext;
        public override Basket GetBasket(bool create)
            // Member is not logged on use default behavior
            if (!Member.IsLoggedOn()) return base.GetBasket(create);
        public override Basket GetBasket()
            return GetBasket(false);

Now we’re actually detecting whether the customer is logged in and use the default behavior of OrderContext for customers not logged in.

Right now that means that the code is going to fail if a customer logs in, so lets add the final piece where we load the basket basket based on the current member id. If we can’t find a basket like that we’ll have to create one. Here we go.

using System;
using System.Linq;
using UCommerce.Entities;
using UCommerce.Runtime;
using umbraco.cms.businesslogic.member;
namespace MyUCommerceApp.Library
    public class MyOrderContext : OrderContext
        protected ICatalogContext CatalogContext { get; set; }
        public MyOrderContext(ICatalogContext catalogContext) : base(catalogContext)
            CatalogContext = catalogContext;
        public override Basket GetBasket(bool create)
            // Member is not logged on use default behavior
            if (!Member.IsLoggedOn()) return base.GetBasket(create);
            // Otherwise try and load a basket for the current member, create one if it doesn't exist
            Basket basket = GetBasketForCurrentMember() ?? CreateBasket();
            return basket;
        public override Basket GetBasket()
            return GetBasket(false);
        private Basket GetBasketForCurrentMember()
            PurchaseOrder order = PurchaseOrder.SingleOrDefault(
                x => x.OrderProperties.Where(y => y.OrderId == x.OrderId && y.Key == "MemberId" && y.Value == Member.CurrentMemberId().ToString()).Count() > 0 
                    && x.OrderStatusId == 1);
            if (order != null) return new Basket(order);
            return null;
        private Basket CreateBasket()
            var catalogId = 0;
            int.TryParse(CatalogContext.CurrentCatalogName, out catalogId);
            var catalog = ProductCatalog.SingleOrDefault(c => c.Name.Equals(CatalogContext.CurrentCatalogName)) ??
                ProductCatalog.SingleOrDefault(c => c.ProductCatalogId == catalogId);
            if (catalog == null)
                throw new InvalidOperationException("Cannot create basket when not in product catalog. Make sure that SiteContext.Current.CatalogContext.CurrentCatalogName contains the name of the current product catalog.");
            return CreateBasket(catalog.PriceGroups.First().Currency);
        private Basket CreateBasket(Currency currency)
            var catalogGroup = ProductCatalogGroup.SingleOrDefault(g => g.Name.Equals(CatalogContext.CurrentCatalogGroupName));
            if (catalogGroup == null)
                throw new InvalidOperationException("Cannot create basket without product catalog group. Make sure that SiteContext.Current.CatalogContext.CurrentCatalogGroupName contains the name of the current product catalog group.");
            PurchaseOrder order = new PurchaseOrder();
            order.OrderStatusId = 1;// (int)PurchaseOrder.StatusCode.Basket;
            order.ProductCatalogGroup = catalogGroup;
            order.CurrencyId = currency.CurrencyId;
            order.BasketId = Guid.NewGuid();
            order.CreatedDate = DateTime.Now;
            // Set the member id on the order so we can retrieve it later on
            order["MemberId"] = Member.CurrentMemberId().ToString();
            return new Basket(order);

The thing that makes the code above tick is the used of dynamic order properties. Basically a way of setting custom data on the order or individual order lines. Whenever a new basket is created by MyOrderContext it will store the current member id on the order itself and use that to load the basket the next time around.

Registering MyOrderContext with uCommerce

To test our new context class we’ll have to let uCommerce know it exists. The way to do this is to edit the components.config file, which holds information about all the components of uCommerce. You’ll the file in /umbraco/ucommerce/configuration/components.config and this is what it looks like.


We’re looking for the IOrderContext registration.


A registration basically refers to a service, typically an interface like IOrderContext, a type, which is the actual implementation to use for that particular interface, and a lifestyle, which is how long the object will live. You can read more about lifestyle if you’re interested, but for now just leave that attribute alone.

We’ll have to put in our type and assembly for IOrderContext. For this example my code compiles to MyUCommerceApp.Library.dll and the type is called MyUCommerceApp.Library.MyOrderContext, so that’s what we’re going to swap in to replace the current order context.

<component id="OrderContext"
    service="UCommerce.Runtime.IOrderContext, UCommerce"
    type="MyUCommerceApp.Library.MyOrderContext, MyUCommerceApp.Library" lifestyle="PerWebRequest"/>

What that we’re ready to test our site. The behavior you’ll see is that you’ll get one basket when you’re not logged in, the default behavior, and another basket when you log in, our new custom behavior.

In Summary

As you can see overriding the default basket behavior of uCommerce is straightforward and you can achieve exactly the behavior you want. You saw a couple of interesting pieces put together to make it work: The IOrderContext and OrderContext, which were overridden to inject our custom behavor, the dynamic order property for storing our member if, and finally the component registration to tell uCommerce about our custom component.

Components in particular is a useful thing to know about as there are many opportunities to override the default behavior almost any aspect of uCommerce in there.

Other interesting examples for overriding GetBasket() might be to:

  • Do individual baskets between stores when working with a multiple store setup in the same uCommerce installation to replace the default shared baskets.
  • Work with multiple baskets per customer for wishlist and gift registry scenarios.
  • Support impersonation to enable a customer representative take over the customer basket to help her through checkout.

The sky’s the limit.

posted on Wednesday, 18 May 2011 10:33:33 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Thursday, 10 March 2011


uCommerce 1.5 introduces nice URLs for catalogs, categories, and products. The basic idea is to provide keyword rich URLs for catalog items to increase page rank in search engines like Google and Bing. Really though, who are we kidding here? It’s just for Google  :)

Based on Existing Catalog Information

To keep maintenance low uCommerce generates URLs based on information already present in the catalog. To support multilingual sites display names are used when present otherwise standard internal names are used. This gives webshops built with uCommerce the ability to rank on search terms specific to the culture the online store services, e.g. English terms for English stores, Spanish terms for Spanish stores, etc..

URLs are structured in three parts:

  1. The domain name, which also determines the language to use as per Umbraco hostname
  2. The search engine friendly soft middle
  3. And finally the payload at the end, which enables uCommerce to figure which type of URL it’s dealing with

For a sample URL like www.myonlinestore.com/apparel/c-24 the three pieces are:

  1. “www.myonlinestore.com” – domain name of the store as set up in Umbraco
  2. “apparal” – search engine search term
  3. “c-24” – identifier of the catalog for uCommerce to use

Basically Umbraco and uCommerce only need the first and last pieces while the rest is all for Google.

Nice URLs from XSLT

To start using nice URLs in your own uCommerce solution you’ll need to use one of the following XSLT extensions:

GetNiceUrlForCatalog(string catalogName)
GetNiceUrlForCategory(string catalogName, string categoryName)
GetNiceUrlForProduct(string catalogName, string categoryName, string sku)
GetNiceUrlForProduct(string catalogName, string sku)
GetNiceUrlForVariant(string catalogName, string sku, string variantSku).

There are multiple extensions for each type of URL you’ll generate as they have slightly different needs for the final result. The method will generate the following URLs:

Catalog called “Apparel”

<xsl:variable name="catalogUrl" select="CommerceLibrary:GetNiceUrlForCatalog('Apparel')"/>


Category called “T-shirts” nested in “Shirts” / “Men”

<xsl:variable name="categoryUrl" select="CommerceLibrary:GetNiceUrlForCategory('Apparel', 'TShirts')" />


Product “Short sleeved green t-shirt

<xsl:variable name="categoryUrl" select="CommerceLibrary:GetNiceUrlForProduct('Apparel', 'TShirts', 'Green-TShirt')" />


<xsl:variable name="categoryUrl" select="CommerceLibrary:GetNiceUrlForProduct('Apparel', 'Green-TShirt')" />


Nice URLs from .NET

To generate those same URLs from .NET you’ll use the IUrlService. Using the ObjectFactory class you can resolve the configured instance for the interface. The default implementation is called UrlSerivce. More on that later.

IUrlService urlService = ObjectFactory.Instance.Resolve<IUrlService>();
ProductCatalog catalog = ProductCatalog.SingleOrDefault(x => x.Name == "Apparel");
string catalogUrl = urlService.GetUrl(catalog);
Category category = Category.SingleOrDefault(x => x.Name = "TShirts");
string categoryUrl = urlService.GetUrl(catalog, category);
Product product = Product.SingleOrDefault(x => x.Sku == "Green-TShirt" && x.ParentProductId == null);
string productIncludingCategoryInfoUrl = urlService.GetUrl(catalog, category, product);
string productUrl = urlService.GetUrl(catalog, product);

Building Your Own Nice URLs


If you wish to customize the default nice URLs you can go ahead and inherit the class UrlService and override any methods you’re not happy with. Should you need to replace the default nice URLs generated by uCommerce you can implement the IUrlService interface from scratch.

If for instance you need complete control over the keywords added to the URL your custom implementation might grab information not from the display name, but from a dedicated field on the category or product.

In any case you have to register your custom implementation via /umbraco/ucommerce/configuration/components.config. Just look for the existing registration of IUrlService.

URL Rewrite Rules

UrlRewriting.NET contains the set of rules, which define what URL the customer sees and what that URL should look like to the system.

You will not have to change the existing rules even if you implement your own UrlService as long as you keep the last part of the URL the same, i.e. the /c-xx/c-yy/c-zz part. This is the marker used for the rules to pick up a rewritten URL so you can include anything before that part. If you don’t want the marker as part of your URL you’ll have to modify the default rules.

Each rule is automatically deployed when uCommerce is installed and is found in /config/UrlRewriting.config in your website folder. If you wish to modify the default rules this is the place to do it.


Nice URLs help the search engine optimization process for webshops built with uCommerce and will make pages in your webshop rank higher. Any URL scheme is supported by overriding the default implementation found in UrlService.

posted on Thursday, 10 March 2011 22:32:35 (Romance Standard Time, UTC+01:00)  #    Comments [0] Trackback
# Thursday, 03 March 2011

Probably the most interesting new feature to come to Umbraco lately (for .NET developers anyway) is support for the Razor view engine. The Razor view engine was originally (sounds like it was year ago when in fact it only happened recently) introduced with MVC 3 to reduce friction when writing UI code.

XSLT, .NET, or Both

NET-logoXSLTOne of the first questions I’m asked when I demo uCommerce to new partners is, “should we use XSLT or .NET user control to build our uCommerce sites”.

My advice over the past couple of years has always been to use XSLT for static listings and roll out .NET for the more dynamic pieces like the check out flow or advanced product pickers.

It’s no secret that my background in .NET makes me whip out Visual Studio for almost everything, but XSLT does have some interesting attributes like the ability to build out a UI in no time and reskin existing UIs rapidly. That’s why we built the uCommerce Demo Store in XSLT exclusively and that’s why I originally invested some time in getting to know it.

Now, however, my advice might be about to change. Read on and find out why.

Introducing Razor, Macros on Steroids!

The answer to make .NET devs as efficient creating UIs as XSLT gurus is Razor. While it won’t make developers better designers it will enable them to roll out UIs very rapidly and in a more fluent manner to boot.

The Razor view engine is basically an advanced parser, which enables you to write code much more fluently than what was possible with the WebForms view engine. Gone are the days of <%%> replaced by @.

Basically you can now write code like this in your macros and it will render properly inside your templates.

@using umbraco.cms.businesslogic.member
@if (Member.GetCurrentMember() != null)
    @string.Format("Hello there, {0}, nice to see you again!", Member.GetCurrentMember().LoginName)

And this is what it looks like in Umbraco itself. Pretty straightforward, right? Create a new script file using CSHTML and then create a new macro, select the script you created previously, and you’re good to go.



uCommerce and Razor: Product Listing

So how does this work with uCommerce? As it turns out, quite well. The Active Record pattern combined with LINQ to uCommerce turns out to be a perfect fit for the Razor coding style. Lets see what it takes to get some products into the mix, shall we?

It’s very straightforward: Import the uCommerce entities and query away!

@using UCommerce.EntitiesV2
@foreach (var product in Product.All())


Not surprisingly, the code produces the following result.


But what’s with the 5, 10, and 15? Turns out that the list contains both product, product families, and variants. Lets expand on the query a bit and only display the top level products and families.

Notice how the following query now has a Where clause on the call. What we’re doing is filtering the result to only grab the products we want. See how easy that is? Common operations like filtering, grouping, and even joining is supported which opens up for some very interesting scenarios.

@using UCommerce.EntitiesV2
@foreach (var product in Product.All().Where(x => x.ParentProductId == null))


Simple Basket Page

How about another one just for kicks? What’s interesting here is that we’re leveraging the context aware API of uCommerce to determine the basket given the current customer. Because the API deals with context you don’t have to worry about getting the right data, it’s just there ready to be consumed.

@using UCommerce.Runtime
    <th>SKU</th><th>Name</th><th>Qty</th><th>Unit Price</th><th>Total</th>
    @foreach (var orderLine in SiteContext.Current.OrderContext.GetBasket().PurchaseOrder.OrderLines) 

Again the code above is a full Razor macro in Umbraco, which is placed on a template to achieve the output below. With that we’ve got the beginnings of basket overview page. See how clean that is?



While Razor was introduced in Umbraco 4.6 it’s not really until 4.7 it’s become really usable. In testing uCommerce with Umbraco 4.7 I found the combination of Razor and LINQ to uCommerce to work surprisingly well. The flow inherent in Razor is carried over to the uCommerce API. As a result the code flows naturally just the way we like it.

With Razor .NET developers start to see the same level of productivity which has been exclusive to the XSLT gurus when creating UIs. Not only that but the UI code is very readable and the full .NET framework is available without having to resort to XSLT extensions as is the case with XSLT today.

posted on Thursday, 03 March 2011 22:05:36 (Romance Standard Time, UTC+01:00)  #    Comments [0] Trackback
# Wednesday, 02 March 2011

Social commerce is all about customers engaging each other helping online stores and webshops sell more by leveraging the high degree of credibility inherent in personal recommendations and getting the word out to a wider audience. Social commerce is available in many guises: At uCommerce we tend to think about it as internal- and external social commerce.

Reviews, Ratings, and Comments

The very first step in adopting social commerce is to enable customers to post reviews. As such we’re dealing with internal social commerce as everything happens in the webshop and doesn’t involve interaction with sites like Facebook and Twitter.

Even in online stores stores with product lines changing frequently there’s value to adding reviews to products as customers tend to skip past product information and dive straight into the user generated content to see whether or not a product is worth any further the attention.

Product Ratings

When a customers look at product information the very first thing that will catch her eye is the star rating of a product. uCommerce enables customers to post ratings. Each rating is aggregated into an average rating stored on each product, which can be used for searches, filtering, and custom product listings like “Most popular in this category”.

Ratings with no additional content require no approval and will be aggregated into the overall score by default. This behavior can be overridden by modifying the Product Review Pipeline.

Star Ratings in Google Search Results

Product review in Google Search

When searching for products online which link would you be more inclined to click? The one with no star rating or the one with star rating?  When searching on Google and Bing you’ve probably noticed that some search results are displayed with a star rating. This helps your search results stand out in the crowd and will bring in new customers.

The uCommerce Store supports this out of the box by leveraging a micro format that Google and Bing recognizes and will display as part of the search result bring more “foot traffic” into the webshop.

Product Reviews


uCommerce enables customers to add product reviews on individual products and submit them either directly to the site or, if enabled, for approval by store managers. Product reviews consists of a rating, a review headline, and a review body. If a customer is logged in the review can optionally be associated with that particular customer, which will make the reviews even more effective by letting you display information about the reviewer such as the first name. More on that later.

Because uCommerce supports multiple stores and languages each product review is associated with the store in which it was received, which makes it possible to display just the reviews received in a particular store.

Of course you’ll want to get as much review bang for your buck so more often than not reviews will be displayed from all stores, but you do have a choice.


Comments and Helpful Reviews


To further improve the value of having product reviews on a webshop you can open up for comments on existing reviews. The simplest form of commenting on a review is to indicate whether or not it was helpful, but the customer can go ahead and add a text comment as well to further explain her position or ask questions of the reviewer to get the conversation going.

Customer Information

As you can see in the previous screenshots information about the customer adding content is added to the review or comment. Customers are integrated with site members so you’re effectively free to add as much additional information to the customer profile and by extension the reviews themselves.

Optionally you can require the customer to log in before being able to comment as is the case on Amazon.com or just leave the floodgates open and let anyone comment if they provide an e-mail, which leads us to the next topic: Reporting Abuse.

Reporting Abuse


The internet can be a downright nasty place with scammers and spammers in abundance. When a site opens up to user generated content it better be prepared to deal with spam. Fortunately uCommerce supports multiple kinds of protection. You can enable customers to report abuse and thus bring any unsuitable content to your attention for approval. Abuse can be reported for both reviews and individual commets.

By default content reported as spam is still displayed on the site to prevent users from removing content from the site until it can be reviewed and approved. If content is to be removed from the site immediately you can do so as well by modifying the filters for user generated content which is not to be displayed.

Approval Workflow


Once user generated content is reported as abuse it will show up in the administration backend where store owners and managers approve or unapprove content.

The approval workflow is available both on the product level and more importantly on the store level as well to make sure that the process of approving reviews is as efficient as possible. Reviews can be removed at any time at the store manager’s discretion.

When viewing the “Pending Reviews” tab on each store only reviews and comments, which require attention are displayed. While everything is displayed on the product level.

Should you want to have all reviews and comments screened before allowing them onto your website, you can indicate so on each of the stores by ticking the “Product reviews require approval” check box.


Automatic Workflow via Pipelines

As new ratings, reviews, and comments are received they are processed by uCommerce Pipelines, which enables automatic steps to be carried out for each piece of user generated content. Developers can extend these pipeline with custom logic to support custom requirements.

To give you an idea of what can be done using the pipelines here are some ideas:

You might want to check whether the customer has submitted a high number of reviews inside a short timeframe, which might indicate a spammer or you could notify store managers whenever new content requires attention.

This is also true whenever content is approved or unapproved in the backend. You might want to send an e-mail to the customer who submitted the review when it’s approved so they can see their handiwork on your site (thus bringing back the customer to the store) or you could post teasers from reviews on your Facebook fan page or to Twitter.

Please see uCommerce Pipelines Explained for detailed information on extending the Product Review and Product Review Comment pipelines.


Social commerce is many things to many people, but in the end a good place to start is by opening up for user generated content like ratings, reviews, and comments on your e-commerce site to increase conversion rates. Keep in mind that while user generated content will help sell more there are caveats associated with it. It’s important to ensure that only proper content makes it onto your site either by using an approval workflow like the one previously described, by requiring user login to be able to review, or by letting customers report abuse.

posted on Wednesday, 02 March 2011 11:15:03 (Romance Standard Time, UTC+01:00)  #    Comments [0] Trackback
# Monday, 28 February 2011

To lead off the documentation on how to build the various parts of a uCommerce based e-commerce site I wanted to first describe what those components are. Having worked with a multitude of clients and projects in my career I’ve come to take many of these things for granted. As uCommerce grows in popularity I wanted to share some of these things in the hopes of making your next e-commerce project a bit smoother.

If you missed the first article in the series called Anatomy of an E-commerce Solution: Browse, which deals with product catalogs and product presentation.

Micro Conversions

imageToday e-commerce stores and webshops are all about enabling store owners to tell their story. While the CMS plays a hugely important role in this area, marketing is another story altogether. Marketing can be divided into internal- and external marketing.

Internal marketing is about setting up special offers for customers to further engage them in the buying process. Too often focus is solely on the the macro conversion, i.e. converting the user to a customer when in reality you need to focus equally on micro conversions, i.e. the act of convincing the user to perform minor conversions with the final goal of getting to the macro conversion.

The most common micro conversion is to offer the user to sign up for a newsletter so you might engage her later on  with direct e-mail communication, but there are many opportunities for micro conversions in webshop like getting them to add more demographic information to their profiles to provide better targeting for site ads and discount, getting them to download sales materiales, or get in touch with a sales representative via e-mail or live chat.

Site Ads

You want the user to navigate to interesting products, so why not throw up a banner advertising for the unique selling points of the products or offer up some additional information about the product like a PDF or video? Or how about letting your users compare products? Banners range from the run of the mill “Buy for x amount and get free shipping” to more advanced banner where you tell the customer exactly what they need to do to get the discount, “Buy for x amount more and get shipping shipping, i.e. the banner is aware of the customer context and shows how much more the customer must buy for the get the discount – a much more actionable banner than the first one.

Social Commerce with Customer Reviews and Ratings

imageOne of the most efficient marketing activities is to let customers do marketing on behalf of the store by enabling them to give ratings and perform full product reviews. Reviews and ratings made by actual people have a very high degree of credibility and many users turn to the reviews section of the product page to find out whether the product is right for them or not.

Indeed research today shows an increasing number of customers not willing to buy products without having consulted product reviews prior to the purchase.


At the end of the day store owners need tools to convince the customer to convert. These tools might include incentives like reduced prices, over all discounts on the order itself, or voucher codes. Discounts come in many shapes and forms and are usually grouped in campaigns, which run for a certain amount of time after which they are removed from the site. In other words we’re dealing with temporary pricing and benefits.

Your most common types of discounts include “buy two for one”, “percentage off the order”, “amount off the order”, “volume discount”, “free shipping”, and more.

Vouchers and Gift Cards

Vouchers and gift cards are a certain type of discount which be paired with individual products, entire categories, or just the vanilla stand alone voucher. They enable store owners to pass out codes which can be used during checkout to receive a discount. Vouchers are a very effective means of converting the customer or getting repeat business from existing customers.

Vouchers are often used as a means of increasing the effectiveness of external marketing by including voucher codes with e-mail marketing campaigns, in print media, or on billboards.

Gift cards are basically a variation on the voucher with the main difference being that we’re not really dealing with a discount anymore as a customer will pay full price for the privilege of using the


imageWith ads and discounts in place you’ll want to target customers with your message. For that purpose targeting is often used. Basically targeting will enable a store owner to configure who should be exposed to a particular message and determine when a discount should be triggered for a customer. Targeting often works by collecting information about the anonymous user on the site: Which products did she look at during the visit, which ones are displayed right now, what was the entry point into the store, any search terms which brought her to the store in the first place.

These are the basics, but often you’ll go a step farther and start building a profile about a given customer. By categorizing content and products the profile will be become more complete over time and as that happens targeting will become ever more precise to the point where the anonymous customer can be placed in a segment.

Once the customer logs in the profile will often be carried over and the store owner will know even more about the particular customer. A scary example of this in practice is Amazon, which it seems will pick up which products you look at and some days later will send a targeted e-mail to you offering a special on…. exactly the products you viewed.

Scary and brilliant at the same time. The mechanics are pretty straightforward when you think about it.

External Marketing

External marketing include all the activities which drive new traffic to your site including search engine optimization, search engine marketing, link building, social marketing, etc.. While support for some of these activities can be characterized as convenient others must be supported directly in the platform for your solution to rank highly. These include the ability to add custom meta data to your products, have pretty URLs laden with search terms, having product reviews formatted using one of the micro formats that Google recognizes to display as part of search listings.

Content is king in this matter. You can optimize all you want, but in the end getting incoming links to the store by having great content is what really counts. And it’s more interesting to create too.

Common Pitfalls

One surprise I’ve had far too often when shopping online or dealing with existing webshops is customers getting a discount by accident. By accident I mean the case where customers are never told about the discount until they’re in the check out flow and notice a lower price than what was listed. Store owners who do this sort of thing might as well toss money in the toilet – it’s more fun and would yield the same profit at the end of the day. The customer didn’t know about the discount, she would have bought the product anyway so why bother having a discount at all?

It’s crucial to remember that marketing is not about lowering pricings or giving great discounts it’s about getting the message out. If you don’t get the message out you might as well not bother.


I’ve only started to scratch the surface of what marketing in an online store or webshop entails, but these are some of the scenario that you’ll be expected to support in your e-commerce solution. Some of it is pretty srraightforward to build, other areas not so much. The area which will trip you up is typically the management pieces and targeting of content and discount. These are areas which either require very efficient workflows or complicated logic to achieve.

Check out the first article in the series called Anatomy of an E-commerce Soltion: Browse, which deals with product catalogs and product presentation.

posted on Monday, 28 February 2011 13:50:35 (Romance Standard Time, UTC+01:00)  #    Comments [1] Trackback