Category Archives: Code

HTML5 History / pushState URLs, .htaccess and You

This guide explains the issues with using JavaScript’s HTML5 History (pushState) URLs in Apache and covers how to set up your .htaccess file to handle URL routing.

If you’re not sure about pushState and the HTML5 History API, here’s a solid starter. If you just want the .htaccess code, you can skip the explanation.

So we’ve reached this point now where every half-decent JavaScripter knows their way around the pushState / replaceState History API and the related wrappers/plugins, and has a decent idea of browser support and cross-browser polyfills for HTML5 History. I think.

But at the same time, the very people who want to be using it are faced with a blight that, for love nor money, they can’t fix: HTML5 History URLs screw up Apache. And there are just no damn guides anywhere about how to make it work (until now!)

The Apache web server was designed long before the first murmurings of rewriting URLs without a page refresh were heard, and a certain amount of tomfoolery is required to make dynamically-updating URLs work seamlessly.

So without further ado, I present the problem and the starter-pack solution.

Apache doesn’t like you with your damn pushState

So, as you hopefully know by now, to navigate between different sections, screens or pages of a client-side JavaScript application, you’d traditionally use hash (#) or hash-bang (#!) fragments (e.g. .com/#shopping-cart or .com/#!/profile/yourmum/). The JS code picks up the hashchange event (either natively or via a custom listener/event in older browsers) and fires off a function in your app to switch out the content, or perform some killer action.

When you use HTML5 History, you don’t use hash fragments; instead, your JS app or website uses .pushState(), or you use your library/wrapper of choice, to navigate (update the URL and create an entry in the window history, enabling Back/Forward support) to e.g. .com/shopping-cart or .com/profile/yourmum/ – all without a page refresh.

Perfect. But… when you save/bookmark/send these URLs, then try to visit them a little later on, you may be disappointed to discover that they don’t exist. The horror!

Why don’t they exist?

Think about it – you’re trying to find a resource located at a specific URL. It has to be served through Apache. Apache is gonna look for that file, because it doesn’t have any idea that you’re looking for a dynamic resource, and even if it did, it wouldn’t know what to send back to help you find it!

Apache can handle HTML History/pushState with .htaccess

Apache was just being mean, earlier. It doesn’t have anything against pushState. In fact, it loves pushState: now every user, instead of requesting 20 pages in quick succession, requests only one page, with those 20 states being requested bit-by-bit (as smaller fragments, or however your site or JS app handles it.)

But it does choke a little bit.

As I mentioned before, it has to follow the rules: when a visitor requests a resource (or a location that looks like a resource) Apache has to look for it, first in the .htaccess file, if any, then in the filesystem to see if it can find a matching directory/file.

It won’t find it, so it throws a 404 error. “I wanted to help,” it mumbles, “I just couldn’t find the damn thing you wanted. Not my problem!”

So we gotta tell it where to look!

Where would it look? Well, where is the JavaScript app that’s going to check the URL and route the page/screen/section accordingly?

For most apps, it’s index.html, which would include in all the JavaScript required to handle this. For example, that’s the page containing your single-page app, in Backbone.js, or jQuery, or just (whoa) plain ol’ JavaScript.

And that’s what this solution assumes.

.htaccess rules for HTML5 pushState support:

So the solution: you add a few lines to your .htaccess file.

These lines check firstly whether the requested filename is NOT a static resource (such as an image, stylesheet, or other asset, so that they don’t all get redirected to index.html), then whether the requested resource is not already index.html (uh oh infinite loops!) and then finally redirects everything to – you guessed it – index.html.

# html5 pushstate (history) support:
<ifModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !index
    RewriteRule (.*) index.html [L]
</ifModule>

There might even be a nicer way to write it. I’m no Apache warrior, so to speak, but this works for us.

What does this mean for the visitor?

Obviously, when on the site/single-page app, they don’t notice a thing. Everything works fine.

The kicker is that when they bookmark a page, or email a funny link to their friend, the next time that URL is opened (the one that was navigated to by pushState), Apache will simply direct the visitor to the homepage. At that point, the JavaScript app takes over. Boom.

This works for multiple-levels of nesting, too, which was a big pain-point when finding a solution. Thus the following URL redirects to index.html without a fuss:

.com/profiles/yourmum/images/?starttime=[stalkerishly long time ago]
  -> .com/index.html

At which point the JavaScript code would step in and do it’s nasty business.

Et voila. The .htaccess rules above may not work for everyone and YMMV, but it’s doing it for us.

Further reading:

Any comments? Suggestions, improvements, errors? You know what to do!

PS. I know, I know. “Don’t use Apache blah blah nginx blah.” I know. But people still use Apache.

# edit: Updated .htaccess rules to be a bit better, based on WordPress permalinks’ .htaccess rules.

Convert a table of mixed values to a single currency with money.js

You can use money.js and data from the open exchange rates API to convert/normalise an entire table of values from multiple currencies to any other single currency.

I’m using it in our analytics application to let users compare the money values from assorted items (in different currencies) in a single currency of their choice. Every data table has an option to normalise currencies for all values.

Convert a table of values with money.js

Below you’ll find a table of Christmas-themed adult novelty products. All of the items are in different currencies for some reason (a realistic scenario, if you’ve been scraping data from various websites.)

What if you want to compare the unit price and gross revenue values for each product in a single currency? Try it!

Iframe not loading? You can also view the demo here. I wrote it before Christmas, in case you’re wondering why it’s Christmas-themed!

In this demo, I’m also using underscore.js for data manipulation and client-side templating, jQuery for DOM manipulation/events and accounting.js for number formatting.

The table is built using a very simple underscore.js template, from a matrix of values (array of arrays) representing table rows and individual cells. (If you’re unsure about building tables from data matrices, I wrote a post that deals with it some more, explaining how to format tables of numbers with accounting.js and underscore.js).

The code

The code that does the conversion is a little rough around the edges, but here’s how it breaks down:

  • Define the data table as an array of columns (each an object, with title and metadata) and an array of table rows (each an array of table cells). In your application, this data would probably come from an API.
  • Use the underscore.js template to draw the table and jQuery to render it.
  • When the select box is changed, loop over the table rows (items), and for each one, get the item’s original currency, and use money.js’ fx.convert() to convert the value. Then redraw the table.

Here’s the underscore.js template, some funky syntax highlighting going on there:

<script type="text/template" id="tableTemplate">
    <table>
        <thead>
            <tr>
                <% _(tplColumns).each(function(col) { %>
                    <th data-column="<%= col.key %>"><%= col.title %></th>
                <% }); %>
            </tr>
        </thead>

        <tbody>
            <% _(tplRows).each(function(row) { %>
                <tr>
                    <% _(row).each(function(value, i) { %>
                        <td class="<%= tplColumns[i].type || '' %>">
                            <%= formatCell(value, tplColumns[i].type) %>
                        </td>
                    <% }); %>
                </tr>
            <% }); %>
        </tbody>
    </table>
</script>

So we gots a table header row, with the <th> cells templated from the tplColumns array, and then the table body, with each <th> representing a single item (an array in the tplRows array and each <td> representing a single value. The template relies on a handy formatCell() function, which uses accounting.js to format each table cell’s value, according to its type.

The JavaScript code itself is a little janky, but it works for our purposes:

// Handy callback function to run accounting.js formatting on cells:
function formatCell(value, type) {
    return type === 'number' ? accounting.formatNumber(value)
         : type === 'money' ? accounting.formatNumber(value, 2)
         : value;
}

// On ready:
jQuery(document).ready(function($) {

    // The columns in the table:
    var columns = [
        { title: 'Product',       key: 'name'      },
        { title: 'Units Sold',    key: 'sold',    type: 'number' },
        { title: 'Currency',      key: 'fx',      type: 'fx'     },
        { title: 'Unit Price',    key: 'price',   type: 'money'  },
        { title: 'Gross Revenue', key: 'revenue', type: 'money'  }
    ];

    // The rows of data (corresponding to columns):
    var rows = [
        [ 'His &amp; Hers Prophylactics',         24965, 'USD', 12.99, 324295.35 ],
        [ 'Christmas Stockings, Fishnet',         12600, 'GBP', 16.8,  211680    ],
        [ 'Candy Underwear, Gummy',               8965,  'SEK', 80.5,  721682.5  ],
        [ 'Santa Hat and Santa Suit, Crotchless', 13543, 'EUR', 10.5,  142201.5  ],
        [ 'Vibrating Christmas Crackers x 6',     9954,  'HKD', 108,   1075032   ]
    ];

    // Handy underscore.js template that builds a table from data like the above:
    // (See script tag with template, above)
    var template = _.template( $('#tableTemplate').html() );

    // Template the table's HTML using our data:
    $('#table').html( template({
        tplColumns: columns,
        tplRows: rows
    }));

    // Convert the data:
    $('#currency').change(function() {
        var targetFx = $(this).find(':selected').val();
        var currentFx;

        if ( !targetFx ) return false;

        // Now we're gonna use underscore.js to confapulate the data:
        var newRows = _.map(rows, function(row) {
            // Keeps the original row intact:
            row = _.clone(row);

            // Get the 'from' currency:
            currentFx = row[2];

            // Update the row's currency with the 'target':
            row[2] = targetFx;

            // Convert the numbers yo:
            row[3] = fx.convert(row[3], { from: currentFx, to: targetFx });
            row[4] = fx.convert(row[4], { from: currentFx, to: targetFx });

            return row;
        });

        // Now template the data:
        $('#table').html(template({
            tplColumns: columns,
            tplRows: newRows
        }));

        return false;
    });

    // Reset to original data:
    $('#reset').click(function() {
        // Template the original data:
        $('#table').html( template({
            tplColumns: columns,
            tplRows: rows
        }));
    });
});

Note that the formatting part takes a shortcut and uses predefined indices to find values in the data array (in our app, it’s a little more complicated, as the index of the currency value is unpredictable – so there’s a method to find out which it is, which I’ve left out for brevity.)

This method relies on your using data arrays (e.g. vie AJAX) to build tables dynamically with JavaScript. If your tables are templated on the server-side and delivered as fully-rendered HTML, there are other ways to achieve this result, but I’ll save those for another day.

Any questions, hit me up in the comments!

Bonus points

PS. Here’s the code that loads the data from the exchange rate API into money.js, and also builds the drop-down currency select box:

// Get the latest exchange rates from openexchangerates.org:
$.ajax({
    url: 'http://openexchangerates.org/latest.json?app_id=[YOUR_APP_ID]',
    dataType: 'jsonp',
    success: function(data) {
        fx.rates = data.rates;
        fx.base = data.base;
    }
});

// Get the list of currencies too, and create an extra group in the drop-down:
$.ajax({
    url: 'http://openexchangerates.org/currencies.json',
    dataType: 'jsonp',
    success: function(data) {
        var $optgroup = $('<optgroup label="All Currencies"/>');
        _.each(data, function(name, code) {
            $optgroup.append('<option value="' + code + '">' + name + ' (' + code +')</option>');
        });
        $optgroup.appendTo('#currency');
    }
});

Hope you’ve enjoyed reading this festive exploration of money exchanging extravagance!

The Über-Programmer

If you ever catch me staring quietly into space when shit hits the fan – when it seems as though I should be furiously typing, sweating profusely and throwing back coffee by the litre – recall this quotation by John D. Cook and breathe a sigh of relief:

The romantic image of an über-programmer is someone who fires up Emacs, types like a machine gun, and delivers a flawless final product from scratch. A more accurate image would be someone who stares quietly into space for a few minutes and then says “Hmm. I think I’ve seen something like this before.”

javascript sandbox console – a playground for your users to mess around in (Backbone.js)

While working on an upcoming JavaScript library and open source API service, I accidentally created a mini javascript playground, with the goal of allowing users to easily try out the library’s functionality, without having to open their console.

javascript sandbox console

It seemed like a cool enough concept to warrant taking a break from that project and indulging in an all-night coding marathon to get it finished. Work the next day was painful, but I’m pretty pleased with how version 0.1 came out.

Introducing the javascript sandbox console

The 0.1 release features a pretty design, up/down command history (with localStorage saving), basic syntax highlighting for output and some other cool features.

javascript sandbox console demogithub repository

It’s seriously easy to style with CSS (I’ll add some extra skins soon) and to install on your library/plugin’s homepage. Do it! Your users will thank you.

What’s more, it’s entirely programmable through the global sandbox object, so you can manually feed it commands for the user to try (as on the demo.)

Oh, and it’s not tested in IE, as of publishing, because I don’t have my windows laptop with me.

Enjoy!

The js sandbox console is a javascript playground designed to enhance demos and homepages for javascript libraries, plugins and scripts, giving visitors an easy and chilled-out way to test-drive the functionality – without whacking open their Firebug / Dev Tools console.

The idea is inspired by jsconsole.com and was built with Backbone.js and jQuery, in a strange and terrible all-night code-off. Then tidied up a bit the next day.

PS:

Make sure to hit ‘watch’ on the repository, as it will be getting a bunch of fixes and improvements in the next few months. Please make issues if you find any bugs or have suggestions, and feel free to contribute code.

A little URL generator for Backbone.js

Just something I wrote at work today: our app has a model that acts as an API for submodules, and as part of it, it allows interlinking between different modules (aka ‘screens’).

You can pass this method the ‘slug’ of any screen (module) in the app, plus any number of arguments and it builds a URL for them. Each of the args is separated by a ‘/‘.

Arrays are joined with commas, functions are executed, objects are strigified via jQuery’s $.param, and strings/numbers are just given as-is.

// Build URL for any screen:
urlify: function(slug) {
	slug = slug || "";

	// Create array of strings from arguments:
	var args = _.map(Array.prototype.slice.call(arguments, 1), function(arg) {
		// Join arrays, evaluate functions, stringify objects, leave strings/numbers:
		return _.isArray(arg) ? arg.join(',') : _.isFunction(arg) ? arg() : _.isObject(arg) ? $.param(arg) : arg;
	});
	return (!Backbone.history.options.pushState ? '#' : '') + slug + '/' + ( args.length > 0 ? args.join('/') + '/' : '' );
}

// for example:
Model.urlify('screen-name', 1253431, ["a","b","c"], {a:1});
// => "#screen-name/1253431/a,b,c/a%5Bb%5D=1/"

What the hash?

Note the (!Backbone.history.options.pushState ? '#' : '') ?

When supporting pushState in Backbone.history, some browsers will use e.g. app.com/#page, while others will use simply app.com/page.

But what about when you need to template in links to other sections of your app, but you’re not sure if the user’s browser supports pushState?

I got your back, bro. What this function does is inserts a hash # when pushState is not supported, so that inter-linking modules still get routed to the correct place.

Not sure if any of this makes sense, as currently a little tipsy – will update tomorrow with better info and examples.

Formatting currency columns in tables with underscore.zip and accounting.js

This article runs through and demonstrates using accounting.js and underscore.js to format columns of numbers inside tables. It’s not complicated, and you might find it interesting, but it’s really a specific solution aimed at a common problem.

So. Probably the most common usage example for formatting accounting columns is inside tables, for example:

EXPENSES
Hair Net                $   (1.50) « symbols and units lined up
Treatment Creme         $  (12.99)
Cut and Finish          $ (125.00)

This table is easily templated from an array of arrays (a ‘matrix’), each array representing a row (<tr>) in the table, each value representing a cell (<td>) – like so:

// Each nested array represents a <tr>, each value a <td>
var expenseReport = [
	["Hair Net", -1.5],
	["Treatment Creme", -12.99],
	["Cut and Finish", -125]
];
// Example templated markup:
<table><tbody><tr><td>Hair Net</td><td>-1.5</td>

The problem here is that each of these arrays represents a row, each containing a single one of the values you need – but if you want to column-format those numbers with accounting.js’s formatColumn() method, you’ll need to have those values in an array by themselves, so that you can do this:

var values = [-1.5, -12.99, -125];
accounting.formatColumn(values);
// ["$   (1.50)", "$  (12.99)", "$ (125.00)"]

Hence you need a matrix where each nested array represents a vertical column in the table, like this:

// Each nested array is now a hypothetical 'column' in the table:
var expenseReport = [
	["Hair Net", "Treatment Creme", "Cut and Finish"],
	[1.5, 12.99, 125] // we gots the values!
];

So what you effectively need to do is flip around that matrix of values, so that you have access to all those numbers without having to pluck out the second value from each row manually.

This is a process known as transposing a matrix, and it is exactly this that underscore.js performs with _.zip(). From the underscore.js docs (emphasis added):

zip   _.zip(*arrays)

Merges together the values of each of the arrays with the values at the corresponding position. Useful when you have separate data sources that are coordinated through matching array indexes. If you’re working with a matrix of nested arrays, zip.apply can transpose the matrix in a similar fashion.

_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
=> [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]

Obviously it’s unfeasible to pass in each row of the table manually (e.g. _.zip(row1, row2, row3, ...) so you need to use _.zip.apply([], matrix), which will call _.zip with the matrix’s nested arrays (table rows) as arguments, returning a transposed matrix where all the values are swapped into equivalent positions.

Example of matrix transposition

I threw together a little jsFiddle demo to show what this does. Click the button a few times.

Not loading? View it on jsFiddle here.

The process, step-by-step:

If you have a table represented by a matrix (array of arrays) in a javascript variable, where each array represents a table row, you could use this example code to apply accounting.formatColumn() to a column of values at the 2nd index (row[1]):

// The original matrix:
var expenseReport = [
	["Hair Net", -1.5],
	["Treatment Creme", -12.99],
	["Cut and Finish", -125]
];

// Options for accounting.js (see docs)
var options = {
	symbol: "HK$",
	precision: 0,  
	format: {
		pos : "%s %v",   // for positive values, eg. "$ 1.00"
		neg : "%s (%v)", // for negative values, eg. "$ (1.00)"
		zero : "%s -- "  // for zero values, eg. "$ --"
	}
};

// Transpose the matrix to access the columns as arrays:
expenseReport = _.zip.apply([], expenseReport);

// Format the column of values (at position [1]):
expenseReport[1] = accounting.formatColumn(expenseReport[1], options);

// Transpose the matrix back to original positions:
expenseReport = _.zip.apply([], expenseReport);

Done! The expenseReport matrix now looks like this – an array of rows, ready to be templated into an HTML table:

[
  [
    "Hair Net",
    "HK$   (2)"
  ],
  [
    "Treatment Creme",
    "HK$  (13)"
  ],
  [
    "Cut and Finish",
    "HK$ (125)"
  ]
]

This same logic applies to big tables of data, too – once you’ve used _.zip to access the table’s columns as arrays, you can use formatColumn on as many of them as you need to, with as many different configurations as you like.

The next step

I’m also hoping to implement this into accounting.js somehow, if there’s demand for it. Something like formatTable, although it could get complicated, so it’d probably be implemented as an additional plugin, maybe for jayQwery or the awesome DataTables plugin. Heck, look at me, I’m ramblin’ again.

Comment up if you have questions, comments or personal problems you’d like to discuss.

My weekend project: accounting.js

accounting.js is a tiny JavaScript library for number, money and currency formatting, with optional excel-style column rendering (to line up symbols and decimals). It’s lightweight, fully localisable and has zero dependencies.

I decided to take the couple of number formatting functions I posted last week and turn them into a library, with the key addition being the excel-style column formatting, which takes an array of values and adds padding between the currency symbol and the number, so that the symbols and decimal places are aligned:

Original: With accounting.js:
123.5 $ 123.50
3456.49 $ 3,456.49
777888.99 $ 777,888.99
-5432 $ -5,432.00
// Format list of numbers for display:
accounting.formatColumn([123.5, 3456.49, 777888.99, 12345678, -5432], "$ ");

It also includes functions for formatting any value to currency with custom precision and symbols, and a function to remove all currency formatting:

// Default usage and custom precision/symbol :
accounting.formatMoney(12345678); // $12,345,678.00
accounting.formatMoney(4999.99, "€", 2, ".", ",")); // €4.999,99
accounting.formatMoney(-500000, "£ ", 0) ); // £ -500,000

// Basic number formatting:
accounting.formatNumber(9876543); // 9,876,543 

// Remove formatting:
accounting.unformat("GBP £ 12,345,678.90"); // 12345678.9

It’s early days, but check out the accounting.js homepage for more info and live demos, and watch the github repository for the next version.