diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js
index b63d4d0431..520ba70bcc 100644
--- a/public/src/ajaxify.js
+++ b/public/src/ajaxify.js
@@ -210,7 +210,7 @@ var ajaxify = {};
 
 				data.relative_path = RELATIVE_PATH;
 				
-				templates.parse(tpl_url, data, function(err, template) {
+				templates.parse(tpl_url, data, function(template) {
 					translator.translate(template, function(translatedTemplate) {
 						$('#content').html(translatedTemplate);
 
@@ -235,6 +235,23 @@ var ajaxify = {};
 		});
 	};
 
+	ajaxify.loadTemplate = function(template, callback) {
+		if (templates.cache[template]) {
+			callback(templates.cache[template]);
+		} else {
+			$.ajax({
+				url: RELATIVE_PATH + '/templates/' + template + '.tpl',
+				type: 'GET',
+				success: function(data) {
+					callback(data.toString());
+				},
+				error: function(error) {
+					throw new Error("Unable to load template: " + template + " (" + error.statusText + ")");
+				}
+			});
+		}
+	};
+
 	ajaxify.variables = (function() {
 		var parsedVariables = {};
 
@@ -297,9 +314,8 @@ var ajaxify = {};
 
 			socket.emit('widgets.render', {template: tpl_url + '.tpl', url: url, location: location}, function(err, renderedWidgets) {
 				if (area.html()) {
-					area.html(templates.parse(area.html(), {
-						widgets: renderedWidgets
-					})).removeClass('hidden');
+					area.html(templates.parse(area.html(), {widgets: renderedWidgets}))
+						.removeClass('hidden');
 
 					if (!renderedWidgets.length) {
 						ajaxify.repositionNoWidgets();
@@ -371,18 +387,7 @@ var ajaxify = {};
 			}
 		});
 
-		templates.registerLoader(function(template, callback) {
-			$.ajax({
-				url: RELATIVE_PATH + '/templates/' + template + '.tpl',
-				type: 'GET',
-				success: function(data) {
-					callback(null, data.toString());
-				},
-				error: function(error) {
-					callback({message: error.statusText}, false);
-				}
-			});
-		});
+		templates.registerLoader(ajaxify.loadTemplate);
 
 		$.when($.getJSON(RELATIVE_PATH + '/templates/config.json'), $.getJSON(RELATIVE_PATH + '/api/get_templates_listing')).done(function (config_data, templates_data) {
 			templatesConfig = config_data[0];
diff --git a/public/src/forum/accountposts.js b/public/src/forum/accountposts.js
index 6612119c6e..1609886fa1 100644
--- a/public/src/forum/accountposts.js
+++ b/public/src/forum/accountposts.js
@@ -1,6 +1,6 @@
 'use strict';
 
-/* globals define, app, socket, templates, translator */
+/* globals define, app, socket, ajaxify, templates, translator */
 
 define(['forum/accountheader'], function(header) {
 	var AccountPosts = {},
@@ -38,15 +38,10 @@ define(['forum/accountheader'], function(header) {
 	}
 
 	function onTopicsLoaded(posts) {
-		templates.preload_template('accountposts', function() {
-			templates.accountposts.parse({posts: []});
-
-			var html = templates.prepare(templates.accountposts.blocks.posts).parse({
-				posts: posts
-			});
+		ajaxify.loadTemplate('accountposts', function(accountposts) {
+			var html = templates.parse(templates.getBlock(accountposts, 'posts'), {posts: posts});
 
 			translator.translate(html, function(translatedHTML) {
-
 				$('#category-no-topics').remove();
 
 				html = $(translatedHTML);
diff --git a/public/src/forum/admin/categories.js b/public/src/forum/admin/categories.js
index f71526b9e5..11786a7d0f 100644
--- a/public/src/forum/admin/categories.js
+++ b/public/src/forum/admin/categories.js
@@ -1,5 +1,5 @@
 "use strict";
-/*global define, socket, app, bootbox, templates, RELATIVE_PATH*/
+/*global define, socket, app, bootbox, templates, ajaxify, RELATIVE_PATH*/
 
 define(['uploader'], function(uploader) {
 	var	Categories = {};
@@ -120,12 +120,9 @@ define(['uploader'], function(uploader) {
 					timeout: 2000
 				});
 
-				templates.preload_template('admin/categories', function() {
-					templates['admin/categories'].parse({categories:[]});
-					var html = templates.prepare(templates['admin/categories'].blocks.categories).parse({
-						categories: [data]
-					});
-					html = $(html);
+				ajaxify.loadTemplate('admin/categories', function(adminCategories) {
+					var html = $(templates.parse(templates.getBlock(adminCategories, 'categories'), {categories: [data]}));
+					
 					html.find('[data-name="bgColor"], [data-name="color"]').each(enableColorPicker);
 
 					$('#entry-container').append(html);
diff --git a/public/src/forum/admin/users.js b/public/src/forum/admin/users.js
index 3a9ff65e94..1e25210ee7 100644
--- a/public/src/forum/admin/users.js
+++ b/public/src/forum/admin/users.js
@@ -193,14 +193,9 @@ define(function() {
 							return app.alertError(err.message);
 						}
 
-						templates.preload_template('admin/users', function() {
-							templates['admin/users'].parse({users:[]});
-							var html = templates.prepare(templates['admin/users'].blocks.users).parse({
-								users: data.users
-							}),
-								userListEl = document.querySelector('.users');
-
-							userListEl.innerHTML = html;
+						ajaxify.loadTemplate('admin/users', function(adminUsers) {
+							$('.users').html(templates.parse(templates.getBlock(adminUsers, 'users'), data));
+
 							$('.fa-spinner').addClass('none');
 
 							if (data && data.users.length === 0) {
@@ -226,14 +221,8 @@ define(function() {
 			handleUserCreate();
 
 			function onUsersLoaded(users) {
-				templates.preload_template('admin/users', function() {
-					templates['admin/users'].parse({users:[]});
-					var html = templates.prepare(templates['admin/users'].blocks.users).parse({
-						users: users
-					});
-					html = $(html);
-					$('#users-container').append(html);
-
+				ajaxify.loadTemplate('admin/users', function(adminUsers) {
+					$('#users-container').append($(templates.parse(templates.getBlock(adminUsers, 'users'), {users: users})));
 					updateUserBanButtons(html.find('.ban-btn'));
 					updateUserAdminButtons(html.find('.admin-btn'));
 				});
diff --git a/public/src/forum/category.js b/public/src/forum/category.js
index 7ddb84fc1f..328d63e22e 100644
--- a/public/src/forum/category.js
+++ b/public/src/forum/category.js
@@ -165,11 +165,9 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
 
 	Category.onNewTopic = function(data) {
 		$(window).trigger('filter:categories.new_topic', data);
-		templates.preload_template('category', function() {
-			templates.category.parse({topics:[]});
-			var html = templates.prepare(templates.category.blocks.topics).parse({
-				topics: [data]
-			});
+
+		ajaxify.loadTemplate('category', function(categoryTemplate) {
+			var html = templates.parse(templates.getBlock(categoryTemplate, 'topics'), {topics: [data]});
 
 			translator.translate(html, function(translatedHTML) {
 				var topic = $(translatedHTML),
@@ -249,11 +247,8 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
 
 		findInsertionPoint();
 
-		templates.preload_template('category', function() {
-			templates.category.parse({topics:[]});
-			var html = templates.prepare(templates.category.blocks.topics).parse({
-				topics: topics
-			});
+		ajaxify.loadTemplate('category', function(categoryTemplate) {
+			var html = templates.parse(templates.getBlock(categoryTemplate, 'topics'), {topics: topics});
 
 			translator.translate(html, function(translatedHTML) {
 				var container = $('#topics-container'),
diff --git a/public/src/forum/favourites.js b/public/src/forum/favourites.js
index 6bfc07da4b..6b992c89de 100644
--- a/public/src/forum/favourites.js
+++ b/public/src/forum/favourites.js
@@ -33,14 +33,10 @@ define(['forum/accountheader'], function(header) {
 	}
 
 	function onTopicsLoaded(posts) {
-		templates.preload_template('favourites', function() {
-			templates['favourites'].parse({posts:[]});
-			var html = templates.prepare(templates['favourites'].blocks['posts']).parse({
-				posts: posts
-			});
+		ajaxify.loadTemplate('favourites', function(favouritesTemplate) {
+			var html = templates.parse(templates.getBlock(favouritesTemplate, 'posts'), {posts: posts});
 
 			translator.translate(html, function(translatedHTML) {
-
 				$('#category-no-topics').remove();
 
 				html = $(translatedHTML);
diff --git a/public/src/forum/home.js b/public/src/forum/home.js
index 5a70082de1..18462f87de 100644
--- a/public/src/forum/home.js
+++ b/public/src/forum/home.js
@@ -1,6 +1,6 @@
 'use strict';
 
-/* globals define, socket, app, templates, translator*/
+/* globals define, socket, app, templates, translator, ajaxify*/
 
 define(function() {
 	var	home = {};
@@ -62,19 +62,8 @@ define(function() {
 	}
 
 	function parseAndTranslate(posts, callback) {
-		templates.preload_template('home', function() {
-
-			templates.home.parse({
-				categories: {
-					posts: []
-				}
-			});
-
-			var html = templates.prepare(templates.home.blocks['categories.posts']).parse({
-				categories: {
-					posts: posts
-				}
-			});
+		ajaxify.loadTemplate('home', function(homeTemplate) {
+			var html = templates.parse(templates.getBlock(homeTemplate, 'categories.posts'), {categories: {posts: posts}});
 
 			translator.translate(html, function(translatedHTML) {
 				translatedHTML = $(translatedHTML);
diff --git a/public/src/forum/recent.js b/public/src/forum/recent.js
index e75ecad06b..81f69f098b 100644
--- a/public/src/forum/recent.js
+++ b/public/src/forum/recent.js
@@ -115,15 +115,11 @@ define(function() {
 		});
 	}
 
-	Recent.onTopicsLoaded = function(template, topics) {
-		templates.preload_template(template, function() {
-			templates[template].parse({topics:[]});
-			var html = templates.prepare(templates[template].blocks['topics']).parse({
-				topics: topics
-			});
+	Recent.onTopicsLoaded = function(templateName, topics) {
+		ajaxify.loadTemplate(templateName, function(template) {
+			var html = templates.parse(templates.getBlock(template, 'topics'), {topics: topics});
 
 			translator.translate(html, function(translatedHTML) {
-
 				$('#category-no-topics').remove();
 
 				html = $(translatedHTML);
diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js
index 028e353ae6..387c147b52 100644
--- a/public/src/forum/topic.js
+++ b/public/src/forum/topic.js
@@ -746,14 +746,12 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools'],
 	}
 
 	function parseAndTranslatePosts(data, callback) {
-		templates.preload_template('topic', function() {
-			templates.topic.parse({posts: []});
-			var html = templates.prepare(templates.topic.blocks.posts).parse(data);
+		ajaxify.loadTemplate('topic', function(topicTemplate) {
+			var html = templates.parse(templates.getBlock(topicTemplate, 'posts'), data);
 			translator.translate(html, callback);
 		});
 	}
 
-
 	function onNewPostsLoaded(html, posts) {
 		for (var x = 0, numPosts = posts.length; x < numPosts; x++) {
 			toggle_mod_tools(posts[x].pid, posts[x].display_moderator_tools);
diff --git a/public/src/forum/users.js b/public/src/forum/users.js
index 003b795492..4a74dacb7f 100644
--- a/public/src/forum/users.js
+++ b/public/src/forum/users.js
@@ -59,11 +59,8 @@ define(function() {
 							return;
 						}
 
-						templates.preload_template('users', function() {
-							templates['users'].parse({users:[]});
-							var html = templates.prepare(templates['users'].blocks['users']).parse({
-								users: data.users
-							});
+						ajaxify.loadTemplate('users', function(usersTemplate) {
+							var html = templates.parse(templates.getBlock(usersTemplate, 'topics'), data);
 
 							translator.translate(html, function(translated) {
 								$('#users-container').html(translated);
@@ -111,11 +108,8 @@ define(function() {
 		}
 
 		function onUsersLoaded(users, emptyContainer) {
-			templates.preload_template('users', function() {
-				templates['users'].parse({users:[]});
-				var html = templates.prepare(templates['users'].blocks['users']).parse({
-					users: users
-				});
+			ajaxify.loadTemplate('users', function(usersTemplate) {
+				var html = templates.parse(templates.getBlock(usersTemplate, 'users'), {users: users});
 
 				translator.translate(html, function(translated) {
 					if(emptyContainer) {
diff --git a/public/src/templates.js b/public/src/templates.js
index 82c44d6da8..9520c12ca4 100644
--- a/public/src/templates.js
+++ b/public/src/templates.js
@@ -1,10 +1,11 @@
 "use strict";
 
 (function(module) {
-	var templates = {},
+	var templates = {
+			cache: {}
+		},
 		helpers = {},
 		globals = {},
-		cache = {},
 		loader,
 		originalObj;
 
@@ -22,16 +23,16 @@
 		}
 
 		if (loader && callback) {
-			if (!cache[template]) {
+			if (!templates.cache[template]) {
 				loader(template, function(err, loaded) {
 					if (loaded) {
-						cache[template] = loaded;
+						templates.cache[template] = loaded;
 					}
 
 					callback(err, parse(loaded, obj, bind));
 				});	
 			} else {
-				callback(null, parse(cache[template], obj, bind));
+				callback(null, parse(templates.cache[template], obj, bind));
 			}
 		} else {
 			return parse(template, obj, bind);
@@ -58,13 +59,13 @@
 		var fs = require('fs'),
 			tpl = filename.replace(options.settings.views + '/', '');
 
-		if (!cache[tpl]) {
+		if (!templates.cache[tpl]) {
 			fs.readFile(filename, function(err, html) {
-				cache[tpl] = html.toString();
-				return fn(err, templates.parse(cache[tpl], options));
+				templates.cache[tpl] = html.toString();
+				return fn(err, templates.parse(templates.cache[tpl], options));
 			});
 		} else {
-			return fn(null, templates.parse(cache[tpl], options));
+			return fn(null, templates.parse(templates.cache[tpl], options));
 		}
 	}