Compare commits
No commits in common. "31c541e1c2efe27dc8aa75bf6404dff8c843c90b" and "9c0d18a6d03af1e1c134c711432c43218f062d40" have entirely different histories.
31c541e1c2
...
9c0d18a6d0
|
@ -89,9 +89,7 @@ content目录下的一级目录代表一个分类,如果一级目录下有子
|
||||||
## 更新日志
|
## 更新日志
|
||||||
|
|
||||||
### V3.2
|
### V3.2
|
||||||
* 加入搜索功能
|
|
||||||
* 加入Tag搜索和展示
|
* 加入Tag搜索和展示
|
||||||
* 加入Gitalk评论支持(可选)
|
|
||||||
|
|
||||||
### V3.1
|
### V3.1
|
||||||
* 去掉标题的.MD后缀
|
* 去掉标题的.MD后缀
|
||||||
|
|
|
@ -7,11 +7,6 @@
|
||||||
"webHookSecret": "jixieshi",
|
"webHookSecret": "jixieshi",
|
||||||
"categoryDisplayQuantity": 6,
|
"categoryDisplayQuantity": 6,
|
||||||
"utterancesRepo": "jixishi/blog_docs",
|
"utterancesRepo": "jixishi/blog_docs",
|
||||||
"gitalk_clientID": "2c40e5de269c2c61dc91",
|
|
||||||
"gitalk_clientSecret": "d976941995470662ec039028fe37c0466bd27027",
|
|
||||||
"gitalk_owner": "jixishi",
|
|
||||||
"gitalk_repo": "",
|
|
||||||
"gitalk_repo": "",
|
|
||||||
"timeLayout": "2006.01.02 15:04",
|
"timeLayout": "2006.01.02 15:04",
|
||||||
"siteName": "JiXieShi's Blog",
|
"siteName": "JiXieShi's Blog",
|
||||||
"htmlKeywords": "forest blog,Golang,ARM,BE6,前端,硬件",
|
"htmlKeywords": "forest blog,Golang,ARM,BE6,前端,硬件",
|
||||||
|
@ -21,4 +16,4 @@
|
||||||
"themeColor": "#2196f3",
|
"themeColor": "#2196f3",
|
||||||
"dashboard": "/adminjxs",
|
"dashboard": "/adminjxs",
|
||||||
"themeOption": ["#673ab7","#f44336","#9c27b0","#2196f3","#607d8b","#795548"]
|
"themeOption": ["#673ab7","#f44336","#9c27b0","#2196f3","#607d8b","#795548"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
type Config struct {
|
type Config struct {
|
||||||
userConfig
|
userConfig
|
||||||
systemConfig
|
systemConfig
|
||||||
memosConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package config
|
|
||||||
|
|
||||||
type memosConfig struct {
|
|
||||||
MemosUser string `json:"memos_user"`
|
|
||||||
MemosURL string `json:"memos_url"`
|
|
||||||
MemosAlbumTag string `json:"memos_album_tag"`
|
|
||||||
MemosTalkTag string `json:"memos_talk_tag"`
|
|
||||||
}
|
|
|
@ -5,8 +5,6 @@ type userConfig struct {
|
||||||
|
|
||||||
Author string `json:"author"`
|
Author string `json:"author"`
|
||||||
|
|
||||||
Qq string `json:"qq"`
|
|
||||||
|
|
||||||
Icp string `json:"icp"`
|
Icp string `json:"icp"`
|
||||||
|
|
||||||
TimeLayout string `json:"timeLayout"`
|
TimeLayout string `json:"timeLayout"`
|
||||||
|
@ -19,14 +17,6 @@ type userConfig struct {
|
||||||
|
|
||||||
UtterancesRepo string `json:"utterancesRepo"`
|
UtterancesRepo string `json:"utterancesRepo"`
|
||||||
|
|
||||||
Gitalk_ClientID string `json:"gitalk_clientID"`
|
|
||||||
|
|
||||||
Gitalk_ClientSecret string `json:"gitalk_clientSecret"`
|
|
||||||
|
|
||||||
Gitalk_Repo string `json:"gitalk_repo"`
|
|
||||||
|
|
||||||
Gitalk_Owner string `json:"gitalk_owner"`
|
|
||||||
|
|
||||||
PageSize int `json:"pageSize"`
|
PageSize int `json:"pageSize"`
|
||||||
|
|
||||||
DescriptionLen int `json:"descriptionLen"`
|
DescriptionLen int `json:"descriptionLen"`
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
package controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"blog/config"
|
|
||||||
"blog/models"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Album(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
PhotoTemplate := models.Template.Album
|
|
||||||
|
|
||||||
if err := r.ParseForm(); err != nil {
|
|
||||||
PhotoTemplate.WriteError(w, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
PhotoTemplate.WriteData(w, models.BuildViewData("Album", map[string]interface{}{
|
|
||||||
"memos_url": config.Cfg.MemosURL,
|
|
||||||
"memos_user": config.Cfg.MemosUser,
|
|
||||||
"memos_tag": config.Cfg.MemosAlbumTag,
|
|
||||||
}))
|
|
||||||
|
|
||||||
}
|
|
|
@ -15,7 +15,7 @@ func Article(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
path := models.ArticleShortUrlMap[key]
|
path := models.ArticleShortUrlMap[key]
|
||||||
|
|
||||||
articleDetail, err := models.ReadArticleDetail(path, key)
|
articleDetail, err := models.ReadArticleDetail(path)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
articleTemplate.WriteError(w, err)
|
articleTemplate.WriteError(w, err)
|
||||||
|
|
|
@ -15,7 +15,7 @@ func ExtraNav(w http.ResponseWriter, r *http.Request) {
|
||||||
name := r.Form.Get("name")
|
name := r.Form.Get("name")
|
||||||
for _, nav := range models.Navigation {
|
for _, nav := range models.Navigation {
|
||||||
if nav.Title == name {
|
if nav.Title == name {
|
||||||
articleDetail, err := models.ReadArticleDetail(nav.Path, "")
|
articleDetail, err := models.ReadArticleDetail(nav.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
extraNavTemplate.WriteError(w, err)
|
extraNavTemplate.WriteError(w, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"blog/config"
|
|
||||||
"blog/models"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Talk(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
TalkTemplate := models.Template.Talk
|
|
||||||
|
|
||||||
if err := r.ParseForm(); err != nil {
|
|
||||||
TalkTemplate.WriteError(w, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
TalkTemplate.WriteData(w, models.BuildViewData("Talk", map[string]interface{}{
|
|
||||||
"memos_url": config.Cfg.MemosURL,
|
|
||||||
"memos_user": config.Cfg.MemosUser,
|
|
||||||
"memos_tag": config.Cfg.MemosTalkTag,
|
|
||||||
"author": config.Cfg.Author,
|
|
||||||
"qq": config.Cfg.Qq,
|
|
||||||
}))
|
|
||||||
|
|
||||||
}
|
|
|
@ -139,22 +139,22 @@ func RecursiveReadArticles(dir string) (Articles, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadArticle(path string) (Article, error) {
|
func ReadArticle(path string) (Article, error) {
|
||||||
article, _, err := readMarkdown(path, "")
|
article, _, err := readMarkdown(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return article, err
|
return article, err
|
||||||
}
|
}
|
||||||
return article, nil
|
return article, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadArticleDetail(path, key string) (ArticleDetail, error) {
|
func ReadArticleDetail(path string) (ArticleDetail, error) {
|
||||||
_, articleDetail, err := readMarkdown(path, key)
|
_, articleDetail, err := readMarkdown(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return articleDetail, err
|
return articleDetail, err
|
||||||
}
|
}
|
||||||
return articleDetail, nil
|
return articleDetail, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readMarkdown(path, key string) (Article, ArticleDetail, error) {
|
func readMarkdown(path 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)
|
||||||
|
@ -171,9 +171,7 @@ func readMarkdown(path, key string) (Article, ArticleDetail, error) {
|
||||||
return article, articleDetail, err
|
return article, articleDetail, err
|
||||||
}
|
}
|
||||||
markdown = bytes.TrimSpace(markdown)
|
markdown = bytes.TrimSpace(markdown)
|
||||||
if key != "" {
|
|
||||||
article.ShortUrl = key
|
|
||||||
}
|
|
||||||
article.Path = path
|
article.Path = path
|
||||||
article.Category = GetCategoryName(path)
|
article.Category = GetCategoryName(path)
|
||||||
article.Title = strings.TrimSuffix(strings.ToUpper(mdFile.Name()), ".MD")
|
article.Title = strings.TrimSuffix(strings.ToUpper(mdFile.Name()), ".MD")
|
||||||
|
|
|
@ -12,8 +12,6 @@ type TemplatePointer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type HtmlTemplate struct {
|
type HtmlTemplate struct {
|
||||||
Talk TemplatePointer
|
|
||||||
Album TemplatePointer
|
|
||||||
Article TemplatePointer
|
Article TemplatePointer
|
||||||
Categories TemplatePointer
|
Categories TemplatePointer
|
||||||
Dashboard TemplatePointer
|
Dashboard TemplatePointer
|
||||||
|
@ -50,7 +48,7 @@ func initHtmlTemplate(viewDir string) (HtmlTemplate, error) {
|
||||||
var htmlTemplate HtmlTemplate
|
var htmlTemplate HtmlTemplate
|
||||||
|
|
||||||
tp, err := readHtmlTemplate(
|
tp, err := readHtmlTemplate(
|
||||||
[]string{"index", "extraNav", "dashboard", "categories", "article", "album", "talk"},
|
[]string{"index", "extraNav", "dashboard", "categories", "article"},
|
||||||
viewDir)
|
viewDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return htmlTemplate, err
|
return htmlTemplate, err
|
||||||
|
@ -61,8 +59,6 @@ func initHtmlTemplate(viewDir string) (HtmlTemplate, error) {
|
||||||
htmlTemplate.Dashboard = tp[2]
|
htmlTemplate.Dashboard = tp[2]
|
||||||
htmlTemplate.Categories = tp[3]
|
htmlTemplate.Categories = tp[3]
|
||||||
htmlTemplate.Article = tp[4]
|
htmlTemplate.Article = tp[4]
|
||||||
htmlTemplate.Album = tp[5]
|
|
||||||
htmlTemplate.Talk = tp[6]
|
|
||||||
|
|
||||||
return htmlTemplate, nil
|
return htmlTemplate, nil
|
||||||
}
|
}
|
||||||
|
@ -80,12 +76,12 @@ func readHtmlTemplate(htmlFileName []string, viewDir string) ([]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"
|
|
||||||
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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return htmlTemplate, err
|
return htmlTemplate, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,6 @@ func InitRoute() {
|
||||||
http.HandleFunc("/categories", controller.Category)
|
http.HandleFunc("/categories", controller.Category)
|
||||||
http.HandleFunc("/article", controller.Article)
|
http.HandleFunc("/article", controller.Article)
|
||||||
http.HandleFunc("/extra-nav", controller.ExtraNav)
|
http.HandleFunc("/extra-nav", controller.ExtraNav)
|
||||||
http.HandleFunc("/album", controller.Album)
|
|
||||||
http.HandleFunc("/talk", controller.Talk)
|
|
||||||
|
|
||||||
http.HandleFunc(config.Cfg.GitHookUrl, controller.GithubHook)
|
http.HandleFunc(config.Cfg.GitHookUrl, controller.GithubHook)
|
||||||
http.HandleFunc(config.Cfg.Dashboard, controller.Dashboard)
|
http.HandleFunc(config.Cfg.Dashboard, controller.Dashboard)
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
{{template "header" .}}
|
|
||||||
<div class="sub-title">- {{ .Title }} -</div>
|
|
||||||
<div class="gallery-photos page">
|
|
||||||
<img src="https://cdn.jsdelivr.net/gh/jkjoy/14e/img/loading.svg" style="margin:auto">
|
|
||||||
</div>
|
|
||||||
<link rel="stylesheet" href="https://cdn.staticfile.org/fancyapps-ui/4.0.27/fancybox.min.css" media="print" onload="this.media='all'">
|
|
||||||
<script src="https://cdn.staticfile.org/fancyapps-ui/4.0.27/fancybox.umd.min.js"></script>
|
|
||||||
<style>
|
|
||||||
/* 页面初始化 */
|
|
||||||
.page-title{display: none;}
|
|
||||||
.page-top-card {border-radius: 12px;}
|
|
||||||
/* 页面初始化结束 */
|
|
||||||
#article-container a img {margin: 0; border-radius:0;}
|
|
||||||
.gallery-photos{width:100%;margin-top: 10px;}
|
|
||||||
.gallery-photo{min-height:5rem;width:24.97%;padding:4px;position: relative;}
|
|
||||||
.gallery-photo a{display:block;overflow: hidden;border: var(--leonus-border);}
|
|
||||||
.gallery-photo img{display: block;width:100%;animation: fadeIn 1s;cursor: pointer;transition: all .4s ease-in-out !important;}
|
|
||||||
.gallery-photo span.photo-title,.gallery-photo span.photo-time{max-width: calc(100% - 7px);position:absolute;line-height:1.8;left:4px;font-size:14px;background: rgba(0, 0, 0, 0.3);padding:0px 8px;color: #fff;animation: fadeIn 1s;}
|
|
||||||
.gallery-photo span.photo-title{bottom:4px;}
|
|
||||||
.gallery-photo span.photo-time{top:4px;}
|
|
||||||
.gallery-photo:hover img{transform: scale(1.1);}
|
|
||||||
@media screen and (max-width: 1100px) {
|
|
||||||
.gallery-photo{width:33.3%;}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 900px) {.page-top-card {margin: 0;}}
|
|
||||||
@media screen and (max-width: 768px) {
|
|
||||||
.gallery-photo{width:49.9%;padding:3px}
|
|
||||||
.gallery-photo span.photo-time{display:none}
|
|
||||||
.page-top-card {border-radius: 8px;}
|
|
||||||
.gallery-photo span.photo-title{left:3px;bottom:3px;}
|
|
||||||
}
|
|
||||||
@keyframes fadeIn{0% {opacity: 0;}100%{opacity: 1;}}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
if (1) {
|
|
||||||
let url = '{{ .Data.memos_url }}' // 修改api
|
|
||||||
fetch(url + '/api/v1/memo?creatorId={{ .Data.memos_user }}&tag={{ .Data.memos_tag }}').then(res => res.json()).then(data => {
|
|
||||||
// let url = 'https://notes.starss.cc' // 修改api
|
|
||||||
// fetch(url + '/api/v1/memo?creatorId=JiXieShi&tag=相册').then(res => res.json()).then(data => {
|
|
||||||
let html = '',
|
|
||||||
imgs = []
|
|
||||||
data.forEach(item => {
|
|
||||||
let ls = item.content.match(/\!\[.*?\]\(.*?\)/g)
|
|
||||||
if (ls) imgs = imgs.concat(ls)
|
|
||||||
if (item.resourceList.length) {
|
|
||||||
item.resourceList.forEach(t => {
|
|
||||||
if (t.externalLink) imgs.push(``)
|
|
||||||
else imgs.push(``)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (imgs) imgs.forEach(item => {
|
|
||||||
let img = item.replace(/!\[.*?\]\((.*?)\)/g, '$1'),
|
|
||||||
time, title, tat = item.replace(/!\[(.*?)\]\(.*?\)/g, '$1')
|
|
||||||
if (tat.indexOf(' ') != -1) {
|
|
||||||
time = tat.split(' ')[0]
|
|
||||||
title = tat.split(' ')[1]
|
|
||||||
} else title = tat
|
|
||||||
|
|
||||||
html += `<div class="gallery-photo"><a href="${img}" data-fancybox="gallery" class="fancybox" data-thumb="${img}"><img class="no-lazyload photo-img" loading='lazy' decoding="async" src="${img}"></a>`
|
|
||||||
title ? html += `<span class="photo-title">${title}</span>` : ''
|
|
||||||
time ? html += `<span class="photo-time">${time}</span>` : ''
|
|
||||||
html += `</div>`
|
|
||||||
})
|
|
||||||
console.log(Fancybox);
|
|
||||||
document.querySelector('.gallery-photos.page').innerHTML = html
|
|
||||||
imgStatus.watch('.photo-img', () => { waterfall('.gallery-photos') })
|
|
||||||
window.Lately && Lately.init({ target: '.photo-time' })
|
|
||||||
}).catch()
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<script defer src="https://cdn.jsdelivr.net/gh/jkjoy/14e/js/waterfall.min.js"></script>
|
|
||||||
<script defer src="https://cdn.jsdelivr.net/gh/jkjoy/14e/js/imgStatus.min.js"></script>
|
|
||||||
<script defer src="https://cdn.jsdelivr.net/gh/jkjoy/14e/js/lately.min.js"></script>
|
|
||||||
{{template "footer" .}}
|
|
|
@ -47,5 +47,9 @@
|
||||||
document.getElementById('article').innerHTML = marked({{ .Data.Body }});
|
document.getElementById('article').innerHTML = marked({{ .Data.Body }});
|
||||||
</script>
|
</script>
|
||||||
<script src="/public/js/prism.js"></script>
|
<script src="/public/js/prism.js"></script>
|
||||||
{{template "reviews" .}}
|
{{if ne .Config.UtterancesRepo ""}}
|
||||||
|
<script src="https://utteranc.es/client.js" repo="{{ .Config.UtterancesRepo }}" issue-term="[{{ .Data.Title }}]"
|
||||||
|
theme="github-light" crossorigin="anonymous" async>
|
||||||
|
</script>
|
||||||
|
{{end}}
|
||||||
{{template "footer" .}}
|
{{template "footer" .}}
|
|
@ -60,12 +60,6 @@
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<a href="/blog">Blog</a>
|
<a href="/blog">Blog</a>
|
||||||
<a href="/categories">Categories</a>
|
<a href="/categories">Categories</a>
|
||||||
{{if ne .Config.MemosAlbumTag ""}}
|
|
||||||
<a href="/album">Album</a>
|
|
||||||
{{ end }}
|
|
||||||
{{if ne .Config.MemosTalkTag ""}}
|
|
||||||
<a href="/talk">Talk</a>
|
|
||||||
{{ end }}
|
|
||||||
{{range $nav := .Navs }}
|
{{range $nav := .Navs }}
|
||||||
<a href="/extra-nav?name={{ $nav.Title }}">{{ $nav.Title }}</a>
|
<a href="/extra-nav?name={{ $nav.Title }}">{{ $nav.Title }}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
{{define "reviews"}}
|
|
||||||
{{if ne .Config.UtterancesRepo ""}}
|
|
||||||
<script src="https://utteranc.es/client.js" repo="{{ .Config.UtterancesRepo }}" issue-term="[{{ .Data.Title }}]"
|
|
||||||
theme="github-light" crossorigin="anonymous" async>
|
|
||||||
</script>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if ne .Config.Gitalk_Repo ""}}
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css">
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js"></script>
|
|
||||||
<div id="gitalk-container"></div>
|
|
||||||
<script>
|
|
||||||
var gitalk = new Gitalk({
|
|
||||||
title: "{{ .Data.Title }}",
|
|
||||||
clientID: "{{ .Config.Gitalk_ClientID }}",
|
|
||||||
clientSecret: "{{ .Config.Gitalk_ClientSecret }}",
|
|
||||||
repo: "{{ .Config.Gitalk_Repo }}",
|
|
||||||
owner: "{{ .Config.Gitalk_Owner }}",
|
|
||||||
admin: "[{{ .Config.Gitalk_Owner }}]",
|
|
||||||
id: "{{ .Data.ShortUrl }}", // Ensure uniqueness and length less than 50
|
|
||||||
distractionFreeMode: false // Facebook-like distraction free mode
|
|
||||||
})
|
|
||||||
gitalk.render('gitalk-container')
|
|
||||||
</script>
|
|
||||||
{{end}}
|
|
||||||
{{ end }}
|
|
|
@ -369,20 +369,19 @@ hr:after{
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.search-box{
|
.search-box{
|
||||||
height: 36px;
|
height: 40px;
|
||||||
display: flex;
|
display: flex;
|
||||||
border-radius: 16px;
|
border-radius: 2px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border: 1px solid #673ab7;
|
border: 1px solid #673ab7;
|
||||||
border: 2px solid var(--primary,#673ab7);
|
border: 1px solid var(--primary,#673ab7);
|
||||||
width: 320px;
|
width: 320px;
|
||||||
}
|
}
|
||||||
.search-input{
|
.search-input{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 16px;border-radius: 16px;
|
|
||||||
height: 30px;
|
height: 30px;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,263 +0,0 @@
|
||||||
{{template "header" .}}
|
|
||||||
<div class="sub-title">- {{ .Title }} -</div>
|
|
||||||
<style>
|
|
||||||
/* 页面初始化 */
|
|
||||||
div#page {
|
|
||||||
background: none;
|
|
||||||
border: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme=dark] #twikoo .tk-content,
|
|
||||||
#twikoo .tk-content {
|
|
||||||
padding: 0;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.talk_item,
|
|
||||||
.tk-expand,
|
|
||||||
.tk-comments-container>.tk-comment,
|
|
||||||
.tk-submit:nth-child(1){
|
|
||||||
background: var(--card-bg);
|
|
||||||
border: 1px solid #e0e3ed;
|
|
||||||
box-shadow: 0 5px 10px rgb(189 189 189 / 10%);
|
|
||||||
transition: all .3s ease-in-out;
|
|
||||||
border-radius: 12px;
|
|
||||||
}
|
|
||||||
.talk_item:hover,
|
|
||||||
.tk-comments-container>.tk-comment:hover,
|
|
||||||
.tk-submit:nth-child(1):hover {
|
|
||||||
border-color: #49b1f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tk-submit {
|
|
||||||
padding: 20px 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tk-comments-container>.tk-comment {
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 页面初始化结束 */
|
|
||||||
|
|
||||||
#talk{
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#talk .loading {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
#talk .loading img {
|
|
||||||
width: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.talk_item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 20px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
margin: 0 !important;
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.talk_bottom,
|
|
||||||
.talk_meta {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
.talk_bottom{
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.info {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
span.talk_nick {
|
|
||||||
color: #6dbdc3;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
svg.is-badge.icon {
|
|
||||||
width: 15px;
|
|
||||||
margin-left: 5px;
|
|
||||||
padding-top: 3px;
|
|
||||||
}
|
|
||||||
span.talk_date {
|
|
||||||
opacity: .6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.talk_content {
|
|
||||||
line-height: 1.5;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
.zone_imgbox {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
--w: calc(25% - 8px);
|
|
||||||
gap: 10px;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
.zone_imgbox a {
|
|
||||||
display: block;
|
|
||||||
border-radius: 12px;
|
|
||||||
width: var(--w);
|
|
||||||
aspect-ratio: 1/1;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.zone_imgbox img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0 !important;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
/* 底部 */
|
|
||||||
|
|
||||||
.talk_bottom {
|
|
||||||
opacity: .9;
|
|
||||||
}
|
|
||||||
.talk_bottom .icon {
|
|
||||||
color: var(--font-color);
|
|
||||||
float: right;
|
|
||||||
transition: all .3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.talk_bottom .icon:hover {
|
|
||||||
color: #49b1f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.talk_tag{
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.talk_content>a {
|
|
||||||
margin: 0 3px;
|
|
||||||
color: #ff7d73 !important;
|
|
||||||
}
|
|
||||||
.talk_content>a:hover{
|
|
||||||
text-decoration: none !important;
|
|
||||||
color: #ff5143 !important
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 提醒 */
|
|
||||||
|
|
||||||
.limit {
|
|
||||||
transition: all .3s ease-in-out;
|
|
||||||
color: rgba(76, 73, 72, 0.6);
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme=dark] .limit {
|
|
||||||
color: rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.limit {
|
|
||||||
display: none;
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 20px;
|
|
||||||
color: var(--font-color);
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 900px) {
|
|
||||||
.zone_imgbox {
|
|
||||||
--w: calc(33% - 5px);
|
|
||||||
}
|
|
||||||
#talk{
|
|
||||||
margin: 10px 3px 0
|
|
||||||
}
|
|
||||||
#post-comment{
|
|
||||||
margin: 0 3px
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
|
||||||
.zone_imgbox {
|
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
.zone_imgbox {
|
|
||||||
--w: calc(50% - 3px);
|
|
||||||
}
|
|
||||||
span.talk_date {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div id="talk">
|
|
||||||
<div class='loading'><img src="/img/loading.svg" alt="加载中..."></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="limit">- 只展示最近30条说说 -</div>
|
|
||||||
<script>
|
|
||||||
if(1) {
|
|
||||||
let url = '{{ .Data.memos_url }}'
|
|
||||||
fetch(url + '/api/v1/memo?creatorId={{ .Data.memos_user }}&tag={{ .Data.memos_tag }}&limit=30').then(res => res.json()).then(data => { // 注意修改域名和用户id
|
|
||||||
let items = [],
|
|
||||||
html = '',
|
|
||||||
icon = '<svg viewBox="0 0 512 512"xmlns="http://www.w3.org/2000/svg"class="is-badge icon"><path d="m512 268c0 17.9-4.3 34.5-12.9 49.7s-20.1 27.1-34.6 35.4c.4 2.7.6 6.9.6 12.6 0 27.1-9.1 50.1-27.1 69.1-18.1 19.1-39.9 28.6-65.4 28.6-11.4 0-22.3-2.1-32.6-6.3-8 16.4-19.5 29.6-34.6 39.7-15 10.2-31.5 15.2-49.4 15.2-18.3 0-34.9-4.9-49.7-14.9-14.9-9.9-26.3-23.2-34.3-40-10.3 4.2-21.1 6.3-32.6 6.3-25.5 0-47.4-9.5-65.7-28.6-18.3-19-27.4-42.1-27.4-69.1 0-3 .4-7.2 1.1-12.6-14.5-8.4-26-20.2-34.6-35.4-8.5-15.2-12.8-31.8-12.8-49.7 0-19 4.8-36.5 14.3-52.3s22.3-27.5 38.3-35.1c-4.2-11.4-6.3-22.9-6.3-34.3 0-27 9.1-50.1 27.4-69.1s40.2-28.6 65.7-28.6c11.4 0 22.3 2.1 32.6 6.3 8-16.4 19.5-29.6 34.6-39.7 15-10.1 31.5-15.2 49.4-15.2s34.4 5.1 49.4 15.1c15 10.1 26.6 23.3 34.6 39.7 10.3-4.2 21.1-6.3 32.6-6.3 25.5 0 47.3 9.5 65.4 28.6s27.1 42.1 27.1 69.1c0 12.6-1.9 24-5.7 34.3 16 7.6 28.8 19.3 38.3 35.1 9.5 15.9 14.3 33.4 14.3 52.4zm-266.9 77.1 105.7-158.3c2.7-4.2 3.5-8.8 2.6-13.7-1-4.9-3.5-8.8-7.7-11.4-4.2-2.7-8.8-3.6-13.7-2.9-5 .8-9 3.2-12 7.4l-93.1 140-42.9-42.8c-3.8-3.8-8.2-5.6-13.1-5.4-5 .2-9.3 2-13.1 5.4-3.4 3.4-5.1 7.7-5.1 12.9 0 5.1 1.7 9.4 5.1 12.9l58.9 58.9 2.9 2.3c3.4 2.3 6.9 3.4 10.3 3.4 6.7-.1 11.8-2.9 15.2-8.7z"fill="#1da1f2"></path></svg>';
|
|
||||||
data.forEach(item => { items.push(Format(item)) });
|
|
||||||
if (items.length == 30) document.querySelector('.limit').style.display = 'block';
|
|
||||||
items.forEach(item => {
|
|
||||||
html += `<div class="talk_item"><div class="talk_meta"><img class="no-lightbox no-lazyload avatar" src="https://q1.qlogo.cn/g?b=qq&nk={{ .Data.qq }}&s=5"><div class="info"><span class="talk_nick">{{ .Data.author }}${icon}</span><span class="talk_date">${item.date}</span></div></div><div class="talk_content">${item.content}</div><div class="talk_bottom"><div><span class="talk_tag"># ${item.tag}</span></div><a href="javascript:;"onclick="goComment('${item.text}')"><span class="icon"><i class="fa-solid fa-message fa-fw"></i></span></a></div></div>` // 注意修改头像链接和名称
|
|
||||||
})
|
|
||||||
document.getElementById('talk').innerHTML = html
|
|
||||||
})
|
|
||||||
// 页面评论
|
|
||||||
function goComment(e) {
|
|
||||||
var n = document.querySelector(".el-textarea__inner")
|
|
||||||
n.value = `> ${e}\n\n`;
|
|
||||||
n.focus();
|
|
||||||
btf.snackbarShow("无需删除空行,直接输入评论即可", !1, 2e3);
|
|
||||||
}
|
|
||||||
// 页面内容格式化
|
|
||||||
function Format(item) {
|
|
||||||
let date = getTime(new Date(item.createdTs * 1000).toString()),
|
|
||||||
content = item.content,
|
|
||||||
tag = item.content.match(/\{(.*?)\}/g),
|
|
||||||
imgs = content.match(/!\[.*\]\(.*?\)/g),
|
|
||||||
text = ''
|
|
||||||
if (imgs) imgs = imgs.map(item => { return item.replace(/!\[.*\]\((.*?)\)/, '$1') })
|
|
||||||
if (item.resourceList.length) {
|
|
||||||
if (!imgs) imgs = []
|
|
||||||
item.resourceList.forEach(t => {
|
|
||||||
if (t.externalLink) imgs.push(t.externalLink)
|
|
||||||
else imgs.push(`${url}/o/r/${t.id}/${t.publicId}/${t.filename}`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
text = content.replace(/#(.*?)\s/g, '').replace(/\!?\[(.*?)\]\((.*?)\)/g, '').replace(/\{(.*?)\}/g, '')
|
|
||||||
content = text.replace(/\[(.*?)\]\((.*?)\)/g, `<a href="$2">@$1</a>`);
|
|
||||||
if (imgs) {
|
|
||||||
content += `<div class="zone_imgbox">`
|
|
||||||
imgs.forEach(e => content += `<a href="${e}" data-fancybox="gallery" class="fancybox" data-thumb="${e}"><img class="no-lazyload" src="${e}"></a>` // 2023-02-06更新
|
|
||||||
)
|
|
||||||
content += '</div>'
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
content: content,
|
|
||||||
tag: tag ? tag[0].replace(/\{(.*?)\}/,'$1') : '无标签',
|
|
||||||
date: date,
|
|
||||||
text: text.replace(/\[(.*?)\]\((.*?)\)/g, '[链接]' + `${imgs?'[图片]':''}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 页面时间格式化
|
|
||||||
function getTime(time) {
|
|
||||||
let d = new Date(time),
|
|
||||||
ls = [d.getFullYear(), d.getMonth() + 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()];
|
|
||||||
for (let i = 0; i < ls.length; i++) {
|
|
||||||
ls[i] = ls[i] <= 9 ? '0' + ls[i] : ls[i] + ''
|
|
||||||
}
|
|
||||||
if (new Date().getFullYear() == ls[0]) return ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4]
|
|
||||||
else return ls[0] + '年' + ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{{template "footer" .}}
|
|
4
配置说明.md
4
配置说明.md
|
@ -8,10 +8,6 @@
|
||||||
- "webHookSecret": 博客文章更新勾子的密钥,这里要和你在仓库设置的密钥一样,
|
- "webHookSecret": 博客文章更新勾子的密钥,这里要和你在仓库设置的密钥一样,
|
||||||
- "categoryDisplayQuantity": 在分类页面下,每个分类下最多展示多少篇文章,
|
- "categoryDisplayQuantity": 在分类页面下,每个分类下最多展示多少篇文章,
|
||||||
- "utterancesRepo": 是否开启utterances评论,留空没有评论,否则填写评论存储的仓库name/repo,
|
- "utterancesRepo": 是否开启utterances评论,留空没有评论,否则填写评论存储的仓库name/repo,
|
||||||
- "gitalk_repo": 是否开启Gitalks评论,留空没有评论,否则填写评论存储的仓库repo,
|
|
||||||
- "gitalk_clientID": 应用id,
|
|
||||||
- "gitalk_clientSecret": 应用授权密钥,
|
|
||||||
- "gitalk_owner": 仓库所有者,
|
|
||||||
- "timeLayout": 解析时间的格式,保持和你文章里面的date字段一样,除非了解Golang的时间解析,否则不要修改,
|
- "timeLayout": 解析时间的格式,保持和你文章里面的date字段一样,除非了解Golang的时间解析,否则不要修改,
|
||||||
- "siteName": 网站的名字,
|
- "siteName": 网站的名字,
|
||||||
- "documentGitUrl": 你文章的git地址,应用会把文章克隆在当前目录下,必须公开并且以.git结尾,
|
- "documentGitUrl": 你文章的git地址,应用会把文章克隆在当前目录下,必须公开并且以.git结尾,
|
||||||
|
|
Loading…
Reference in New Issue