add blog example
This commit is contained in:
parent
9c652118a9
commit
38ce7c1559
8 changed files with 217 additions and 1 deletions
92
examples/blog/index.js
Normal file
92
examples/blog/index.js
Normal file
|
@ -0,0 +1,92 @@
|
|||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var render = require('./lib/render');
|
||||
var logger = require('koa-logger');
|
||||
var route = require('koa-route');
|
||||
var views = require('co-views');
|
||||
var koa = require('../..');
|
||||
var app = koa();
|
||||
|
||||
// "database"
|
||||
|
||||
var posts = [];
|
||||
|
||||
// middleware
|
||||
|
||||
app.use(logger());
|
||||
|
||||
// route middleware
|
||||
|
||||
app.use(route.get('/', list));
|
||||
app.use(route.get('/post/new', add));
|
||||
app.use(route.get('/post/:id', show));
|
||||
app.use(route.post('/post', create));
|
||||
|
||||
// route definitions
|
||||
|
||||
/**
|
||||
* Post listing.
|
||||
*/
|
||||
|
||||
function *list() {
|
||||
this.body = yield render('list', { posts: posts });
|
||||
}
|
||||
|
||||
/**
|
||||
* Show creation form.
|
||||
*/
|
||||
|
||||
function *add() {
|
||||
this.body = yield render('new');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show post :id.
|
||||
*/
|
||||
|
||||
function *show(id) {
|
||||
var post = posts[id];
|
||||
if (!post) this.throw(404, 'invalid post id');
|
||||
this.body = yield render('show', { post: post });
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a post.
|
||||
*/
|
||||
|
||||
function *create() {
|
||||
var post = yield parse(this);
|
||||
var id = posts.push(post) - 1;
|
||||
post.created_at = new Date;
|
||||
post.id = id;
|
||||
this.redirect('/');
|
||||
}
|
||||
|
||||
// TODO: use a lib...
|
||||
|
||||
var qs = require('querystring');
|
||||
|
||||
function parse(ctx) {
|
||||
return function(done){
|
||||
var buf = '';
|
||||
var req = ctx.req;
|
||||
req.setEncoding('utf8');
|
||||
req.on('data', function(chunk){ buf += chunk });
|
||||
req.on('end', function(){
|
||||
try {
|
||||
done(null, qs.parse(buf));
|
||||
} catch (err){
|
||||
err.body = buf;
|
||||
err.status = 400;
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// listen
|
||||
|
||||
app.listen(3000);
|
13
examples/blog/lib/render.js
Normal file
13
examples/blog/lib/render.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var views = require('co-views');
|
||||
|
||||
// setup views mapping .html
|
||||
// to the swig template engine
|
||||
|
||||
module.exports = views(__dirname + '/../views', {
|
||||
map: { html: 'swig' }
|
||||
});
|
9
examples/blog/views/index.html
Normal file
9
examples/blog/views/index.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Blog</title>
|
||||
</head>
|
||||
<body>
|
||||
{% for post in posts %}
|
||||
{% endfor %}
|
||||
</body>
|
||||
</html>
|
62
examples/blog/views/layout.html
Normal file
62
examples/blog/views/layout.html
Normal file
|
@ -0,0 +1,62 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>{% block title %}Blog{% endblock %}</title>
|
||||
<style>
|
||||
body {
|
||||
padding: 80px;
|
||||
font: 16px Helvetica, Arial;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
#posts {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#posts li {
|
||||
margin: 40px 0;
|
||||
padding: 0;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#posts li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 500px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
textarea {
|
||||
border: 1px solid #eee;
|
||||
border-top-color: #ddd;
|
||||
border-left-color: #ddd;
|
||||
border-radius: 2px;
|
||||
padding: 15px;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
width: 500px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<section id="content">
|
||||
{% block content %}
|
||||
<p>Missing content!</p>
|
||||
{% endblock %}
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
17
examples/blog/views/list.html
Normal file
17
examples/blog/views/list.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
{% extends 'layout.html' %}
|
||||
|
||||
{% block title %}Posts{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Posts</h1>
|
||||
<p>You have <strong>{{ posts.length }}</strong> posts!</p>
|
||||
<p><a href="/post/new">Create a Post</a></p>
|
||||
<ul id="posts">
|
||||
{% for post in posts %}
|
||||
<li>
|
||||
<h2>{{ post.title }}</h2>
|
||||
<p><a href="/post/{{ post.id }}">Read post</a></p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
13
examples/blog/views/new.html
Normal file
13
examples/blog/views/new.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% extends 'layout.html' %}
|
||||
|
||||
{% block title %}New Post{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>New Post</h1>
|
||||
<p>Create a new post.</p>
|
||||
<form action="/post" method="post">
|
||||
<p><input type="text" placeholder="Title" name="title"></p>
|
||||
<p><textarea placeholder="Contents" name="body"></textarea></p>
|
||||
<p><input type="submit" value="Create"></p>
|
||||
</form>
|
||||
{% endblock %}
|
8
examples/blog/views/show.html
Normal file
8
examples/blog/views/show.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
{% extends 'layout.html' %}
|
||||
|
||||
{% block title %}{{ post.title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ post.title }}</h1>
|
||||
<p>{{ post.body }}</p>
|
||||
{% endblock %}
|
|
@ -40,7 +40,9 @@
|
|||
"ejs": "~0.8.4",
|
||||
"koa-logger": "~1.0.1",
|
||||
"koa-static": "~1.2.0",
|
||||
"co-busboy": "git://github.com/cojs/busboy"
|
||||
"co-busboy": "git://github.com/cojs/busboy",
|
||||
"koa-route": "~1.0.2",
|
||||
"swig": "~1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "> 0.11.4"
|
||||
|
|
Loading…
Reference in a new issue