Working version of wiki
This commit is contained in:
parent
2971151540
commit
5a1b0f85f4
42
app.js
42
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);
|
||||||
|
57
db.js
Normal file
57
db.js
Normal file
@ -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);
|
||||||
|
};
|
@ -1,8 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "wiki-contest",
|
"name": "wiki-contest",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"author": "Tim Caswell <tim@c9.io>",
|
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"express": "2.5.5",
|
||||||
|
"jade": ">= 0.0.1",
|
||||||
|
"markdown": "~0.3.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
# Home Page
|
||||||
|
|
||||||
|
This is the homepage of the wiki.
|
||||||
|
|
||||||
|
Cool stuff here.
|
8
public/stylesheets/style.css
Normal file
8
public/stylesheets/style.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
body {
|
||||||
|
padding: 50px;
|
||||||
|
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #00B7FF;
|
||||||
|
}
|
31
routes/index.js
Normal file
31
routes/index.js
Normal file
@ -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);
|
||||||
|
});
|
||||||
|
}
|
13
server.js
13
server.js
@ -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);
|
|
||||||
|
|
4
views/edit.jade
Normal file
4
views/edit.jade
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
h1= title
|
||||||
|
form(method="post", action="/" + name)
|
||||||
|
textarea(name="markdown")= markdown
|
||||||
|
input(type="submit")
|
6
views/layout.jade
Normal file
6
views/layout.jade
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
!!!
|
||||||
|
html
|
||||||
|
head
|
||||||
|
title= title
|
||||||
|
link(rel='stylesheet', href='/stylesheets/style.css')
|
||||||
|
body!= body
|
3
views/view.jade
Normal file
3
views/view.jade
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
h1= title
|
||||||
|
.article!= html
|
||||||
|
a(href="/" + name + "/edit")= (exists ? "Edit" : "Create") + " this Page"
|
Loading…
Reference in New Issue
Block a user