A very simple file based blog on Jaxer

This tutorial is a sample of some functionality you can quickly achieve in Jaxer. In this case we'll be building a very basic file-based "blog".

The idea is simple: Create an HTML page that will show all the "posts". A post is created by creating or FTPing a txt file to the server and naming it so it will appear in the order desired. We'll also add the ability to use Markdown syntax in the txt file so you can easily do some basic HTML without the HTML syntax.

You can easily extend this to add a page where posts can be written and previewed, re-ordered/renamed, move to using a DB instead of txt files, etc.

We'll want a folder named "articles" as a sub-folder of our project. Next we'll create a simple index HTML page as a peer of that folder, with a div inside the body containing the id "posts".

<html>
<head>
<title>My Blog</title>
</head>
<body>
<h1>My Blog</h1>
<div id="posts"></div>
</body>
</html>

To get started writing server side Javascript we 'll add a script tag in the head with a runat attribute set to server:

<script runat="server">
</script>

Jaxer has a nice API that allows you to work with the filesystem directly on the server. We're going to take advantage of that to have it grab files inside the "articles" folder that is a peer of our html file on the server:

function init() {
var path = Jaxer.Dir.resolvePath("articles");
var dir = new Jaxer.Dir(path);
var files = dir.readDir().map(function(file) {
return file.getLeaf();
});
}

Now we have a function which grabs the "articles" directory and then gets a listing of all the filenames inside that directory. Next we want to loop over the files, read in their contents and append it to a string that we'll be pushing back into the div with id "posts".

var html = "";
for (var i = 0; i < files.length; i++) {
var read = Jaxer.File.read("articles/" + files[i]);
html+= read;
}
document.getElementById('posts').innerHTML = html;

Pretty simple. We read all the files, concat their contents together into a string and then push that into the posts div. We can try it out by having this function run when the server has loaded the page/DOM. We just modify the body tag like so:

<body onserverload="init();">

This tells Jaxer to run our init function when it has completed creation of the page's load process.

Obviously, concatenating all the files contents together doesn't look too nice. Lets wrap each file's contents in a div with class "post" so we can style it later.

var read = Jaxer.File.read("articles/" + files[i]);
html+= makePost(read);

function makePost(contents) {
return "<div class=\"post\">" + contents + "</div>\n";
}

That's much better. Now we don't have all the files in one giant string.

But this hasn't bought us much - we still have to write the HTML tags inside the txt files if we want to do any styling or marking up of the content. Let's provide a markup syntax to allow users to use simple text conventions to generate HTML. One such library is Markdown. We're going to use a nice Markdown in JS library provided from: http://softwaremaniacs.org/playground/showdown-highlight/

It's pretty simple to use. First we include the library on the server side:

<script src="showdown.js" runat="server"/>

Next, we use it to mark up the file's contents before we wrap it in the div:

...
var read = Jaxer.File.read("articles/" + files[i]);
html+= makePost(markdown(read));
...
function markdown(content) {
var converter = new Showdown.converter();
return converter.makeHtml(contents);
}

And there you have it. We now have a blog index page which will grab all of our article text files, run them through markdown and insert them into post divs for us.

To wrap up here's the full code:

<html>
<head>
<title>Articles</title>
</head>
<script src="/showdown.js" runat="server">
</script>
<script runat="server">
var converter = new Showdown.converter();
function createPost(contents){
// Run markdown filter on contents
var text = converter.makeHtml(contents);
return "<div class=\"post\">" + text + "</div>";
}
function init() {
try {
// read all the articles in text files in "articles" sub-dir of this dir (#.txt)
var articlesPath = Jaxer.Dir.resolvePath("articles");
var files = new Jaxer.Dir(articlesPath).readDir();
var string = "";
var i = 0;
for (i = 0; i < files.length; i++) {
var filename = Jaxer.Dir.combine(articlesPath, files[i].getLeaf());
if (new Jaxer.FileUtils().ext(filename) == "txt") {
var raw = Jaxer.File.read(filename);
string += createPost(raw);
}
}
document.getElementById('output').innerHTML = string;
}
catch (err) {
document.getElementById('output').innerHTML = err.description;
}
}
</script>
<body onserverload="init()">
<div id="output"></div>
</body>
</html>