网站安全性怎么做,一个网站开发的意义,wap游戏天下网游,经典网站赏析前面我们介绍了文章详情页面的展示的逻辑代码实现#xff0c;这一节#xff0c;我们将继续讲解文章列表的读取和展示、文章根据分类进行筛选、最新文章、热门文章等的调用处理逻辑。首先#xff0c;我们先编写文章列表页的前端代码。这里#xff0c;我们文章采用类似WordPr…前面我们介绍了文章详情页面的展示的逻辑代码实现这一节我们将继续讲解文章列表的读取和展示、文章根据分类进行筛选、最新文章、热门文章等的调用处理逻辑。首先我们先编写文章列表页的前端代码。这里我们文章采用类似WordPress博客的形式直接将首页作为文章列表页面的展示。因此我们在template文件夹下创建index.html博客首页/文章列表html代码{% include partial/header.html %}
div classlayui-container indexdiv classlayui-row layui-col-space15div classlayui-col-md8div classlayui-carddiv classlayui-card-bodyul classarticle-list{% for item in articles %}li classitema href/article/{{item.Id}} classlinkh5 classtitle{{item.Title}}/h5div classdescription{{item.Description}}/divdiv classmeta{% if item.Category %}span{{item.Category.Title}}/span{% endif %}span{{stampToDate(item.CreatedTime, 2006-01-02)}}/spanspan{{item.Views}} 阅读/span/div/a/li{% endfor %}/ul/div{% if prevPage || nextPage %}div classlayui-card-body text-centerdiv classlayui-box layui-laypagea href{{prevPage}} classlayui-laypage-prev{% if !prevPage %} layui-disabled{% endif %}上一页/aa href{{nextPage}} classlayui-laypage-next{% if !nextPage %} layui-disabled{% endif %}下一页/a/div/div{% endif %}/div/divdiv classlayui-col-md4{% include partial/author.html %}div classlayui-carddiv classlayui-card-header文章分类/divdiv classlayui-card-bodyul classaside-list{% for item in categories %}li classitema href/?category_id{{item.Id}} classlinkh5 classtitle{{item.Title}}/h5/a/li{% endfor %}/ul/div/divdiv classlayui-carddiv classlayui-card-header热门文章/divdiv classlayui-card-bodyul classaside-list{% for item in populars %}li classitema href/article/{{item.Id}} classlinkh5 classtitle{{item.Title}}/h5span classextra{{item.Views}}阅读/span/a/li{% endfor %}/ul/div/div/div/div
/div
{% include partial/footer.html %}列表页中我们将页面分割成两栏左边栏大约占2/3右边栏大约占1/3。左边栏中为文章的列表、上下页信息。文章列表中我们将展示包括文章标题、文章简介、文章分类、文章发布时间、文章浏览量等信息。右边栏中用来展示分类列表、热门文章等内容。左边显示的文章分类信息中我们注意到显示文章分类使用的是{{item.Category.Title}}这是因为我们定义文章模型的时候article.Category 它指向的是文章分类的模型article.Category.Title 就能访问到文章分类的名称了。并且文章并不一定会存在分类因此我们需要先判断分类是否存在{% if item.Category %}span{{item.Category.Title}}/span{% endif %}即文章存在分类的时候我们才输出分类信息。同样这里的文章发布时间我们使用了{{stampToDate(article.CreatedTime, 2006-01-02)}}来显示。stampToDate是我们前面自定义的模板函数它可以将时间戳按照给定的格式格式化输出。这里我们将文章发布的时间戳按照2006-01-02的格式来输出显示。这里我们还注意到输出上下页信息的时候先判断是否存在上下页{% if prevPage || nextPage %} ... {% endif %}只要上一页存在或下一页存在我们才输出上下页的标签否则这一整块都不显示。当这一块显示的时候如果没有上一页则上一页按钮不可点击{% if !prevPage %} layui-disabled{% endif %}同样没有下一页的时候下一页按钮也不能点击{% if !nextPage %} layui-disabled{% endif %}。博客首页/文章列表控制器函数文章博客首页/文章列表页面控制器我们写在controller/index.go index.go中修改IndexPage()函数func IndexPage(ctx iris.Context) {currentPage : ctx.URLParamIntDefault(page, 1)categoryId : uint(ctx.URLParamIntDefault(category_id, 0))//一页显示10条pageSize : 10//文章列表articles, total, _ : provider.GetArticleList(categoryId, id desc, currentPage, pageSize)//读取列表的分类categories, _ : provider.GetCategories()for i, v : range articles {if v.CategoryId 0 {for _, c : range categories {if c.Id v.CategoryId {articles[i].Category c}}}}//热门文章populars, _, _ : provider.GetArticleList(categoryId, views desc, 1, 10)totalPage : math.Ceil(float64(total)/float64(pageSize))prevPage : nextPage : urlPfx : /?var category *model.Categoryif categoryId 0 {urlPfx fmt.Sprintf(category_id%d, categoryId)category, _ provider.GetCategoryById(categoryId)}if currentPage 1 {prevPage fmt.Sprintf(%spage%d, urlPfx, currentPage-1)}if currentPage int(totalPage) {nextPage fmt.Sprintf(%spage%d, urlPfx, currentPage1)}if currentPage 2 {prevPage strings.TrimRight(prevPage, page1)}ctx.ViewData(total, total)ctx.ViewData(articles, articles)ctx.ViewData(populars, populars)ctx.ViewData(totalPage, totalPage)ctx.ViewData(prevPage, prevPage)ctx.ViewData(nextPage, nextPage)ctx.ViewData(category, category)ctx.View(index.html)
}在首页文章列表控制器中我们需要从url中获取两个参数一个是当前页面的页码currentPage : ctx.URLParamIntDefault(page, 1)另一个是当前页面的分类idcategoryId : uint(ctx.URLParamIntDefault(category_id, 0))。这里我们都是获取的int类型的数据并且在没有获取到数据的时候使用默认值来代替因此我们使用了URLParamIntDefault方法。我们每页显示10条可以让列表页面差不多维持在2屏到2屏半左右的高度。pageSize : 10。接着就是读取根据条件读取文章列表了articles, total, _ : provider.GetArticleList(categoryId, id desc, currentPage, pageSize)。我们在 provider/article.go 中增加GetArticleList函数func GetArticleList(categoryId uint, order string, currentPage int, pageSize int) ([]*model.Article, int64, error) {var articles []*model.Articleoffset : (currentPage - 1) * pageSizevar total int64builder : config.DB.Model(model.Article{})if categoryId 0 {builder builder.Where(category_id ?, categoryId)}if order ! {builder builder.Order(order)}if err : builder.Count(total).Limit(pageSize).Offset(offset).Find(articles).Error; err ! nil {return nil, 0, err}return articles, total, nil
}获取文章列表函数接收4个参数categoryId 是分类id如果指定分类id则只显示当前分类的文章列表。order 是排序规则传入order参数可以根据指定的字段规则进行排序如id desc则表示按id倒序来显示。currentPage 是当前读取的页数这个参数一般由url参数中获取。pageSize 是一页显示数量这里我们默认显示10条。这里面我们通过当前页码和每页显示数量来计算出mysql的offsetoffset : (currentPage - 1) * pageSize。再通过判断categoryId是否大于零来确定是否传入了分类id如果有分类id则添加分类id的条件builder builder.Where(category_id ?, categoryId)。如果传入了order排序规则则添加order条件builder builder.Order(order)。因为这是列表的展示因此我们还需获取所有符合条件的文章数量用来计算分页数量和分页展示信息var total int64。最后将文章列表、符合条件的文章数量、错误信息返回给控制器。接着我们继续读取所有的分类用来将分类赋值给文章列表中的文章categories, _ : provider.GetCategories()
for i, v : range articles {if v.CategoryId 0 {for _, c : range categories {if c.Id v.CategoryId {articles[i].Category c}}}
}同样地我们需要获取所有分类也需要在 provider/category.go 中添加GetCategories函数func GetCategories() ([]*model.Category, error) {var categories []*model.Categorydb : config.DBerr : db.Where(status ?, 1).Find(categories).Errorif err ! nil {return nil, err}return categories, nil
}我们只读取status 1的分类因为我们开始的时候定义了status为1 表示正常的数据status为0表示审核的数据status为99表示已删除的数据。我们在处理数据的时候不采取直接删除的方式这么做是为了防止手误等各种意外操作造成数据误删而没有恢复的机会。首页列表中我们在右边栏中显示了热门文章。这里我们将浏览量最多的文章认为是热门文章。populars, _, _ : provider.GetArticleList(categoryId, views desc, 1, 10)同样地热门文章我们也使用GetArticleList函数来获取数据我们只需要将排序规则views desc传入即可得到浏览量最多的文章。这里我们不需要读取分页也不需要获取符合条件的数量因此我们使用populars, _, _来接收数据只保留文章列表存入populars变量中其他变量忽略使用下划线_表示。接着我们通过计算算出是否有上一页、下一页以及根据条件拼接上一页、下一页的连接。prevPage : nextPage : urlPfx : /?var category *model.Categoryif categoryId 0 {urlPfx fmt.Sprintf(category_id%d, categoryId)category, _ provider.GetCategoryById(categoryId)}if currentPage 1 {prevPage fmt.Sprintf(%spage%d, urlPfx, currentPage-1)}if currentPage int(totalPage) {nextPage fmt.Sprintf(%spage%d, urlPfx, currentPage1)}if currentPage 2 {prevPage strings.TrimRight(prevPage, page1)}最后将页面需要使用的变量都注入到view中供前端使用并指定前端页面模板ctx.ViewData(total, total)
ctx.ViewData(articles, articles)
ctx.ViewData(populars, populars)
ctx.ViewData(totalPage, totalPage)
ctx.ViewData(prevPage, prevPage)
ctx.ViewData(nextPage, nextPage)
ctx.ViewData(category, category)ctx.View(index.html)配置首页文章列表页面路由首页的路由在一开始的时候我们便已经配置过了因此在这里我们不需要再次配置。它在route/route.go 中我们给路由增加是否登录判断中间件app.Get(/, controller.Inspect, controller.IndexPage)至此我们的首页文章列表已经完成。我们的首页列表具有了分页功能也能根据分类来筛选显示文章了。验证结果我们重启一下项目我们先在浏览器中访问http://127.0.0.1:8001/来看看效果。如果不出意外可以看到这样的画面 教程用例源码完整的项目示例代码托管在GitHub上访问github.com/fesiong/goblog 可以查看完整的教程项目源代码建议在查看教程的同时认真对照源码可以有效提高码代码速度和加深对博客项目的认识。建议直接fork一份来在上面做修改。欢迎点Star。