現(xiàn)在我們來(lái)給博客增加標(biāo)簽和標(biāo)簽頁(yè)。
我們?cè)O(shè)定:每篇文章最多有三個(gè)標(biāo)簽(少于三個(gè)也可以),當(dāng)點(diǎn)擊主頁(yè)左側(cè)標(biāo)簽頁(yè)鏈接時(shí),跳轉(zhuǎn)到標(biāo)簽頁(yè)并列出所有已存在標(biāo)簽;當(dāng)點(diǎn)擊任意一個(gè)標(biāo)簽鏈接時(shí),跳轉(zhuǎn)到該標(biāo)簽頁(yè)并列出所有含有該標(biāo)簽的文章。
首先我們來(lái)實(shí)現(xiàn)給文章添加標(biāo)簽的功能。
打開 post.ejs ,在
后添加:
標(biāo)簽:<br />
<input type="text" name="tag1" /><input type="text" name="tag2" /><input type="text" name="tag3" /><br />
打開 index.js ,將 app.post('/post') 內(nèi)的:
var currentUser = req.session.user,
post = new Post(currentUser.name, req.body.title, req.body.post);
修改為:
var currentUser = req.session.user,
tags = [req.body.tag1, req.body.tag2, req.body.tag3],
post = new Post(currentUser.name, req.body.title, tags, req.body.post);
打開 post.js ,將:
function Post(name, title, post) {
this.name = name;
this.title= title;
this.post = post;
}
修改為:
function Post(name, title, tags, post) {
this.name = name;
this.title = title;
this.tags = tags;
this.post = post;
}
將:
var post = {
name: this.name,
time: time,
title: this.title,
post: this.post,
comments: []
};
修改為:
var post = {
name: this.name,
time: time,
title: this.title,
tags: this.tags,
post: this.post,
comments: []
};
現(xiàn)在我們就可以在發(fā)表文章的時(shí)候添加標(biāo)簽了。接下來(lái)我們修改 index.ejs 、 user.ejs 和 article.ejs 來(lái)顯示文章的標(biāo)簽。
修改 index.ejs 、 user.ejs 和 article.ejs,將:
<p class="info">
作者:<a href="/u/<%= post.name %>"><%= post.name %></a> |
日期:<%= post.time.minute %>
</p>
修改為:
<p class="info">
作者:<a href="/u/<%= post.name %>"><%= post.name %></a> |
日期:<%= post.time.minute %> |
標(biāo)簽:
<% post.tags.forEach(function (tag, index) { %>
<% if (tag) { %>
<a class="tag" href="/tags/<%= tag %>"><%= tag %></a>
<% } %>
<% }) %>
</p>
最后,在 style.css 中添加如下樣式:
.tag{background-color:#ff0000;border-radius:3px;font-size:14px;color:#ffffff;display:inline-block;padding:0 5px;margin-bottom:8px;}
.tag:hover{text-decoration:none;background-color:#ffffff;color:#000000;-webkit-transition:color .2s linear;}
至此,我們給博客添加了標(biāo)簽功能。趕緊看看效果吧!
添加標(biāo)簽頁(yè)
接下來(lái)我們給博客增加標(biāo)簽頁(yè)。
修改 header.ejs ,在archive
下一行添加:
<span><a title="標(biāo)簽" href="/tags">tags</a></span>
修改 index.js ,在 app.get('/archive') 后添加如下代碼:
app.get('/tags', function (req, res) {
Post.getTags(function (err, posts) {
if (err) {
req.flash('error', err);
return res.redirect('/');
}
res.render('tags', {
title: '標(biāo)簽',
posts: posts,
user: req.session.user,
success: req.flash('success').toString(),
error: req.flash('error').toString()
});
});
});
打開 post.js ,在最后添加:
//返回所有標(biāo)簽
Post.getTags = function(callback) {
mongodb.open(function (err, db) {
if (err) {
return callback(err);
}
db.collection('posts', function (err, collection) {
if (err) {
mongodb.close();
return callback(err);
}
//distinct 用來(lái)找出給定鍵的所有不同值
collection.distinct("tags", function (err, docs) {
mongodb.close();
if (err) {
return callback(err);
}
callback(null, docs);
});
});
});
};
注意:這里我們用了 distinct (詳見《mongodb權(quán)威指南》)返回 tags 鍵的所有不同值,因?yàn)橛袝r(shí)候我們發(fā)表文章的標(biāo)簽是一樣的,所以這樣避免了獲取重復(fù)的標(biāo)簽。
在 views 文件夾下新建 tags.ejs ,添加如下代碼:
<%- include header %>
<% posts.forEach(function (tag, index) { %>
<a class="tag" href="/tags/<%= tag %>"><%= tag %></a>
<% }) %>
<%- include footer %>
至此,我們就給博客添加了標(biāo)簽頁(yè)。
現(xiàn)在我們來(lái)添加特定標(biāo)簽的頁(yè)面,即當(dāng)點(diǎn)擊任意一個(gè)標(biāo)簽鏈接時(shí),跳轉(zhuǎn)到該標(biāo)簽頁(yè)并列出所有含有該標(biāo)簽的文章信息。
修改 post.js ,在最后添加如下代碼:
//返回含有特定標(biāo)簽的所有文章
Post.getTag = function(tag, callback) {
mongodb.open(function (err, db) {
if (err) {
return callback(err);
}
db.collection('posts', function (err, collection) {
if (err) {
mongodb.close();
return callback(err);
}
//查詢所有 tags 數(shù)組內(nèi)包含 tag 的文檔
//并返回只含有 name、time、title 組成的數(shù)組
collection.find({
"tags": tag
}, {
"name": 1,
"time": 1,
"title": 1
}).sort({
time: -1
}).toArray(function (err, docs) {
mongodb.close();
if (err) {
return callback(err);
}
callback(null, docs);
});
});
});
};
修改 index.js ,在 app.get('/tags') 后添加如下代碼:
app.get('/tags/:tag', function (req, res) {
Post.getTag(req.params.tag, function (err, posts) {
if (err) {
req.flash('error',err);
return res.redirect('/');
}
res.render('tag', {
title: 'TAG:' + req.params.tag,
posts: posts,
user: req.session.user,
success: req.flash('success').toString(),
error: req.flash('error').toString()
});
});
});
在 views 文件夾下新建 tag.ejs ,添加如下代碼:
<%- include header %>
<ul class="archive">
<% var lastYear = 0 %>
<% posts.forEach(function (post, index) { %>
<% if (lastYear != post.time.year) { %>
<li><h3><%= post.time.year %></h3></li>
<% lastYear = post.time.year } %>
<li><time><%= post.time.day %></time></li>
<li><a href="/u/<%= post.name %>/<%= post.time.day %>/<%= post.title %>"><%= post.title %></a></li>
<% }) %>
</ul>
<%- include footer %>
最后,別忘了修改 edit.ejs ,為了保持和 post.ejs 一致。將 edit.ejs 修改為:
<%- include header %>
<form method="post">
標(biāo)題:<br />
<input type="text" name="title" value="<%= post.title %>" disabled="disabled" /><br />
標(biāo)簽:<br />
<input type="text" name="tag1" value="<%= post.tags[0] %>" disabled="disabled" />
<input type="text" name="tag2" value="<%= post.tags[1] %>" disabled="disabled" />
<input type="text" name="tag3" value="<%= post.tags[2] %>" disabled="disabled" /><br />
正文:<br />
<textarea name="post" rows="20" cols="100"><%= post.post %></textarea><br />
<input type="submit" value="保存修改" />
</form>
<%- include footer %>
注意:這里我們?cè)O(shè)定了編輯時(shí)不能編輯文章的標(biāo)題和標(biāo)簽。
現(xiàn)在,我們的博客就增加了標(biāo)簽和標(biāo)簽頁(yè)的功能。