Static HTML generation for slashie.net website using MustacheJS

I did some back-end changes for the slashie.net website, with the idea of making it easier to include new projects and update their status. About one year ago I went for a single page layout, but was doing maintenance over the HTML file… which was a bit frustrating. With the new approach I can easily manipulate how the list of projects is shown. You can see the current results at slashie.net

I looked around a bit for a static site generator, but in the end decided to roll my own since what I was going for was extremely simple and didn’t want to meddle with the setup of any of these.

What I needed was generating a single HTML file based on a JSON file with the information of all my projects. I decided to go for nodejs using mustachejs for the template; the script is dead simple… I thought I’d share what I did, in case someone needs something similar. This approach gives you a lot of flexibility, as long as you don’t need to maintain a lot of different pages.

Mustache

First, the data, it’s basically a structured list of all my projects

{	
	"sections": [
		{
			"name": "Games",
			"id": "games",
			"items": [
				{
					"title": "Ananias",
					"image": "img/buttons/ananias.png",
					"text": "Dive to the bottom of the Tomb of Ananias using your smartphone or computer. Take adventure with you everywhere!.",
					"status": "published",
					"buttons": [
						{
							"title": "Play Online",
							"url": "http://ananiasgame.com/"
						},
						{
							"title": "Android Version",
							"url": "https://play.google.com/store/apps/details?id=co.slashland.ananias"
						},
						{
							"title": "Desktop Version",
							"url": "http://slash.itch.io/ananias"
						}
					],
					"tags": ["turn-based", "stable", "denzi", "roguelike", "pixel-art", "javascript", "android"]
				},
				{
					"title": "Rodney",
					"image": "img/buttons/rodney.png",
					"text": "Slash your way to the bottom of the Dungeons of Doom, learn new skills and use tactics to survive.",
					"status": "published",
					"buttons": [
						{
							"title": "Play Online",
							"url": "http://games.slashware.net/rodney"
						}
					],
					"tags": ["turn-based", "stable", "oryx", "roguelike", "pixel-art", "javascript"]
				}
			]
		}
	]
}

Now, the generator itself, it basically reads the data and the template, parses the JSON and then renders it using MustacheJS

function generateFile(){
	var file = fs.readFileSync('data.json').toString();
	var template = fs.readFileSync('template.html').toString();
	var data = JSON.parse(file);
	groupByStatus(data); // Groups by status and sorts items
	calculateNewRows(data); // Adds the newRow and endRow attributes
	var output = Mustache.render(template, data);
	fs.writeFile('index.html', output);
}

Now, I had to add the groupByStatus and calculateNewRows functions in order to do some processing over the raw project data (namely grouping the projects by status and grouping them by 3); Mustache declares itself as a logic-less template system, which means it lacks if/else statements or loops. All it does is replacing stuff. You may have to do something similar, depending on how complex you need your page to be.

Finally, this is my Mustache template, as you can see, it’s pretty simple

<!DOCTYPE html>
<html lang="en">
<head>
	<title>Slashie.net</title>
	<link rel="icon" type="image/png" href="img/icon.png">
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
	<link href="lib/bs3/css/bootstrap.css" rel="stylesheet">
	<link href="css/slashland.css" rel="stylesheet">
	<!--[if lt IE 9]>
		<script src="lib/bs3/js/html5shiv.js"></script>
		<script src="lib/bs3/js/respond.min.js"></script>
	<![endif]-->
	<script type="text/javascript" src="lib/jquery-1.10.2.min.js"></script>
	<script type="text/javascript" src="lib/bs3/js/bootstrap.js"></script>
</head>
<body>
<section class = "container">
	<section class = "page-header">
		<div class = "row">
			<div class="col-md-2">
				<div id="logoImage"></div>
			</div>
			<div class="col-md-5">
				<h3>Welcome...</h3>
				<p>I'm Slash. This is my collection of game projects, I hope you like them!.</p>
				<p>You might also want to check <a href = "http://slashwareint.com">Slashware Interactive</a>, which is my brand for finished products.</p>
				<ul class="nav nav-pills">
					<li><a href = "http://blog.slashie.net" target = "_blank">Blog</a></li>
					<li><a href = "https://twitter.com/slashie_" target = "_blank">Twitter</a></li>
				</ul>
			</div>
		</div>
	</section>
</section>
{{#sections}}
<section id = "{{id}}">
	<div class = "container">
		<h1>{{name}}</h1>
		{{#count}}<h2>{{count}} projects</h2>{{/count}}
		<p>{{text}}</p>
		<div class = "container">
			{{#items}}
			{{#newRow}}
			<div class = "row">
			{{/newRow}}
				<div class="col-md-4">
					<div class="thumbnail">
						{{#image}}
						<img src = "{{image}}"/>
						{{/image}}
						<div class="caption">
							<h3>{{title}}</h3>
							<p>
								{{#tags}}
								<span class = "label label-success">{{.}}</span>
								{{/tags}}
							</p>
							<p>{{{text}}}</p>
							{{#buttons}}
							<a href = "{{url}}" target = "_blank" class = "btn btn-primary" role = "button">{{title}}</a>
							{{/buttons}}
						</div>
					</div>
				</div>
			{{#endRow}}
			</div>
			{{/endRow}}
			{{/items}}
		</div>
	</div>
</section>
{{/sections}}

<div id = "footer" class = "text-right">
	<p>Copyright (c) 2004 - 2016 Santiago Zapata</p>
	<p>Generated using <a href = "https://github.com/janl/mustache.js/" target = "_blank">mustachejs</a></p>
</div>
</body>
</html>

You can find the mustache tags in the “sections” section, as you can see mustache interprets each attribute contextually from the source object.

The # mustache tags (for example {{#sections}}) represent a repeating block; the contents inside will be replicated for each one of the objects if the attribute is a list, or once if the attribute exists. (this is used for example on the {{#image}} block, to only show the image tag if the project has an image)

The double and triple mustache tags {{}} and {{{}}} are replaced with the value of the attribute of the given name on the context object. The triple mustache leaves HTML content unscaped, which may be useful if you want to include HTML content directly.

Finally, the {{.}} tag is used to include the value of an object directly, it’s useful for example to include the content of arrays of strings.

And that’s about it! now I can easily add new projects without having the worry about the page layout! My program sorts the projects in alphabetical order and groups them by type and status. What’s also important for me is it takes care of the grouping by 3 items which is required by the way I’m using bootstrap.

And of course, the main point of this is decoupling the data from the view, which in turns takes me to the following point: I may in the future work a bit in the frontend side, to maybe get rid of bootstrap and include some filters…

I hope this is useful for someone to create a simple portfolio or similar page.

Keeping things online….

SlashwareInt.com is almost ready, access to ArcherFire and Vuelta a Colombia has been reestablished….

Vuelta a Colombia
Vuelta a Colombia

Virtual Games on the other hand, was a complete pain… Struggled a lot and in the end, SWFs were not showing up. I had a bad feeling that there’s some URLs hardcoded inside them… Finally, it stroke me: This is a sign I should just give it up, let it go and focus on something else… So I decided to drop support for Virtual Games for now.

Gosh! sorting this all out takes so much time! I better go back to developing instead of wasting time like this… :/

Yet Another (Big) Restructuring

Some changes again going on!

Slashware Interactive has revived as a game development brand, Slashware Software Solutions is now the brand name for the currently inactive corporate software development line and the ancient Slashie.net has arisen again! that has brought the following website changes…

Slashie.net
Slashie.net

slashie.net has revived (and slashland.co is gone); the ancient e107 installation has been removed and its contents merged with the former slashland.co. slashie.net is my collection of game projects, with a very personal touch.

SlashwareInt.com
SlashwareInt.com

slashwareint.com (New website); holds the games that are finished products meant for public consumption. It’s still a bit buggy, there’s work to be done to reenable SSL certificates, relocate stuff and update some of the games to the latest changes on the facebook micropayments API.

Slashware.co
Slashware.co

Finally, slashware.co acts as the website for Slashware Software Solutions, basically holding the entry points for Slashware’s three products that still gotta be polished for the public (However they are readily accesible already!)

Slashland, on the other hand, is this blog… and it’s very closely tied to slashie.net, except I can find no way for them both to coexist since wordpress.com won’t let me host the blog in a subdomain (or does it?) in any case it may end up as either slashland.co or blog.slashie.net

Let me know what you think and any findings! I’m keeping all pending tasks for the websites on this trello board.

Guardian of RogueBasin

Slashware Interactive has been appointed as the Guardian of RogueBasin, the roguelike wiki. We are hoping to make a good job to ensure its continuous operation and growth

The Guardian of the Roguebasin is the person or company responsible for keeping the RogueBasin software up and running.

The title was established on August 2011, because of the need of having a visible head in front of maintaining the operation of the wiki.

The Guardian of Roguebasin has the following functions:

  • Keep the wiki software up to date
  • Ensure protection against spam and spambots, by coordinating efforts with the community
  • Install new components as per community request
  • Ensure the wiki content is according to the community guidelines
  • Take monthly backups of RogueBasin database and place it on a publicly available online location

The Slashie.net OpenXRL initiative

“XRLs” are roguelikes themed around a popular series, in this page you will find games based on classic Nintendo series such as Castlevania, Metroid, Zelda and Megaman. You will also find a tribute to Richard Garriots’ “Ultima” series, in the shape of “Escape from Mt. Drash: The Roguelike” (Which, paradoxically, was not produced by Mr. Garriot)

All of these games have something in common, they are intended not to be overly complex to get into: keybindings have been reduced, music has been introduced (and graphics in some of them) and gameplay is straightforward. They can be considered coffeebreak roguelikes

Over the years, I have been developing them on and off, but I have found my limited human energy not to be enough to turn them into what I want; they have remained interesting – yet unpolished. Thus, the openXRL initiative came into being.

I have released all of these games under the GPLv3 Open Source License, you are now free to develop them. If you want to become the (official) maintainer of one of these games, just contact me and I will be glad to be of assistance. The following are the only requirements.

  • Proficiency on Java Development
  • Love for the series on which the game is based
  • Having developed another roguelike is desired
  • Be Warned, the source code of some of these is scary, only brave people go ahead!

So, without any further ado, I present you the games! TAKE A LOOK!

Plans for March 2010

Week 1: Slashware.net: Integrate slashie.net and slashware.net under the same flag!

Week 2: 2010 7DRL Challenge: Participate, because I cant break my record!

Week 3: Expedition: Winner of the March Powerpoll!

Week 4: Pixal: Integrate everything into the world browser