main
JiXieShi 2024-05-03 22:14:21 +08:00
parent ce45736f28
commit 080c41d458
6 changed files with 121 additions and 25 deletions

View File

@ -154,23 +154,28 @@ func ReadArticleDetail(path, key string) (ArticleDetail, error) {
return articleDetail, nil return articleDetail, nil
} }
// readMarkdown 读取 Markdown 文件内容
func readMarkdown(path, key string) (Article, ArticleDetail, error) { func readMarkdown(path, key string) (Article, ArticleDetail, error) {
var article Article var article Article
var articleDetail ArticleDetail var articleDetail ArticleDetail
mdFile, err := os.Stat(path)
// 获取文件信息
mdFile, err := os.Stat(path)
if err != nil { if err != nil {
return article, articleDetail, err return article, articleDetail, err
} }
if mdFile.IsDir() { if mdFile.IsDir() {
return article, articleDetail, errors.New("this path is Dir") return article, articleDetail, errors.New("this path is Dir")
} }
markdown, err := ioutil.ReadFile(path)
// 读取 Markdown 文件内容
markdown, err := ioutil.ReadFile(path)
if err != nil { if err != nil {
return article, articleDetail, err return article, articleDetail, err
} }
markdown = bytes.TrimSpace(markdown) markdown = bytes.TrimSpace(markdown)
// 设置文章属性
if key != "" { if key != "" {
article.ShortUrl = key article.ShortUrl = key
} }
@ -179,6 +184,7 @@ func readMarkdown(path, key string) (Article, ArticleDetail, error) {
article.Title = strings.TrimSuffix(strings.ToUpper(mdFile.Name()), ".MD") article.Title = strings.TrimSuffix(strings.ToUpper(mdFile.Name()), ".MD")
article.Date = Time(mdFile.ModTime()) article.Date = Time(mdFile.ModTime())
// 处理 开头JSON 格式的文章信息
if !bytes.HasPrefix(markdown, []byte("```json")) { if !bytes.HasPrefix(markdown, []byte("```json")) {
article.Description = cropDesc(markdown) article.Description = cropDesc(markdown)
articleDetail.Article = article articleDetail.Article = article
@ -191,6 +197,7 @@ func readMarkdown(path, key string) (Article, ArticleDetail, error) {
article.Description = cropDesc(markdownArrInfo[1]) article.Description = cropDesc(markdownArrInfo[1])
// 解析 JSON 内容
if err := json.Unmarshal(bytes.TrimSpace(markdownArrInfo[0]), &article); err != nil { if err := json.Unmarshal(bytes.TrimSpace(markdownArrInfo[0]), &article); err != nil {
article.Title = "文章[" + article.Title + "]解析 JSON 出错,请检查。" article.Title = "文章[" + article.Title + "]解析 JSON 出错,请检查。"
article.Description = err.Error() article.Description = err.Error()

View File

@ -25,13 +25,14 @@ func GetCategoryName(path string) string {
return categoryName return categoryName
} }
// GroupByCategory 按类别对文章进行分组
func GroupByCategory(articles *Articles, articleQuantity int) Categories { func GroupByCategory(articles *Articles, articleQuantity int) Categories {
var categories Categories var categories Categories
categoryMap := make(map[string]Articles) categoryMap := make(map[string]Articles)
// 根据类别将文章分组
for _, article := range *articles { for _, article := range *articles {
_, existedCategory := categoryMap[article.Category] _, existedCategory := categoryMap[article.Category]
if existedCategory { if existedCategory {
categoryMap[article.Category] = append(categoryMap[article.Category], article) categoryMap[article.Category] = append(categoryMap[article.Category], article)
@ -39,10 +40,13 @@ func GroupByCategory(articles *Articles, articleQuantity int) Categories {
categoryMap[article.Category] = Articles{article} categoryMap[article.Category] = Articles{article}
} }
} }
// 遍历类别映射,构建分类信息
for categoryName, articles := range categoryMap { for categoryName, articles := range categoryMap {
articleLen := len(articles) articleLen := len(articles)
var articleList Articles var articleList Articles
// 根据指定数量截取文章列表
if articleQuantity <= 0 { if articleQuantity <= 0 {
articleList = articles articleList = articles
} else { } else {
@ -52,12 +56,16 @@ func GroupByCategory(articles *Articles, articleQuantity int) Categories {
articleList = articles[0:articleQuantity] articleList = articles[0:articleQuantity]
} }
} }
// 添加分类信息到结果集
categories = append(categories, Category{ categories = append(categories, Category{
Name: categoryName, Name: categoryName,
Quantity: articleLen, Quantity: articleLen,
Articles: articleList, Articles: articleList,
}) })
} }
// 对分类结果集进行排序
sort.Sort(categories) sort.Sort(categories)
return categories return categories
} }

View File

@ -11,17 +11,20 @@ type Nav struct {
} }
type Navs []Nav type Navs []Nav
// initExtraNav 初始化额外导航栏
func initExtraNav(dir string) (Navs, error) { func initExtraNav(dir string) (Navs, error) {
var navigation Navs var navigation Navs
var extraNav Articles var extraNav Articles
// 递归读取文章
extraNav, err := RecursiveReadArticles(dir) extraNav, err := RecursiveReadArticles(dir)
if err != nil { if err != nil {
return navigation, err return navigation, err
} }
sort.Sort(extraNav) sort.Sort(extraNav)
// 将文章标题格式化为大写开头的标题,并添加到导航栏中
for _, article := range extraNav { for _, article := range extraNav {
title := strings.Title(strings.ToLower(article.Title)) title := strings.Title(strings.ToLower(article.Title))
navigation = append(navigation, Nav{Title: title, Path: article.Path}) navigation = append(navigation, Nav{Title: title, Path: article.Path})

View File

@ -37,36 +37,53 @@ func (t TemplatePointer) WriteError(w io.Writer, err error) {
} }
} }
// BuildViewData 构建视图数据
//
// Parameters:
//
// title: 页面标题
// data: 页面数据
//
// Returns:
//
// map[string]interface{}: 包含标题、数据、网站配置和导航栏信息的映射
func BuildViewData(title string, data interface{}) map[string]interface{} { func BuildViewData(title string, data interface{}) map[string]interface{} {
return map[string]interface{}{ return map[string]interface{}{
"Title": title, "Title": title, // 页面标题
"Data": data, "Data": data, // 页面数据
"Config": config.Cfg, "Config": config.Cfg, // 网站配置
"Navs": Navigation, "Navs": Navigation, // 导航栏数据
} }
} }
// initHtmlTemplate 初始化 HTML 模板
//
// Parameters:
//
// viewDir: 视图文件目录路径
//
// Returns:
//
// HtmlTemplate: HTML 模板对象
// error: 错误信息(如果有)
func initHtmlTemplate(viewDir string) (HtmlTemplate, error) { func initHtmlTemplate(viewDir string) (HtmlTemplate, error) {
var htmlTemplate HtmlTemplate
tp, err := readHtmlTemplate( tp, err := readHtmlTemplate(
[]string{"index", "extraNav", "dashboard", "categories", "article", "album", "talk"}, []string{"index", "extraNav", "dashboard", "categories", "article", "album", "talk"},
viewDir) viewDir)
if err != nil { if err != nil {
return htmlTemplate, err return HtmlTemplate{}, err
} }
htmlTemplate.Index = tp[0] return HtmlTemplate{
htmlTemplate.ExtraNav = tp[1] Index: tp[0],
htmlTemplate.Dashboard = tp[2] ExtraNav: tp[1],
htmlTemplate.Categories = tp[3] Dashboard: tp[2],
htmlTemplate.Article = tp[4] Categories: tp[3],
htmlTemplate.Album = tp[5] Article: tp[4],
htmlTemplate.Talk = tp[6] Album: tp[5],
Talk: tp[6],
return htmlTemplate, nil }, nil
} }
func SpreadDigit(n int) []int { func SpreadDigit(n int) []int {
var r []int var r []int
for i := 1; i <= n; i++ { for i := 1; i <= n; i++ {
@ -75,21 +92,33 @@ func SpreadDigit(n int) []int {
return r return r
} }
// readHtmlTemplate 读取 HTML 模板文件
//
// Parameters:
//
// htmlFileName: HTML 文件名列表
// viewDir: 视图文件目录路径
//
// Returns:
//
// []TemplatePointer: HTML 模板指针列表
// error: 错误信息(如果有)
func readHtmlTemplate(htmlFileName []string, viewDir string) ([]TemplatePointer, error) { func readHtmlTemplate(htmlFileName []string, viewDir string) ([]TemplatePointer, error) {
var htmlTemplate []TemplatePointer var htmlTemplate []TemplatePointer
head := viewDir + "/layouts/head.html" head := viewDir + "/layouts/head.html"
footer := viewDir + "/layouts/footer.html" footer := viewDir + "/layouts/footer.html"
reviews := viewDir + "/layouts/reviews.html" reviews := viewDir + "/layouts/reviews.html"
for _, name := range htmlFileName {
for _, name := range htmlFileName {
tp, err := template.New(name+".html"). tp, err := template.New(name+".html").
Funcs(template.FuncMap{"SpreadDigit": SpreadDigit}). Funcs(template.FuncMap{"SpreadDigit": SpreadDigit}).
ParseFiles(viewDir+"/"+name+".html", head, footer, reviews) ParseFiles(viewDir+"/"+name+".html", head, footer, reviews)
if err != nil { if err != nil {
return htmlTemplate, err return nil, err
} }
htmlTemplate = append(htmlTemplate, TemplatePointer{tp}) htmlTemplate = append(htmlTemplate, TemplatePointer{tp})
} }
return htmlTemplate, nil return htmlTemplate, nil
} }

View File

@ -0,0 +1,47 @@
<!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->
<!-- Todo: add easing -->
<svg width="57" height="57" viewBox="0 0 57 57" xmlns="http://www.w3.org/2000/svg" stroke="#fff">
<g fill="none" fill-rule="evenodd">
<g transform="translate(1 1)" stroke-width="2">
<circle cx="5" cy="50" r="5">
<animate attributeName="cy"
begin="0s" dur="2.2s"
values="50;5;50;50"
calcMode="linear"
repeatCount="indefinite" />
<animate attributeName="cx"
begin="0s" dur="2.2s"
values="5;27;49;5"
calcMode="linear"
repeatCount="indefinite" />
</circle>
<circle cx="27" cy="5" r="5">
<animate attributeName="cy"
begin="0s" dur="2.2s"
from="5" to="5"
values="5;50;50;5"
calcMode="linear"
repeatCount="indefinite" />
<animate attributeName="cx"
begin="0s" dur="2.2s"
from="27" to="27"
values="27;49;5;27"
calcMode="linear"
repeatCount="indefinite" />
</circle>
<circle cx="49" cy="50" r="5">
<animate attributeName="cy"
begin="0s" dur="2.2s"
values="50;50;5;50"
calcMode="linear"
repeatCount="indefinite" />
<animate attributeName="cx"
from="49" to="49"
begin="0s" dur="2.2s"
values="49;5;27;49"
calcMode="linear"
repeatCount="indefinite" />
</circle>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -45,6 +45,7 @@
} }
#talk .loading { #talk .loading {
vertical-align: middle;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -52,7 +53,8 @@
} }
#talk .loading img { #talk .loading img {
width: 200px; width: 50px;
background-color:var(--primary,#673ab7);
} }
.talk_item { .talk_item {
@ -193,7 +195,7 @@
</style> </style>
<div id="talk"> <div id="talk">
<div class='loading'><img src="/img/loading.svg" alt="加载中..."></div> <div class='loading'><img src="/public/img/loading.svg" alt="加载中..."></div>
</div> </div>
<div class="limit">- 只展示最近30条说说 -</div> <div class="limit">- 只展示最近30条说说 -</div>