Saturday, May 27, 2017

Technical Problem or Wrong User Experience?

I'm going to start off with some general statements:
  • Programmers by their nature love solving problems, the harder the problem the more satisfied we feel when we have the solution.
  • Programmers also love to try new things, new programming languages, frameworks or technically challenging features we've seen somewhere.
  • Product owners have a tendency to want to use familiar features they have seen in software or websites they use often.
  • When designing software with any kind of UI it's surprisingly easy to forget that it needs to be used by another human being.
  • Many technical problems aren't obvious until a solution is exposed to production size data and load.

Why do any of these statements matter?

A couple anecdotes from my professional career:

How many soccer games are there in the world at any one time...
I worked with a great team on a sports betting website for many years and soccer was (and probably still is) the most popular sport for most of the year. One day we had to look into some performance problems with the site, it wasn't loading quickly enough and our clients were complaining. To give you some rough numbers to put things into perspective:
  • 1 League on average is ~ 21 KB of data to display the games and odds
  • 50 Leagues would take ~ 1 MB
  • 1,024 users getting that much data would consume ~ 1 GB
  • 1,048,576 (~100k) users would consume ~ 1 TB
These are very conservative numbers for this site but they're nice numbers to work with to illustrate the problem and how quickly it can grow under production load.
The solution the team was given in order to solve the problem was to use infinite load (made popular by Twitter and Facebook) in order to keep the initial transfer small and fast. A quick discussion with the team identified a few problems with this approach so it was tweaked a bit, implemented and released. In most teams, this would have been the end of the discussion but at this point, my team had been listening to me (and once converted helping me) evangelise User Experience for a few years and this turned out to be a bit of a catalyst. We put ourselves in our user's shoes and asked as a user if I've never bet on soccer and probably never will, can we load the sport, league or game I'm most likely there to place a bet on by default. By going straight to what the user wants and not loading something the user had no interest in we were able to provide a better experience and save on that wasted transfer and load time. The resulting change in how we looked at our site, UI and UX affected many of the projects that came afterwards.

How many commercials are being sent to broadcasters at any one time...
Years later I'm at a new company in a completely different part of the world and industry and I find myself in a familiar situation. I'm working with another very talented team on some interesting and complex problems and I see my old friend the infinite load. Without getting into too much detail about the overall process it turns out when creating and delivering TV commercials to broadcasters there are many people interested in whether or not the commercial has been delivered. To solve this problem there was a tracking page which loaded everything the user had access to and may be interested in. To avoid overwhelming the browser this page also used an infinite load to keep adding deliveries as the user scrolled down. I'll try not to go off on a tangent on why infinite load is a horrible user experience, suffice it to say that the most popular uses of it are on sites where people go to essentially waste time and don't really know what they're looking for. So I started looking at this page and asking, from a users perspective is this really a good experience for me?
For example, as someone who has created an order and is trying to deliver multiple files to multiple broadcasters, I'm probably very interested in those deliveries as a group.
Now change takes time and there's always more work to be done than time to do it so at the time of writing this I can't say whether or not I've been able to incept the same type of change in the company but I'm happy to say that I can see a change within the team members and the questions they ask.

At this point, I hope you're nodding along and thinking about some of the less than ideal experiences you see, use and may have even built and you're now considering how they could be improved. There are many influencing factors, the statements I made at the start are some of the easy ones to identify in order to see why a particular design, solution or experience has been chosen. I've found that when a technical problem is hit it's a good time to take a step back and re-examine what it is you're trying to achieve.

TL;DR
If you hit a technical limitation in software intended for use by a person ask yourself if you should be solving the technical problem or changing the user experience and design so it's actually usable. Usually, by giving the user a better experience you also eliminate the need to solve that technical problem.

Here are a few questions you can use to get the wheel turning:
What is the user trying to do or what information are they most interested in?
Do you currently have the data needed to give them a customised experience (if not can you get it)?
When you use the software/system are you shown information or intermediate steps that you really don't care about?

When working with software for work and business the user is trying to accomplish something as quickly and efficiently as possible. As someone who builds software, you should always be asking if the user is being given the best possible experience to achieve their goal.

Sunday, February 15, 2015

That's not Agile it's Fragile

You hear the word Agile thrown around a lot these days, people use it as a catch all term without really understanding what's necessary to truly be Agile. You see companies advertising they're doing Agile using words like scrum, sprint, user stories, and kanban. Someone in management hears they should be doing Agile and they hire an Agile expert or a Scrum master who comes in and tells them they need to do daily meetings standing up, write their requirements in terms of user stories, somewhere in there a chicken and pig analogy will come up to illustrate peoples new roles then they're told to stop wasting time doing design and just deliver features. A lot of these things are good when used in the right scenario after the proper foundation for a truly agile process is in place and yet the majority of the time the foundation is completely left out. Whoever brought in the consultant to get the department doing Agile will pat themselves on the back and if they're lucky they will see some improvement just long enough to get a big raise or bonus in their annual review. It won't take long before the features being developed take a bit longer than the 2 week sprint and every release will get reverted because of bugs that weren't found before the release went out. The daily scrum will go from a quick meeting to discuss blocking issues to a drawn out one that's mostly just a status update which can clearly be seen on the kanban board. This will build up until eventually the company falls back into old habits and claims this Agile thing doesn't work, or worse continues to claim they are still Agile.

The foundation of Agile software development is Test Driven Development, Continuous Integration and Continuous Deployment. Without these 3 things in place you're not being or doing Agile you're building a Fragile system that will eventually fall apart. There are of course exceptions to every rule and there are edge cases that are working quite well for some people but I'm talking about the general case.

There's already a lot written about Test Driven Development and how to do it properly so if this is a new subject for you I'll just give a high level introduction. As the name suggests you start with Test's, these usually come in the form of either Unit Tests or Acceptance Tests. The ideal you should strive for is a high level of coverage for both types of test and it's generally OK if you never reach that 100% coverage mark.

Unit Tests will focus on one piece of the code to make sure that it does what you expect, you write the failing test, run it to see it fail, write the code that will pass it and run it again to see it pass. It takes time to get used to developing software this way but the process encourages you to break the problems down into small enough pieces that you end up writing the code in less time overall than if you tried to do it all at once. There are many other benefits like never ending up with code you don't need/use etc. but that's too detailed to go into here.

Acceptance Tests take a bit more work to set up but the time spent is well worth it. These are end to end tests of the software/system as a whole that verify the functionality works as expected. Again these should be set up as much as possible before writing the actual code but sometimes you'll need to build some basic pieces in order to be able to run the test. An acceptance test may stay in the failing state while the functionality is being built but once they pass (usually you'll have many tests for one feature) you can be sure that the feature is finished. Part of the Acceptance test process should always be to build the set up and automated deployment of the software, this helps to identify potential road blocks you would normally run into once you're "finished" where most software hits the well known "the last 10% takes 90% of the time" problem. At this point you have automated Unit Tests for the internal logic, automated Acceptance Tests for the features and automated deployment and integration all set up. This is the foundation you're going to use in order to develop quickly while still maintaining the existing code and features. With each new feature added if you keep this process up you have a full regression suite that runs automatically to ensure the software is stable and the current functionality is always kept intact. You may be thinking "of course this is obvious", well you're probably a software developer who already knows all of this or a technically minded person.

Why is the foundation, the most important and arguably the only necessary part the one that somehow escapes the initial migration to Agile software development? The main reason is it's initially hard, it takes a lot of time and effort to put in place, specially with existing legacy software and it will slow things down while it's being set up. If you're hiring a consultant to come in and make the department or organization Agile and they have 2 weeks or a month to do this then they can't produce a measurable improvement in that amount of time (unless you have no existing software to start with). So they take the process's and practices that will give them a quick win to get their large consulting fee and move on to the next company while ignoring all of the hard but necessary things that should be in place first.

Since the majority of people will need to deal with legacy systems while getting this set up I'm going to tell you that your software is probably not in the best condition to go in and start writing unit tests. If you try you're probably going to have to rewrite it and in the process you're going to break things and that's going to be very demotivating. The best approach for legacy systems is to put the Acceptance Tests in place first and try to cover as much of the functionality as you can. This will give enough confidence to be able to get in and start rewriting the code and add unit tests because the Acceptance Tests will let you know when you've broken something. Another good practice to have that will help with legacy code as well as maintaining your new code is to write a test to reproduce a bug when one is found. This can be either a unit test or acceptance test or both in some cases but the first step should always be to reproduce the bug with a test that can be automated. Once you have the test in place go ahead and fix the bug and run the test to verify it, now you can be sure that bug will never rear it's ugly head again.

OK my company now has all of this in place and we're releasing stable software every week, this is awesome! I can fire my whole QA department and save the company even more money right?
Well maybe but probably not, QA will almost always be necessary because most software is being written to be used by humans and there's never a replacement for a real live human actually using the software to make sure it's working properly. Your QA department should actually be the ones helping to set up the Acceptance Tests to ensure the feature has enough automated coverage as well as doing exploratory testing with the software to make sure the UI doesn't have any bugs since UI testing is extremely hard to automate and is generally not worth the time and effort.

If you're in the process of having Agile introduced to your company and you don't see the foundation even being mentioned now would be a great time to bring this up and get your technical people involved. If you've tried Agile and had it fail I'd like to know if any of this information is new to you, I'm always interested in knowing when it just doesn't work even when it's done properly. If you're looking at moving to a company claiming to be Agile just ask what percentage of Acceptance Test coverage and Unit Test coverage they generally aim for and how long it took them to get there. If you get an open mouthed blank stare or the equivalent of a politician's response back then it's time to thank them for their time and move on.

Saturday, September 20, 2014

Mobile First Website Development

What is mobile first?

Put simply Mobile First means you start designing for the smallest, least capable device your customer may be using. Whether you're starting a completely new project or adding a new feature to an existing site you start with mobile. Once you have the experience figured out on the smallest, least capable device you plan on supporting you move up from there, this normally means phone -> tablet -> laptop/desktop. I like to take this one step further and design a "Basic" site that utilizes the bare minimum CSS and no JavaScript at all so you end up with something like Basic -> Mobile -> Tablet -> PC. I've found this ensures that no matter what device, connection speed or any other factor that I haven't considered comes up, the basic functionality always works even if it doesn't look so great.

What mobile first is NOT

Mobile first does not mean you fully develop something only for mobile, release that and then start over again potentially providing a completely different experience and/or functionality for other devices. This is a common mistake that many businesses make and don't even realize, take a look at this article on Forbes: Why Mobile-First May Not Be The Best Strategy After All
Now this author and the CEO he interviewed for the article have completely missed the mark and don't even realize it. You DO NOT build completely separate teams that will then build completely separate systems each with their own unique experience and functionality. You build individual components that are integrated together in the best way possible for each experience, starting with ... Mobile First. To be fair this is so common that even a company as huge as Facebook regularly gets it wrong leaving out or hiding very important functionality in their mobile app and website. I can't tell you how many times I've congratulated someone on an important life event only to get bombarded with notices that other people also commented on the same post and Facebook decided that their mobile users didn't need a way to disable notifications. This feature used to be there for all experiences and it felt like it would get removed or hidden around the same time I would comment on a post like that so I ended up just not using the mobile experience at all.

Why mobile first?

In case you haven't heard mobile devices are on the rise and in some countries are already more common than "regular" computers. If you're one of those people that needs facts to back up a claim here's a link to more numbers than you should ever need:
The Future of Mobile: 2014 [Slide Deck]
The Future of Digital: 2013 [Slide Deck]

OK, now that we all agree mobile is of ever increasing importance to the success of your site why does the order matter?

By designing for the least capable device you get a very efficient focused design right from the start. You're probably not going to come up with requirements to load some huge chunk of information that wouldn't even show on a high powered, full size desktop, you're going to figure out how to design an interaction that gets the user as close to what they're interested in with the least amount of taps or clicks. Once you have this worked out for mobile scaling up is easy, you may change the layout to make it look better once you have more space or present other components on the screen at the same time but the core functionality will be there for all experiences on all devices.
The design process should actually speed up, you have so little space to work with that you don't waste time trying to figure out what to stick in whitespace left over. The most important feature is put front and center and there's just no room left for useless filler and when you move up to a larger screen then you decide if it's worth cluttering the UI with something else or not.

When is mobile first a bad idea?

Really the only good argument for not doing mobile first is you have zero mobile users and the same amount of interest in getting and supporting them in the future. This may be the right choice for your organization or you could be shooting yourself in the foot only to watch your business wither as you lose customers.
A common argument you will hear for not doing mobile first is a need to support older browsers on older systems, now at first this may make sense until you actually think about it and realize that these "old" systems are less capable than a phone. This means you probably shouldn't be doing too much client side in terms of CSS or JavaScript because you need to support some very old browsers running on hardware that may have less CPU and memory than the smartphone in your pocket. So if you go up to the opening paragraph you will see that I've said you are designing for the smallest, least capable device. There are techniques to handle this and if you know in advance that a large number of your users are stuck on very old systems then this should be one of the factors in every project right from the start. In my opinion this argument against mobile first actually adds another reason why this process works, the assumption that all PC's are more capable than mobile phones or tablets is just wrong.
As it turns out all the processes and practices needed to make this work repeatedly are already pretty well known. To explain how they all work together deserves an entire post of it's own but if you're ready to change your process now and adopt Mobile First for your website all you need is to use Progressive Enhancement and Responsive Design along with it and you're on the right track.
Of course there will always be edge cases and you may find that you want to develop a Single Page App (SPA) optimized for each device rather than try to make one that works for all of them. In my humble opinion even this has a better solution than 3 or 4 independent complex Apps all targeted at a specific device because the cost of building and maintaining all of them needs to be offset by the returns you get. I've hinted at the approach I would actually take earlier on but this is another topic I feel should be fully explained in order to be properly understood and appreciated. As with any process there will inevitably be scenarios that it just doesn't work for so use some common sense and don't try to make it fit if it's not right to begin with.

Wednesday, September 17, 2014

Proper TDD - The case for simple tests

I've been trying to evangelize Test Driven Development (TDD) for quite a while now and come to the conclusion that in order to really appreciate it you need to fully commit to doing it properly. It won't really hit you the first day, first week and may take more than a month but at some point you will hit that moment when it just feels wrong to write code without first writing a test for it.

During a code review once I saw a very simple test for some very simple code and was asked by my peer reviewer what is the point of this?
I hadn't written either the code or the test and looking at both I didn't see the need for the test at all, it wasn't until afterwards I realized that the original coder was most likely doing TDD properly though. If you don't start with a breaking test then you're not doing it right so even very simple code should have at least one test.

Since that day I've taken on some very complex projects and continued my quest to convert fellow software developers over, without much success but I'm still trying. I have also written code using TDD in less than a day that I'm pretty sure would have taken me well over a week to finish and debug had I not followed TDD from the start.

I found this free talk by one of the best proponents for TDD there is, Uncle Bob and he does a great job of explaining this along with a Code Kata to show how TDD is really done: Advanced TDD by Uncle Bob.

In this talk Uncle Bob mentions the The Transformation Priority Premise and this is very important to consider while practicing TDD so here's a couple links to help explain this further:
http://blog.8thlight.com/uncle-bob/2013/05/27/TheTransformationPriorityPremise.html http://en.wikipedia.org/wiki/Transformation_Priority_Premise

If you are a TDD convert please pass along these links to anyone you know starting out with TDD. If you're not a convert yet give it an honest try and don't give up when you're pressured to "finish quickly". If you stick with it you will have solid reliable code that breezes through QA so any of that  time you feel is lost writing your tests will be recovered by time you don't have to spend hunting down hard to find bugs.

Friday, July 26, 2013

Create a SignalR Chat Module for Kooboo CMS


Summary

This is my attempt at getting the classic SignalR chat demo working inside a Kooboo CMS Module. The point of this module is a proof of concept to see how a fairly complex module is set up since the SignalR routes for the hubs need to be registered properly for the demo to work and there is no controller or easy route to set up in order to get this working.

Pre-Requisites

You will need Visual Studio (2010 or 2012) installed with the most up to date version of the .NET Framework and ASP.NET MVC. If you haven't already please follow the Kooboo CMS Installation Guide to download the latest version of the code and install the templates for Visual Studio.

Getting things set up

Open Visual Studio and start a new project using the "Kooboo.CMS.ModuleArea" template you installed, you can find it under Templates->Visual C#->Web. Choose whatever name you'd like, I'm calling mine "ChatModule", as well as the usual options when starting a project and click OK. After your project is created and initialized run a build (press F6) before changing anything. When I do this I see 4 errors in the "~/Areas/SampleModule/ModuleAction.cs" file so let's open that up first to fix these. The errors are just references that can't be resolved so prefix "Sites.Models.Site site" with "Kooboo.CMS" to end up with "Kooboo.CMS.Sites.Models.Site site". Try your build again (F6) and then proceed with dealing with the same reference problems in the next file "~/Areas/Empty/ModuleAction.cs". Let's try building one more time and this time it should succeed, hopefully these errors are fixed in a future version of the template.

Adding SignalR to your project

Now that the project builds we need to add in support for SignalR. Go to Tools->Library Package Manager->Manage NuGet Packages for Solution... Search for "SignalR" and you should find "Microsoft ASP.NET SignalR" then click the install button. If you want to skip all that just open up the Package Manager Console and type in: "PM> Install-Package Microsoft.AspNet.SignalR"

Customizing your Module

Let's customize the Module a little, pick a name for your module keeping in mind once it's published and installed in the CMS it can't be changed. I will use "ChatModule" for this example, open up the Areas folder in solution explorer and rename "SampleModule" to "ChatModule". Next open up the "ModuleAreaRegistration.cs" file in the newly renamed folder and replace "SampleModule" with "ChatModule" (there's a variable and also a namespace reference in here). From past experience I already know there are a few references left in the code to "SampleModule" and that it's safe to do a simple find and replace on all of them. Run a Replace in Files (Ctrl+Shift+H) and replace all instances of "SampleModule" with "ChatModule", in my case I found and replaced 10 instances. You should be able to do a Build at this point and see that everything is still OK.

Coding the Chat Module

Server Side

To save some time I won't go through cleaning up the existing files, you can safely get rid of some of the sample Controllers, Models, Views etc. when creating your own module but you should leave the Admin related code there. If you're just getting started with Kooboo then it's probably safer to just leave the existing code as is until you're more familiar with it. We will need a class that derives from the SignalR Hub so add a new class to your ChatModule folder, I'll call mine "Chat.cs". The code itself is very simple you just need to inherit from Hub and implement a Send method:
using Microsoft.AspNet.SignalR;

namespace ChatModule.Areas.ChatModule
{
 public class Chat : Hub
 {
  public void Send(string name, string message)
  {
   Clients.All.addMessage(name, message);
  }
 }
}
If you were following along with the quick start at this point you would add the call to register the SignalR Hubs to your Global.asax, this won't work for your Kooboo Module though so you need to create a new class that will take advantage of the Dependency Injection in Kooboo so you can register the routes when the Application starts up. I'm calling my class "SignalRConfig.cs" and this is also added to the ChatModule folder:
using Kooboo.CMS.Common.Runtime;
using Kooboo.CMS.Common.Runtime.Dependency;
using Kooboo.Collections;
using Kooboo.Web.Mvc;
using System;
using System.Web.Mvc;
using System.Web.Routing;

namespace Kooboo.CMS.Web
{
 [Dependency(typeof(Kooboo.CMS.Common.IHttpApplicationEvents), Key = "SignalRConfig", Order = -1)]
 public class SignalRConfig : Kooboo.CMS.Common.HttpApplicationEvents
 {
  public override void Application_Start(object sender, EventArgs e)
  {
   RouteTable.Routes.MapHubs();

   base.Application_Start(sender, e);
  }
 }
}
In order to make sure the SignalR routes aren't overridden you need to add an ignore rule to the "routes.config" file in your Module:
    <add name="signalr" url="signalr/{*pathInfo}"/>
Next Add a new Empty controller in your ChatModule, I'll call mine "ChatController" with just one method for Index that returns the default View:
using System.Web.Mvc;

namespace ChatModule.Areas.ChatModule.Controllers
{
    public class ChatController : Controller
    {
        //
        // GET: /ChatModule/Chat/
        public ActionResult Index()
        {
            return View();
        }

    }
}

Client Side

Now we need the actual View so right click on "View" in the Index ActionResult and select "Add View..." I will use the Front.cshtml layout page that's in my ChatModule's Shared views. You will get a default Index.cshtml file, I'm going to just paste in some demo code from the SignalR quick start guide with a few minor changes:
@{
    ViewBag.Title = "Chat Demo";
    Layout = "~/Areas/ChatModule/Views/Shared/Front.cshtml";
}

<h2>SignalR Chat</h2>
<div id="signalr-chat">
    <script src="~/Scripts/jquery.signalR-1.1.2.min.js" type="text/javascript"></script>
    <script src="@Url.Content("~/signalr/hubs")" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            // Proxy created on the fly
            var chat = $.connection.chat;

            // Declare a function on the chat hub so the server can invoke it
            chat.client.addMessage = function (name, message) {
                $('#messages').append('<li><strong>' + name + '</strong>: ' + message + '</li>');
                $('#msg').val("");
                $('#msg').focus();
            };

            $("#msg").on('keydown', function (event) {
                // Manually bind the enter key to submit the message
                if (event.keyCode == 13) {
                    $("#broadcast").click();
                    return false;
                }
            });

            // Get the user name and store it to prepend to messages.
            $('#displayname').val(prompt('Enter your name:', ''));
            // Set initial focus to message input box.  
            $('#msg').focus();

            // Start the connection
            $.connection.hub.start().done(function () {
                chat.server.send($('#displayname').val(), "Has entered the chat ...");
                $("#broadcast").click(function () {
                    // Call the chat method on the server
                    chat.server.send($('#displayname').val(), $('#msg').val());
                });
            });

            // Detect when the connection is stopped
            $(window).bind("beforeunload", function () {
                chat.server.send($('#displayname').val(), "Has left the chat ...");
            });
        });
    </script>
    <input id="msg" name="msg" type="text" />
    <input id="broadcast" name="broadcast" type="button" value="Send" />
    <input id="displayname" name="displayname" type="hidden" />
    <ul id="messages"></ul>
</div>
The code is pretty straight forward, you need a reference to the SignalR jquery library for the chat to work as well as the dynamically generated hub script. Before running the code open up the Project Properties and in the Web tab change the Start Action to Specific Page and leave it blank, save that change and close the properties window. In order to see the Module on a page we need to log into the Admin section and add it to a page so run the project and wait for the site to start up. Click the Login link in the top right corner and use the default admin admin credentials to log into the admin section. Click on the SampleSite and remove all the pages, once it's cleaned up click the button to add a new page. Hover over the main place holder and select the "Add a module" option. Select the ChatModule and set the Entry Controller to "Chat" you can leave the Entry Action as "Index". Set the page name, I'm using "ChatDemo" and click the Save & publish option. At this point you can log out of the admin section and close the site. When I try to run the project the SignalR routes don't get registered properly unless I do a Rebuild All before running it. If you're seeing errors related to the signalr/hubs file not loading then try doing a Clean then a Rebuild and run the project, if you just do a Build it probably won't work properly.

Source Code

If you'd like to just grab the source code yourself and start working with it it's available on GitHub: SignalR Chat Demo Source

References

Kooboo CMS Module Development
SignalR Quick Start
Another SignalR Tutorial

Friday, June 14, 2013

Kooboo CMS Module Creation and Development

Summary

This is a quick introduction to Module development for Kooboo CMS. I ran into a few issues while I was trying to follow the official guide so I thought I would document the process for future reference.

Pre-Requisites

You will need Visual Studio (2010 or 2012) installed with the most up to date version of the .NET Framework and ASP.NET MVC. If you haven't already please follow the Kooboo CMS Installation Guide to download the latest version of the code and install the templates for Visual Studio.

Create a Module

Open Visual Studio and start a new project using the "Kooboo.CMS.ModuleArea" template you installed, you can find it under Templates->Visual C#->Web. Choose whatever name you'd like as well as the usual options when starting a project and click OK. After your project is created and initialized go ahead and run a build (press F6) before changing anything. When I do this I see 4 errors in the "~/Areas/SampleModule/ModuleAction.cs" file so let's open that up first to fix these. The errors are just references that can't be resolved so go ahead and prefix "Sites.Models.Site site" with "Kooboo.CMS" to end up with "Kooboo.CMS.Sites.Models.Site site". Try your build again (F6) and then proceed with dealing with the same reference problems in the next file "~/Areas/Empty/ModuleAction.cs". Let's try building one more time and this time it should succeed. At this point you can build and run (press F5) to see the site working and play around with it if you want to familiarize yourself with it.
Let's try to customize a Module a little to see what the process is like, pick a name for your module keeping in mind once it's published and installed in the CMS it can't be changed. I will use "KBModule" for this example, open up the Areas folder in solution explorer and rename "SampleModule" to "KBModule". Next open up the "ModuleAreaRegistration.cs" file in the newly renamed folder and replace "SampleModule" with "KBModule" (there's a variable and also a namespace reference in here). If you were following along with the original instructions on the Kooboo site at this point you should be able to build and run again, the build will succeed but running is a different story. Let's try to figure out why we get a 500 internal server error while running the code.
If you take a look at the exceptions being thrown while running it's obvious that there's still references to "SampleModule" in the code, since we've renamed it we will need to track these down and replace them with "KBModule". Let's do a Find in Files (Ctrl+Shift+F) for "SampleModule" to see which files still need to be updated. You should find 8 matches in 7 files so go ahead and replace all instances of "SampleModule" with "KBModule". I find it's always a good idea to go in and look at the code instead of simply replacing all automatically to help understand the code and also make sure you're not changing something you shouldn't. In this instance however it's safe to go ahead and just run a Replace in Files (Ctrl+Shift+H). Once you're done you should be able to build and run the code again without any problems.

Testing the Module

Let's build and run the code now, hit F5 and after the site starts up click on the LogOn link in the top right corner. Use the default credentials Username:admin Password:admin and change the Redirect to: Admin page then click Login. Click the SampleSite link in the main area to open it up so you can edit and change settings. If you open up the Articles page for editing (click the right arrow to see the menu) and check the Module it's using it should already be set to KBModule in the 2 place holders. At this point you should check all the settings for the controller (Article) and action (Categories for the menu, List for the main area) used in order to figure out where you can play around to make changes and see them on the sample site.

Breaking down the pieces

Back-end (Admin) Controllers and Views

There are two sample back-end controllers included in the project template:
"AdminController.cs", which has two methods: InitializeModule and GenerateModuleInfo.
InitializeModule is used for exactly what it sounds like, after adding the module to Kooboo if you need to do any kind of initialization before using it here's where you'll add the code. Since the module can be used on multiple sites it's advised to do the initialization here rather than during the installation process. I would also recommend writing your code to ensure it can be run multiple times without any adverse affects. An example would be creating/modifying/populating a table in a database that is used by the Module.
GenerateModuleInfo is used to generate the "module.config" file which is the ModuleInfo Class serialized.
"NewsAdminController.cs", is just a sample controller to demonstrate how to create custom data management instead of using the general content management.
The Views for each of these controllers are located under the usual Views folder in the Admin and NewsAdmin folders.

Back-end (Admin) Menu

The back-end Module menu can be integrated into the Kooboo CMS main menu, to customize it edit the "Menu.config" file. The default items are "Settings", "Initialize" and "News", it's good to note that the permission is also set in this file using the "role" attribute.

Back-end (Admin) Routing

The back-end URL routes are added to the "ModuleAreaRegistration.cs" file which is the same as MVC Areas if you're already familiar with them.

Front-end Controllers and Views

There are two sample front-end controllers included in the project template: "ArticleController.cs", which inherits from ModuleControllerBase and "NewsController.cs", which inherits from Controller
The front-end controllers run on Kooboo CMS Page positions rather than MVC area so they cannot inherit from "AreaController", you can use either "ModuleControllerBase" or the generic "Controller". The difference between the two is "ModuleControllerBase" adds a couple flags and methods that are useful for Module development, if you're starting from scratch then inherit from this class although it's not necessary if you're trying to create a module from an existing codebase.
When you add a module to a Page Position you will have to specify the front-end controller in the entry controller and a method in the entry action. You can also specify this using the admin interface for the module after adding it to your site by changing the default settings. Another option is to specify these in the module.config that is generated from the GenerateModuleInfo method in the Admin Controller.
You can't use the regular Master layout because the module view is only rendered as a piece of the HTML page and it won't be validated. There are a couple helper methods "Html.FrontHtml()" and "Url.FrontUrl" you can use in your front-end views only if you have the necessary access and knowledge of the target site. Otherwise it's recommended to use "Html.ModuleHtml()" and "Url.ModuleUrl()". Take a look at the class "ModuleViewHelperExtension" to see the rest of the methods you can take advantage of (ModuleAjax, AjaxHelper, ModuleHtml, HtmlHelper and UrlHelper).

Front-end Routing

To add or modify the routing in the front-end open up the "routes.config" file. For anyone who's already worked with ASP.Net MVC before this should look pretty familiar. If you need more information on working with this file just use any existing samples you can find for a regular ASP.Net MVC project, there's more than enough information and samples available online.

Publishing a Module

Let's save publishing and using the module in Kooboo for it's own article.

References:

http://www.kooboo.com/docs/Kooboo-CMS/Module-development

Monday, June 3, 2013

Kooboo CMS Installation Guide

Summary

I recently started evaluating Kooboo for potential use where I work to replace our existing CMS. We do a lot of website development in MVC.Net so Kooboo seemed like a good fit for our environment and existing skill set. A lot of the documentation and examples they currently have are a little hard to follow and I found just getting the code and opening it in Visual Studio using their instructions was a bit difficult so here's the easiest way to get started.

Installing Kooboo the easy way

If you're trying to get started with Kooboo CMS here is the easiest way to download and install it with all of it's dependencies:
  1. Download and install the latest version of WebMatrix (http://www.microsoft.com/web/webmatrix/).
  2. After installation is complete open WebMatrix and select "New" -> "App Gallery".
  3. Select the CMS category on the left-hand side or just type in Kooboo in the search input at the top.
  4. Find Kooboo CMS in the list, select it, enter a site name in the input at the bottom and press Next.
  5. You'll have to agree to the EULA to start the download and install.
  6. Once it's finished you will see the source code in WebMatrix and it should start the Kooboo website in your default browser.
  7. You can now log in using the default UserName: admin and Password: admin.

Now that you have the code and a working installation of Kooboo CMS you'll probably want to open it up in Visual Studio:
  1. In WebMatrix right click on the root of the website and select "Show in File Explorer".
  2. Start Visual Studio and select "File" -> "Open Web Site..." or (Shift + Alt + O).
  3. Copy and paste the path from File Explorer or navigate to it and click the Open button.
  4. You can now build and run the website from within Visual Studio.

Note: The current version as of writing this has an error which will come up when you try to build and run from Visual Studio:

'Kooboo.CMS.Web.Areas.Sites.Models.PagePublishViewModel' does not contain a definition for 'FullName' and no extension method 'FullName' accepting a first argument of type 'Kooboo.CMS.Web.Areas.Sites.Models.PagePublishViewModel' could be found (are you missing a using directive or an assembly reference?)

You can safely delete or comment out the offending code in "~/Areas/Sites/Views/Page/Publish.cshml" and continue:

@{
    var page = new Kooboo.CMS.Sites.Models.Page(Kooboo.CMS.Sites.Models.Site.Current,Model.FullName);
}
@if (ServiceFactory.PageManager.HasDraft(page))
{
    @Html.EditorFor(m => m.PublishDraft, new { @class = "medium draft" })
}


Now you can head over the to download page on Kooboo.CodePlex.com to get the Visual Studio templates for Modules (Kooboo.CMS.ModuleArea.vsi) and Plug-Ins (Kooboo.CMS.PluginTemplate.vsi).

References

http://www.kooboo.com/docs/Kooboo-CMS/Installation-guide-1
http://kooboo.codeplex.com/
http://www.microsoft.com/web/gallery/kooboocms.aspx
http://www.iis.net/learn/develop/installingpublishing-apps-with-webmatrix/kooboo-cms-faq