上一节我们介绍了文章列表的展示和文章根据分类筛选功能的实现。这一节我们将介绍通过文章分类来获取相邻的关联文章列表方法。

往往,我们在文章详情的右侧,右侧放一些相关的文章内容,比如最新发布的文章、本文相关的文章等信息展示。现在我们就在我们的文章右侧放置最新文章和相关文章列表。

最新文章、相关文章的html代码

打开template/article/detail.html,在右侧代码中增加最新文章、相关文章的展示代码:

<div class="layui-col-md4">
    {% include "partial/author.html" %}
    <div class="layui-card">
        <div class="layui-card-header">最新文章div>
        <div class="layui-card-body">
            <ul class="aside-list">
                {% for item in newest %}
                <li class="item">
                    <a href="/article/{{item.Id}}" class="link">
                        <h5 class="title">{{item.Title}}h5>
                        <span class="extra">{{stampToDate(article.CreatedTime, "2006-01-02")}}span>
                    a>
                li>
                {% endfor %}
            ul>
        div>
    div>
    <div class="layui-card">
        <div class="layui-card-header">相关文章div>
        <div class="layui-card-body">
            <ul class="aside-list">
                {% for item in relationList %}
                <li class="item">
                    <a href="/article/{{item.Id}}" class="link">
                        <h5 class="title">{{item.Title}}h5>
                        <span class="extra">{{item.Views}}阅读span>
                    a>
                li>
                {% endfor %}
            ul>
        div>
    div>
div>

最新文章显示标题和发布时间,用来显示这篇文章的发布时间。相关文章则显示文章的阅读量,因为相关文章往往都比较旧,再显示发布时间就不太合适了,显示阅读量会更好一些。

最新文章、相关文章的控制器代码

接着,我们在controller/article.go 中的 ArticleDetail() 函数中,增加最新文章、相关文章的的读取代码:

//最新文章
newest, _, _ := provider.GetArticleList(article.CategoryId, "id desc", 1, 10)
//相邻相关文章
relationList, _ := provider.GetRelationArticleList(article.CategoryId, id, 10)

最新文章沿用的是文章列表的读取函数,因此我们不需要再额外的编写逻辑代码,只需要调用provider.GetArticleList()即可。当然,因为我们需要得到的是最新的文章,而发布文章的id是递增的,所以我们可以通过id desc 设置排序规则按id倒序来实现获取最新文章列表。

相邻相关文章列表,我们就需要重新实现一个函数来处理了。我们在 provider/article.go 中,添加 GetRelationArticleList() 函数:

func GetRelationArticleList(categoryId uint, id uint, limit int) ([]model.Article, error) {
	var articles []model.Article
	var articles2 []model.Article
	db := config.DB
	if err := db.Model(model.Article{}).Where("`status` = 1").Where("`id` > ?", id).Where("`category_id` = ?", categoryId).Order("id ASC").Limit(limit/2).Find(&articles).Error; err != nil {
		//no
	}
	if err := db.Model(model.Article{}).Where("`status` = 1").Where("`id` < ?", id).Where("`category_id` = ?", categoryId).Order("id DESC").Limit(limit/2).Find(&articles2).Error; err != nil {
		//no
	}
	//列表不返回content
	if len(articles2) > 0 {
		for _, v := range articles2 {
			articles = append(articles, v)
		}
	}

	return articles, nil
}

获取相关文章的时候,我们通过当前文章的分类id来作为相关文章的关联因素。如果后期我们给文章增加更多标签的时候,我们也可以使用更多标签作为相关文章的关联因素。比如具有相同的话题标签、相同的关键词等。这里因为我们只给文章增加了分类属性,所以我们只能依靠分类id来做关联。

为了让每篇文章的相关文章重复概率降低,我们将获取相关文章列表拆分成2部分,一部分是比当前文章id大的最相近的相关文章,另一部分是比当前文章id小的最相近的相关文章。然后再将这两部分合并起来作为相关文章列表展示。

完整的项目示例代码托管在GitHub上,需要查看完整的项目代码可以到github.com/fesiong/goblog 上查看,也可以直接fork一份来在上面做修改。