Iām in the process of rewiring the backend for Ethernet Bucket using Express. If you donāt know what express is, hereās a good primer. The goal today is to write something that can take blog entries in MongoDB (that part not covered) and turn them into web pages.
The first thing we need to do is install express.
npm install -g express
Then we initialize our project.
express MyBlog
# and then as per instructions
cd MyBlog
npm install
Youāll notice that express made a lot of files for you, most importantly are the files in the āroutesā folder and the files in the āviewsā folder. The way I wanted my blog to work was for a url like āwww.ethernetbucket.com/article/whateverā to link to the article āwhateverā. Additionally I wanted the url āwww.ethernetbucket/category/myCategoryā to link to a page that listed articles of that category. To do this we need routes.
Article Route
Add a file to the routes folder called article.js. To get it setup to query Mongo add something like this:
var databaseUrl = "myDatabase",
collections = ["articles"],
db = require("mongojs").connect(databaseUrl, collections),
u = require("underscore");
// also probably a good time to install underscore and mongojs
exports.servePage = function (req, res){
}
Weāre setting up a function called āservePageā that express will use to to respond to requests for articles. In order to hook this function into the process of an article request, we have to modify app.js in the top of the directory. App.js comes looking like this:
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Weāre going to replace āuserā with article. So line something like this:
var user = require('./routes/user');
// changes to
var article = require('./routes/article');
// and
app.get('/users', user.list);
// changes to
app.get('/article/:article_name', user.servePage);
Now express will route (hence the name) all get requests that are of the format ā/articleā to our servePage function that does something which we havenāt written yet. Lets fill it inā¦
exports.servePage = function (req, res){
db.articles.findOne({url: req.params.article_name},function(err,result){
if (err) {
// oops - we'll deal with this later
} else if (!result){
// oops again - this would be a 404
} else {
res.render('article', result);
}
})
}
Two things happening here. First in the mongo query I reference āreq.params.article_nameā. This parameter was defined in app.js at the same time we defined the route for article. The second thing is at the end there you see āres.render(āarticleā,result)ā. This tells express to render the view āarticleā (yet to be written) with the data from mongoDB.
Article View
In the views folder, you see index.jade and layout.jade; both are jade templates (duh). layout.jade has āblocksā that can be filled by other templates which āextendā layout.jade. We need an article.jade file. It should look like this:
extends layout
block css
each val in css
link(rel='stylesheet', href='/stylesheets/'+val.file)
block headertags
!= headertags
block content
article
if hidetitle == false
h2= title
if publishDate
date
strong= publishDate
each val in content
if val.type == 'p'
p= val.text
if val.type == 'h2'
h2= val.text
if val.type == 'HTML'
!= val.text
if val.type == 'pre'
div.codebox
header Code
pre.prettyprint.linenums.lang-js= val.text
The template above actually makes the page youāre looking at right now. The āblocksā hook into certain parts of layout.js that looks like this:
doctype 5
html
head
title= title
script(src='/javascripts/example.js')
link(rel="stylesheet",href='/stylesheets/example.css')
block css
block headertags
body
header(id='masthead')
h1
a(href='/') My Blog!!!
nav
//- perhaps some nav stuff here
block content
footer
p Copywrite 2013
script
window.onload = function(){
// do some code
}
You can see there there is example javascript and css files included in layout.jade. These files would live in the āpublicā directory created by express when we initialized our project. Using a layout template is really awesome because we can put any other template, for example the template for the category page, into the layout. So if we need to change our nav section or change our stylesheets we only have to go to one place and make one change.
Finishing up
What we have so far is enough to get articles to render using the /article route. Some things that will need to be done in the future are making a 404 and 503 template to let readers know of errors. We need to fill out our index.jade template because its pretty bare at this point. And obviously we havent written the route for category or the view for it, but I think you can see from what weāve done so far how you should go about doing it.
If you want to see what this project ultimately came to be checkout Wato Blog Tool