layui获得列表json数据_golang实战开发之博客功能篇:文章列表的读取与展示和分类筛选展示处理...
前面我們介紹了文章詳情頁面的展示的邏輯代碼實現,這一節,我們將繼續講解文章列表的讀取和展示、文章根據分類進行篩選、最新文章、熱門文章等的調用處理邏輯。
首先,我們先編寫文章列表頁的前端代碼。這里,我們文章采用類似WordPress博客的形式,直接將首頁作為文章列表頁面的展示。因此我們在template文件夾下創建index.html:
博客首頁/文章列表html代碼
{% include "partial/header.html" %} <div class="layui-container index"><div class="layui-row layui-col-space15"><div class="layui-col-md8"><div class="layui-card"><div class="layui-card-body"><ul class="article-list">{% for item in articles %}<li class="item"><a href="/article/{{item.Id}}" class="link"><h5 class="title">{{item.Title}}</h5><div class="description">{{item.Description}}</div><div class="meta">{% if item.Category %}<span>{{item.Category.Title}}</span>{% endif %}<span>{{stampToDate(item.CreatedTime, "2006-01-02")}}</span><span>{{item.Views}} 閱讀</span></div></a></li>{% endfor %}</ul></div>{% if prevPage || nextPage %}<div class="layui-card-body text-center"><div class="layui-box layui-laypage"><a href="{{prevPage}}" class="layui-laypage-prev{% if !prevPage %} layui-disabled{% endif %}">上一頁</a><a href="{{nextPage}}" class="layui-laypage-next{% if !nextPage %} layui-disabled{% endif %}">下一頁</a></div></div>{% endif %}</div></div><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 categories %}<li class="item"><a href="/?category_id={{item.Id}}" class="link"><h5 class="title">{{item.Title}}</h5></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 populars %}<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></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, currentPage+1)}if currentPage == 2 {prevPage = strings.TrimRight(prevPage, "page=1")}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, currentPage+1)}if currentPage == 2 {prevPage = strings.TrimRight(prevPage, "page=1")}最后,將頁面需要使用的變量,都注入到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。
總結
以上是生活随笔為你收集整理的layui获得列表json数据_golang实战开发之博客功能篇:文章列表的读取与展示和分类筛选展示处理...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python ndarray appen
- 下一篇: 计算机检索技术与技巧的检索式为,第四章计