Programming and stuff

A client I’ve been working with for a while requested that a page with quite a lot of different ‘widgets’ on it, needs to be able to be changed by them on a whim.  By ‘changed’, I mean that they can change the layout, styling and positioning of these ‘widgets’.

The original page was using WebForms with UserControls and WebControls etc, and would have been a pain to somehow allow some customisation, so I started to think about how to do it with NancyFX and knocked up a small sample app.

Basically, I have a View Model, SiteLayoutSettings, that describes which section on the page these widgets will go into.

public class SiteLayoutSettings
{
    public string LayoutName { get; set; }
    public List<Section> Sections { get; set; }
}
 
public class Section
{
    public int Index{ get; set; }
    public List<Item> Items { get; set; }
}
 
public class Item
{    
    public string PartialName { get; set; }
    public dynamic Data { get; set; }
}

The Item class is the interesting one, as this described which partial view to load up for the widget and then the data that gets passed to it. At design-time though, this data is unknown, so I’ve set the type to be dynamic.

The setup side of the system then just has to store how they would like the page laid out, so that on the display side this View Model can be populated.

For this sample app, I’ve hardcoded one as follows:

var siteLayout = new SiteLayoutSettings() 
{ 
    Layout="Something",
    Sections = new List<Section> 
    { 
        new Section
        { 
            Index = 0,
            Items = new List<Item> 
            {
                new Item 
                {
                    PartialName = "_oneType",
                    Data = new OneTypeOfData 
                    { 
                        Url = "bbc.co.uk", 
                        Name = "BBC" 
                    }
                },
                new Item
                {
                    PartialName = "_otherType",
                    Data = new AnotherTypeOfData 
                    {  
                        Title = "Dave", 
                        Value = "10" 
                    }
                }
            }
        },
        new Section
        {
            Index = 1,
            Items = new List<Item>
            {
                new Item
                {
                    PartialName = "_otherType",
                    Data = new AnotherTypeOfData 
                    { 
                        Title = "Pete", 
                        Value = "20" 
                    } 
                }
            }
        }
    }
}

 

The two ‘data’ classes are as follows:

public class OneTypeOfData
{
    public string Name { get; set; }
    public string Url { get; set; }
}

public class AnotherTypeOfData
{
    public string Title { get; set; }
    public string Value { get; set; }
}

What I then do in my module’s Get is choose the view to return (based on which overall layout the client has selected, probably stored in a db), and pass in the layout settings:

return View["ThreeColumnLayout.cshtml", siteLayout]; 
 
or
 
return View["GridLayout.cshtml", siteLayout]; 
 
etc

 

In the views, in each section, I then iterate over the Items collection in each section, rendering a partial with the name and the data for each one:

@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<NestedTest.SiteLayoutSettings>
@{
    Layout = "Master.cshtml";
}

<h1>Layout is @Model.Layout</h1>

<div section="1" style="border:1px solid Red;">
    <h1>section 1</h1>

    @foreach (var item in Model.Sections[0].Items)
    {
        @Html.Partial(item.PartialName, item.Data);
    }
</div>

<div section="2" style="border:1px solid Green;">
    <h1>section 2</h1>
    @foreach (var item in Model.Sections[1].Items)
    {
        @Html.Partial(item.PartialName, item.Data);
    }
</div>

 

_oneType.cshtml

@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<NestedTest.OneTypeOfData>

<h2>Url = @Model.Url</h2>
<h2>Name = @Model.Name</h2>

 

_anotherType.cshtml

@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<NestedTest.AnotherTypeOfData>

<h2>Title = @Model.Title</h2>
<h2>Title = @Model.Value</h2>

 

What I love about this approach is the flexibility of it. As long as I’ve got some data and a view, I can push anything into one of these layout pages.  And the layout pages can be crafted in any way I like, all I have to do is put in the inline code to render out the section (which, will shortly be in a class of it’s own, RenderWidgetSection(1) or something).  But the greatest thing? Not a line of server side generated html in sight, which would have been my first thought had I gone down the WebForms route.

Advertisements

First, a history

My professional coding career started at a small software house in the Midlands when I decided I’d had enough clicking ‘Next, Next, Next’ as an installer for them and moved into development.  This was a Visual Foxpro house. Surprised smileThere was no such thing as architecture, object oriented programming, design patterns, unit testing etc. Everything was either on a form load, button click or in one massive great ‘helper’ file.  And by ‘everything’, I mean ‘everything’: File access, database calls, presentation code, web service calls.  It was, in hindsight, a massive horrible mess that was fragile, difficult to work with, frightening and bug-ridden.  But I wasn’t aware of any other way, so this was just how it was done.

When I left that job, I moved to an ASP.NET / C# role (which is where I am now). The way of doing things here was slightly different. Database called were in a project called <something>Service where there would reside a massive class called <something>Manager.  This <something>Manager would be tightly coupled to Typed Datasets (back in the day) or Linq To Sql (or both).  There would then be a web project that would call methods on that Manager class to do stuff.  More often than not the automatically generated classes from the Typed Datasets or Linq To Sql would be returned from the Manager class and used directly in the web project (sometimes directly in the aspx). One other added complication was that nearly all of the business rules for the application would be in the Sql Server as stored procedures.

I wasn’t sure why, but doing things this was was getting me down. I started to slowly lose my coding mojo.  I wasn’t thinking about code, I wasn’t trying new stuff, I was just getting my job done and that was that. 

As time has gone by this way of doing things has irked me somewhat. I am irked. The main driving factor of my irk-age was the desire to unit test. So I started to look at unit testing, read some books, downloaded samples, listened to talks. And it all made sense, but still I couldn’t get my head around how to structure my apps so that all of that decoupled-ness and unit-testing-ness would be possible.

The click

Within a week of each other, I read Scott Millett’s book Professional ASP.NET Design Patterns and watched Uncle Bob’s Clean Code video on Architecture.  It was like having my eyes opened for the first time. It was like I was Neo and I could finally see The Matrix. I could also feel my long-lost coding mojo coming back. I’d catch myself thinking about Interfaces, IOC, design patterns, architecture at all times of the day.  I’d see something in some legacy code and immediately start to think of ways to decouple it, test it, clean it and improve it. The contents of my “Documents\Visual Studio 2010\Projects” folder was increasing by the day. I was happy. I am happy.

All those concepts that I’d been reading about, like coding to interfaces, forgetting about the database (for a while), seeing all those aspx’s as ‘details’, tell don’t ask, single responsibility, separation of concerns suddenly coalesced into something I could do and use.

The future

This is just the start, and I intend to blog my progress for as long as it takes. Which, will probably be forever as who on earth can claim that they’ve finished learning? 

Following on from Part 1, we’ve had a approximately six months with our new monthly budgeting strategy and the release of stress has been fantastic.

While each normal month is now taken care of, abnormal months still caused us a bit of a problem.  Being dumped with a massive bill for a couple of new tyres in a month or unexpected events like Christmas Winking smilewould wipe out any spare cash and cause problems for the month.

So, we need a longer term strategy to complement our monthly plan.

First thing we had to come to terms with, and I know this sounds pretty obvious, is that most of the unexpected outgoings aren’t unexpected at all. We know full well when there are going to be bills for things like MOTs, car tax, Christmas, so it makes sense to prepare for them so when they do hit it’s as painless as those weekly food bills.

So a couple of weeks ago, we sat down with a year calendar and put into each month the big expenses we know about; May Dave’s car tax £160, August Holiday £400, etc.  We then split each big payment by the number of months between then and now. 

For example:
My car tax in May: £160
Number of months between then and now: 5
Amount to save each month: £32

So if I save the relatively small amount of £32 each month, that potentially monthly money devastating payment of £160 will be eliminated.

We did this for all of the large payments and then double checked each month to make sure that we could afford the saving amounts.  It all looked good. Smile

Having the knowledge that all of these things are accounted for and under control is another massive weight off.

Of course, there is the slight pain of starting something like this. Normally I will be able to split that car tax payment over 12 months, but you’ve got to start somewhere, so it’s going to be a lot for the next 5 months, but after that will only be just over £13 a month.

Once we’ve got that plan settled in, it’ll be time to start thinking about such things as reducing overdrafts, saving, investing.  But one step at a time eh?

Early last year my wife and I realised something.  We realised that the growing sense of unease and stress we were both feeling was mainly to do with money.

There were a few problems:

  • Neither of us knew what was in our accounts at any time.
  • Our money was running out way before the end of the month.
  • As a result of the above, we were always dipping into savings to pay for the last couple of weeks’ worth of essentials.
  • No savings
  • Large non-monthly expenses such as MOTs, Kids birthdays, Christmas were hitting us hard.
  • Lastly, and this is a biggie, communication about money was non-existent.

There came a point in June last year where we decided that this state of affairs had to stop.  We just couldn’t carry on living like that. It was far too stressful.

First thing we did was to get all the cards on the table.  We got our laptops and logged into our separate bank accounts so we could both see the situation. No more secrets. No more ‘I don’t want to worry her/him’. Everything from now on out in the open. Just this first step is a massive release of stress.

Next step was to work out what we had coming in each month and what needed to go out.  I fired up excel and started adding things in like salary, family credit, bills, mortgage, food, petrol, etc, etc, etc.  It became obvious that the Direct Debit things like mortgage were ok because they went out first of the month, but things like the food budget was disappearing because it wasn’t protected in any way. It was just part of the ‘what’s left after bills’ amount.  This meant that throughout the month it would be chipped away at for all sorts of other things leaving it low or empty for those last couple of food shops.

So, we took action to protect the food budget. We worked out what the total food budget for the month would be and as soon as we’re paid, we would take that out as cash and split it into each week.  The relief of knowing *for sure* that there is money for each week’s shopping is immense.

After deciding that the food shop ‘ring-fencing’ (ugh!) was a good idea I took on the other thing that tended to run out: petrol money. So again, I worked out what my budget for the month would be and then I would take it out as cash and split it into each fill up.  Sorted. Stress removed.  As an aside, what this part also achieved was highlighting to me the cost of the petrol which in turn has made me think about ways to reduce said cost. Like working from home a couple of days a week, and (this is the main one), driving within the speed limit / more defensively.

So, by talking about money and carefully planning what we are going to spend and protecting that money, we managed to bring our monthly finances back under control.

But, it’s by no means finished, as eagle eyed readers may well have spotted that these solutions don’t address the one-off big expenses such as car stuff (MOT, tax etc) and Christmas.  That’s for the next post.

UPDATE: Part 2 here

Every Day’s a School Day

With Marie going back to College to do a maths course and Tom starting at nursery, there’s learning in the air!  I’m going to take advantage of the scholarly atmosphere and dive into some topics that I either need to brush up on or learn from scratch.  The aim is to at least get comfortable (again, in some cases) with the following (not necessarily in this order):

  • Silverlight 3
  • LINQ to Entities
  • ASP.NET MVC
  • Azure
  • Something non-Microsoft like ruby.
  • HTML5 & CSS3
  • NHibernate

My main problem when I get home is that once dinner is finished with and the kids are in bed all I am usually thinking about is Tea, TV and bed.  If I can dedicate a couple of hours a couple of nights a week, then I’ll be happy.

PS: I’m going to keep this post updated as I think of more things I want to learn.

It’s only when I ask my wife to install something on her laptop that I discover how easy (or not) the install experience is.  The number of times I have to get up off the sofa and go and assist always shows up the more frustrating experiences. 

Any of the Windows Live products fill this “up off the sofa too many times” category. 

This morning I installed Windows Live Writer.  That’s all I needed.  So I found the download page (http://download.live.com/writer), clicked download and ran the exe expecting to install Live Writer.  First thing I see is this screen:

LiveInstaller

All I wanted was Live Writer.  Now I know that Windows Live is a suite of programs, but my wife (and I’m guessing many more people who don’t really care what Microsoft are doing) doesn’t, so straight away she doesn’t know what to do.  Does she need these other programs?  Cue first “Daaaave!!” of the install experience.  If you don’t notice these options and just click Install, everything gets installed which takes an age to download and install, when all you wanted was a relatively small blog post editor.

Once the download and install has happened, you get this screen:

LivePostInstallOptions

Cue another “Daaaaave!!”.  I just want to install Live Writer, why is this asking me about search providers and my home page.  Do I need to do this?  Does it help with the Live Writer experience?  I don’t think I would mind so much if they weren’t ticked as default.  Which, as an aside, “Help Improve Windows Live” isn’t, so they really want you to use Bing and MSN, but aren’t that bothered about improving Windows Live.

And don’t get me started on Windows 7 missing Movie Maker and simple image editing in the image preview, and them being things I have to download from Windows Live.

Anyway, rant over, in summary, Live Writer : Great, Live Writer Install Experience: Sucks.

Tag Cloud