Tuesday, January 22, 2013

Introducing ContentService aka the v6 API

The website and the source code used in this tutorial is available on GitHub.

In this little tutorial, I’ll show you how the new APIs in Umbraco 6 works, by importing a CSV file with products into Umbraco nodes.

For a start, I’ve downloaded Umbraco 6 (currently the RC) and installed the Basic starter kit with the “Sweet As” skin. That gives me a nice baseline for a simple site and also confirms that Umbraco 6 is compatible with most of the existing packages.

The products that I want to import, comes from our own ERP in the HQ. We use a SaaS product called E-conomic (which is awesome, btw) and it’s easy to export our products into an Excel/csv file. For simplicity, I’ve kept it to a very simple model where each product has a Product Id, a Name, a Group and a price.

So to prepare for the import, I’ve made three Document Types:

  • A “Store” document type, which is basically just a container for the products
  • A “Product Group” that lives beneath the store. It has a single property which is the e-conomic (our ERP) GroupId. As we only had seven product groups, I’ve just created them manually.
  • A “Product” that is a child of “Product Group”. To match my exported data it has a Product Id, a Name and a Price. The nice thing about the Umbraco CMS is that I can always enrich the boring ERP product data with Umbraco properties such as photos and Rich text descriptions (including embedded YouTube videos to show off the product).

Let’s get started

As I won’t go into details about parsing CSV files (you can look at the full source for that), the code shown in this tutorial is the simplified methods that takes a Name, Product Id, Price and a Product Group and creates it as a node. But as I want to be able to upload a CSV file, I’ll add a simple .NET UserControl to the Dashboard inside the Umbraco backoffice which contains a File Control and a button. It’ll look something like this:

Screen Shot 2013-01-22 at 12.10.30 PM

If you’ve never played with customizing the Umbraco Dashboard, it’s as easy as editing the /Config/Dashboard.config file. In that file you can add tabs to sections, place User Controls inside the tabs and even add permissions to what type of users can see what tabs. The details, however is a different story – this tutorial are supposed to be about the new API!

Meet ContentService

The new API consists of a number of services which is your “gateway” to Umbraco data. In this tutorial we’ll look at the ContentService which – as you may have guessed – is our “gateway” to interact with content in Umbraco.

When you’re in a User Control or a Template, accessing the ContentService is easy and we’ll get to that in a minute. But before we show you the easiest way, it’s good to know that there are various ways to get to the ContentService. Most of all it depends on whether you’re already in a context of an Umbraco page (technically in an UmbracoContext - for instance in a Template or a view) or if you’re in a Console App (yes, that works!). No matter where you are you can always get to the ContentService via ApplicationContext.Current.Services.ContentService. The ApplicationContext as well as the various Services lives in the Umbraco.Core namespace and is part of the Umbraco.Core.dll. The UmbracoContext and UmbracoUserControl is found in the Umbraco.Web namespace which is a part of the “umbraco.dll” assembly (and that is the name – not Umbraco.Web as that would break backwards compatibility with v4).

So to get started, you’ll need to make a reference to “umbraco.dll” in your Visual Studio project. When you use the ContentService through a User Control, it’s also a good idea to make a reference to “Umbraco.Core.dll”. This allows you to make your User Control inherit from “Umbraco.Web.UmbracoUserControl” instead of the normal “System.Web.UI.UserControl” and gives you super easy access to local Umbraco data as well as the ContentService.

In this example I am using an UmbracoUserControl, but be aware that all the examples could also work in a webservice, a console app or even a Windows Service as long as you can get hold of a valid ApplicationContext.

Ok, enough boring theory – let’s import some products

As you may remember, the original purpose of this tutorial was to show you how simple it is to import our ERP product data as Umbraco Content items (nodes). Now that we’ve learned about the ContentService, UmbracoUserControl and our product Document Type, it’s really easy to creating content items:

privatevoid ImportProduct(int productId, string name, int productGroup, int price) { // Get the Umbraco Content Service var contentService = Services.ContentService; var product = contentService.CreateContent( name, // the name of the product 1000, // the parent id should be the id of the group node "product", // the alias of the product Document Type 0); // We need to update properties (product id, original name and the price) product.SetValue("productId", productId); product.SetValue("originalName", name); product.SetValue("priceDKK", price); // finally we need to save and publish it (which also saves the product!) - that's done via the Content Service contentService.SaveAndPublish(product); }

Because we’re in an UmbracoUserControl, we can access the ContentService via a local variable called “Services”. The ContentService has a handy method to create content called “CreateContent” which takes 4 parameters:

  • Name of the new Content item being created
  • The parent id of the new Content item
  • The alias of the document type
  • The id of the user creating the content

The CreateContent method returns a Content item (an IContent) which also allows us to easily edit custom properties via the SetValue method that simply takes the alias of your custom property and a value (Object).

Once we’ve populated our content item, it’s time to Save and maybe also Publish it. It’s as simple as passing our Content object (product) to the SaveAndPublish method of our ContentService.

If you’re used to the old APIs, then you know that this wasn’t needed as data was saved the moment you assigned values to the properties. This caused a lot of database queries and really not considered good practice. With the new API, it’s not until you pass the Content item to the ContentService that a database query is made within a single transaction. With the old API the code above would generate at least five queries but maybe even more if the cache wasn’t up to date.

In the old API you also had to call two different publish methods – one that prepared the document for publish and one that refreshed the cache. With the ContentService, all you need to do is call the SaveAndPublish() method and you’re in business.

The Visual Studio sample project contains a more thorough example where I also update existing Content items and use the fabulous uQuery to look for data.

More to come

In this little tutorial we’ve shown you the first glimpse of what the ContentService can do for you and I’ve deliberately tried to keep it very simple. But the ContentService is more than just simple save and publish - it also support transactional bulk saves as well as bulk publishes. I’ll show you how we can easily refactor the code to support this in a coming tutorial.

Is there other examples or things you’d like to see covered? Let me know in the comments!

Want to be updated on everything Umbraco?

Sign up for the Umbraco newsletter and get the latest news and special offers send directly to your inbox