Programming and stuff

Archive for the ‘Uncategorized’ Category

Dynamic layout & partials with NancyFX

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

Getting our finances in order (Part 2)

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?

Getting our finances in order (Part 1)

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.

Tag Cloud