<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="http://jamessouth.me/rss/xslt"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>James Jackson-South</title>
    <link>http://jamessouth.me/</link>
    <description>Microsoft MVP, Creator of ImageSharp, ImageProcessor and ResponsiveBP, Web developer, Lifter of heavy weights, and all round nice guy.</description>
    <generator>Articulate, blogging built on Umbraco</generator>
    <item>
      <guid isPermaLink="false">1120</guid>
      <link>http://jamessouth.me/archive/fun-with-umbracovirtualnoderoutehandler/</link>
      <category>System.String[]</category>
      <title>Fun with UmbracoVirtualNodeRouteHandler</title>
      <description>&lt;p&gt;This morning I answered a question on &lt;a href="https://our.umbraco.org/forum/umbraco-7/using-umbraco-7/64766-IIS-Rewrite-or-ContentFinder-UrlSegments"&gt;Our Umbraco&lt;/a&gt; regarding the best approach to provide a url allowing deep links for virtual nodes in Umbraco. In my answer I demonstrated how to use &lt;code&gt;UmbracoVirtualNodeRouteHandler&lt;/code&gt; as a means of telling Umbraco what node to pass as my &lt;code&gt;RenderModel&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Shannon talks about the &lt;code&gt;UmbracoVirtualNodeRouteHandler&lt;/code&gt; with custom routing on his &lt;a href="http://shazwazza.com/post/Custom-MVC-routes-within-the-Umbraco-pipeline"&gt;blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I thought I'd expand on some of the functionality available to the developer by documenting  a trick I use with implementations of &lt;code&gt;UmbracoVirtualNodeRouteHandler&lt;/code&gt; to provide custom routing.&lt;/p&gt;
&lt;h3&gt;Use Case&lt;/h3&gt;
&lt;p&gt;Quite often I find myself reusing a single document type with multiple templates; I'm sure you have also. Most commonly a &lt;em&gt;LoginRegisterPage&lt;/em&gt; or similar. &lt;/p&gt;
&lt;p&gt;Now I don't know about you but one of the things I miss when using Umbraco is the ability to use &lt;code&gt;Url.Action&lt;/code&gt; to generate urls for my content. I like routing in MVC and I think it's important, especially with the type of page as above to be able to generate the correct urls from within your views or controllers.&lt;/p&gt;
&lt;p&gt;To understand what I am going to do here you first need to understand how routing works in Umbraco.&lt;/p&gt;
&lt;p&gt;If you have the &lt;em&gt;DocumentType&lt;/em&gt; &lt;code&gt;LoginRegisterPage&lt;/code&gt; with the assigned template &lt;code&gt;LoginPage&lt;/code&gt; this will map to a &lt;em&gt;RenderMvcController&lt;/em&gt; called &lt;code&gt;LoginRegisterPageController&lt;/code&gt; with an &lt;em&gt;ActionResult&lt;/em&gt; &lt;code&gt;LoginPage&lt;/code&gt;. This behaviour is standardised and predictable so we can utilise it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DocumentType == Controller&lt;/li&gt;
&lt;li&gt;Template == ActionResult&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;p&gt;So let's start by creating some routes.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Custom routing for the membership pages so we can use
// proper redirects. 
RouteTable.Routes.MapUmbracoRoute(
&amp;quot;LoginPage&amp;quot;,
&amp;quot;Login/&amp;quot;,
new
{
    controller = &amp;quot;LoginRegisterPage&amp;quot;,
    action = &amp;quot;LoginPage&amp;quot;
},
new LoginRegisterPageNodeRouteHandler());

RouteTable.Routes.MapUmbracoRoute(
&amp;quot;RegisterPage&amp;quot;,
&amp;quot;Register/&amp;quot;,
new
{
    controller = &amp;quot;LoginRegisterPage&amp;quot;,
    action = &amp;quot;RegisterPage&amp;quot;
},
new LoginRegisterPageNodeRouteHandler());
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here I have created two routes that map to the relative urls &lt;em&gt;/Login&lt;/em&gt; and &lt;em&gt;/Register&lt;/em&gt;. They both map to the same controller but since two different templates are used it will map to two different &lt;em&gt;ActionResult&lt;/em&gt; methods. &lt;/p&gt;
&lt;div class="alert"&gt;

Note: I didn't use the word "virtual" in my handler names since I am mapping to actual nodes.

&lt;/div&gt;
&lt;p&gt;From here I will create a class that takes advantage of the predictability.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// An Umbraco route handler that allows the retrieval of the template alias name from the route action. 
/// &amp;lt;/summary&amp;gt;
public abstract class TemplatedUmbracoVirtualNodeRouteHandler : UmbracoVirtualNodeRouteHandler
{
    /// &amp;lt;summary&amp;gt;
    /// Get the template from the current route.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;requestContext&amp;quot;&amp;gt;
    /// The &amp;lt;see cref=&amp;quot;RequestContext&amp;quot;/&amp;gt; containing information about the current HTTP request and route. 
    /// &amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;
    /// The &amp;lt;see cref=&amp;quot;string&amp;quot;/&amp;gt; representing the template alias.
    /// &amp;lt;/returns&amp;gt;
    protected virtual string GetTemplateAlias(RequestContext requestContext)
    {
        return requestContext.RouteData.GetRequiredString(&amp;quot;action&amp;quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This class adds an additional method &lt;code&gt;GetTemplateAlias&lt;/code&gt; to our handler pulling in the &lt;em&gt;RouteData&lt;/em&gt; &lt;code&gt;action&lt;/code&gt; variable which we know matches the template name of the node we want in the content tree.&lt;/p&gt;
&lt;p&gt;And from here we can implement this our handler.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// The generic login/register page node route handler.
/// &amp;lt;/summary&amp;gt;
public class LoginRegisterPageNodeRouteHandler : TemplatedUmbracoVirtualNodeRouteHandler
{
    /// &amp;lt;summary&amp;gt;
    /// returns the &amp;lt;see cref=&amp;quot;IPublishedContent&amp;quot;/&amp;gt; associated with the route.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;requestContext&amp;quot;&amp;gt;
    /// The request context.
    /// &amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;umbracoContext&amp;quot;&amp;gt;
    /// The umbraco context.
    /// &amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;
    /// The &amp;lt;see cref=&amp;quot;IPublishedContent&amp;quot;/&amp;gt;.
    /// &amp;lt;/returns&amp;gt;
    protected override IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext)
    {
        UmbracoHelper helper = new UmbracoHelper(umbracoContext);
        string alias = typeof(LoginRegisterPage).Name;
        string templateAlias = this.GetTemplateAlias(requestContext);

        return helper.TypedContentAtRoot()
            .First()
            .Descendants()
            .First(d =&amp;gt; d.DocumentTypeAlias.InvariantEquals(alias)
                     &amp;amp;&amp;amp; d.GetTemplateAlias().InvariantEquals(templateAlias));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;div class="alert"&gt;

Note: I use &lt;a href="https://github.com/leekelleher/umbraco-ditto"&gt;Ditto&lt;/a&gt; to create strong-typed models for my back office content. It's ace, you should give it a go!

&lt;/div&gt;
&lt;p&gt;If you look at the code in my handler you will see that I am searching the content for nodes that match both the name and template of the one I want.&lt;/p&gt;
&lt;p&gt;It's as simple as that really... I can now use &lt;code&gt;Url.Action(&amp;quot;LoginPage&amp;quot;, &amp;quot;LoginRegisterPage&amp;quot;)&lt;/code&gt; and &lt;code&gt;Url.Action(&amp;quot;RegisterPage&amp;quot;, &amp;quot;LoginRegisterPage&amp;quot;)&lt;/code&gt; throughout my code to provide the correct urls to my respective pages priding me with functionality I sorely missed.&lt;/p&gt;
</description>
      <pubDate>Wed, 13 May 2015 05:37:56 Z</pubDate>
      <a10:updated>2015-05-13T05:37:56Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1119</guid>
      <link>http://jamessouth.me/archive/experiments-with-umbracos-icontentservice/</link>
      <category>System.String[]</category>
      <title>Experiments with Umbraco's IContentService</title>
      <description>&lt;p&gt;I haven't had very much experience with the Umbraco &lt;a href="https://our.umbraco.org/documentation/Reference/Management-v6/Models/Content"&gt;ContentService&lt;/a&gt;. I've only just started playing around with it so if I've missed something obvious please tell me in the comments.&lt;/p&gt;
&lt;h3&gt;A Confusing API&lt;/h3&gt;
&lt;p&gt;Reading through the documentation, it seems a shade basic considering the importance of the subject matter and really doesn't go out of it's way to explain what to do and what will happen. &lt;/p&gt;
&lt;p&gt;When saving an item using the content service, the methods signature for the first overload available for setting a property value is as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IContentBase.SetValue(string propertyAlias, object value);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;According to the documentation you should be able to set different types as the second argument. At time of writing they give the following example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Given a `ContentService` object get Content by its Id, set a few values
// and saves the Content through the `ContentService`
var content = contentService.GetById(1234);
content.SetValue(&amp;quot;bodyText&amp;quot;, &amp;quot;This text will be added to by RTE field&amp;quot;);
content.SetValue(&amp;quot;date&amp;quot;, DateTime.Now);
contentService.Save(content);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the &lt;code&gt;DateTime.Now&lt;/code&gt; instance there. Unfortunately support for the different types seems extremely limited. Passing a float causes the following exception.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The best overloaded method match for
'Umbraco.Core.Models.ContentBase.SetPropertyValue(string, string)' has
some invalid arguments.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yowza! That really doesn't give a great developer experience.&lt;/p&gt;
&lt;h3&gt;Magic Strings&lt;/h3&gt;
&lt;p&gt;Not much in Umbraco when dealing with content is strong-typed. If I were to hazard a guess as to why, &lt;del&gt;I would imagine it was because the code tooling to do some of the conversion functionality we can now was not available when the API's were designed.&lt;/del&gt; (&lt;strong&gt;Update&lt;/strong&gt; Turns out it was just a design decision). I have, however, felt the distinct impression at times through conversation that strong-typing is not wanted in certain areas. &lt;/p&gt;
&lt;p&gt;I'm doing my best to provide it to developers when dealing with the cached  &lt;code&gt;IPublishedContent&lt;/code&gt; methods by contributing to &lt;a href="https://github.com/leekelleher/umbraco-ditto"&gt;Ditto&lt;/a&gt;. Content services, however, are not part of the scope for that project so having spent so much time developing with Umbraco in a strong-typed manner, coming across them here was a bit of a shock.&lt;/p&gt;
&lt;p&gt;Let's look at that method again.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IContentBase.SetValue(string propertyAlias, object value);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first parameter accepts a string. Now I don't know about you but the most common use case I would imagine for the method would be uploading a form or importing content through another service. &lt;/p&gt;
&lt;p&gt;That form or service would contain classes with properties and using the API in this format would require the developer to insert magic strings for every property or use reflection to loop through with the property info name manipulating them for each instance. &lt;/p&gt;
&lt;p&gt;Not code I want to write...&lt;/p&gt;
&lt;h3&gt;Expression Trees to the Rescue!&lt;/h3&gt;
&lt;p&gt;I wanted a way that I could call the method in the following format and not have to write those pesky strings:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IContentBase.SetValue(() =&amp;gt; Class.Property);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In order to do that I will need to create an extension method that uses an &lt;a href="https://msdn.microsoft.com/en-us/library/bb397951.aspx?f=255&amp;amp;MSPPError=-2147217396"&gt;Expression Tree&lt;/a&gt;. This is done by  creating a Lambda Expression to represent the property.&lt;/p&gt;
&lt;p&gt;Once inside our method we check to see whether, a property is being passed, and if so, coerce the various property values to call the old method with sanitized values.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Sets the value of an &amp;lt;see cref=&amp;quot;IContentBase&amp;quot;/&amp;gt; property to the given value.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;contentBase&amp;quot;&amp;gt;
/// The &amp;lt;see cref=&amp;quot;IContentBase&amp;quot;/&amp;gt;.
/// &amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;propertyLambda&amp;quot;&amp;gt;
/// The &amp;lt;see cref=&amp;quot;Expression&amp;quot;/&amp;gt; designating the value to save.
/// &amp;lt;/param&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;
/// The &amp;lt;see cref=&amp;quot;Type&amp;quot;/&amp;gt; of the property value.
/// &amp;lt;/typeparam&amp;gt;
/// &amp;lt;exception cref=&amp;quot;ArgumentException&amp;quot;&amp;gt;
/// Thrown if the given &amp;lt;see cref=&amp;quot;Expression&amp;quot;/&amp;gt; is not in the correct form.
/// &amp;lt;/exception&amp;gt;
public static void SetValue&amp;lt;T&amp;gt;(this IContentBase contentBase, Expression&amp;lt;Func&amp;lt;T&amp;gt;&amp;gt; propertyLambda)
{
    MemberExpression expression = propertyLambda.Body as MemberExpression;

    if (expression == null)
    {
        throw new ArgumentException(&amp;quot;You must pass a lambda of the form: '() =&amp;gt; Class.Property' or '() =&amp;gt; object.Property'&amp;quot;);
    }

    PropertyInfo property = expression.Member as PropertyInfo;
    if (property != null)
    {
        MemberExpression member = (MemberExpression)expression.Expression;
        ConstantExpression constant = (ConstantExpression)member.Expression;
        object fieldInfoValue = ((FieldInfo)member.Member).GetValue(constant.Value);
        object value = property.GetValue(fieldInfoValue, null);
        string name = property.Name.ToSafeAlias(true);
        contentBase.SetValue(name, value.ToString());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's basic and doesn't take into account type conversion to and from strings, nor existing supported types but it's certainly a step in the right direction and better than what was there before.&lt;/p&gt;
&lt;p&gt;Obviously, also, there is a an element of assumption in that technique in that we cannot predict what the alias will be and can only go on the most likely name based on the property. Personally though I don't believe the alias should be human editable and should be abstracted away with greater convention. That allows greater predictability and better quality code.&lt;/p&gt;
&lt;p&gt;I would like to see more API signatures in Umbraco like the example I have created and would be more than happy to help try to tighten up the various APIs for the next major version.&lt;/p&gt;
&lt;p&gt;Let me know what you think.&lt;/p&gt;
</description>
      <pubDate>Wed, 25 Mar 2015 10:59:31 Z</pubDate>
      <a10:updated>2015-03-25T10:59:31Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1117</guid>
      <link>http://jamessouth.me/archive/cruncher-v3/</link>
      <category>System.String[]</category>
      <title>Cruncher v3</title>
      <description>&lt;h1&gt;No More &lt;kbd&gt;Ctrl-F5&lt;/kbd&gt;&lt;/h1&gt;
&lt;p&gt;Last night  at a ridiculous hour I released the latest version of my asset preprocessor for .NET&lt;/p&gt;
&lt;p&gt;Cruncher is a cool bit of kit. It makes optimizing your resources easy. It can bundle unlimited combinations of remote and local CSS, Less, Sass, JavaScript, and CoffeeScript files. Like really... Mix and match them anyway you like and Cruncher will preprocess them accordingly and produce links to the processed output.&lt;/p&gt;
&lt;p&gt;Cruncher can handle nested CSS &lt;code&gt;@import&lt;/code&gt; statements, re-maps relative resource urls and has a self cleaning cache should any changes be made to any of the referenced files. It can also parse CSS and add vendor prefixes to rules by &lt;a href="http://caniuse.com/"&gt;Can I Use&lt;/a&gt; using &lt;a href="https://github.com/postcss/autoprefixer"&gt;AutoPrefixer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can, and most definitely should get it &lt;a href="https://www.nuget.org/packages/Cruncher/"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;How it works&lt;/h2&gt;
&lt;p&gt;When processing a collection of inputs, Cruncher will identify the content type and apply the correct preprocessor to the input converting it to CSS or JavaScript accordingly. CSS files are then passed through an AutoPrefixer postprocessor if it is enabled (By default it is). It will then, if you are running in release mode minify the output using the &lt;a href="http://ajaxmin.codeplex.com/"&gt;Microsoft Ajax Minifier&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Finally links are produced in the page as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;/assets-cruncher/-1287271604.css&amp;quot;&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/assets-cruncher/-1661000378.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where the name is the hash of the combined output. This allows the native static file handler to take over which is great for performance (though all this activity is also heavily cached both in the browser and the server).  If any changes are detected by file monitors for each file and imported files then the number will change which forces the browser to request the updated output. That allows instant propagation of changes made to the input files. No More &lt;kbd&gt;Ctrl-F5&lt;/kbd&gt;!&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;It really couldn't be easier. Simply add &lt;code&gt;@using Cruncher&lt;/code&gt; to your view and use the following methods to add resources. This all works in webforms syntax also.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Default.
@CruncherBundler.RenderCSS(&amp;quot;style.css&amp;quot;, &amp;quot;style.less&amp;quot;, &amp;quot;style.scss&amp;quot;)

// Render the link wth a media query.
@CruncherBundler.RenderCSS(new HtmlString(&amp;quot;media=\&amp;quot;(max-width: 800px)\&amp;quot;&amp;quot;), &amp;quot;style.css&amp;quot;, &amp;quot;style.less&amp;quot;, &amp;quot;style.scss&amp;quot;)

// Default.
@CruncherBundler.RenderJavaScript(&amp;quot;jquery-2.1.1&amp;quot;, &amp;quot;test.coffee&amp;quot;, &amp;quot;test.js&amp;quot;)

// Render the script with the 'async' boolean enabled.
@CruncherBundler.RenderJavaScript(JavaScriptLoadBehaviour.Async, &amp;quot;jquery-2.1.1&amp;quot;, &amp;quot;test.coffee&amp;quot;, &amp;quot;test.js&amp;quot;)

// Render the script with the 'defer' boolean enabled.
@CruncherBundler.RenderJavaScript(JavaScriptLoadBehaviour.Defer, &amp;quot;jquery-2.1.1&amp;quot;, &amp;quot;test.coffee&amp;quot;, &amp;quot;test.js&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There's a great writeup of the &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;defer&lt;/code&gt; attributes &lt;a href="http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Feel free to have a good look through the &lt;a href="https://github.com/JimBobSquarePants/Cruncher"&gt;sourcecode&lt;/a&gt;. It's all, as ever, open source under the Apache 2.0 license and contributions are most welcome.&lt;/p&gt;
&lt;h2&gt;Thanks&lt;/h2&gt;
&lt;p&gt;I'd very much like to thank both &lt;a href="https://github.com/Alain-es"&gt;Alain (I'm so sorry I have forgotten your surname)&lt;/a&gt; for providing some simply awesome ideas and code and &lt;a href="https://github.com/jbreuer"&gt;Jeroen Breuer&lt;/a&gt; for reporting bugs and providing me with projects to tests against for this release. You both got me revisiting code I'd long forgotten about and didn't realise anyone was using. &lt;/p&gt;
</description>
      <pubDate>Sun, 30 Nov 2014 03:17:44 Z</pubDate>
      <a10:updated>2014-11-30T03:17:44Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1112</guid>
      <link>http://jamessouth.me/archive/on-why-i-built-a-responsive-framework/</link>
      <category>System.String[]</category>
      <title>On Why I built a Responsive Framework</title>
      <description>&lt;h3&gt;Why?&lt;/h3&gt;
&lt;p&gt;One of the things a work on in my spare time is a &lt;a href="http://responsivebp.com"&gt;responsive framework&lt;/a&gt;. You might have already seen it.&lt;/p&gt;
&lt;p&gt;A few people have asked my why I built it, as there's already several popular frameworks out there. There's one answer I give every time:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Because I needed it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Complexity&lt;/h3&gt;
&lt;p&gt;The other, sadly more popular frameworks, are great pieces of work. A lot of effort has gone into building and testing them and they do a pretty good job for the most part. They all have the same problem though - They're all too design opinionated.&lt;/p&gt;
&lt;p&gt;If I'm  building a website the last thing I need to do is overwrite styles that have already been added by the base stylesheet. Every single change that you have to perform introduces greater opportunity for error and adds weight to the websites resources. Each change also introduces complexity and makes a website more difficult to maintain. &lt;/p&gt;
&lt;p&gt;That's the last thing I need when I'm working with a tight deadline hanging over me. &lt;/p&gt;
&lt;p&gt;Avoiding the issue of opinionated design has been paramount in the development of &lt;a href="http://responsivebp.com"&gt;Responsive&lt;/a&gt;. Every bit of CSS has been coded specifically not to force excessive styles on the developer. Only the required code is present to provide the functionality to build a cross-browser responsive experience&lt;/p&gt;
&lt;h3&gt;Accessibility&lt;/h3&gt;
&lt;p&gt;Another issue that isn't handled properly with other frameworks is accessibility. There's been meagre attempt to remedy this from other frameworks but for the most part they are a mess. I needed something that would handle the greater bulk of accessibility requirements without the developer having to do anything additional. As a result, every JavaScript component within &lt;a href="http://responsivebp.com"&gt;Responsive&lt;/a&gt; handles the creation and manipulation of &lt;a href="http://www.w3.org/TR/wai-aria/"&gt;ARIA&lt;/a&gt; attribution to ensure that its behaviour is accessible to screen readers.&lt;/p&gt;
&lt;h3&gt;Internationalisation&lt;/h3&gt;
&lt;p&gt;None of the frameworks that I am aware of have support for right-to-left languages built in. Developers shouldn't have to jump through hoops to do this. Grids, floated and positioned elements should switch, touchable components should reverse their behaviour, and directional keyboard events should reverse their behaviour all with the minimum of change required by the developer. &lt;a href="http://responsivebp.com"&gt;Responsive&lt;/a&gt; allows you to switch this by adding the attribute &lt;code&gt;dir=&amp;quot;rtl&amp;quot;&lt;/code&gt; to the html element&amp;#42;&lt;/p&gt;
&lt;h3&gt;In Summary&lt;/h3&gt;
&lt;p&gt;By now you should see why I created the framework and why both you and I should be developing our websites both responsive and fixed with &lt;a href="http://responsivebp.com"&gt;Responsive&lt;/a&gt;. Web development has never been more complicated, we're trying to do so much more with less time and more devices than ever before and we need the best setup possible to ensure that we can build performant, flexible, accessible sites. So give it a go, you'll be surprised at how much there is to offer.&lt;/p&gt;
&lt;p&gt;&amp;#42; &lt;em&gt;There has been conversation with other developers based on an outdated information in this &lt;a href="http://www.w3.org/International/questions/qa-html-dir"&gt;article&lt;/a&gt; that states that we should not do this as it reverses the position of the scrollbar in certain obsolete browsers. Instead, we should hack the document by adding a child element to the body setting the attribute on that. In my humble opinion that is ass-backwards (pun intended) If there is a browser bug in any of the non-obsolete browsers report it, don't hack around it.&lt;/em&gt;&lt;/p&gt;
</description>
      <pubDate>Tue, 02 Sep 2014 21:23:00 Z</pubDate>
      <a10:updated>2014-09-02T21:23:00Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1113</guid>
      <link>http://jamessouth.me/archive/image-processing-for-everybody/</link>
      <category>System.String[]</category>
      <title>Image Processing for Everybody!</title>
      <description>&lt;h2&gt;Happy ImageProcessing Day!&lt;/h2&gt;
&lt;p&gt;Today marks the new release of my open source project &lt;a href="http://imageprocessor.org/"&gt;ImageProcessor&lt;/a&gt;. I'm very proud of it.&lt;/p&gt;
&lt;p&gt;Inspired by the frantic codings of the brilliant people I met at this years &lt;a href="http://codegarden14.com/"&gt;Umbraco CodeGarden&lt;/a&gt; retreat this release has turned into an almost complete rewrite of the library. I've dramatically simplified the code required to write plugins whilst making the library much more robust and modular adding a few very cool (I think so anyway) features.&lt;/p&gt;
&lt;p&gt;We now have the following:&lt;/p&gt;
&lt;h3&gt;ImageProcessor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Automatic image file type detection&lt;/li&gt;
&lt;li&gt;Automatic plugin detection&lt;/li&gt;
&lt;li&gt;Ability to extend image file type support via the &lt;code&gt;ISupportedImageFormat&lt;/code&gt; interface&lt;/li&gt;
&lt;li&gt;Ability to extend individual processors via the &lt;code&gt;IGraphicsProcessor&lt;/code&gt; interface &lt;/li&gt;
&lt;li&gt;Methods to load embedded native (unmanaged) libraries from within plugins&lt;/li&gt;
&lt;li&gt;True separation of concerns from the .Web extension.&lt;/li&gt;
&lt;li&gt;More specific error handling feedback&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ImageProcessor.Web&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Automatic plugin detection&lt;/li&gt;
&lt;li&gt;Ability to extend individual processors via the &lt;code&gt;IWebGraphicsProcessor&lt;/code&gt; interface &lt;/li&gt;
&lt;li&gt;Improved and more consistent parsing syntax.&lt;/li&gt;
&lt;li&gt;Improved processing and caching performance&lt;/li&gt;
&lt;li&gt;More images are now cached (theoretically 409,600,000,000)&lt;/li&gt;
&lt;li&gt;Post processing events to tap into. &lt;code&gt;ImageProcessingModule.OnPostProcessing&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Improved error handling for remote image requests&lt;/li&gt;
&lt;li&gt;Url configurable EXIF preservation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There's more but it's probably best for you to read the &lt;a href="http://imageprocessor.org/"&gt;documentation&lt;/a&gt;. As ever, it's a work in progress but I've tried to make them readable and precise. If you want to help at any point to improve the library, there is always a good place to start.&lt;/p&gt;
&lt;p&gt;I'd really like to thank &lt;a href="http://www.hanselman.com/"&gt;Scott Hanselman&lt;/a&gt; for sharing the library on his blog and the &lt;a href="http://umbraco.com/"&gt;Umbraco&lt;/a&gt; team and community for their continuing support and faith in my ability. You guys absolutely rock! #h5yr's and approving nods all round! 
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;img src="http://jamessouth.me/media/1003/mccoy-kirk.gif" alt="Kirk McCoy nodding original" /&gt;
&lt;img src="http://jamessouth.me/media/1003/mccoy-kirk.gif?width=150" alt="Kirk McCoy nodding resized" /&gt;&lt;/p&gt;
</description>
      <pubDate>Wed, 27 Aug 2014 02:51:45 Z</pubDate>
      <a10:updated>2014-08-27T02:51:45Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1111</guid>
      <link>http://jamessouth.me/archive/filepath-too-long/</link>
      <category>System.String[]</category>
      <title>Filepath too long?</title>
      <description>&lt;p&gt;I thought I'd write this post as a reminder to myself and as a helper for anyone daft enough to try to use Node on a Windows machine.&lt;/p&gt;
&lt;p&gt;Node has a mental system for managing packages which involves deeply nesting dependencies in the &lt;code&gt;node_modules&lt;/code&gt; folder. This can lead to all sorts of problems on Windows machines like making the &lt;code&gt;--watch&lt;/code&gt; overload for Jekyll die on its ass.&lt;/p&gt;
&lt;p&gt;You can't even delete the damn thing properly due to Windows path constraints. It's really annoying to say the least but at least they know about &lt;a href="https://github.com/npm/npm/issues/3697"&gt;it&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here's a quick method I use to remove the folder when I need to.&lt;/p&gt;
&lt;p&gt;Open a command prompt or whatever your shell tool of choice is, navigate to the parent folder of the &lt;code&gt;node_modules&lt;/code&gt; folder and type in the following commands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir foo
robocopy foo node_modules /MIR
del foo
del node_modules
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This command uses the &lt;a href="http://technet.microsoft.com/en-us/library/cc733145.aspx"&gt;robocopy utility&lt;/a&gt; and the /MIR &amp;quot;mirror&amp;quot; flag to mirror the empty &lt;code&gt;foo&lt;/code&gt;  directory to the &lt;code&gt;node_modules&lt;/code&gt; folder emptying it out. You can then delete both directories.&lt;/p&gt;
&lt;p&gt;Voilà :)&lt;/p&gt;
</description>
      <pubDate>Tue, 05 Aug 2014 13:57:28 Z</pubDate>
      <a10:updated>2014-08-05T13:57:28Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1110</guid>
      <link>http://jamessouth.me/archive/a-call-to-arms/</link>
      <category>System.String[]</category>
      <title>A Call To Arms</title>
      <description>&lt;blockquote&gt;
&lt;p&gt;The popularity of the Internet is the most important single development in the world of computing since the IBM PC was introduced in 1981. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Bill Gates was quoted as saying that. I'd go further. &lt;/p&gt;
&lt;p&gt;I believe that the Internet is the &lt;strong&gt;single most important invention we have ever created&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;With the Internet we can now universally share information like never before. We can pool resources to solve problems, provide education resources for each other and future generations, and provide support and services (sometimes lifesaving) for almost all our needs. It has revolutionised almost every aspect of our interaction as a species with billions of people now having access to the largest, free, information portal that has ever been created. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The internet is a Good Thing&lt;/strong&gt; &amp;#0153;&lt;/p&gt;
&lt;p&gt;I am a web developer. I imagine that you, reading this are one also. As such we possess a unique and special set of skills that allow us to create software to expand upon and improve the Internet. I believe that as developers we have an obligation, I would say a privileged one, to &lt;strong&gt;ensure that every single piece of work we produce is delivered to the highest possible standard&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To do that requires effort on our part. It requires dedication, passion, craftsmanship, and an attention to detail.&lt;/p&gt;
&lt;p&gt;At present I don't believe as a profession we do this. I won't go into specific technical details with this post but I will list some of the common mistakes I see professionals make on a daily basis.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multiple blocking requests of unminified resources in the head of the document.&lt;/li&gt;
&lt;li&gt;Incorrect use of elements rendering websites inaccessible.&lt;/li&gt;
&lt;li&gt;Sporadic, in-line JavaScript and CSS. &lt;/li&gt;
&lt;li&gt;Unoptimized, massive image requests increasing page weight.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;This is bread and butter stuff, day one stuff and we really should do better.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So here is my challenge to you: Every time you release a piece of work, ask yourself whether it is the best that you can do. Is it fast, lightweight? Is it accessible? Have you followed the defined standards? Have you tested it?&lt;/p&gt;
&lt;p&gt;If you haven't, you are doing not only yourself a disservice but also one to the people who consume your work, who depend on your work and you should question your fitness for such an important role.&lt;/p&gt;
&lt;p&gt;Strong words I know but we have a duty of care.&lt;/p&gt;
</description>
      <pubDate>Sat, 26 Jul 2014 12:54:03 Z</pubDate>
      <a10:updated>2014-07-26T12:54:03Z</a10:updated>
    </item>
  </channel>
</rss>