Created
March 11, 2011 18:59
-
-
Save rjungemann/866377 to your computer and use it in GitHub Desktop.
Work-in-progress RESTful wiki using Node + Connect + CoffeeScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require.paths.unshift 'vendor/connect/lib' | |
require.paths.unshift 'vendor/markdown-js/lib' | |
connect = require 'connect' | |
markdown = require 'markdown' | |
class CoffeeWiki | |
constructor: -> | |
# The endpoint for the wiki. | |
@baseUrl = '/pages' | |
@softlinkModules = [ | |
(args...) => | |
url = if args[0].match /^http(s{0,1}):\/\// || args[0].match /^\// | |
args[0] | |
else | |
"#{@baseUrl}/#{@sluggerize args[0]}" | |
"<a href=\"#{url}\">#{args[1] || args[0]}</a>" | |
] | |
# A default set of pages that are loaded. | |
@pages = { | |
welcome: { | |
title: "Welcome" | |
rawContents: "Hello world! Check out the [[links]] page." | |
} | |
links: { | |
title: "Links" | |
rawContents: "Second page. Return to the [[welcome|first page]]." | |
} | |
} | |
# Turn a title into a url-friendly format, which can also be used as a key | |
# to find the page later. | |
sluggerize: (string) => | |
string.replace(/\W+/g, '_').replace(/\_+/, '_').replace(/^\_|\_$/, '') | |
# Process wiki-styled links in an extensible way. Currently supports | |
# internal and external links, but could be extended to support loading | |
# images or other media using a wiki-styled syntax. | |
softlink: (string) => | |
string.replace /\[\[(.+?)\]\]/g, (m, s) => | |
for i in [0..(@softlinkModules.length - 1)] | |
result = @softlinkModules[i].apply null, s.split /\|/ | |
if result then return result | |
app: (app) => | |
# Retrieve a page by slug | |
app.get "#{@baseUrl}/:slug", (req, res, next) => | |
page = @pages[req.params.slug] | |
page.contents ?= @softlink page.rawContents | |
body = JSON.stringify page | |
res.writeHead 200, { | |
'Content-Type': 'application/json' | |
'Content-Length': body.length | |
} | |
res.end body | |
# Create or update a page at a user-specified location represented by a | |
# slug. | |
app.put "#{@baseUrl}/:slug", (req, res, next) => | |
slug = req.params.slug | |
@pages[slug] ?= {} | |
@pages[slug].title = req.body.title | |
@pages[slug].rawContents = req.body.contents | |
@pages[slug].contents = @softlink req.body.contents | |
body = JSON.stringify @pages[slug] | |
res.writeHead 200, { | |
'Content-Type': 'application/json' | |
'Content-Length': body.length | |
} | |
res.end body | |
# Create or update a page. This page's slug is determined by sluggerizing | |
# the provided title. | |
app.post @baseUrl, (req, res, next) => | |
slug = @sluggerize req.body.title | |
@pages[slug] ?= {} | |
@pages[slug].rawContents = req.body.contents | |
@pages[slug].contents = @softlink req.body.contents | |
body = JSON.stringify @pages[slug] | |
res.writeHead 200, { | |
'Content-Type': 'application/json' | |
'Content-Length': body.length | |
} | |
res.end body | |
# Delete a page by slug. The page existing at that url is returned. | |
app.delete "#{@baseUrl}/:slug", (req, res, next) => | |
slug = req.params.slug | |
body = JSON.stringify @pages[slug] | |
@pages[slug] = null | |
res.writeHead 200, { | |
'Content-Type': 'application/json' | |
'Content-Length': body.length | |
} | |
res.end body | |
# Get a list of pages | |
app.get @baseUrl, (req, res, next) => | |
body = JSON.stringify @pages | |
res.writeHead 200, { | |
'Content-Type': 'application/json' | |
'Content-Length': body.length | |
} | |
res.end body | |
coffeeWiki = new CoffeeWiki | |
server = connect.createServer( | |
connect.bodyDecoder() | |
connect.router coffeeWiki.app | |
) | |
server.listen 9292 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment