Archive for the 'Umbraco' Category

UI-O-Matic Event Model 0

The most recent version of UI-O-Matic (1.4.0 at this moment) introduces a couple of events that allow you to do some interesting stuff. The events are all placed on the PetaPocoObjectController (that’s the controller responsable for handling the crud operations).

Following the Umbraco convention there are before and after events.

BuildingQuery and BuildedQuery

These execute when UI-O-Matic builds the sql query for fetching the list view data. By default UI-O-Matic will fetch all the data from the table but using these events you can limit that by still having control over the query before it is executed.

CreatingObject and CreatedObject

These will execute when UI-O-Matic is inserting an object, so you can use these events to set values.

UpdatingObject and UpdatedObject

These will execute when UI-O-Matic is updating an object


1 public class EventHandlerscs: ApplicationEventHandler 2 { 3 protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) 4 { 5 UIOMatic.Controllers.PetaPocoObjectController.CreatingObject += PetaPocoObjectController_CreatingObject; 6 UIOMatic.Controllers.PetaPocoObjectController.BuildingQuery += PetaPocoObjectController_BuildingQuery; 7 } 8 9 void PetaPocoObjectController_CreatingObject(object sender, UIOMatic.ObjectEventArgs e) 10 { 11 if (e.Object.GetType() == typeof (ccpEvent)) 12 { 13 ccpEvent ob = (ccpEvent) e.Object; 14 ob.IsApproved = true; 15 } 16 } 17 18 void PetaPocoObjectController_BuildingQuery(object sender, UIOMatic.QueryEventArgs e) 19 { 20 if (e.TableName == ccpEvent) 21 e.Query.Where(AREAID = @0, 2); 22 } 23 }

UI-O-Matic, handling Foreign Keys 10

Something you’ll bump into sooner or later when working with custom tables are relationships between tables.

Let’s say we have the following 2 pocos (and matching tables)


1 [UIOMatic("People", "icon-users", "icon-user",SortColumn="FirstName")] 2 [TableName("People")] 3 public class Person : IUIOMaticModel 4 { 5 public Person() { } 6 7 [UIOMaticIgnoreField] 8 [PrimaryKeyColumn(AutoIncrement = true)] 9 public int Id { get; set; } 10 11 [UIOMaticField("Firstname","Enter your firstname")] 12 public string FirstName { get; set; } 13 14 [UIOMaticField("Lastname", "Enter your lastname")] 15 public string LastName { get; set; } 16 17 [UIOMaticField("Picture", "Please select a picture",View ="file")] 18 public string Picture { get; set; } 19 20 public override string ToString() 21 { 22 return FirstName + " " + LastName; 23 } 24 25 public IEnumerable<Exception> Validate() 26 { 27 var exs = new List<Exception>(); 28 29 if (string.IsNullOrEmpty(FirstName)) 30 exs.Add(new Exception("Please provide a value for first name")); 31 32 if (string.IsNullOrEmpty(LastName)) 33 exs.Add(new Exception("Please provide a value for last name")); 34 35 36 return exs; 37 } 38 }


1 [UIOMatic("Dogs", "icon-users", "icon-user", RenderType = UIOMaticRenderType.List)] 2 [TableName("Dogs")] 3 public class Dog : IUIOMaticModel 4 { 5 public Dog() { } 6 7 [UIOMaticIgnoreField] 8 [PrimaryKeyColumn(AutoIncrement = true)] 9 public int Id { get; set; } 10 11 12 public string Name { get; set; } 13 14 [UIOMaticField("Is castrated", "Has the dog been castrated")] 15 public bool IsCastrated { get; set; } 16 17 18 19 public int OwnerId { get; set; } 20 21 public override string ToString() 22 { 23 return Name; 24 } 25 26 public IEnumerable<Exception> Validate() 27 { 28 var exs = new List<Exception>(); 29 30 if (string.IsNullOrEmpty(Name)) 31 exs.Add(new Exception("Please provide a value for name")); 32 33 if (OwnerId == 0) 34 exs.Add(new Exception("Please select an owner")); 35 36 37 return exs; 38 } 39 }

You’ll see that the Dog class has an property of type int called OwnerId, this will be populated with the id of a Person.

If we let UI-O-Matic render this you’ll get an input of type number but that isn’t what we want since we don’t know which number matches a certain person.

Screen Shot 2015-10-26 at 10.57.47

So instead we want the see the persons full name and be able to select it from a dropdown.

All that we’ll need to do is use the UIOMaticField attribute and say that we want to use a dropdown and pass our dropdown some configuration

1 [UIOMaticField("Owner", "Select the owner of the dog", View = "dropdown", 2 Config = "{’typeName’: ‘Example.Models.Person, Example’, ‘valueColumn’: ‘Id’, ’sortColumn’: ‘FirstName’, ‘textTemplate’ : ‘FirstName + \" \"+ LastName ‘}")] 3 public int OwnerId { get; set; }

So the view is set to dropdown and the config we are passing is (in json format)

  • The name of the type that will be used to populate the dropdown
  • The column used for the value of the item
  • The template used for the text of the item
  • The column used for sorting

Now if we let UI-O-Matic render this we’ll get the following result

Screen Shot 2015-10-26 at 11.04.57

Besides dropdown you can also use a checkboxlist or radiobuttonlist, for more info please check the documentation

UI-O-Matic + T4 Templates = Almost instant CRUD UI for your custom tables in Umbraco 0

I’ve just published a new package on Nuget that makes it even easier to generate an integrated CRUD UI for custom tables in Umbraco, as you know for UI-O-Matic you only need to create a PetaPoco poco and decorate that with some additional attibute + implement an interface for each table, if you have a lot of tables that’s really boring work mapping a table manually to a poco. So I’m happy to introduce you to the t4 templates that will do that mapping for you.

Show me

Simply install the package through nuget

PM> Install-Package Nibble.Umbraco.UIOMaticT4Templates

That will add 3 new files to your project

  • \Models\Generated\
  • \Models\Generated\UIOMatic.Core.ttinclude
  • Models\Generated\UIOMatic.Generator.ttinclude

To now generate your pocos you’ll just have to save the file, if no connectionstring is supplied it will use the Umbraco one, but if you point it to a different conn string (by adding it’s name) it will use that.


I must note that I only modified the PetaPoco t4 templates so all credit for the excellent work in that one goes to the PetaPoco team.

Introducing UI-O-Matic for Umbraco, Integrated crud UI for custom db tables in minutes 12

With great pleasure I can announce the first release of a new package: UI-O-Matic.

What can it do?

Well a bit over a year ago I showed an example of how you could create a crud UI for a third party db table. As you can see in that post it is quite a bit of work to make it function…it consists of a petapoco poco, a tree controller, an api controller, angularjs views and controllers and more…

Instead of doing that now you can simply use UI-O-Matic, UI-O-Matic makes it super simple to create a crud ui for your tables, all you need to do is add some additional attributes and implement an interface that has a single member on your poco. UI-O-Matic will use that information to auto generate the UI for you.

Example please

If you have the following db table

1 CREATE TABLE [People] ( 2 [Id] int IDENTITY (1,1) NOT NULL 3 , [FirstName] nvarchar(255) NOT NULL 4 , [LastName] nvarchar(255) NOT NULL 5 , [Picture] nvarchar(255) NOT NULL 6 );

This class

1 [UIOMaticAttribute("People","icon-users","icon-user")] 2 [TableName("People")] 3 public class Person: IUIOMaticModel 4 { 5 public Person() { } 6 7 [UIOMaticIgnoreField] 8 [PrimaryKeyColumn(AutoIncrement = true)] 9 public int Id { get; set; } 10 11 [UIOMaticField("First name","Enter the persons first name")] 12 public string FirstName { get; set; } 13 14 [UIOMaticField("Last name", "Enter the persons last name")] 15 public string LastName { get; set; } 16 17 [UIOMaticField("Picture", "Select a picture", View = "file")] 18 public string Picture { get; set; } 19 20 public override string ToString() 21 { 22 return FirstName + " " + LastName; 23 } 24 25 public IEnumerable<Exception> Validate() 26 { 27 var exs = new List<Exception>(); 28 29 if(string.IsNullOrEmpty(FirstName)) 30 exs.Add(new Exception("Please provide a value for first name")); 31 32 if (string.IsNullOrEmpty(LastName)) 33 exs.Add(new Exception("Please provide a value for last name")); 34 35 36 return exs; 37 } 38 }`

will generate the following integrated crud UI


Where can I get it?

You can simply install it from nuget (after installation make sure to give your users access to the new section)

PM> Install-Package Nibble.Umbraco.UIOMatic

Is there documentation?

Yup, you can find that at

And there is also a recent uHangout showing the state of the project

Now what?

So please give it a try (it should do an awesome job on simple tables but haven’t tested that much on complex ones) and let me know if there are any issues , of course it’s open for collab so fork and submit pull request at will!

One Umbraco package action to rule all config transforms 3

While working on the page not found manager one of the final steps is to package up the project and release it as an umbraco package and nuget package. Sometimes your package will need to update existing files (adding a app setting to the web.config,…)

Something that is extremely useful when working with nuget is that you can include xdt files that will transform config files.

And for the umbraco package you can use package actions to perform those actions but that can quickly end up in having to use different actions and even having to write custom ones since the functionality of individual package actions is pretty specific. (for example take a look at the ones for Optimus)

Why not make it possible to also use xdt files…

So now instead of having to write or use different package actions to update config/xml files you can use this single config transform package action.

For example this is how you could add an additional provider to the config/embeddedmedia.config

1 <Action runat="install" undo="false" alias="PNFM.TransformConfig" file="~/config/embeddedmedia.config" xdtfile="~/app_plugins/temp/embeddedmedia.xdt"></Action>

And the xdt file contents will looks like

1 <?xml version="1.0"?> 2 <embed xmlns:xdt=""> 3 4 <provider name="Instagram" type="Umbraco.Web.Media.EmbedProviders.OEmbedJson, umbraco" xdt:Transform="Insert"> 5 <urlShemeRegex><![CDATA[instagram\.com/]]></urlShemeRegex> 6 <apiEndpoint><![CDATA[]]></apiEndpoint> 7 <requestParams type="Umbraco.Web.Media.EmbedProviders.Settings.Dictionary, umbraco"></requestParams> 8 </provider> 9 10 11 </embed>

If you aren’t familiar with xdt check out this link.

Currently the package action is part of the page not found manager project but I’ll also release this as a standalone package making it possible to include it in your own projects.

EAsy Custom 404 Pages for Umbraco 2

Introducing a small new package that allows you to set your Umbraco site 404 page(s) from within the UI. The page not found manager will extend the content context menu for admins with a new option “404 page”.

Screen Shot 2015-09-22 at 10.44.23

The new option will open a dialog where you are able to select a 404 page for the current page and it’s children (either by searching or selecting a page from the content tree).

Screen Shot 2015-09-22 at 10.48.34

So you can also setup multiple 404 pages (in case you have a multilingual site or an umbraco instance running multiple sites). Since it works this way it’s more versatile then the standard umbraco 404 page setup.

You can download the package on

Or install it through nuget

If you are insterested in the sourcecode that can be found on GitHub

And if you wanna learn more you can view a live demo and a run through of the code on this weeks uHangout

Seek and destroy 1.0 Release 4

SeekAndDestroyLogoThe ajax locator package I’ve been working on the last couple of freedom fridays is available as a package on today Smile

If you haven’t seen it in action make sure to check out this quick preview video.

Here is a quick overview of it’s features

Dashboard control

It features a dashboard control (in the developer section) that can install the google maps datatype, add a new property of that type to your doc type(s) and then geocode existing content based on the address you have stored. So you should be up and running in a couple of minutes (even if you don’t have any coordinates on your content documents yet).


Fully Customizable AJAX Locator control

By inserting the macro you have a working locator in a couple of clicks but of course it’s output is fully customizable just by updating the Partial View Macro File associated with the Macro. So you can tailor it to your needs! If you want custom google map markers check out ( and



The locator control includes some nice features, it loads a default location based on the users IP address, you can set it in street view mode and there is also a directions mode.


So the package is available for download on

If you are interested in the sourcecode that’s available on github

Please not that since this pacakge uses an UmbracoAPIController you’ll need at least Umbraco v6.1 to run this package

Extending the Umbraco Backend Using MVC 20

1 thing I wanted to do while creating Optimus for Umbraco was creating the page that is responsible for editing the bundle use the MVC framework instead of Webforms

The backoffice of Umbraco v4/v6 is still Webforms but it’s perfectly possible to plug in pages that use MVC.

The sourcecode for Optimus is available and you can use that to figure out how it’s done but I thought It would be even easier if I created a starter project for that Smile

Umbraco MVC Backoffice Pages

So I’ve just published a new project on github that does exactly that

You might have come accros this post by Bart de Meyer that also talks about this subject but there is a difference in the approach I’m using since I’m not making use of a SurfaceController (since those are for frontend use) and I’m also trying to keep things seperated by working in the /App_plugins folder (~\App_Plugins\UmbracoMVCBackofficePages\ folder in this case)

Solution setup


The vs solution consist of 2 projects, 1 test site that just contains Umbraco and the the project where we’ll add our code and push to the test site using post build events.

The post build events (moving the assembly and the views/icons used)

xcopy "$(ProjectDir)bin\UmbracoMVCBackofficePages.*" "$(ProjectDir)..\TestSite\bin\" /Y
xcopy "$(ProjectDir)Icons\*.*" "$(ProjectDir)..\TestSite\App_Plugins\UmbracoMVCBackofficePages\Icons\" /Y   
xcopy "$(ProjectDir)Views\*.*" "$(ProjectDir)..\TestSite\App_Plugins\UmbracoMVCBackofficePages\Views\" /Y 

Step 1: Data

So first step it to create some data that we’ll be working with as this is an example I just creates a very simple Person class and another class that will return some sample data

Person class:

 public class Person
        public Person(int id, string firstName, string lastName)
            Id = id;
            FirstName = firstName;
            LastName = lastName;
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public override string ToString()
            return FirstName + " " + LastName;


Data class:

 public class Data
        public static IEnumerable<Person> GetAll()
            var data = new List<Person>();
            data.Add(new Person(1, "Jeff", "Trent"));
            data.Add(new Person(2, "Paula", "Trent"));
            data.Add(new Person(3, "Lieutenant", "Harper"));
            data.Add(new Person(4, "Colonel", "Edwards"));
            data.Add(new Person(5, "Patrolman", "Larry"));
            return data;
        public static Person GetById(int id)
            return GetAll().Where(p => p.Id == id).FirstOrDefault();

So imagine that this interacts with your datasource….

Step 2: The Tree

Next I’ll add a tree to the settings section that will list my data

 [Tree("settings", "exampleTree", "Example")]
    public class ExampleTree : BaseTree
        public ExampleTree(string application)
            : base(application)
        protected override void CreateRootNode(ref XmlTreeNode rootNode)
            rootNode.NodeType   = "example";
            rootNode.NodeID     = "init";
            rootNode.Menu =  new List<IAction> { ActionRefresh.Instance };
        public override void Render(ref XmlTree tree)
            foreach (var person in Data.GetAll())
                var node = XmlTreeNode.Create(this);
                node.NodeID = person.Id.ToString();
                node.NodeType = "person";
                node.Text = person.ToString();
                node.Action = string.Format("javascript:openExamplePage({0});",
                node.Icon = "../../../App_Plugins/UmbracoMVCBackofficePages/Icons/example-icon.png";
                node.OpenIcon = "../../../App_Plugins/UmbracoMVCBackofficePages/Icons/example-icon.png";
                node.HasChildren = false;
                node.Menu = new List<IAction>();
                OnBeforeNodeRender(ref tree, ref node, EventArgs.Empty);
                if (node != null)
                    OnAfterNodeRender(ref tree, ref node, EventArgs.Empty);
        public override void RenderJS(ref System.Text.StringBuilder Javascript)
               @"function openExamplePage(id) {


Important part here is the js function that will open the edit page and pass it the id (check the node action)


Of course we’ll need to make sure ../App_Plugins/UmbracoMVCBackofficePages/Index get’s routed correctly (more in the next steps)

Step 3: Routing

Since I’m not making use of an Umbraco SurfaceController I need to take care of the routing

So my route config looks like

 public class RouteConfig
        public static void RegisterRoutes(RouteCollection routes)
               name: "ExampleMVCBackofficePages",
               url: "App_Plugins/UmbracoMVCBackofficePages/{action}/{id}",
               defaults: new { controller = "Example", action = "Index", id = UrlParameter.Optional }

And to make sure that is done when the application is started I have an Umbraco ApplicationEventHandler (since I’m using 6.1 +) in place

public class StartUpHandlers : ApplicationEventHandler
        protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)


Step 4: VIew model

Pretty simple model making use of data annotations

public class PersonViewModel
        public int Id { get; set; }
        [Display(Name = "First name:")]
        public string FirstName { get; set; }
        [Display(Name = "Last name:")]
        public string LastName { get; set; }


Step 5: Controller

An  MVC controller inheriting from UmbracoAuthorizedController that takes care of the authentication (so you can’t access App_Plugins/UmbracoMVCBackofficePages/Index if you aren’t logged into the backoffice)

public class ExampleController : UmbracoAuthorizedController
        public ActionResult Index(int id)
            var p = Data.GetById(id);
            PersonViewModel model = new PersonViewModel();
            model.Id = p.Id;
            model.FirstName = p.FirstName;
            model.LastName = p.LastName;
            return View("~/App_Plugins/UmbracoMVCBackofficePages/Views/Index.cshtml", model);
        public ActionResult Edit(PersonViewModel person)
            if (ModelState.IsValid) { }
                //do something
            TempData["success"] = true;
            return View("~/App_Plugins/UmbracoMVCBackofficePages/Views/Index.cshtml",person);

But notice that I do specify the view path since it won’t look in that directory by default

Step 6: View

Strongly typed view that uses the same js/css/markup as the backoffice webforms pages so it also has the same look Smile (and also shows the speech bubble when the form was submitted successfully)

@model UmbracoMVCBackofficePages.Models.PersonViewModel
<!doctype html>
    <title>Example editor</title>
    <script src="~/umbraco_client/ui/jquery.js" type="text/javascript"></script>
    <script src="~/umbraco_client/Application/NamespaceManager.js" type="text/javascript"></script>
    <script src="~/umbraco_client/Application/UmbracoApplicationActions.js" type="text/javascript"></script>
    <script src="~/umbraco_client/Application/UmbracoUtils.js" type="text/javascript"></script>
    <script src="~/umbraco_client/Application/UmbracoClientManager.js" type="text/javascript"></script>
    <script src="~/umbraco_client/ui/default.js" type="text/javascript"></script>
    <link href="~/umbraco_client/ui/default.css" rel="stylesheet" />
    <link href="~/umbraco_client/menuicon/style.css" rel="stylesheet" />
    <link href="~/umbraco_client/panel/style.css" rel="stylesheet" />
    <link href="~/umbraco_client/propertypane/style.css" rel="stylesheet" />
    <link href="~/umbraco_client/scrollingmenu/style.css" rel="stylesheet" />
        #save {
            height: 26px;
            margin: 0;
            padding: 0;
        #save img {
            padding: 0;
            margin: 0;
    @if (TempData["success"] != null)
            UmbClientMgr.mainWindow().UmbSpeechBubble.ShowMessage(’save’, ‘Saved’, ’successfully saved’);
        @using (Html.BeginForm("Edit", "Example"))
        <div id="body_UmbracoPanel" class="panel" style="width:100%;">
            <div class="boxhead">
                <h2 id="body_UmbracoPanelLabel">Example Editor</h2>
            <div class="boxbody">
                <div id="body_UmbracoPanel_menubackground" class="menubar_panel">
                    <span id="body_UmbracoPanel_menu">
                        <table id="body_UmbracoPanel_menu_tableContainer">
                                <tr id="body_UmbracoPanel_menu_tableContainerRow">
                                    <td id="body_UmbracoPanel_menu_tableContainerButtons">
                                        <button type="submit" id="save">
                                            <img src="~/umbraco/images/editor/save.gif" alt="Save Bundle" class="editorIcon"/>
                <div id="body_UmbracoPanel_content" class="content">
                    <div class="innerContent" id="body_UmbracoPanel_innerContent">
                        <h2 class="propertypaneTitel">Details</h2>
                        @Html.HiddenFor( m => m.Id)
                        <div class="propertypane">
                                <div class="propertyItem">
                                    <div class="propertyItemheader">@Html.LabelFor(m => m.FirstName)</div>
                                    <div class="propertyItemContent">
                                        @Html.EditorFor(m => m.FirstName)
                                        @Html.ValidationMessageFor(m => m.FirstName)
                                <div class="propertyItem">
                                    <div class="propertyItemheader">@Html.LabelFor(m => m.LastName)</div>
                                    <div class="propertyItemContent">
                                        @Html.EditorFor(m => m.LastName)
                                         @Html.ValidationMessageFor(m => m.LastName)
                                <div class="propertyPaneFooter">-</div>
            <div class="boxfooter">
                <div class="statusBar">


So that are the different bits and the end result should look like


Again source code for this project is available at

(I’ll also do a follow up post to show you how to get create/delete working)

Introducing Optimus Lite, instantly make any Umbraco website faster! 0

OptimusLiteLogoIf you’ve been following the latest blog posts you know I’ve been working on Optimus (bundling and minification for Umbraco built on top of the web optimization framework). In the comments Dima Stefantsov pointed out that there is another nice framework out there called  Request reduce.

Request reduce

Compared to the web optimization framework request reduce creates bundles automaticity, this means it’s just a matter of installing and your site performance is immediately improved.

For full overview please check out 

Of course all credits for this package goes to the Request reduce creator Matt Wrock

The only change I made was to make sure it ignores the umbraco backoffice since that had some side effects.


To see it in action check out this screenr



Package is available on

Optimus 1.0 release 0

We are done with the finishing touches to the Optimus package for Umbraco and are glad to announce that the 1.0 release is available today!

If you haven’t seen it in action yet, be sure to check out this quick overview


What’s new?

web optimization framework 1.1.0

The web optimization framework has been updated to the latest version (1.1.0), so you can make use of the Element template strings if you want full control over the link/script tag that will be inserted (this one’s for you James South)

@Scripts.RenderFormat(“<script src=’{0}’ async></script>”,”~/bundles/jquery”)

No empty trees

You’ll only get the dynamic scripts/stylesheet tree if you have at least 1 of the providers installed


Possible to disable minification on a bundle with the bundle editor UI


Bundle dynamic stylesheets/scripts directly

As requested by Jeavon Leopold it’s now possible to include less/sass/typescript/coffeescript files directly in a bundle (needs to be enabled in the \App_Plugins\Optimus\config\bundles.config file)


Some code refactor has been done to speed up several parts of the core


And finally the installer now handles the necessary files updates (thanks to the package action contrib team for the helpful snippets)


The package is available at

If you are interested in the sourcecode that can be found at

Next Page »