现在,我们来实现主页的功能。修改 routes/index.js,添加如下代码:

var Models = require('../lib/core');
var $Topic = Models.$Topic;

exports.get = function* () {
  var tab = this.query.tab;
  var p = this.query.p || 1;

  yield this.render('index', {
    topics: $Topic.getTopicsByTab(tab, p)
  });
};

为了显示主页,我们需将 partials 目录下所有卡片的视图都补齐。对应修改如下:

partials/userCard.ejs

<% var userInfo = yield $User.getUserByName(name) %>

<div class="ui cards">
  <div class="card">
    <div class="content">
      <div class="userCard">
        <img src="<%=: userInfo.email | gravatar %>">
        <div class="info">
          <p><%= userInfo.name %></p>
          <p class="meta"><%= userInfo.gender %></p>
        </div>
      </div>
      <div class="description">
        <%= userInfo.signature %>
      </div>
    </div>
    <% if ($this.session.user) { %>
      <div class="extra content">
        <a href="/user/<%= userInfo.name %>" class=""><i class="home icon"></i>个人主页</a>
        <a href="#" class="right floated"><i class="setting icon"></i>设置</a>
      </div>
    <% } else { %>
      <div class="extra content">
        <a class=""><i class="send icon"></i>私信</a>
        <a class="right floated"><i class="plus icon"></i>加好友</a>
      </div>
    <% } %>
  </div>
</div>

partials/createCard.ejs

<div class="ui cards">
  <div class="card">
    <div class="content">
      <a class=" ui green button fluid" href="/create">发表话题</a>
    </div>
  </div>
</div>

partials/noReplyCard.ejs

<% var noReplyTopics = yield $Topic.getNoReplyTopics() %>

<div class="ui cards">
  <div class="card">
    <div class="content">
      <b>无人回复的话题</b>
      <div class="ui divider"></div>
      <div class="ui list">
        <% noReplyTopics.forEach(function (topic) { %>
          <a class="item summary" href="/topic/<%= topic._id %>"><%= topic.title %></a>
        <% })%>
      </div>
    </div>
  </div>
</div>

partials/linkCard.ejs

<div class="ui cards">
  <div class="card">
    <div class="content">
      <b>友情链接</b>
      <div class="ui divider"></div>
      <div class="ui list">
        <div class="item">
          <a href="https://cnodejs.org/" target="_blank"><img src="/images/cnode.png" style="width:100%"></a>
        </div>
      </div>
    </div>
  </div>
</div>

partials/tab.ejs

<div class="ui top attached tabular menu">
  <a href="/" class="item <%= (!$this.query.tab || ($this.query.tab == $app.tabs[0])) ? 'active' : '' %>"><%= $app.tabs[0] %></a>
  <% $app.tabs.slice(1).forEach(function (tab) { %>
    <a href="/?tab=<%= tab %>" class="item <%= ($this.query.tab == tab) ? 'active' : '' %>"><%= tab %></a>
  <% }) %>
</div>

partials/list.ejs

<div class="ui bottom attached active tab segment">
  <div class="ui list">
    <% var topicsLen = topics.length; %>
    <% topics.forEach(function (topic, index) { %>
      <div class="item">
        <a class="ui image" href="/user/<%= topic.user.name %>"><img src="<%=: topic.user.email | gravatar %>"></a>
        <div class="content">
          <a class="header" href="/topic/<%= topic._id %>"><%= topic.title %></a>
          <p class="topic"><a href="/user/<%= topic.user.name %>"><b><%= topic.user.name %></b></a> 发起了话题 • <%= topic.pv %> 次浏览 • <%= topic.comment %> 个回复 • <%=: topic.updated_at | fromNow %> • <%= topic.tab %></p>
        </div>
      </div>
      <% if (topicsLen > index + 1) { %>
        <div class="ui divider"></div>
      <% } %>
    <%  }); %>
  </div>
</div>

partials/pagination.ejs

<%
  var count = yield $Topic.getTopicsCount($this.query.tab);
  var pages = Math.ceil(count / 10);
  var page = +$this.query.p || 1;
  var tab = $this.query.tab || '';
  var items = [page-2, page-1, page, page+1, page+2];
  var prePage = '?tab=' + tab + '&p=' + (page - 1);
  var nextPage = '?tab=' + tab + '&p=' + (page + 1);
%>
<div class="ui pagination menu">
  <% if (page && page > 1) { %>
    <a class="icon item" href="?tab=<%= tab %>&p=<%= page - 1 %>">
      <i class="left arrow icon"></i>
    </a>
  <% } %>

  <% items.forEach(function (item) { %>
    <% if (item && (item > 0) && (item <= pages) && (pages > 1)) { %>
      <a class="<%= (page == item) ? 'active': '' %> item" href="?tab=<%= tab %>&p=<%= item %>"><%= item %></a>
    <% } %>
  <% }); %>

  <% if (page && page < pages) { %>
    <a class="icon item" href="?tab=<%= tab %>&p=<%= page + 1 %>">
      <i class="right arrow icon"></i>
    </a>
  <% } %>
</div>

从 pagination.ejs 可以看出,我们可以使用一个特殊的变量 $this,它即是 koa 中的 this。我们还可以直接在 co-ejs 模版中使用 yield 并执行一个数据库操作的函数。

最后,修改 index.ejs 如下:

<% include header %>

<div class="container">
  <div class="ui two column centered grid">
    <div class="right floated left aligned four wide column">
      <% if ($this.session.user) { %>
        <% var name = $this.session.user.name; %>
        <% include partials/userCard %>
        <% include partials/createCard %>
      <% } %>
      <% include partials/noReplyCard %>
      <% include partials/linkCard %>
    </div>
    <div class="left floated  twelve wide column">
      <% include partials/tab %>
      <% include partials/list %>
      <% include partials/pagination %>
    </div>
  </div>
</div>

<% include footer %>

至此,我们就实现了主页和版块的功能。