Apple MacOS UK Keyboard Layout for Windows & the Command key for Control

If like me, you swap between Mac and PC you’ll have been irritated by everso slightly different keyboard layouts. So here’s my Apple Extended UK Keyboard Layout for Windows Installer.

When I wrote it I was using one of these:
Apple Pro Keyboard
But since the Apple full-size layout hasn’t actually changed since then, I still use it for my aluminium keyboard.

Swapping between Mac and Windows

In addition – even if using a PC keyboard – a Mac-PC swapper will undoubtedly suffer repeated Cmd and Ctrl shortcut confusion: You want to type Cmd-X for cut and suddenly the Win-X menu comes up instead.

My preferred solution for this is an AutoHotkey script, partly because after using Autohotkey for a few weeks I realised it was an utterly brilliant, all-singing, all-dancing customise-your-Windows-in-every-way tool, with an all-but-zero footprint.
My script is, which also has shortcut keys for arranging windows on a big screen.

The other reason I use autohotkey is that it enables a cherry-picking approach to swapping or duplicating Cmd-key/Ctrl-key shortcuts, which I find works much much better than doing a straight Cmd<=>Ctrl key swap. I got this approach from the keyboard layout used by Parallels on the Mac, which simply duplicated common shortcuts such as Ctrl-X, Ctrl-V to the Cmd-key. If you swap regularly between Mac & PC, this approach works well.

Inverting Mouse Scroll Direction

Since about the time that iPhone launched, OS X scroll direction, both mouse and keyboard, has used the metaphor of “push the document up to move it up the window” rather than the previous “push the scroll bar up to move the document down the window.” Windows has stayed firmly on the scrollbar metaphor.
Oddly enough, Microsoft mice come with a Windows driver that let you reverse scroll direction via the UI. For other mice, you can FlipFlopScrollWheel. Oddly, this is not per-user but per mouse/usb port combination, which means if you plug the same mouse into a different port it’s scrolls in the opposite direction.

Back to the Keyboard

If you do want a more complete Cmd<=>Ctrl key swap, then you do it with Randy’s SharpKeys.

Warning! You can’t swap keys around with it so do just this: map Left-Windows key to Left-Control. The right windows key will then still open the Windows menu and do all the Windows-Key stuff that it should do, such as Windows-L for Lock screen/Switch User:

Sharp Keys: Map just the left Windows key to Control key

If you want other keyboards than Apple UK, download the Microsoft Keyboard Layout Creator to tweak your layout.

An Asp.Net MVC HtmlHelper.RadioButtonsFor helper

These overloads will do the hopefully-obvious thing with a Model => Model.Property and a List of SelectListItems (or a single SelectListItem)

Use the RadioButtonLabelLayout setting to control whether you nest the radio button inside its label, or lay them out as siblings; and whether you like text before button or vice versa.

    public static class HtmlHelperRadioButtonExtensions
        /// <summary>
        /// Returns radio buttons for the property in the object represented by the specified expression.
        /// A radio button is rendered for each item in <paramref name="listOfValues"/>.
        /// Use <paramref name="labelLayout"/> to control whether each label contains its button, or is a sibling, 
        /// and whether button precedes text or vice versa.
        /// <list type="bullet">
        /// <item>
        ///     <term>Example result for the default labelLayout= RadioButtonLabelLayout.LabelTagContainsButtonThenText:</term>
        ///     <description>
        ///     &lt;label for="Object_Property_Red"&gt;&lt;input id="Object_Property_Red" name="Object.Property" type="radio" value="Red" /&gt; Red&lt;/label&gt; 
        ///     &lt;label for="Object_Property_Blue"&gt;&lt;input id="Object_Property_Blue" name="Object.Property" type="radio" value="Blue" /&gt; Blue&lt;/label&gt; 
        ///     </description>
        /// </item>
        /// <item>
        ///     <term>Example result for labelLayout= RadioButtonLabelLayout.SiblingBeforeButton:</term>
        ///     <description>
        ///     &lt;label for="Object_Property_Red"&gt;Red&lt;/label&gt; &lt;input id="Object_Property_Red" name="Object.Property" type="radio" value="Red" /&gt;
        ///     &lt;label for="Object_Property_Blue"&gt; Blue&lt;/label&gt; &lt;input id="Object_Property_Blue" name="Object.Property" type="radio" value="Blue" /&gt;
        ///     </description>
        /// </item>
        /// </list>
        /// </summary>
        /// <param name="listOfValues">Used to generate the Value and the Label Text for each radio button</param>
        /// <param name="labelLayout">One <see cref="RadioButtonLabelLayout"/> to control the layout of the rendered button and its label.</param>
        /// <returns>
        /// An MvcHtmlString for the required buttons 
        /// </returns>
        public static MvcHtmlString 
            RadioButtonsFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
                                                    Expression<Func<TModel, TProperty>> expression,
                                                    IEnumerable<SelectListItem> listOfValues,
                                                    RadioButtonLabelLayout labelLayout = RadioButtonLabelLayout.LabelTagContainsButtonThenText)
            if (listOfValues == null) { return null; }
            var buttons= listOfValues.Select(item => RadioButtonFor(htmlHelper, expression, item, labelLayout));
            return MvcHtmlString.Create(buttons.Aggregate(new StringBuilder(), (sb, o) => sb.Append(o), sb => sb.ToString()));

        /// <summary> Create an <see cref="IEnumerable{T}"/> list of radio buttons ready for individual processing before rendering</summary>
        public static IEnumerable<MvcHtmlString> RadioButtonListFor<TModel, TProperty>(
                    this HtmlHelper<TModel> htmlHelper,
                    Expression<Func<TModel, TProperty>> expression,
                    IEnumerable<SelectListItem> listOfValues,
                    RadioButtonLabelLayout labelLayout)
            if (listOfValues == null) { return new MvcHtmlString[0]; }
            return listOfValues.Select( item =>  RadioButtonFor(htmlHelper, expression, item, labelLayout) );

        public static MvcHtmlString RadioButtonFor<TModel, TProperty>(
                                HtmlHelper<TModel> htmlHelper, 
                                Expression<Func<TModel, TProperty>> expression, 
                                SelectListItem item, 
                                RadioButtonLabelLayout labelLayout)
            var id = htmlHelper.IdFor(expression) + " " + item.Value;
            var radio = htmlHelper.RadioButtonFor(expression, item.Value, new {id}).ToHtmlString();
            var labelText = HttpUtility.HtmlEncode(item.Text);
            TagBuilder nestingLabel = null;
            switch (labelLayout)
                case RadioButtonLabelLayout.LabelTagContainsTextThenButton:
                    nestingLabel = new TagBuilder("label") {InnerHtml = labelText + " " + radio};
                    return MvcHtmlString.Create(nestingLabel.ToString());
                case RadioButtonLabelLayout.LabelTagContainsButtonThenText:
                    nestingLabel = new TagBuilder("label") {InnerHtml = radio + " " + labelText};
                    return MvcHtmlString.Create(nestingLabel.ToString());
                case RadioButtonLabelLayout.SiblingBeforeButton:
                    return MvcHtmlString.Create(radio + " " + htmlHelper.Label(id, labelText));
                case RadioButtonLabelLayout.SiblingAfterButton:
                    return MvcHtmlString.Create(htmlHelper.Label(id, labelText) + " " + radio);
                    throw new ArgumentOutOfRangeException("labelLayout", labelLayout, 
                                "This is not a valid RadioButtonLayoutStyle for rendering a radio button");

    public enum RadioButtonLabelLayout
        LabelTagContainsButtonThenText = 0,
        LabelTagContainsTextThenButton = 1,
        SiblingBeforeButton = 2,
        SiblingAfterButton = 3,

A Manifesto for Post-Agile Software Development


In nearly 15 years since the Agile manifesto was penned, an entire generation of the software industry has grown up having known only ‘Agile’ methodologies. Their experience has not been entirely positive.

The ‘new’ criticisms made against agile – that is, by those who have grown up with it, not those who opposed it in the first place – are rarely criticisms of the agile manifesto. They are, often, reactions against the (abusive) experience of being pushed into processes, behaviours & relationships which are unsatisfactory; whilst at the same being stripped of any power to improve them.

We should always react against people being pushed about, and made powerless.

A manifesto is a small thing. It can fall on deaf ears. It can be interpreted to mean the opposite of what was intended, it can be misused to manipulate people. But if we make the effort to keep in touch with each other, and to keep trying to re-state what was meant, it can continue to be a valuable guide. And so I propose a 15th anniversary postscript.

Manifesto for Post-Agile Software Development: A Postscript

  • The agile manifesto was not and is not a prescription for people to impose conformity, nor a tool for controlling people.
  • There is a deeper theme to agile. At the core it is based on trust and respect, promoting workplace relationships which value people. We oppose methods, structures and behaviours which reduce respect and trust, and which reduce people to assets with no power.
  • Agile will always demand shared learning and shared improvement. Without critical reflection and learning – both from their own experiences and from the wider community – teams cannot remain agile. Without improvement based on that learning, ‘agile’ becomes fossilization.

Manifesto for Agile Software Development: A Reminder of the Original

The Agile Manifesto:

We are uncovering better ways of developing software by doing it and helping others do it. Through this work we have come to value:

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan

That is, while there is value in the items on the right, we value the items on the left more.


You may wonder why the term ‘post-agile’. It may be pointless, but it’s already in use, so we could choose to go along with those who want to learn, change and improve on their experience of ‘agile’.

As I see it, there are two essentials to agile: treating people well; and never stop learning. Each of these two is only truly possible when the other is also practised.

  • The phrase and much of the bullet point ‘There is a deeper theme…’ comes from About the Manifesto.
  • The emphasis on continuous learning is for some so obvious as to need no explanation. But some are stuck in a so-called "agile" process which they are powerless to change or improve. The irony of naming such an structure ‘Agile’ would be funny if it weren’t so painful.
    • Ron Jeffries’s reaction to criticisms of Scrum has been: "The essence of what makes Scrum work isn’t the three roles, the five meetings, the one artifact. It’s Inspect and Adapt. When things are not going as you like, you’re supposed to fix it."
    • To cry out that without continuous learning and change there is no agile, can be a powerful tool for the disempowered.
    • Calling for change in a broken process can become a step towards changing broken relationships.


The main alternative to a ‘post-agile’ slogan is surely Alastair Cockburn’s ‘Heart of Agile’.

A rather rushed and incomplete bibliography

Draft – Comment & Contribution Welcome.

WordPress – Unable to create directory – Is its parent directory writable by the server?

One of the annoyances of teh interwebs (mostly stackexchange, actually, but not in this case) is when the wrong answer comes top of the google rankings for a common question.

So here’s my contribution to making WordPress Forums for Unable to create directory – Is its parent directory writable by the server? the top google hit for this problem.

The problem, for me and many others, is not directory permissions but the path-to-uploads setting. Fix it by logging in with your admin account, and correct the path in:

Settings -> Media -> Uploading Files : Store uploads in this folder

WordPress Settings Media Upload Path

Why was it incorrect in the first place? Because I had changed hosting provider.