Nibble

Archive for April, 2013

Single page CRUD app with Umbraco 6 33

A little experiment in using Umbraco as a datasource for a single page CRUD app. Making use of the new Umbraco APIs (ContentService and UmbracoAPIController).

 

Umbraco setup

Using Umbraco 6.1 beta (since that includes the UmbracoApiController).

Default rendering engine is set to MVC (this is setup in the /config/umbracoSettings.config).

Two doctype are in place

    • HomePage (with a property footer of type richtext editor)
    • Status (with a property message of type textbox multiple)

So this is how the content structure looks (and with the app we’ll be able to list/create/update/delete status content docs)

image

Creating the model

The data that we’ll pass between client and server, It’s a pretty simple model with only a couple of properties (the id, need that to be able to edit, and 2 other properties that will be used for the content name and the message field).

   public class Status
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Message { get; set; }
 
    }

 

Creating the API

Since we want to create a RESTful application the obvious choice would be to use WEB API and use a API controller, you can do that in Umbraco, there is a base Web Api controller you can inherit from that will expose Umbraco related services and objects, the UmbracoApiController (available since 6.1 beta)

It’s important that the controller class name is suffixed with "ApiController"

public class StatusApiController : UmbracoApiController
{
}

With that in place we can start adding the methods that we’ll need

Fetching documents

For querying published content we’ll be working with strongly typed Content (of type IPublishedContent).

Getting all status docs underneath a certain parent and mapping them to the type of our model

 public IEnumerable<Status> GetAllStatuses(int parentId)
        {
            UmbracoHelper help = new UmbracoHelper(UmbracoContext);
            return help.TypedContent(parentId)
                .Children
                .Where(c => c.DocumentTypeAlias == StatusDocTypeAlias)
                .Select(obj => new Status()
            {
                Title = obj.Name,
                Message = obj.GetPropertyValue<string>(MessagePropertyAlias),
                Id = obj.Id
            });
        }

 

Getting a doc by it’s id and mapping it to our model type

        public Status GetStatus(int id)
        {
            UmbracoHelper help = new UmbracoHelper(UmbracoContext);
            var content  = help.TypedContent(id);
            return new Status
            {
                Id = content.Id,
                Title = content.Name,
                Message = content.GetPropertyValue<string>(MessagePropertyAlias)
            };
        }

Create/Update/Delete documents

For this we’ll make use of the new APIs available in v6, the new API consists of a number of services since we are interacting with content we’ll be using the ContentService. Because our controller inherits from the UmbracoAPIController we can easily access the ContentService with Services.ContentService

Creating a new doc (+ setting prop value + save and publish)

 public Status PostStatus(Status status, int parentId)
        {
            var cs = Services.ContentService;
            var content = cs.CreateContent(status.Title, parentId, StatusDocTypeAlias);
            content.Name = status.Title;
            content.SetValue(MessagePropertyAlias, status.Message);
            cs.SaveAndPublish(content);
            status.Id = content.Id;
            return status;
        
        }

Updating a doc

 public Status PutStatus(Status status)
        {
            var cs = Services.ContentService;
            var content = cs.GetById(status.Id);
            content.Name = status.Title;
            content.SetValue(MessagePropertyAlias, status.Message);
            cs.SaveAndPublish(content);
            return status;
 
        }

Deleting a doc

 public void DeleteStatus(int statusId)
        {
            var cs = Services.ContentService;
            var content = cs.GetById(statusId);
            cs.Delete(content);
        }

 

The App

To create the actual app that will make use of our api   I used AngularJS, that made it pretty simple.

To show a small snippet (http delete against the DeleteStatus method)

            $http({ method: ‘DELETE’, url: ‘/umbraco/api/StatusApi/DeleteStatus/’, params: { statusId: $routeParams.Id } })
                .success(function (data) {
                    
                    $rootScope.alert = true;
                    $rootScope.alertMessage = "Status removed";
                    
                    $location.path(‘/list’);
                })
                .error(function () {
                    $scope.error = "An Error has occured while deleting!";
                });

For an intro on AngularJS check http://www.egghead.io/ 

For the UI Bootstrap is used

Source code

Complete example site and source code is available on github

https://github.com/TimGeyssens/UmbracoSinglePageCrudApp