簡單總結分享這次go部落格前台開發

簡單總結分享這次go部落格前台開發

有網友讓分享,簡單說說吧

最後更新 2022/10/10 上午9:41
沙漠尽头的狼
預計閱讀 8 分鐘
分類
更多語言
標籤
Go

大家好,我是沙漠盡頭的狼。

本文寫作由來

站長用 Go 寫的這版部落格前台程式碼比較原生,既沒用什麼框架,本來想著後面重構後再詳細寫寫分享的,今天群友提了,就簡單寫寫吧。

線上訪問位址:https://go.dotnet9.com

首頁截圖:

本文寫得很簡單,還是來個目錄:

  1. Go 基礎學習
  2. Go 搭建部落格參考
  3. Go 版本部落格原始碼
  4. 後面計劃

1. Go 基礎學習

上面的網址和 PDF,適合打基礎、鞏固 Go 的基礎語法。其中 PDF 檔案應該不是京東售賣的《Go Web 程式設計》([新加坡] 鄭兆雄)一書,但也非常不錯,講解了不少 web 基礎知識,應該是網上一位大佬的總結,值得一讀,下面是該 PDF 目錄:

Go web PDF

上面的基礎資料建議未接觸 Go 的同學閱讀,基礎很重要。

2. Go 搭建部落格參考

現重構的部落格前台模板和 Go 版本學習資料出處:

影片目錄如下:

碼神之路 B 站影片教程目錄

影片配套的博文截圖:

碼神之路個人部落格

影片適合學習、動手實踐,Up 主配套的博文則適合輔助檢查程式碼是否正確,部落格配套的前端模板在 Up 主群裡有分享(群號【718840650】),站長程式碼倉庫也有上傳,但是有部分與 Up 主改動不同,部分個性化修改如下:

  • 站長未新增前台文章編輯:Dotnet9 網站有後台文章管理功能,功能重合了。
  • ORM 選擇不同:站長選擇的 GORM。
  • 文章搜尋站長直接呼叫 Dotnet9 網站後端介面,未在 Go 中再寫介面實現:Web API 與前台職責分明,也為了其他客戶端介面共用,例如 Razor Pages 部落格前台也使用了相同的文章搜尋介面。
  • 其他。

3. Go 版本部落格原始碼

如 B 站 Up 主【碼神之路】影片教程標題所說「原生 Go 語言部落格實戰教程,練手級專案實戰教程,未使用任何框架,通俗易懂」,重點是原生,站長實踐後發現 Up 主的路由相關寫法與 ASP.NET CoreMinimal APIs(最小 API)相像,當然前者主要是寫 Web(MVC),後者是寫 Web API,實踐中與自己熟悉的技術比較學習能加深理解,下面對 Go 版部落格原始碼進行部分簡單介紹。

3.1 入口

main.go 為程式入口檔案,相當於 ASP.NET CoreProgram.cs 檔案,檔名可以修改,只要程式碼第一行為 package main

全部程式碼如下:

package main

import (
	"log"
	"net/http"
	"dotnet9.com/goweb/common"
	"dotnet9.com/goweb/router"
)

func init() {
	// 模板載入:html 檔案,比如首頁文章列表、分類文章列表、頁頭、頁尾等
	common.LoadTemplate()
}

func main() {
	server := http.Server{
		Addr: "127.0.0.1:8080",
	}
	router.Router()
	if err := server.ListenAndServe(); err != nil {
		log.Fatal(err)
	}
}

服務綁定 IP 與連接埠是寫死的,可寫到設定檔,你就說和如下 ASP.NET Core 最小 API 像不像吧:

var app = WebApplication.Create(args);

app.MapGet("/", () => "Hello World!");

app.Run("http://localhost:3000");

router.Router() 是簡單封裝的路由(封裝如下),和上面最小 API app.MapGet("/", () => "Hello World!"); 像幾分,能給到 8 分不?:

go 的簡單路由封裝:router.go

package router

import (
	"net/http"
	"dotnet9.com/goweb/views"
	"dotnet9.com/goweb/api"
)

func Router() {
	http.HandleFunc("/", views.HTML.Index)
	http.HandleFunc("/c/", views.HTML.Category)
	http.HandleFunc("/p/", views.HTML.Detail)
	http.HandleFunc("/login", views.HTML.Login)
	http.HandleFunc("/api/v1/post", api.API.SaveAndUpdatePost)
	http.Handle("/resource/", http.StripPrefix("/resource/", http.FileServer(http.Dir("public/resource/"))))
}

路由首頁程式碼如下:

./views/index.go

package views

import (
	"errors"
	"log"
	"net/http"
	"strconv"
	"dotnet9.com/goweb/common"
	"dotnet9.com/goweb/service"
)

func (*HTMLApi) Index(w http.ResponseWriter, r *http.Request) {
	// 這裡是業務程式碼,讀取文章列表,綁定模板
}

3.n 模板綁定

中間跳過 orm 等使用,說說模板綁定:

這是 Go 的文章列表模板:./template/layout/post-list.html

{{define "post-list"}}
<ul class="post-box">
  {{range $index, $elem := .Posts}}
  <li class="post-label">
    <a href="/p/{{$elem.Slug}}"><h2>{{$elem.Title}}</h2></a>
    <p>{{$elem.Description}}</p>
    <div class="post-action">
      <span>
        <i class="iconfont icon-yonghu"></i>
        &nbsp; {{$elem.Original}}
      </span>
      <span>
        <i class="iconfont icon-wenjianjia"></i>
        {{range $catIndex, $cat := $elem.Categories}}
        &nbsp;<a href="/c/{{$cat.Slug}}">{{$cat.Name}}</a>
        {{end}}
      </span>
      <span>
        <i class="iconfont icon-riqi"></i>
        &nbsp;{{$elem.CreationTime}}
      </span>
      <span>
        <i class="iconfont icon-yanjing"></i>
        &nbsp;{{$elem.ViewCount}}
      </span>
    </div>
  </li>
  {{end}}
</ul>
{{end}}

對比這是 Razor Pages 文章列表模板綁定:

@page
@inject IOptionsSnapshot<SiteOptions> SiteOptions
@using Dotnet9.Web.ViewModel.Commons
@model IndexModel
@{
    ViewData["Title"] = "首頁";
}

<ul class="post-box">
    @if (Model.BlogPosts?.Any() == false)
    {
        <span>沒有資料哦</span>
    }
    else
    {
        @foreach (var blogPost in Model.BlogPosts!)
        {
            <li class="post-label">
                <a href="@blogPost.CreationTime.ToString("/yyyy/dd")/@blogPost.Slug">
                    <h2>@blogPost.Title</h2>
                </a>
                <p>@blogPost.Description</p>
                <div class="post-action">
                    <span>
                        <i class="iconfont icon-yonghu"></i>
                        &nbsp; @(blogPost.Original.IsNullOrWhiteSpace() ? SiteOptions.Value.Owner : blogPost.Original)
                    </span>
                    <span>
                        <i class="iconfont icon-wenjianjia"></i>
                        &nbsp;
                        @foreach (var cat in blogPost.Categories)
                        {
                            <a href="/cat/@cat.Slug" title="@cat.Description">@cat.Name</a>
                        }
                    </span>
                    <span>
                        <i class="iconfont icon-riqi"></i>
                        &nbsp;@blogPost.CreationTime.ToString("yyyy-MM-dd")
                    </span>
                    <span>
                        <i class="iconfont icon-yanjing"></i>
                        &nbsp;@blogPost.ViewCount
                    </span>
                </div>
            </li>
        }
    }
</ul>

@await Html.PartialAsync("_PaginationPartial", new PaginationModel(Model.Current, Model.Pages, Model.Total, Model.PageSize, Model.PageCount))

程式碼看個大概:

  • Go 模板綁定使用 {{.物件欄位}},注意前面的點
  • Razor 語法綁定使用 @Model.物件

語言都是相似的,熟悉一個技術棧,其他技術棧可以觸類旁通。

3.n+1 評論

評論對接的第三介面 Valine,後面考慮自己開發:

Valine - 一款快速、簡潔且高效的無後端評論系統。

特性

  • 快速
  • 安全
  • Emoji 😉
  • 無後端實現
  • MarkDown 全語法支援
  • 輕量易用
  • 文章閱讀量統計 v1.2.0+

網站使用截圖:

Valine 留言後台管理:

4. 後面計劃

學習 Go,或者一門新技術,不能光是學,需要找機會用起來。嘗試使用 Go 做一個自己感興趣的專案,比如開發一個簡單的部落格前台,相信自己會學習得更有動力,起初可以嘗試原生開發,即不使用框架,對了解一門語言的基礎語法很有益處。

當想快速進行業務開發、迭代時,可以考慮框架了,站長最近有關注 goframe

GoFrame 是一款模組化、高效能、企業級的 Go 基礎開發框架。GoFrame 是一款通用性的基礎開發框架,是 Golang 標準庫的一個增強擴展級,包含通用核心的基礎開發元件,優點是實戰化、模組化、文件全面、模組豐富、易用性高、通用性強、面向團隊。如果您想使用 Golang 開發一個業務型專案,無論是小型還是中大型專案,GoFrame 是您的不二之選。如果您想開發一個 Golang 元件庫,GoFrame 提供開箱即用、豐富強大的基礎元件庫也能助您的工作事半功倍。如果您是團隊 Leader,GoFrame 豐富的資料文件、詳盡的程式碼註解、活躍的社群成員將會極大降低您的指導成本,支援團隊快速接入、語言轉型與能力提升。

GoFrame 官方文件:https://goframe.org/pages/viewpage.action?pageId=1114119

後面就用 goframe 重構這版 go 部落格吧,當然前提是先把 Razor Pages 版本部落格開發完善了,包括後台...

水文結束(花了 2 小時),只要肯花時間學,沒什麼學不會的,不服就一個字:整。

繼續探索

延伸閱讀

更多文章