About Me

My name is Thomas Mathews also known as Tingtom. I love to code and currently work as a Web Developer, my favourite language is C++!

Are you not credited or mentioned on the site when you should be? Please contact me!

Contact Me

How is the website built?


This website is built on the "newest" technologies which are Node, SASS, Jade and Mongo DB for learning purposes. It was being built last year but has changed from a custom build to an integrated CMS and now has a better design by Jack Lumsden.

The CMS is based on Keystone JS which is a easy to use and dynamic CMS that bases itself on the models you create for it, the website itself only has 7 models for the blog posts, downloads, categories, page info, services, projects and users it also handles routing and rendering templates based on these routes where each template can choose what data is pulled from the database.


Routing is multi layered and follows the following order:

  • Remove trailing slashes
  • Force HTTPS
  • Match / with the index template
  • Handle post on / for the contact form
  • Handle services
  • Handle blog posts
  • Handle the blog list
  • Handle projects

Creating these routes also allows you to pass in middleware which are functions that get passed through before the route is handled and the page is rendered which allowed me to selectively generate variables and handle forms. For example the generateBreadcrumbs function which generates an array of links for selected pages based on the current slug:

exports.generateBreadcrumbs = function (req, res, next) {
	var slugs = req.originalUrl.split("/"), url = "/";
	res.locals.breadcrumbs = [{
		name: "Home",
		href: url
	var ignore = ["services"];
	slugs.forEach( function(el){
		if( el )
			url += el + "/";
				name: el.replace(/-/g, " ").replace(/\b[a-z]/g, function () {
					return arguments[0].toUpperCase();
				}).replace(/[1-9]/g, "").replace(/[1-9]/g, "").trim(),
				href: ignore.indexOf(el) === -1 ? url : "#"


Below is the page model that is used to set titles, basic content and meta information for SEO. In the structure passed to the add function each field is defined with a type and various other parameters defined here, the name and key are required to be set and the key has to be set when you add a new "Page" item as it is used to match a page with the model in the database.

var Page = new keystone.List('Page', {
	map: {name: 'name'}

	name: { type: String, required: true },
	key: { type: String, required: true, initial: true },
	metaTitle: { type: String },
	metaDescription: { type: Types.Textarea },
	content: { type: Types.Html, wysiwyg: true, height: 400 }

Page.defaultColumns = 'name, key|20%';

Each page has a default middleware that is executed which is used to populate basic information such as the accessing the Page model above which is matched using the key field which is then used in Jade. This code defines a common middleware:

keystone.pre('routes', middleware.initLocals);