Docpad and Jade

Fri Mar 14 2014

As you may realise, this site is entirely written in Node.js using the Docpad framework. I've also started using the Jade templating plugin. Docpad is able to run a number of templating systems such as Eco or Markdown - as well as straight html. And they can all be running simultaneously within the one application (although I would imagine it might be quite tricky for a developer to be constantly switching templating systems).

A lot of node applications, however, seem to use the Jade templating system. I'd mostly been using CoffeeScript and Eco up until now. So I thought it was time to get into Jade. It was a bit of a learning curve. Below is the Jade code that generates the home page. You'll notice that it actually calls a Docpad "partial" written in CoffeeScript, which was actually legacy code written for a previous version of the site. The plan was to update that code to Jade - but it does demonstrate the interoperability of Docpad.

	section#homepage-hero
		.row.centered-text.align-bottom
			.large-12.columns
				h4 Node.js and Web Development
				h1 Steve McArthur
	section#main-content
		.row.centered-text(style='margin-top: 4em; margin-bottom: 3em;')
			.large-12.columns
				h2
					| Hi, Im Steve, a Web Developer specializing in Javascript and Node.js development.
		.row.centered-text
			.large-12.columns.subheader.bigtext
				| Originally from Perth, Western Australia, now living in the UK.
		.row.centered-text
			hr.margin-bottom-40px
			span
			- posts = getCollection('posts').toJSON()
			!= partial('post-snippet.html.coffee',{posts:posts,number_posts:3,trimTo:500})


Node.js

Fri Mar 25 2011

Have been playing around with Node.js a lot lately. I like what I see. The essential feature of Node is writing JavaScript on the server side and not just on the client. There’s a lot of sense to that. But there’s also a bit more to it. Making use of the whole asynchronous approach that JavaScript lends itself so well to, is also a feature that I’m liking here. All the beginner tutorials seem to demonstrate something around the creation of a simple web server. And in my playing arounds I am no different.

//load the http object
var http = require("http");
//load the file system object
var fs = require("fs");

http.createServer(function(request, response) {
		
	if (request.url.indexOf('index.html') > 0) {
		fs.readFile("index.html", 'utf-8', function (error, data) {
			console.log('reading file');
			response.writeHead(200, {
				'Content-Type' : 'text/html'
			});
			//write out the contents of the html file
			//to the response stream
			response.end(data);
		});
	}else{
		console.log("not index.html");
	}

}).listen(8080);

console.log("Server has started.");


Some kind of disk I/O error occurred - SQLite

Tue Dec 14 2010

I got the extremely helpful "Some kind of disk I/O error occurred" message using the System.Data.SQLite .net assembly today. This was a big SQLite show stopper. So I thought it was about time I figured out what was causing this. The error was occurring when I tried to post an update to the SQLite database in the local App_Data folder of an asp.net application. As soon as the application attempted to post the update I got the dreaded "Some kind of.." error and a SQLite journal file was created in the database folder. After this, the database became unavailable. It became available again once the journal file was deleted, but I was then back in the same situation once another update was attempted. The curious thing was that this behaviour didn't occur in the development environment, only when uploaded to the live server. My first thought was that the application for some reason didn't have rights to write to the App_Data folder. But the journal file was writing to the location with no troubles. Finally I hit upon a forum post on the System.Data.SQLite forum. This pointed in the direction of using the statement to set the journal_mode value to something other than "DELETE". The PRAGMA statement is executed exactly like a query, so all that needs to be done is to execute the statement using a SQLiteCommand object in the same way you would execute any other SQL statement.

using(SQLiteConnection conn = new SQLiteConnection(sqliteConnectionString)) {
	conn.Open();
	SQLiteCommand cmd = new SQLiteCommand();
	cmd.Connection = conn;
	string pragma = "PRAGMA journal_mode = OFF";
	cmd.CommandText = pragma;
	cmd.ExecuteNonQuery();
}


Ajax basics

Sun May 30 2010

When we talk about Ajax we are usually talking about updating a web page without reloading the entire page. It also, in reality, includes a series of techniques around ways to modify the content of a web page, usually at the behest of the page user. However, most of the time we are talking about the browser making requests to a website for more data and processing this update in the browser. There are actually a number of ways to do this, but the method we generally mean when using the "Ajax" term is XMLHttpRequest. In short, this is an object within the browser that allows Javascript to make calls/requests to websites - HTTP requests in other words. In normal circumstances these requests would be for whole HTML web pages, but it doesn't have to be. In the Ajax/Javascript environment we generally don't want a whole page. And since the server is aware that someone is going to request data other than HTML pages, it has kindly provided "data only" pages specifically for that purpose. This is what the XMLHttpRequest calls. The typical function for creating an Ajax object in javascript looks like the following:

var xmlHttp;
function ajaxFunction() {
	try {
		// Firefox, Opera 8.0+, Safari
		xmlHttp = new XMLHttpRequest();
	} catch (e) {
		// Internet Explorer
		try {
			xmlHttp = new ActiveXObject('Msxml2.XMLHTTP');
		} catch (e) {
			try {
				xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
			} catch (e) {
				alert('Your browser does not support AJAX!');
				return false;
			}
		}
	}
}

It's actually more ugly than it needs to be. Most of the ugliness comes from the differences between Internet Explorer and the others. Up until version 7, Internet Explorer had implemented the XMLHttpRequest object as an ActiveX add-on, whereas the others implement it as a native object. As a result, since we can't be sure what browser our Javascript is going to be loaded, we need to implement code that will create both forms where necessary. Having created the Ajax object we can then make our request:

//the function that will do all our processing when the ajax call returns
function my_callback_function() {

	//the function is called everytime its status changes,
	//not just when the call returns, so we need to check the
	//readyState property and then the status property
	if (xmlHttp.readyState == 4 /* complete */)	{
		if (xmlHttp.status == 200 || xmlHttp.status == 304) {
			//get an element on the page that you want
			//to update with the results of the ajax call
			var srch = document.getElementById("search_results");

			//extract the text from our xmlHttp object
			var txt = xmlHttp.responseText;

			//evaluate the text response as a javascript object
			var o = eval("(" + txt + ")");

			//build the html from the js object which in this example is
			//an object with two properties: title and content
			var html = "

" + o.title + "

" + o.content; //update the element srch.innerHTML = html; } else { // error occurred } } } //assign the function to be called when the request returns xmlHttp.onreadystatechange = my_callback_function; //configure how the call will be made. //In this case using the http method 'GET' and a dummy json file xmlHttp.open('GET', 'MyTest.json', true); //make the actual request xmlHttp.send();


Calling ASP.net pagemethods from ExtJS

Fri Mar 19 2010

I use asp.net PageMethods in conjunction with ExtJS almost on a daily basis. PageMethods are simply server side methods that are callable from client side script. However, Microsoft assumes that you will be using PageMethods in conjunction with its Ajax framework, in particular the ScriptManager control which creates a JavaScript proxy on the client side for the server side PageMethods. If you are using a JavaScript framework like ExtJS then you probably don't want to include the unnecessary clutter and page weight of the MS Ajax framework. Luckily PageMethods are callable like any other Ajax call. The trick is that it is expecting the name of the method as a forward slash parameter after the page name and the methods parameters as jsonData in the postdata. In ExtJS this translates as something like this:

Ext.Ajax.request({      
	url: 'Default.aspx/myMethod',       
	method: 'POST',       
	success: onReturn,       
	failure: onFailure,       
	jsonData: '{Param1:"MyString",Param2: 1}',       
		headers: {       
			'Content-Type': 'application/json; charset=utf-8'       
		}       
     });

Note the headers property. This is the final piece in the puzzle. If you forget this then asp.net will think you are asking for the page and return the page itself instead of calling the PageMethod and returning the result of the method call as a json object. A couple of other 'gotchas' to watch out for is to make sure your web.config file has the configurations in it to allow PageMethods to be called from client script. Normally this is done for you when you create an Ajax enabled application, but if you're converting from a non-Ajax application it boils down to entries in the httpHandlers and httpModules sections. httpHandlers:

	<remove verb="*" path="*.asmx"/>      
	<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral,PublicKeyToken=31BF3856AD364E35"/> 
httpModules:
	<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

The last gotcha is a difference between how the json data is returned from a .net 3.5 application and a 2.0 application. In 3.5 the data is returned as a property called "d" of an otherwise empty json object. Whereas in version 2 the returned data was simply the result of the method call in json format.