diff --git a/app.js b/app.js index b010653..4d0b492 100644 --- a/app.js +++ b/app.js @@ -1,4 +1,40 @@ -var Stack = require('stack'); +var Express = require('express'); +var Routes = require('./routes'); -module.exports = Stack.compose( -); +// TODO: Uncomment when we have internet +// var TryCatch = require('./trycatch'); + +var App = module.exports = Express.createServer(); + +// Configuration + +App.configure(function(){ + App.set('views', __dirname + '/views'); + App.set('view engine', 'jade'); + // This gives us scoped errors with long stack traces + // TODO: Uncomment when we have internet + // App.use(function (req, res, next) { + // TryCatch(next, next); + // }); + App.use(Express.bodyParser()); + App.use(Express.methodOverride()); + App.use(App.router); + App.use(Express.static(__dirname + '/public')); +}); + +App.configure('development', function(){ + App.use(Express.errorHandler({ dumpExceptions: true, showStack: true })); +}); + +App.configure('production', function(){ + App.use(Express.errorHandler()); +}); + +// Routes +App.get('/', Routes.index); +App.get('/:name', Routes.view); +App.get('/:name/edit', Routes.edit); +App.post('/:name', Routes.save); + +App.listen(process.env.PORT || 3000); +console.log("Express server listening on port %d in %s mode", App.address().port, App.settings.env); diff --git a/db.js b/db.js new file mode 100644 index 0000000..b36cdf0 --- /dev/null +++ b/db.js @@ -0,0 +1,57 @@ +var FS = require('fs'); +var Path = require('path'); +var Markdown = require('markdown').markdown; + +// This function is used to map wiki page names to files +// on the real filesystem. +function pathFromName(name) { + return Path.join(__dirname, "pages", name + ".markdown"); +} + +// Load a file from disk and parse out the title and generate the HTML +exports.loadPage = function (name, callback) { + // Attempt to load the file from disk + var path = pathFromName(name); + FS.readFile(path, 'utf8', function (err, markdown) { + var exists = true; + if (err) { + // If it's not there, generate a placeholder body + if (err.code === "ENOENT") { + markdown = "# " + name.replace(/_/g, " ") + "\n\n" + + "This page does not exist yet. Be the first to write it."; + exists = false; + } else { + // Forward all other errors on + return callback(err); + } + } + + // Parse the markdown extracting the first header as the title + // and then render as an HTML string + var tree = Markdown.parse(markdown); + var title = name; + for (var i = 1, l = tree.length; i < l; i++) { + if (tree[i] && tree[i][0] === "header") { + title = tree[i][2]; + tree.splice(i, 1); + break; + } + } + var html = Markdown.toHTML(tree); + + // Send back the page as an object + callback(null, { + name: name, + title: title, + exists: exists, + markdown: markdown, + html: html, + }); + }); +}; + +// Saving is simple. Just put the markdown in the file +exports.savePage = function (name, value, callback) { + var path = pathFromName(name); + FS.writeFile(path, value, callback); +}; diff --git a/lib/db.js b/lib/db.js deleted file mode 100644 index e69de29..0000000 diff --git a/package.json b/package.json index 2161edd..de95d17 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,10 @@ { "name": "wiki-contest", "version": "0.0.0", - "author": "Tim Caswell ", "private": true, "dependencies": { + "express": "2.5.5", + "jade": ">= 0.0.1", + "markdown": "~0.3.1" } -} +} \ No newline at end of file diff --git a/pages/home.markdown b/pages/home.markdown index e69de29..c522f2e 100644 --- a/pages/home.markdown +++ b/pages/home.markdown @@ -0,0 +1,5 @@ +# Home Page + +This is the homepage of the wiki. + +Cool stuff here. \ No newline at end of file diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css new file mode 100644 index 0000000..30e047d --- /dev/null +++ b/public/stylesheets/style.css @@ -0,0 +1,8 @@ +body { + padding: 50px; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; +} + +a { + color: #00B7FF; +} \ No newline at end of file diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..1572f0d --- /dev/null +++ b/routes/index.js @@ -0,0 +1,31 @@ +// Load our model abstraction so we can load and save pages in the wiki. +var DB = require('../db'); + +// When the wiki is initially loaded, simply redirect to the `home` page. +exports.index = function(req, res) { + res.redirect("/home"); +}; + +// Load a page from the database and render as html +exports.view = function (req, res, next) { + DB.loadPage(req.params.name, function (err, page) { + if (err) return next(err); + res.render('view', page); + }); +}; + +// Load a page from the database and render edit form +exports.edit = function (req, res, next) { + DB.loadPage(req.params.name, function (err, page) { + if (err) return next(err); + res.render('edit', page); + }); +}; + +// Save changes to a page and redirect to view page +exports.save = function (req, res, next) { + DB.savePage(req.params.name, req.body.markdown, function (err) { + if (err) return next(err) + res.redirect("/" + req.params.name); + }); +} \ No newline at end of file diff --git a/server.js b/server.js deleted file mode 100644 index 50df215..0000000 --- a/server.js +++ /dev/null @@ -1,13 +0,0 @@ -var Http = require('http'); -var Stack = require('stack'); -var Creationix = require('creationix'); -var App = require('./app'); - -var PORT = process.env.PORT || 8080; - -Http.createServer(Stack( - Creationix.log(), - App -)).listen(PORT); -console.log("Server listening on http://localhost:%s/", PORT); - diff --git a/views/edit.jade b/views/edit.jade new file mode 100644 index 0000000..010a1a9 --- /dev/null +++ b/views/edit.jade @@ -0,0 +1,4 @@ +h1= title +form(method="post", action="/" + name) + textarea(name="markdown")= markdown + input(type="submit") \ No newline at end of file diff --git a/views/layout.jade b/views/layout.jade new file mode 100644 index 0000000..1a36941 --- /dev/null +++ b/views/layout.jade @@ -0,0 +1,6 @@ +!!! +html + head + title= title + link(rel='stylesheet', href='/stylesheets/style.css') + body!= body \ No newline at end of file diff --git a/views/view.jade b/views/view.jade new file mode 100644 index 0000000..3d49644 --- /dev/null +++ b/views/view.jade @@ -0,0 +1,3 @@ +h1= title +.article!= html +a(href="/" + name + "/edit")= (exists ? "Edit" : "Create") + " this Page" \ No newline at end of file