From 978d22de67af0baff3c294653fb55c651f8b06a5 Mon Sep 17 00:00:00 2001
From: Marcin Kurczewski <mkurczew@gmail.com>
Date: Tue, 2 Sep 2014 09:36:42 +0200
Subject: [PATCH] Added template loading through AJAX

---
 public_html/.htaccess                         |   4 +
 public_html/index.html                        | 126 +-----------------
 public_html/js/Presenters/LoginPresenter.js   |  10 +-
 .../js/Presenters/RegistrationPresenter.js    |  10 +-
 .../js/Presenters/TopNavigationPresenter.js   |  10 +-
 public_html/js/Util.js                        |  56 ++++++++
 public_html/templates/login-form.tpl          |  47 +++++++
 public_html/templates/registration-form.tpl   |  50 +++++++
 public_html/templates/top-navigation.tpl      |  18 +++
 9 files changed, 197 insertions(+), 134 deletions(-)
 create mode 100644 public_html/js/Util.js
 create mode 100644 public_html/templates/login-form.tpl
 create mode 100644 public_html/templates/registration-form.tpl
 create mode 100644 public_html/templates/top-navigation.tpl

diff --git a/public_html/.htaccess b/public_html/.htaccess
index 29176dc6..169fbf32 100644
--- a/public_html/.htaccess
+++ b/public_html/.htaccess
@@ -1,2 +1,6 @@
 RewriteEngine On
 RewriteRule ^/?api/(.*) api-dispatch.php?q=$1 [L]
+
+<IfModule mod_mime.c>
+AddType text/html .tpl
+</IfModule>
diff --git a/public_html/index.html b/public_html/index.html
index 2bf34047..12c16564 100644
--- a/public_html/index.html
+++ b/public_html/index.html
@@ -25,134 +25,11 @@
 		</div>
 	</div>
 
-	<script type="text/template" id="top-navigation-template">
-		<ul>
-			<!-- todo: check privileges -->
-			<li class="users">
-				<a href="#/users">Users</a>
-			</li>
-			<% if (!loggedIn) { %>
-				<li class="login">
-					<a href="#/login">Login</a>
-				</li>
-				<li class="register">
-					<a href="#/register">Register</a>
-				</li>
-			<% } else { %>
-				<li class="logout">
-					<a href="#/logout">Logout</a>
-				</li>
-			<% } %>
-		</ul>
-	</script>
-
-	<script type="text/template" id="login-form-template">
-		<div id="login-form">
-			<p>
-				If you don't have an account yet,<br/>
-				<a href="#/register">click here</a> to create a new one.
-			</p>
-
-			<div class="messages"></div>
-
-			<form method="post" class="form-wrapper">
-				<div class="form-row">
-					<label for="login-user" class="form-label">User name:</label>
-					<div class="form-input">
-						<input autocomplete="off" type="text" name="user" id="login-user"/>
-					</div>
-				</div>
-
-				<div class="form-row">
-					<label for="login-password" class="form-label">Password:</label>
-					<div class="form-input">
-						<input autocomplete="off" type="password" name="password" id="login-password"/>
-					</div>
-				</div>
-
-				<div class="form-row">
-					<label class="form-label"></label>
-					<div class="form-input">
-						<button class="submit" type="submit">Log in</button>
-						&nbsp;
-						<input type="hidden" name="remember" value="0"/>
-						<label class="checkbox-wrapper">
-							<input type="checkbox" name="remember" value="1"/>
-							<span></span>
-							Remember me
-						</label>
-					</div>
-				</div>
-			</form>
-
-			<div class="help">
-				<p>Problems logging in?</p>
-				<ul>
-					<li><a href="#/password-reset">I don't remember my password</a></li>
-					<li><a href="#/activate-account">I haven't received activation e-mail</a></li>
-					<li><a href="#/register">I don't have an account</a></li>
-				</ul>
-			</div>
-		</div>
-	</script>
-
-	<script type="text/template" id="registration-form-template">
-		<div id="registration-form">
-			<p>
-				Registered users can view more content,<br/>
-				upload files and add posts to favorites.
-			</p>
-
-			<div class="messages"></div>
-
-			<form method="post" class="form-wrapper">
-				<div class="form-row">
-					<label for="registration-user" class="form-label">User name:</label>
-					<div class="form-input">
-						<input autocomplete="off" type="text" name="user" id="registration-user" placeholder="e.g. darth_vader" value=""/>
-					</div>
-				</div>
-
-				<div class="form-row">
-					<label for="registration-password" class="form-label">Password:</label>
-					<div class="form-input">
-						<input autocomplete="off" type="password" name="password1" id="registration-password" placeholder="e.g. &#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;" value=""/>
-					</div>
-				</div>
-
-				<div class="form-row">
-					<label for="registration-password-confirm" class="form-label">Password (repeat):</label>
-					<div class="form-input">
-						<input autocomplete="off" type="password" name="password2" id="registration-password-confirm" placeholder="e.g. &#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;" value=""/>
-					</div>
-				</div>
-
-				<div class="form-row">
-					<label for="registration-email" class="form-label">E-mail address:</label>
-					<div class="form-input">
-						<input autocomplete="off" type="text" name="email" id="registration-email" placeholder="e.g. vader@empire.gov" value=""/>
-					</div>
-				</div>
-
-				<div class="form-row">
-					<label class="form-label"></label>
-					<div class="form-input">
-						<button class="submit" type="submit">Register</button>
-					</div>
-				</div>
-			</form>
-
-			<p id="email-info">
-				Your e-mail will be used to show your <a href="http://gravatar.com/">Gravatar</a>.<br/>
-				Leave blank for random Gravatar.
-			</p>
-		</div>
-	</script>
-
 	<script type="text/javascript" src="/js/DI.js"></script>
 	<script type="text/javascript" src="/js/State.js"></script>
 	<script type="text/javascript" src="/js/Api.js"></script>
 	<script type="text/javascript" src="/js/Auth.js"></script>
+	<script type="text/javascript" src="/js/Util.js"></script>
 	<script type="text/javascript" src="/js/Presenters/TopNavigationPresenter.js"></script>
 	<script type="text/javascript" src="/js/Presenters/LoginPresenter.js"></script>
 	<script type="text/javascript" src="/js/Presenters/LogoutPresenter.js"></script>
@@ -161,6 +38,5 @@
 	<script type="text/javascript" src="/js/Presenters/UserListPresenter.js"></script>
 	<script type="text/javascript" src="/js/Router.js"></script>
 	<script type="text/javascript" src="/js/Bootstrap.js"></script>
-
 </body>
 </html>
diff --git a/public_html/js/Presenters/LoginPresenter.js b/public_html/js/Presenters/LoginPresenter.js
index 386f43d0..34ae0c08 100644
--- a/public_html/js/Presenters/LoginPresenter.js
+++ b/public_html/js/Presenters/LoginPresenter.js
@@ -3,6 +3,7 @@ App.Presenters = App.Presenters || {};
 
 App.Presenters.LoginPresenter = function(
 	jQuery,
+	util,
 	topNavigationPresenter,
 	messagePresenter,
 	auth,
@@ -13,7 +14,12 @@ App.Presenters.LoginPresenter = function(
 
 	var $el = jQuery('#content');
 	var $messages;
-	var template = _.template(jQuery('#login-form-template').html());
+	var template;
+
+	util.loadTemplate('login-form').then(function(html) {
+		template = _.template(html);
+		render();
+	});
 
 	var eventHandlers = {
 
@@ -41,8 +47,6 @@ App.Presenters.LoginPresenter = function(
 	if (appState.get('loggedIn'))
 		router.navigateToMainPage();
 
-	render();
-
 	function render() {
 		$el.html(template());
 		$el.find('form').submit(eventHandlers.loginFormSubmit);
diff --git a/public_html/js/Presenters/RegistrationPresenter.js b/public_html/js/Presenters/RegistrationPresenter.js
index 0cd531e0..1b2912f2 100644
--- a/public_html/js/Presenters/RegistrationPresenter.js
+++ b/public_html/js/Presenters/RegistrationPresenter.js
@@ -3,6 +3,7 @@ App.Presenters = App.Presenters || {};
 
 App.Presenters.RegistrationPresenter = function(
 	jQuery,
+	util,
 	topNavigationPresenter,
 	messagePresenter,
 	api) {
@@ -10,7 +11,12 @@ App.Presenters.RegistrationPresenter = function(
 	topNavigationPresenter.select('register');
 
 	var $el = jQuery('#content');
-	var template = _.template(jQuery('#registration-form-template').html());
+	var template;
+
+	util.loadTemplate('registration-form').then(function(html) {
+		template = _.template(html);
+		render();
+	});
 
 	var eventHandlers = {
 
@@ -50,8 +56,6 @@ App.Presenters.RegistrationPresenter = function(
 		},
 	};
 
-	render();
-
 	function render() {
 		$el.html(template());
 		$el.find('form').submit(eventHandlers.registrationFormSubmit);
diff --git a/public_html/js/Presenters/TopNavigationPresenter.js b/public_html/js/Presenters/TopNavigationPresenter.js
index 340010ed..781a8103 100644
--- a/public_html/js/Presenters/TopNavigationPresenter.js
+++ b/public_html/js/Presenters/TopNavigationPresenter.js
@@ -1,10 +1,15 @@
 var App = App || {};
 App.Presenters = App.Presenters || {};
 
-App.Presenters.TopNavigationPresenter = function(jQuery, appState) {
+App.Presenters.TopNavigationPresenter = function(util, jQuery, appState) {
 
 	var selectedElement = null;
-	var template = _.template(jQuery('#top-navigation-template').html());
+	var template;
+
+	util.loadTemplate('top-navigation').then(function(html) {
+		template = _.template(html);
+		render();
+	});
 	var $el = jQuery('#top-navigation');
 
 	var eventHandlers = {
@@ -14,7 +19,6 @@ App.Presenters.TopNavigationPresenter = function(jQuery, appState) {
 	};
 
 	appState.startObserving('loggedIn', 'top-navigation', eventHandlers.loginStateChanged);
-	render();
 
 	function select(newSelectedElement) {
 		selectedElement = newSelectedElement;
diff --git a/public_html/js/Util.js b/public_html/js/Util.js
new file mode 100644
index 00000000..f8559245
--- /dev/null
+++ b/public_html/js/Util.js
@@ -0,0 +1,56 @@
+var App = App || {};
+
+App.Util = (function(jQuery) {
+
+	var templateCache = {};
+
+	function loadTemplate(templateName) {
+		return loadTemplateFromCache(templateName)
+			|| loadTemplateFromDOM(templateName)
+			|| loadTemplateWithAJAX(templateName);
+	}
+
+	function loadTemplateFromCache(templateName) {
+		if (templateName in templateCache) {
+			return new Promise(function(resolve, reject) {
+				resolve(templateCache[templateName]);
+			});
+		}
+	}
+
+	function loadTemplateFromDOM(templateName) {
+		var $template = jQuery('#' + templateName + '-template');
+		if ($template.length) {
+			return new Promise(function(resolve, reject) {
+				resolve($template.html());
+			});
+		}
+		return null;
+	}
+
+	function loadTemplateWithAJAX(templateName) {
+		return new Promise(function(resolve, reject) {
+			var templatesDir = '/templates';
+			var templateUrl = templatesDir + '/' + templateName + '.tpl';
+			var templateString;
+
+			$.ajax({
+				url: templateUrl,
+				method: 'GET',
+				success: function(data, textStatus, xhr) {
+					resolve(data);
+				},
+				error: function(xhr, textStatus, errorThrown) {
+					console.log(Error('Error while loading template ' +  templateName + ': ' + errorThrown));
+					reject();
+				},
+			});
+		});
+	}
+
+	return {
+		loadTemplate: loadTemplate,
+	};
+});
+
+App.DI.registerSingleton('util', App.Util);
diff --git a/public_html/templates/login-form.tpl b/public_html/templates/login-form.tpl
new file mode 100644
index 00000000..20dacbda
--- /dev/null
+++ b/public_html/templates/login-form.tpl
@@ -0,0 +1,47 @@
+<div id="login-form">
+	<p>
+		If you don't have an account yet,<br/>
+		<a href="#/register">click here</a> to create a new one.
+	</p>
+
+	<div class="messages"></div>
+
+	<form method="post" class="form-wrapper">
+		<div class="form-row">
+			<label for="login-user" class="form-label">User name:</label>
+			<div class="form-input">
+				<input autocomplete="off" type="text" name="user" id="login-user"/>
+			</div>
+		</div>
+
+		<div class="form-row">
+			<label for="login-password" class="form-label">Password:</label>
+			<div class="form-input">
+				<input autocomplete="off" type="password" name="password" id="login-password"/>
+			</div>
+		</div>
+
+		<div class="form-row">
+			<label class="form-label"></label>
+			<div class="form-input">
+				<button class="submit" type="submit">Log in</button>
+				&nbsp;
+				<input type="hidden" name="remember" value="0"/>
+				<label class="checkbox-wrapper">
+					<input type="checkbox" name="remember" value="1"/>
+					<span></span>
+					Remember me
+				</label>
+			</div>
+		</div>
+	</form>
+
+	<div class="help">
+		<p>Problems logging in?</p>
+		<ul>
+			<li><a href="#/password-reset">I don't remember my password</a></li>
+			<li><a href="#/activate-account">I haven't received activation e-mail</a></li>
+			<li><a href="#/register">I don't have an account</a></li>
+		</ul>
+	</div>
+</div>
diff --git a/public_html/templates/registration-form.tpl b/public_html/templates/registration-form.tpl
new file mode 100644
index 00000000..6a8bae28
--- /dev/null
+++ b/public_html/templates/registration-form.tpl
@@ -0,0 +1,50 @@
+<div id="registration-form">
+	<p>
+		Registered users can view more content,<br/>
+		upload files and add posts to favorites.
+	</p>
+
+	<div class="messages"></div>
+
+	<form method="post" class="form-wrapper">
+		<div class="form-row">
+			<label for="registration-user" class="form-label">User name:</label>
+			<div class="form-input">
+				<input autocomplete="off" type="text" name="user" id="registration-user" placeholder="e.g. darth_vader" value=""/>
+			</div>
+		</div>
+
+		<div class="form-row">
+			<label for="registration-password" class="form-label">Password:</label>
+			<div class="form-input">
+				<input autocomplete="off" type="password" name="password1" id="registration-password" placeholder="e.g. &#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;" value=""/>
+			</div>
+		</div>
+
+		<div class="form-row">
+			<label for="registration-password-confirm" class="form-label">Password (repeat):</label>
+			<div class="form-input">
+				<input autocomplete="off" type="password" name="password2" id="registration-password-confirm" placeholder="e.g. &#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;&#x25cf;" value=""/>
+			</div>
+		</div>
+
+		<div class="form-row">
+			<label for="registration-email" class="form-label">E-mail address:</label>
+			<div class="form-input">
+				<input autocomplete="off" type="text" name="email" id="registration-email" placeholder="e.g. vader@empire.gov" value=""/>
+			</div>
+		</div>
+
+		<div class="form-row">
+			<label class="form-label"></label>
+			<div class="form-input">
+				<button class="submit" type="submit">Register</button>
+			</div>
+		</div>
+	</form>
+
+	<p id="email-info">
+		Your e-mail will be used to show your <a href="http://gravatar.com/">Gravatar</a>.<br/>
+		Leave blank for random Gravatar.
+	</p>
+</div>
diff --git a/public_html/templates/top-navigation.tpl b/public_html/templates/top-navigation.tpl
new file mode 100644
index 00000000..f19aac89
--- /dev/null
+++ b/public_html/templates/top-navigation.tpl
@@ -0,0 +1,18 @@
+<ul>
+	<!-- todo: check privileges -->
+	<li class="users">
+		<a href="#/users">Users</a>
+	</li>
+	<% if (!loggedIn) { %>
+		<li class="login">
+			<a href="#/login">Login</a>
+		</li>
+		<li class="register">
+			<a href="#/register">Register</a>
+		</li>
+	<% } else { %>
+		<li class="logout">
+			<a href="#/logout">Logout</a>
+		</li>
+	<% } %>
+</ul>