Single page CRUD app with Umbraco 6 1
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)
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
