Simple Blog with CoffeeScript, Node.js and CouchDB

The combination of CoffeeScript, Node.js and CouchDB as a language, a server-side environment and database isn’t just amazingly cool and hip. It’s cool and hip for a reason. And that reason is because it is outrageously simple and blazingly fast to write a very cool web application. But as fast and simple as it is, tutorials and documentation are somehow lacking or non-existent and following them just leave beginners frustrated. So here is a comprehensive tutorial on building a simple blog made with CoffeeScript, NodeJS and CouchDB. It’s not really for professionals but great for the curious and hobbyists who want to move from more traditional server-side technologies to Node.

Update: I have changed a couple of things to make it much more easier for first time CoffeeScript, NodeJS or CouchDB users. So if you find yourself in a bit of trouble, make sure you read the Tips before you start doing anything.

The Aim

Forget the “Hello Worlds!” let’s build a simple blog! For a simple blog I want to be able to:

  • To view all the posts
  • To add a post

Two simple objectives. To achieve this, we’re going to use the following software. If you want to follow along, I recommend installing these using the links given (most need the Node Package Manager).

Tip: For CoffeeScript, Express and Jade, you can install them using the command “npm install ” in your terminal. Depending on your system and privileges, you may want to install CoffeeScript and Express globally by the command “sudo npm install -g ” to take advantage of their command-line interfaces. Or, you may install it locally to save it in your local node_modules folder. If you are unsure about installing packages globally, check out this

1. Setting Up

For this simple blog, I recommend creating a project folder “couchpress”, a subfolder called “views” and another one called “public”.

Now let’s understand this structure a bit. All the application logic, the CoffeeScript and JavaScript files go in the project folder, the root directory that I’ve called “couchpress”. The /views folder contains all the template files using the Jade Template Engine and the /public folder contains all the static content; images, client-side JavaScripts and stylesheets.

Now that we’re organised in our mind what goes where, let’s tell NodeJS, the server-side environment of our blog. Let’s create a file named “main.coffee” with the following in it:

# Requires and Variables
exp = require 'express'
app = exp.createServer()

# App Configuration
app.configure () ->
    app.set 'view engine', 'jade'
    app.set 'views', __dirname + '/views'
    app.use exp.static __dirname + '/public'
    app.use exp.bodyParser()
    app.use exp.methodOverride()

# Run App
app.listen 1337
console.log 'Server running at http://localhost:1337/'

Tip: While it looks like I’ve put the indentation (the tabs) on the file to make it look pretty, they are actually necessary in CoffeeScript. Make sure you follow the indentation as I have in this tutorial. As a rule of thumb, indent when you write the lines of a function or some other kind of block like an “if” statement. If you do not follow the indentation, CoffeeScript will not understand which lines are for which function and throw errors at you.

NodeJS can run off a single JavaScript file like this main.coffee which contains all the code to essentially create the server. I’m using Express, a web development framework for NodeJS, which essentially relieves me of creating all the server stuff over and over again for each project. Instead, the first two lines are nearly all that is necessary. The first to tell Node that we need Express and will call it ‘exp’ from now on and the second to create the server.

The configuration is pretty simple as well. Let’s go through it:

  • Line 7 sets the template engine, Jade, as the view engine. We’ll talk about this later but it means we don’t have to add the “.jade” extension.
  • Lines 8 and 9 sets the folders for views (template files) in the /views folder and the static folder as the /public folder. Notice the “__dirname” part sorts out the location of the current file and everything else is in relation to that.
  • Line 10 tells Express to use methodOverride() that let’s us use Node using RESTful methods. With this, we will be able to post forms to a specific location and let Node handle it. We need this in our new post form.
Finally, the last two lines just tell us to connect it to port 1337, my favourite port for Node and the console.log gives us a response when running it.
 

2. Connecting Up the Database

Now that we’ve got the boring stuff out of the way, let’s have some fun with the database. If you’ve followed the installation guides for CouchDB well enough, you should be able to hit up http://localhost:5984/_utils/ to access Futon, the command centre for your database. Or, if you’re on a Mac, you can open up the application CouchDBX.

Let’s create a new database using the “New Database” button (I’ve called mine “couchpress”) and get straight on to creating our first viewto simply list all the posts. The quickest and easiest way to do this is to open up the database you’ve just created and select “Temporary view…” in the dropdown box in the top right. We just need to save this default view using the “Save As” button and save it in the design document “_design/couchpress” with the view name of “all“.

If you’re unfamiliar with views, they’re the lifeblood of CouchDB and makes querying very much faster because it generates the results of a query ahead of time. It’s really the equivalent of a report. But much cooler. If you want to know more, try the CouchDB Guide.

Tip: If you would like to learn how to add a new post through Futon (the name of this CouchDB utility), go back to the main screen and click on your database and create a new document using the “New Document” button. The “_id” of the document is automatically generated by CouchDB so we will let it be but let’s create two fields using the “Add Field” button. Create a “body” and a “title” field and put in there what you would like. A “Hello World” will do in each case.

Now that the database is set up (I know quick, right?), we need to connect with it. For this, I’m creating a class called “Articler” to handle all the article functions in a file called articler.coffee, also in the same folder as our main.coffee. This is what’s in it:

# Articler Class - Handles all article functions
cradle = require 'cradle'

class Articler
    constructor: (host, port) ->
        @connect = new cradle.Connection host, port, {
            cache: true
            raw: false
        }
        @db = @connect.database 'couchpress'

    findAll: (callback) ->
        @db.view 'couchpress/all', {descending: true}, (err, res) ->
            if (err)
                callback err
            else
                docs = []
                res.forEach (row) ->
                    docs.push row
                callback null, docs

    save: (articles, callback) ->
        @db.save articles, (err, res) ->
            if (err)
                callback err
            else
                callback null, articles

exports.Articler = Articler

Tip: Those ‘@’ signs look funny don’t they? An @ sign in CoffeeScript simply stands for “this.”. It is just a quick shortcut that is very useful to know.

Articler looks a bit complicated but everything is really easy. Articler has three methods: the constructor (which connects with database), findAll (which displays all the posts) and save (which saves, duh):

  • The constructor method lets us do all the talking through the namespace @db as we set it to our database ‘couchpress’ and in the rest of the methods, we simply do an action towards the database.
  • In findAll, we pointed to the view document we created just moments ago using:
    @db.view ‘couchpress/all’
  • In save, we save the variable articles, which will be an array we will be putting in it using:
    @db.view articles

The rest is just callback functions so that we can pass on the variables gathered from the database. For example, in findAll, we put everything into the array called docs so that we can present it on the screen.

To join our newly created Articler class to our main.coffee file, we just need to add these lines after the configuration to grab the Articler class and then point in the direction of our CouchDB url in new instance of Articler:

# Articler Class
Articler = require('./articler').Articler
article = new Articler 'http://localhost', 5984

There we go! The great thing is that the Articler class can be copied and pasted in every app where you want to contact a CouchDB.

Tip: Before you continue, you may want to check that you have created the database correctly and the view correctly by going to your database folder through your browser. In my case, that is http://localhost:5984/couchpress/. If you see the doc_count to be greater than 0, then you should have done everything but if you have a doc_count of 0, try going over the steps to see if you have missed something.

3. Creating the Frontend

Now that we’ve got the server and the database, we can turn our attention to the displaying of our information. First, we’ll create a jade template file called layout.jade in the /views folder. Express uses this file as a template for every page. Therefore, you want to put things like the header and footer in there. I’ve also took the liberty of creating a CSS stylesheet but you should be able to do that. Remember create the stylesheet in the /public folder and link it as below:

!!! 5
html(lang="en")
    head
        title= title
        link(rel= 'stylesheet', href= '/style.css')
    body
        header
            a(href='/')
                h1= 'CouchPress'
        section.content
            != body

Jade is a templating engine that lets us create markup by just writing the tag and then putting the contents of that tag either after the equal signs (i.e. h1= ‘Couchpress’) or on the next lines marked by a tab (like the header tag). What’s more is that anything not in quotation marks can be a variable. For example, we will be changing the title of the page to reflect what we’re doing. Furthermore, the rest of the page is marked by the != body.

Tip: You will notice that there Jade includes a lot of logic. That is part of the beauty but also the font of most of your annoyance. Make sure you keep with the indentation and type everything, especially the symbols correctly. Jade will not be as sympathetic as HTML.

To fill the body, let’s create an index page called index.jade also in the /views folder where we will be listing all the posts:

- each article in articles
    .article
        h1= article.title
        span.created= article.created_at
        span.body= article.body

This is where Jade comes to its prime. It is able to use a bit of logic in the form of JavaScript to iterate over an array, like the JSON one that CouchDB is going to give us. The first line marked with the “-” is the JavaScript that tells Jade to go through every item in the array that we will pass to it.

Finally, I’ll create a quick form called new.jade also in the /views folder to create new posts:

form(method="post")
    input(type="text", name="title", placeholder="Title")

textarea(name="body", rows="20")
input(type="submit", value="Publish")

Great. We’ve created three files in the /views folder: layout.jade for the template, index.jade to list all the articles and new.jade to create a form to publish new posts.

4. The Final Bits

The last thing we have to do now is to join up what the user does in the browser to everything we’ve created. In Express, the easy way to do this is via routing. Routing uses the usual HTTP commands like “get” and “post” but allows us to code our own magic to each of these.

Ok, let’s start with the index. When people go to the domain (which we call “/”), we want to grab the findAll function of Articler and then put it all in the index.jade to show us all the post. For this, we need the following lines in main.coffee (after everything else we’ve done):

app.get '/', (req, res) ->
    article.findAll (err, docs) ->
        res.render 'index', {
            locals: {
                title: 'CouchPress'
                articles: docs
             }
        }

Notice that we render ‘index’ which is the ‘index.jade’. Because we set the view engine to jade and the view folder to /views, Express knows where to look and doesn’t need to extension ‘.jade’. And, remember the variables we put in the Jade files? Well, they’re the “local” variables. I want to set the page title to ‘Couchpress’ and the articles as the docs that Articler is going to give us.

Now, we can deal with posting a new post. First we have to display the form when the user goes to “/new” or in our case, “http://localhost:1337/new”. That’s as simple as this:

app.get '/new', (req, res) ->
    res.render 'new', {locals: {title: 'CouchPress / New Post'}}

And then to process the form, we grab the form details that will be posted to “/new” and then save it using the Articler method save. You can grab the form post parameters by using req.param and then the name of the input, like so:

app.post '/new', (req, res) ->
    article.save {
        title: req.param 'title'
        body: req.param 'body'
        created_at: new Date()
    }, (err, docs) ->
        res.redirect('/')

Don’t forget, the last line is the callback to tell the browser to redirect when it is all good and done!

5. Running

Wow it’s been quite a journey! Now let’s test it. First, if you haven’t been using the nifty CoffeeScript command “coffee –watch”, then we have to compile the files. Direct your terminal to the project folder (for me, that’s couchpress), and then use the following command:

coffee --compile main.coffee articler.coffee

If you look at the folder now, coffee has created two files into JavaScript for you. Awesome! Now, you can run your project (while double-crossing your fingers hoping that you’ve done nothing wrong). To run the project, just run:

node main.js

If you get your message “Server running at http://localhost:1337″, you can breathe a little easier. Now, you can try out your baby! Because we don’t have any posts, go to http://localhost:1337/new in your favourite browser and create a post. And, because we’ve made a redirect, so it should redirect you to http://locahost:1337/ and you can view your site!

Tip: Node will give you an error if go straight to “/” because there’s nothing in the database. But I am sure that you can now figure out how to deal with an empty database (hint: we’ve put in nice little error variables so you can pass on errors).

There it is! A quick blogging platform that let’s you view all the posts and save them!

Conclusion

While our blog is not quite production ready, we have managed to create a basic server, link it to a database, create a frontend and join it altogether in less than 100 lines of code (go on count it) and for me, under an hour. And, it works! Furthermore, this little blog software which can retrieve entries from a database, display it with Jade files and save entries into a database forms the basis of almost any application. So you’ve learnt quite enough to make your own applications! In under 100 lines! I hope this article shows that the combination of CoffeeScript, NodeJS and CouchDB (along with all the other technologies we’ve used) is an amazing mix of fast and innovative technology that allows one to create quick and elegant web applications.

This entry was posted in Tutorial. Bookmark the permalink.
  • http://twitter.com/Seppigio Samuel Andert

    Can you upload on github a complete working solution, for the case that we can not reproduce it, which is actually mine case ;)  

    • Anonymous

      Sorry Samuel, I didn’t see your comment! I will try and look into uploading it on github but for the moment, what seems to be the problem? I would be happy to help.

  • Pingback: OAuth: Logging In with EveryAuth and NodeJS | KOO Studios Blog

  • http://peepcode.com Geoffrey Grosenbach

    Two improvements:

    * You don’t need a period after the at sign. It already means “this.”, so you can use @connect instead of @.connect   

    * Node can run .coffee files natively. Just require(‘coffee-script’) anywhere in a .js file and any other .coffee files will be run directly. It makes it much easier than running a separate watch script or compiling to .js every time.

     

    • Anonymous

      Hi @topfunky:disqus 
      Thanks so much for the feedback! I do think that I should use the at sign properly too but it is a such a habit of mine to put a dot after it. It somehow makes more sense to me in my head and it compiles anyway so I’ve never paid much attention to getting it right. I will try to use the standard notation in future tutorials.

      I actually use require(‘coffee-script’) myself and its great but it does depend on how you install CoffeeScript as my first installation of CoffeeScript was not the node module and therefore could not be reached through the require function. However, if anyone has CoffeeScript as a node module, it is much easier to use require (‘coffee-script’).

      • http://peepcode.com Geoffrey Grosenbach

        Even if you installed CoffeeScript elsewhere, you can install it locally with “npm install coffee-script –save”. 

        This will install it to the local “node_modules” and add it to package.json for the current app. 

        And it makes it tons easier to deploy when you’re done developing.

  • http://twitter.com/arvidkahldev Arvid Kahl

    Great tutorial, very insightful and still useful for a beginner. Two hints for people who run into problems:

    - indentation matters (which might be somewhat surprising for someone coming from non-python languages or just JS)

    - the /new POST request is empty unless you add “app.use exp.bodyParser()” to the config part. express seems to work only with this kind of middleware.

    Thanks again for the whole thing :) Exactly what i was looking for.

    • Anonymous

      @twitter-343990983:disqus Thanks for pointing out the app.use exp.bodyParser() is missing! Yes the bodyParser() is the necessary middleware for the /new POST request to work.

      I’m glad you liked it and thank you for the great hints! 

  • tim

    hey great tutorial – I’ve followed it closely, however I’m getting the following error when trying to run node.

    Air:couchpress tim$ node main.js node.js:201        throw e; // process.nextTick error, or ‘error’ event on first tick              ^TypeError: Cannot call method ‘call’ of undefined    at HTTPServer.configure (/Users/tim/Desktop/couchpress/node_modules/express/lib/http.js:542:61)    at Object. (/Users/tim/Desktop/couchpress/main.js:8:7)    at Object. (/Users/tim/Desktop/couchpress/main.js:52:4)    at Module._compile (module.js:441:26)    at Object..js (module.js:459:10)    at Module.load (module.js:348:31)    at Function._load (module.js:308:12)    at Array.0 (module.js:479:10)    at EventEmitter._tickCallback (node.js:192:40)

    • Anonymous

      Thanks for reading. I’d be happy to help you if you with your problem. Perhaps it would be better if you paste your main.js code with a service like http://pastebin.com and put the link to it here so we can have a look at your code?

  • http://twitter.com/Seppigio Samuel Andert

    Sorry just saw your answer right now. My problem is after I go on my localhost:1337/new and try to write a new post, my publish button won’t work at all. And when going straight to localhost:1337 I get the following error:

    TypeError: /Users/Samuel/apps/couchpress/views/index.jade:1
    > 1| – each article in articles
    2| .article
    3| h1= article.title
    4| span.created= article.created_at

    Cannot read property ‘length’ of undefined
    at eval at (/Users/Samuel/apps/couchpress/node_modules/jade/lib/jade.js:160:8)
    at eval at (/Users/Samuel/apps/couchpress/node_modules/jade/lib/jade.js:160:8)
    at Object. (/Users/Samuel/apps/couchpress/node_modules/jade/lib/jade.js:165:12)
    at ServerResponse._render (/Users/Samuel/apps/couchpress/node_modules/express/lib/view.js:425:21)
    at ServerResponse.render (/Users/Samuel/apps/couchpress/node_modules/express/lib/view.js:318:17)
    at /Users/Samuel/apps/couchpress/main.js:26:18
    at /Users/Samuel/apps/couchpress/articler.js:22:18
    at Request._callback (/Users/Samuel/apps/couchpress/node_modules/cradle/lib/cradle.js:198:20)
    at Request.callback (/Users/Samuel/apps/couchpress/node_modules/cradle/node_modules/request/main.js:119:22)
    at Request. (/Users/Samuel/apps/couchpress/node_modules/cradle/node_modules/request/main.js:525:16)Any idea?

    • Anonymous

      Hi, thanks for following @twitter-213294402:disqus ! My apologies as there may have been some changes and fixes to the blog post but I can hopefully help you with fixing your problem.

      Firstly, the reason why the publish button does not work most probably because there was a missing “app.use exp.bodyParser()” in the app configuration. Express requires that middleware to route the post function.
      Secondly, your error is the same error as the one I’ve mentioned in the Tip just above the conclusion. When the database is empty or cannot be connected, the “article” variable is undefined. Because I’ve kept the blog simple, it does not deal with an undefined “article” although that is very easy to fix with a typeOf article check. However, as you seemed to have found out, Cradle is also needed to connect to the database. That is what the Articler class uses.

      Thanks again for reading.

      • http://twitter.com/Seppigio Samuel Andert

        I still couldn’t get it to work, so I would appreciate, if you can upload it to your new github project and then I will happily start contributing to the greatest CMS to be ;)

  • http://twitter.com/Seppigio Samuel Andert

    In order to get main.js running there is one more dependency missing.
    Just use “npm install cradle” to get it going.

    • Anonymous

      Hi @twitter-213294402:disqus , thanks for pointing this out. I had missed introducing Cradle in the setting up phase. Sorry for the confusion. In the future though, if you see require in code, it probably means that there is a file that it needs to point to.

  • Gerardo

    Thank you for this tutorial; it’s great. I’d suggest to add the URL: “http://localhost:5984/_utils/” because I thought I was doing it wrong. :)

    • Anonymous

      Thanks for the tip @05d4d311fe21848f8f0ee156b662900e:disqus ! I’ve added the URL for Futon.

  • http://www.theonlineaudioschool.com/ Pro tools courses

    The dwell on-line lessons are finest to attend.  one in every of the primary benefits of professionalfessional instruments course is of studying at dwelling.  You are stay with the lecture however there is no want to sit down within the category as you could be sitting at residence calm and relaxed.  whenever you get enrolled into the course, the account and password can be given to you on which you will obtain the entire e-mail alerts. 

  • Edwardtrunk

    I appreciate your intro tutorial. I’m not able to publish, have tried inserting console.log, it appears that the route is not being resolve

      app.post(‘/new’, function(req, res) {    return article.save({      title: req.param(‘title’),      body: req.param(‘body’),      created_at: new Date()    }, function(err, docs) {      return res.redirect(‘/’);    });  });

  • عقاري الشبكة

    nice post but bit complex can make it more easy by adding some more details..

  • nicotine

    Hello, it was the same error form me.
    It seems that express.js make some changes to set the args to jade. You don’t have to had the locals property.
    try this (it’s working for me) :

    app.get ‘/’, (req, res) ->
    article.findAll (err, docs) ->
    res.render ‘index’, {
    title: ‘Dam’
    articles: docs
    }