diff --git a/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js b/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js
index d0c161f2aad559874db70bf2b839e59e8fffa8f8..3885b0f43b2bb0eb9b17f2a38abf206923ee7715 100644
--- a/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js
+++ b/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js
@@ -1,6 +1,7 @@
 /* global Flash */
 
 import sqljs from 'sql.js';
+import _ from 'underscore';
 import Spinner from '../../spinner';
 
 class BalsamiqViewer {
@@ -52,6 +53,10 @@ class BalsamiqViewer {
     return thumbnails[0].values.map(BalsamiqViewer.parsePreview);
   }
 
+  getTitle(resourceID) {
+    return this.database.exec(`SELECT * FROM resources WHERE id = '${resourceID}'`);
+  }
+
   renderPreview(preview) {
     const previewElement = document.createElement('li');
 
@@ -62,13 +67,14 @@ class BalsamiqViewer {
   }
 
   renderTemplate(preview) {
-    let template = BalsamiqViewer.PREVIEW_TEMPLATE;
-
-    const title = this.database.exec(`SELECT * FROM resources WHERE id = '${preview.resourceID}'`);
-    const name = JSON.parse(title[0].values[0][2]).name;
+    const title = this.getTitle(preview.resourceID);
+    const name = BalsamiqViewer.parseTitle(title);
     const image = preview.image;
 
-    template = template.replace(/{{name}}/g, name).replace(/{{image}}/g, image);
+    const template = BalsamiqViewer.PREVIEW_TEMPLATE({
+      name,
+      image,
+    });
 
     return template;
   }
@@ -77,6 +83,10 @@ class BalsamiqViewer {
     return JSON.parse(preview[1]);
   }
 
+  static parseTitle(title) {
+    return JSON.parse(title[0].values[0][2]).name;
+  }
+
   static onError() {
     const flash = new Flash('Balsamiq file could not be loaded.');
 
@@ -84,13 +94,13 @@ class BalsamiqViewer {
   }
 }
 
-BalsamiqViewer.PREVIEW_TEMPLATE = `
+BalsamiqViewer.PREVIEW_TEMPLATE = _.template(`
   <div class="panel panel-default">
-    <div class="panel-heading">{{name}}</div>
+    <div class="panel-heading"><%- name %></div>
     <div class="panel-body">
-      <img class="img-thumbnail" src="data:image/png;base64,{{image}}"/>
+      <img class="img-thumbnail" src="data:image/png;base64,<%- image %>"/>
     </div>
   </div>
-`;
+`);
 
 export default BalsamiqViewer;
diff --git a/spec/javascripts/blob/balsamiq/balsamiq_viewer_spec.js b/spec/javascripts/blob/balsamiq/balsamiq_viewer_spec.js
index 10db4175ca4e3314c54f6dc37653eb6777e66392..557eb721a2b8cf5ff9dd51cf288abf6c6a75a2be 100644
--- a/spec/javascripts/blob/balsamiq/balsamiq_viewer_spec.js
+++ b/spec/javascripts/blob/balsamiq/balsamiq_viewer_spec.js
@@ -216,6 +216,35 @@ describe('BalsamiqViewer', () => {
     });
   });
 
+  describe('getTitle', () => {
+    let database;
+    let resourceID;
+    let resource;
+    let getTitle;
+
+    beforeEach(() => {
+      database = jasmine.createSpyObj('database', ['exec']);
+      resourceID = 4;
+      resource = 'resource';
+
+      balsamiqViewer = {
+        database,
+      };
+
+      database.exec.and.returnValue(resource);
+
+      getTitle = BalsamiqViewer.prototype.getTitle.call(balsamiqViewer, resourceID);
+    });
+
+    it('should call database.exec', () => {
+      expect(database.exec).toHaveBeenCalledWith(`SELECT * FROM resources WHERE id = '${resourceID}'`);
+    });
+
+    it('should return the selected resource', () => {
+      expect(getTitle).toBe(resource);
+    });
+  });
+
   describe('renderPreview', () => {
     let previewElement;
     let innerHTML;
@@ -261,54 +290,50 @@ describe('BalsamiqViewer', () => {
 
   describe('renderTemplate', () => {
     let preview;
-    let database;
+    let name;
     let title;
+    let template;
     let renderTemplate;
 
     beforeEach(() => {
-      preview = { reosourceID: 1, image: 'image' };
-      title = [{ values: [['{}', '{}', '{ "name": "name" }']] }];
-      database = jasmine.createSpyObj('database', ['exec']);
-
-      database.exec.and.returnValue(title);
+      preview = { resourceID: 1, image: 'image' };
+      name = 'name';
+      title = 'title';
+      template = `
+        <div class="panel panel-default">
+          <div class="panel-heading">name</div>
+          <div class="panel-body">
+            <img class="img-thumbnail" src="data:image/png;base64,image"/>
+          </div>
+        </div>
+      `;
 
-      balsamiqViewer = {
-        database,
-      };
+      balsamiqViewer = jasmine.createSpyObj('balsamiqViewer', ['getTitle']);
 
-      spyOn(JSON, 'parse').and.callThrough();
-      spyOn(String.prototype, 'replace').and.callThrough();
+      spyOn(BalsamiqViewer, 'parseTitle').and.returnValue(name);
+      spyOn(BalsamiqViewer, 'PREVIEW_TEMPLATE').and.returnValue(template);
+      balsamiqViewer.getTitle.and.returnValue(title);
 
       renderTemplate = BalsamiqViewer.prototype.renderTemplate.call(balsamiqViewer, preview);
     });
 
-    it('should call database.exec', () => {
-      expect(database.exec).toHaveBeenCalledWith(`SELECT * FROM resources WHERE id = '${preview.resourceID}'`);
+    it('should call .getTitle', () => {
+      expect(balsamiqViewer.getTitle).toHaveBeenCalledWith(preview.resourceID);
     });
 
-    it('should call JSON.parse', () => {
-      expect(JSON.parse).toHaveBeenCalledWith(title[0].values[0][2]);
+    it('should call .parseTitle', () => {
+      expect(BalsamiqViewer.parseTitle).toHaveBeenCalledWith(title);
     });
 
-    it('should call String.prototype.replace', () => {
-      const allArgs = String.prototype.replace.calls.allArgs();
-
-      expect(allArgs.length).toBe(2);
-      expect(allArgs[0]).toEqual([/{{name}}/g, 'name']);
-      expect(allArgs[1]).toEqual([/{{image}}/g, 'image']);
+    it('should call .PREVIEW_TEMPLATE', () => {
+      expect(BalsamiqViewer.PREVIEW_TEMPLATE).toHaveBeenCalledWith({
+        name,
+        image: preview.image,
+      });
     });
 
     it('should return the template string', function () {
-      const template = `
-        <div class="panel panel-default">
-          <div class="panel-heading">name</div>
-          <div class="panel-body">
-            <img class="img-thumbnail" src="data:image/png;base64,image"/>
-          </div>
-        </div>
-      `;
-
-      expect(renderTemplate.replace(/\s/g, '')).toEqual(template.replace(/\s/g, ''));
+      expect(renderTemplate.trim()).toBe(template.trim());
     });
   });
 
@@ -335,6 +360,29 @@ describe('BalsamiqViewer', () => {
     });
   });
 
+  describe('parseTitle', () => {
+    let title;
+    let parseTitle;
+
+    beforeEach(() => {
+      title = [{ values: [['{}', '{}', '{"name":"name"}']] }];
+
+      spyOn(JSON, 'parse').and.callThrough();
+
+      parseTitle = BalsamiqViewer.parseTitle(title);
+    });
+
+    ClassSpecHelper.itShouldBeAStaticMethod(BalsamiqViewer, 'parsePreview');
+
+    it('should call JSON.parse', () => {
+      expect(JSON.parse).toHaveBeenCalledWith(title[0].values[0][2]);
+    });
+
+    it('should return the name value', () => {
+      expect(parseTitle).toBe('name');
+    });
+  });
+
   describe('onError', () => {
     let onError;