鍍金池/ 教程/ HTML/ 第9章 增加標(biāo)簽和標(biāo)簽頁(yè)面
第9章 增加標(biāo)簽和標(biāo)簽頁(yè)面
番外篇之——使用 Mongoose
番外篇之——使用 Async
第4章 實(shí)現(xiàn)用戶頁(yè)面和文章頁(yè)面
第12章 增加友情鏈接
第14章 增加頭像
第7章 實(shí)現(xiàn)分頁(yè)功能
第5章 增加編輯與刪除功能
第11章 增加文章檢索功能
第3章 增加文件上傳功能
番外篇之——部署到 Heroku
第2章 使用 Markdown
第13章 增加404頁(yè)面
第16章 增加日志功能
第1章 一個(gè)簡(jiǎn)單的博客
番外篇之——使用 Handlebars
第10章 增加pv統(tǒng)計(jì)和留言統(tǒng)計(jì)
番外篇之——使用 Passport
第15章 增加轉(zhuǎn)載功能和轉(zhuǎn)載統(tǒng)計(jì)
第8章 增加存檔頁(yè)面
番外篇之——使用 generic pool
番外篇之——使用 _id 查詢
番外篇之——使用 Disqus
番外篇之——使用 KindEditor
第6章 實(shí)現(xiàn)留言功能

第9章 增加標(biāo)簽和標(biāo)簽頁(yè)面

現(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)簽的文章。

添加標(biāo)簽

首先我們來(lái)實(shí)現(xiàn)給文章添加標(biāo)簽的功能。

打開(kāi) post.ejs ,在
后添加:

標(biāo)簽:<br />
<input type="text" name="tag1" /><input type="text" name="tag2" /><input type="text" name="tag3" /><br />

打開(kāi) 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);

打開(kāi) 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()
    });
  });
});

打開(kāi) 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 (詳見(jiàn)《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è)。

添加特定標(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è)的功能。