Day 3 - HTML Templates
The two popular template engines for Node/Express are Jade and EJS. Jade looks promising with some sort of interesting minimal syntax similar to:
!!! 5
html(lang="en")
body
h1 This saves a lot of keystrokes
It does seem to have a bit of potential for frustration - and it seems to compile to HTML without newlines, so I'm going to go with EJS for now.
EJS allows for HTML to be written in HTML, so what I see when debugging is what I see when writing the
'code'. It seems to have a nice concept of layouts, which let me do something like this:
layout.ejs (default name for the "global" layout)
<!DOCTYPE html>
<html>
<body>
<%- body %>
</body>
</html>
editor.ejs
<h1>I'm a document with a variable <%= foo %>.</h1>
These layouts can be nested.
Back to init.js, first we need to tell Express to use EJS when rendering pages
app.set('view engine', 'ejs');
Then, inside our editor.js response callback, we can use render instead of send:
response.render("editor.ejs", {
foo: "bar"
});
Result
<!DOCTYPE html>
<html>
<body>
<h1>I'm a document with a variable bar.</h1>
</body>
</html>
So far this looks really nice. Global variables can be accessed, and local variables can be explicitly passed through.
Tomorrow, I'll start to actually create some content to test out the template engine properly (and hopefully figure out what is going on with my MongoDB - it suddenly started working).
My Node.js Experiences
Tuesday, November 29, 2011
Monday, November 28, 2011
Node.js - Day 2
Day 2 - MongoDB
Despite being skeptical about MongoDB, I think it is worth going the whole hog and getting the full experience.
First, my example data model sketch (something like a survey engine):
{
"Q1": {
"sort": "single",
"text": "What is your age?",
"choices": [
{ "code": "Q1", "text": "18 to 29" },
{ "code": "Q1", "text": "30 to 39" }
]
},
"status": "unseen",
"optional": false,
"answer": "",
"next": "end"
}
}
To minimise frustration with schema definition I installed Mongoose following Googles advise, and I'm on my way!
Mongoose seems to have a concept of a document Schema which looks handy - converting my data model sketch into a schema:
db.js
exports.create_schema = function(mongoose) {
var Schema = mongoose.Schema;
var Docs = {};
var QuestionChoice = new Schema({
code: String,
text: String
});
var Question = new Schema({
sort: String,
text: String,
choices: [QuestionChoice],
status: String,
optional: Boolean,
answer: String,
next: String
});
var Survey = new Schema({
questions: [Question]
});
Docs.Survey = mongoose.model("Survey", Survey);
Docs.Question = mongoose.model("Question", Question);
Docs.QuestionChoice = mongoose.model("QuestionChoice", QuestionChoice);
return Docs;
}
This was a little frustrating - I wanted to assign Survey, Question, and QuestionChoice to exports, but the Node.js docs say that exports should only be assigned to on the initial require("package.js").
Adding to init.js:
var mongoose = require("mongoose");
mongoose.connect('mongodb://localhost/test');
var Docs = db.create_schema(mongoose);
Sadly, this is not working - docs.questions is showing as []. This is frustrating, and it's well past midnight, so I'm going to try to fix this on Day 3.
Despite being skeptical about MongoDB, I think it is worth going the whole hog and getting the full experience.
First, my example data model sketch (something like a survey engine):
{
"Q1": {
"sort": "single",
"text": "What is your age?",
"choices": [
{ "code": "Q1", "text": "18 to 29" },
{ "code": "Q1", "text": "30 to 39" }
]
},
"status": "unseen",
"optional": false,
"answer": "",
"next": "end"
}
}
To minimise frustration with schema definition I installed Mongoose following Googles advise, and I'm on my way!
Mongoose seems to have a concept of a document Schema which looks handy - converting my data model sketch into a schema:
db.js
exports.create_schema = function(mongoose) {
var Schema = mongoose.Schema;
var Docs = {};
var QuestionChoice = new Schema({
code: String,
text: String
});
var Question = new Schema({
sort: String,
text: String,
choices: [QuestionChoice],
status: String,
optional: Boolean,
answer: String,
next: String
});
var Survey = new Schema({
questions: [Question]
});
Docs.Survey = mongoose.model("Survey", Survey);
Docs.Question = mongoose.model("Question", Question);
Docs.QuestionChoice = mongoose.model("QuestionChoice", QuestionChoice);
return Docs;
}
This was a little frustrating - I wanted to assign Survey, Question, and QuestionChoice to exports, but the Node.js docs say that exports should only be assigned to on the initial require("package.js").
Adding to init.js:
var mongoose = require("mongoose");
mongoose.connect('mongodb://localhost/test');
var Docs = db.create_schema(mongoose);
var survey1 = new Docs.Survey();
var question1 = new Docs.Question();
question1.code = "Q1";
question1.text = "Question Text";
survey1.questions.push({"text":"Question"});
survey1.save(function (err) {
if(err) {
console.log("Unable to save survey.");
} else {
console.log("Saved survey.");
Docs.Survey.findOne({}, function(err, docs) {
console.dir(docs.questions);
});
}
});
Sadly, this is not working - docs.questions is showing as []. This is frustrating, and it's well past midnight, so I'm going to try to fix this on Day 3.
Thursday, November 24, 2011
Nodeing for a Month
Writing code everyday in Node.js for a month
Edit: Jump to a future day (right now you are on Day 1):
http://nodeing.blogspot.com/2011/11/nodejs-day-2.html
http://nodeing.blogspot.com/2011/11/nodejs-day-3.html
To add to the Internet Soap Opera surrounding Node, I thought it might be interesting to actually implement something in Node.js and write down my experiences. So, for the next month I will write some Node.js code every day (each day making the program slightly bigger), and jot down my thoughts on the process here.
While I'm at it, I may as well chuck in MongoDB.
Where I'm coming from
During the day I work as a programmer on boring code using well tested (old) underlying technology (including very large quantities of Tcl code which surprisingly works well and a very old reliable SQL engine). Bugs are almost never found to be from a bug in the platform in my day job.
My uneducated thoughts before beginning this exercise
Good programming style might overcome some of these issues.
Getting Started
Npm (Node Package Manager) is definitely not ready for use on non-Cygwin Windows. The Node.js MSI installer works fine for Node, but npm is not able to install anything successfully - ryppi.py works fine though (thanks Jeroen Janssen!), so I'm off. I've installed express because that seems to be the thing to do.
Writing my first Node.js code
misc.js - Starting off with some boiler-place for binding my URLs - I really like the simple module system.
// Iterate through each module, bind its 'urls' assoc array.
bindurls = function(app, modules) {
for(var i=0; i<modules.length; i++) {
if(modules[i].urls) {
for(var key in modules[i].urls) {
app.get('/' + key, modules[i].urls[key]);
}
}
}
};
exports.bindurls = bindurls;
editor.js - A stub for testing out the binding
create = function(request, response) {
response.send('Hello from editor.create');
};
exports.urls = {'create': create};
init.js - A clean entry point
var express = require('express');
var editor = require('editor');
var misc = require('misc');
var app = express.createServer(express.logger());
misc.bindurls(app, [editor]);
app.get('/', function (request, response) {
response.send("<a href='/create'>Create New Thing</a>");
});
app.listen(80, function() {
console.log('Listening!');
});
First Thoughts
So far it feels good - I can understand the attraction of writing server-side code in Javascript! The code up to this point just had one bug, and the stack trace was rather odd - it will be interesting to this copes when the program starts to get some complexity.
Tomorrow
Bringing in MongoDB, and sketching out what the program will actually do.
Edit: Jump to a future day (right now you are on Day 1):
http://nodeing.blogspot.com/2011/11/nodejs-day-2.html
http://nodeing.blogspot.com/2011/11/nodejs-day-3.html
To add to the Internet Soap Opera surrounding Node, I thought it might be interesting to actually implement something in Node.js and write down my experiences. So, for the next month I will write some Node.js code every day (each day making the program slightly bigger), and jot down my thoughts on the process here.
While I'm at it, I may as well chuck in MongoDB.
Where I'm coming from
During the day I work as a programmer on boring code using well tested (old) underlying technology (including very large quantities of Tcl code which surprisingly works well and a very old reliable SQL engine). Bugs are almost never found to be from a bug in the platform in my day job.
My uneducated thoughts before beginning this exercise
- Both Node and MongoDB seem terribly error prone. If a Node instance has an uncaught exception and goes down, it is going to break things for several users I'm guessing.
- Joins and query plans are both very useful. Explicit joins are going to be tedious, but at least the programmer will have a good idea of exactly what will happen on a join.
- Error handling code full of anonymous function callbacks is going to be interesting (by which I mean horrific)
Good programming style might overcome some of these issues.
Getting Started
Npm (Node Package Manager) is definitely not ready for use on non-Cygwin Windows. The Node.js MSI installer works fine for Node, but npm is not able to install anything successfully - ryppi.py works fine though (thanks Jeroen Janssen!), so I'm off. I've installed express because that seems to be the thing to do.
Writing my first Node.js code
misc.js - Starting off with some boiler-place for binding my URLs - I really like the simple module system.
// Iterate through each module, bind its 'urls' assoc array.
bindurls = function(app, modules) {
for(var i=0; i<modules.length; i++) {
if(modules[i].urls) {
for(var key in modules[i].urls) {
app.get('/' + key, modules[i].urls[key]);
}
}
}
};
exports.bindurls = bindurls;
editor.js - A stub for testing out the binding
create = function(request, response) {
response.send('Hello from editor.create');
};
exports.urls = {'create': create};
init.js - A clean entry point
var express = require('express');
var editor = require('editor');
var misc = require('misc');
var app = express.createServer(express.logger());
misc.bindurls(app, [editor]);
app.get('/', function (request, response) {
response.send("<a href='/create'>Create New Thing</a>");
});
app.listen(80, function() {
console.log('Listening!');
});
First Thoughts
So far it feels good - I can understand the attraction of writing server-side code in Javascript! The code up to this point just had one bug, and the stack trace was rather odd - it will be interesting to this copes when the program starts to get some complexity.
Tomorrow
Bringing in MongoDB, and sketching out what the program will actually do.
Subscribe to:
Posts (Atom)