fix: custom page support embed

This commit is contained in:
henry.chen
2025-07-21 20:07:26 +08:00
parent b69248f6a4
commit aee4194c71
9 changed files with 77 additions and 10 deletions

View File

@@ -16,6 +16,11 @@ pages:
- name: 自定义页面
path: /page/custom.html
showinnav: true
isembed: false
- name: 自定义页面2
path: /page/custom2.html
showinnav: true
isembed: true
general: # 常规配置
pagenum: 10 # 首页展示文章数量
pagesize: 20 # 管理界面

View File

@@ -0,0 +1,11 @@
{{define "custom2.html"}}
<title>Custom Page</title>
<div id=content class=inner>
<article class="post" itemscope itemtype="http://schema.org/Article">
<h1 class=title itemprop=headline>Custom Page</h1>
<div class="entry-content" itemprop=articleBody>
<p>Custom Page</p>
</div>
</article>
</div>
{{end}}

View File

@@ -1 +1 @@
<!DOCTYPE html><html lang="zh-cn"><head><meta charset="utf-8"><meta content="width=device-width,minimum-scale=1.0" name="viewport"><meta name="format-detection" content="telephone=no"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="referrer" content="always"><title>{{.Title}}</title>{{.AdSense}}<script>!function(n,t){function e(){o("nls",1)}function c(){t.documentElement.style.display="none",u(),location.reload()}function r(n){var t="";try{t=f[n]||"",t.length<99&&c()}catch(e){u()}return t}function i(n,t){try{f[n]=t,t!==f[n]&&u()}catch(e){u()}}function o(n,e){var c=999;e||(c=-1),c=new Date(+new Date+864e5*c).toGMTString();var r=n+"="+e+";path=/;secure;expires="+c;t.cookie=r}function a(n){var e=t.getElementById(n).innerHTML;i(n,e)}function l(e,c){var i=r(e),o=t.createElement(c?"script":"style");return n.execScript&&c?n.execScript(i):(o.innerHTML=i,void t.head.appendChild(o))}function u(){o("v",0)}var f,h=function(){},d=n.L={h:h,l:h,c:h};try{f=localStorage,d.h=a,d.l=l,d.c=o}catch(p){e()}}(this,document);</script>{{if .Version}}<script>L.c('v', {{.Version}})</script>{{end}}<link rel="apple-touch-icon" href="//{{.Qiniu.Domain}}/static/img/favicon.ico"><link rel="search" type="application/opensearchdescription+xml" href="//{{.Domain}}/opensearch.xml" title="{{.BTitle}}">{{if .Version}}<style id="blog_css">{{template "blog_css" .}}</style><script>L.h('blog_css')</script>{{else}}<script>L.l("blog_css")</script>{{end}}<link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="//{{.Domain}}/rss.html"><meta name="description" content="{{.Description}}"><meta name="twitter:card" content={{.Twitter.Card}}><meta name="twitter:site" content="@{{.Twitter.Site}}"><meta name="twitter:title" content="{{.Title}}"><meta name="twitter:description" content="{{.Description}}"><meta name="twitter:image" content="https://{{.Twitter.Image}}"></head><body><div class="container"><div class="left-col"><div class="intrude-less"><header id="header" class="inner"><div class="profilepic"><a href="/"></a></div><h1><a href="/">{{.BlogName}}</a></h1><p class="subtitle">{{.SubTitle}}</p><nav id="main-nav"><ul><li {{if eq .Path "/"}}class="on" {{end}}><a href="/"><span>首页</span></a></li><li {{if eq .Path "/series.html"}}class="on" {{end}}><a href="/series.html"><span>专题</span></a></li><li {{if eq .Path "/archives.html"}}class="on" {{end}}><a href="/archives.html"><span>归档</span></a></li><li {{if eq .Path "/post/blogroll.html"}}class="on" {{end}}><a href="/post/blogroll.html"><span>友链</span></a></li><li {{if eq .Path "/post/about.html"}}class="on" {{end}}><a href="/post/about.html"><span>关于</span></a></li>{{range $index, $element := .Pages}}{{if $element.ShowInNav}}<li {{if eq .Path $element.Path}}class="on" {{end}}><a href="{{$element.Path}}" target="_blank"><span>{{$element.Name}}</span></a></li>{{end}}{{end}}</ul></nav><nav id="sub-nav"><div class="social"><a target="_blank" class="twitter external" rel="nofollow" href="//{{.Twitter.Address}}" title="Twitter" aria-label="Twitter">Twitter</a><a target="_blank" class="rss" href="//{{.Domain}}/rss.html" title="RSS 订阅" aria-label="RSS 订阅">RSS</a><a class="search" href="/search.html" title="站内搜索" aria-label="站内搜索">Search</a></div></nav></header></div></div><div class="mid-col"><div class="mid-col-container">{{.LayoutContent}}</div><footer id=footer class=inner>© {{.CopyYear}} - {{.BTitle}}{{if .BeiAn}} - <a target="_blank" rel="nofollow designer" class="external beian" href="https://beian.miit.gov.cn">{{.BeiAn}}</a>{{end}}<br>Powered by <a target=_blank href="//github.com/eiblog/eiblog">Eiblog</a> & <a target=_blank rel="nofollow designer" class=external href="//github.com/deepzz0">Deepzz</a></footer></div></div><input type=hidden id=CURRENT_PAGE value="{{.CurrentPage}}"><input type=hidden id=CDN_DOMAIN value="//{{.Qiniu.Domain}}">{{if .Version}}<script id="ana_js">{{template "ana_js"}}</script><script>L.h('ana_js')</script>{{else}}<script>L.l('ana_js', 1)</script>{{end}}{{if .Version}}<script id="jq_js">{{template "jq_js"}}</script><script>L.h('jq_js')</script>{{else}}<script>L.l('jq_js', 1)</script>{{end}}{{if .Version}}<script id="hl_js">{{template "hl_js"}}</script><script>L.h('hl_js')</script>{{else}}<script>L.l('hl_js', 1)</script>{{end}}{{if .Version}}<script id="blog_js">{{template "blog_js" .}}</script><script>L.h('blog_js')</script>{{else}}<script>L.l('blog_js', 1)</script>{{end}}</body></html>
<!DOCTYPE html><html lang="zh-cn"><head><meta charset="utf-8"><meta content="width=device-width,minimum-scale=1.0" name="viewport"><meta name="format-detection" content="telephone=no"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="referrer" content="always"><title>{{.Title}}</title>{{.AdSense}}<script>!function(n,t){function e(){o("nls",1)}function c(){t.documentElement.style.display="none",u(),location.reload()}function r(n){var t="";try{t=f[n]||"",t.length<99&&c()}catch(e){u()}return t}function i(n,t){try{f[n]=t,t!==f[n]&&u()}catch(e){u()}}function o(n,e){var c=999;e||(c=-1),c=new Date(+new Date+864e5*c).toGMTString();var r=n+"="+e+";path=/;secure;expires="+c;t.cookie=r}function a(n){var e=t.getElementById(n).innerHTML;i(n,e)}function l(e,c){var i=r(e),o=t.createElement(c?"script":"style");return n.execScript&&c?n.execScript(i):(o.innerHTML=i,void t.head.appendChild(o))}function u(){o("v",0)}var f,h=function(){},d=n.L={h:h,l:h,c:h};try{f=localStorage,d.h=a,d.l=l,d.c=o}catch(p){e()}}(this,document);</script>{{if .Version}}<script>L.c('v', {{.Version}})</script>{{end}}<link rel="apple-touch-icon" href="//{{.Qiniu.Domain}}/static/img/favicon.ico"><link rel="search" type="application/opensearchdescription+xml" href="//{{.Domain}}/opensearch.xml" title="{{.BTitle}}">{{if .Version}}<style id="blog_css">{{template "blog_css" .}}</style><script>L.h('blog_css')</script>{{else}}<script>L.l("blog_css")</script>{{end}}<link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="//{{.Domain}}/rss.html"><meta name="description" content="{{.Description}}"><meta name="twitter:card" content={{.Twitter.Card}}><meta name="twitter:site" content="@{{.Twitter.Site}}"><meta name="twitter:title" content="{{.Title}}"><meta name="twitter:description" content="{{.Description}}"><meta name="twitter:image" content="https://{{.Twitter.Image}}"></head><body><div class="container"><div class="left-col"><div class="intrude-less"><header id="header" class="inner"><div class="profilepic"><a href="/"></a></div><h1><a href="/">{{.BlogName}}</a></h1><p class="subtitle">{{.SubTitle}}</p><nav id="main-nav"><ul><li {{if eq .Path "/"}}class="on" {{end}}><a href="/"><span>首页</span></a></li><li {{if eq .Path "/series.html"}}class="on" {{end}}><a href="/series.html"><span>专题</span></a></li><li {{if eq .Path "/archives.html"}}class="on" {{end}}><a href="/archives.html"><span>归档</span></a></li><li {{if eq .Path "/post/blogroll.html"}}class="on" {{end}}><a href="/post/blogroll.html"><span>友链</span></a></li><li {{if eq .Path "/post/about.html"}}class="on" {{end}}><a href="/post/about.html"><span>关于</span></a></li>{{range $index, $element := .Pages}}{{if .ShowInNav}}<li {{if eq $.Path .Path}}class="on" {{end}}><a href="{{.Path}}" {{if not .IsEmbed}}target="_blank"{{end}}><span>{{.Name}}</span></a></li>{{end}}{{end}}</ul></nav><nav id="sub-nav"><div class="social"><a target="_blank" class="twitter external" rel="nofollow" href="//{{.Twitter.Address}}" title="Twitter" aria-label="Twitter">Twitter</a><a target="_blank" class="rss" href="//{{.Domain}}/rss.html" title="RSS 订阅" aria-label="RSS 订阅">RSS</a><a class="search" href="/search.html" title="站内搜索" aria-label="站内搜索">Search</a></div></nav></header></div></div><div class="mid-col"><div class="mid-col-container">{{.LayoutContent}}</div><footer id=footer class=inner>© {{.CopyYear}} - {{.BTitle}}{{if .BeiAn}} - <a target="_blank" rel="nofollow designer" class="external beian" href="https://beian.miit.gov.cn">{{.BeiAn}}</a>{{end}}<br>Powered by <a target=_blank href="//github.com/eiblog/eiblog">Eiblog</a> & <a target=_blank rel="nofollow designer" class=external href="//github.com/deepzz0">Deepzz</a></footer></div></div><input type=hidden id=CURRENT_PAGE value="{{.CurrentPage}}"><input type=hidden id=CDN_DOMAIN value="//{{.Qiniu.Domain}}">{{if .Version}}<script id="ana_js">{{template "ana_js"}}</script><script>L.h('ana_js')</script>{{else}}<script>L.l('ana_js', 1)</script>{{end}}{{if .Version}}<script id="jq_js">{{template "jq_js"}}</script><script>L.h('jq_js')</script>{{else}}<script>L.l('jq_js', 1)</script>{{end}}{{if .Version}}<script id="hl_js">{{template "hl_js"}}</script><script>L.h('hl_js')</script>{{else}}<script>L.l('hl_js', 1)</script>{{end}}{{if .Version}}<script id="blog_js">{{template "blog_js" .}}</script><script>L.h('blog_js')</script>{{else}}<script>L.l('blog_js', 1)</script>{{end}}</body></html>

View File

@@ -20,7 +20,7 @@ import (
var (
XMLTemplate *template.Template // template/xml模板
HTMLTemplate *template.Template // website/html模板
HTMLTemplate *template.Template // page/html | website/html模板
Store store.Store // 数据库存储
Ei *Cache // 博客数据缓存
@@ -49,6 +49,11 @@ func init() {
// should not read dir & .DS_Store
return strings.HasPrefix(fi.Name(), ".")
})
root = filepath.Join(config.EtcDir, "page")
pageFiles := tools.ReadDirFiles(root, func(fi fs.DirEntry) bool {
return !strings.HasSuffix(fi.Name(), ".html")
})
files = append(files, pageFiles...)
HTMLTemplate, err = template.New("eiblog").Funcs(tools.TplFuncMap).ParseFiles(files...)
if err != nil {
logrus.Fatal("init html template: ", err)

View File

@@ -1,4 +1,4 @@
package page
package pages
import (
"bytes"

View File

@@ -1,4 +1,4 @@
package page
package pages
import (
"bytes"
@@ -14,6 +14,7 @@ import (
"github.com/eiblog/eiblog/cmd/eiblog/config"
"github.com/eiblog/eiblog/cmd/eiblog/handler/internal"
pconfig "github.com/eiblog/eiblog/pkg/config"
"github.com/eiblog/eiblog/pkg/third/disqus"
"github.com/eiblog/eiblog/tools"
@@ -382,16 +383,53 @@ func handleBeaconPage(c *gin.Context) {
c.Status(http.StatusNoContent)
}
// handleCustomPage 自定义页面
func handleCustomPage(c *gin.Context) {
path := c.Request.URL.Path
if !strings.HasSuffix(path, ".html") {
handleNotFound(c)
return
}
// find config
var page *pconfig.CustomPage
for _, p := range config.Conf.Pages {
if p.Path == path {
page = &p
break
}
}
if page == nil {
handleNotFound(c)
return
}
var params gin.H
if page.IsEmbed {
params = baseFEParams(c)
params["Path"] = c.Request.URL.Path
params["Title"] = page.Name + " | " + internal.Ei.Blogger.SubTitle
}
// serve custom page
name := c.Param("path")
renderHTMLHomeLayout(c, name, params)
}
// renderHTMLHomeLayout homelayout html
func renderHTMLHomeLayout(c *gin.Context, name string, data gin.H) {
c.Header("Content-Type", "text/html; charset=utf-8")
// special page
if name == "disqus.html" {
switch {
case name == "disqus.html":
err := internal.HTMLTemplate.ExecuteTemplate(c.Writer, name, data)
if err != nil {
panic(err)
}
return
case data == nil:
err := internal.HTMLTemplate.ExecuteTemplate(c.Writer, name, nil)
if err != nil {
panic(err)
}
return
}
buf := bytes.Buffer{}
err := internal.HTMLTemplate.ExecuteTemplate(&buf, name, data)

View File

@@ -1,9 +1,14 @@
package page
package pages
import (
"github.com/gin-gonic/gin"
)
// RegisterRoutesCustomPages 注册自定义页面
func RegisterRoutesCustomPages(e *gin.Engine) {
e.GET("/page/:path", handleCustomPage)
}
// RegisterRoutes register routes
func RegisterRoutes(e *gin.Engine) {
e.NoRoute(handleNotFound)

View File

@@ -7,7 +7,7 @@ import (
"github.com/eiblog/eiblog/cmd/eiblog/config"
"github.com/eiblog/eiblog/cmd/eiblog/handler/admin"
"github.com/eiblog/eiblog/cmd/eiblog/handler/file"
"github.com/eiblog/eiblog/cmd/eiblog/handler/page"
"github.com/eiblog/eiblog/cmd/eiblog/handler/pages"
"github.com/eiblog/eiblog/cmd/eiblog/handler/swag"
"github.com/eiblog/eiblog/pkg/middleware"
@@ -44,20 +44,21 @@ func runHTTPServer(endRun chan error) {
// static files, page
e.Static("/static", filepath.Join(config.EtcDir, "assets"))
// custom pages
e.Static("/page", filepath.Join(config.EtcDir, "page"))
pages.RegisterRoutesCustomPages(e)
// static files
file.RegisterRoutes(e)
// frontend pages
page.RegisterRoutes(e)
pages.RegisterRoutes(e)
// unauthz api
admin.RegisterRoutes(e)
// admin router
group := e.Group("/admin", middleware.AuthFilter)
{
page.RegisterRoutesAuthz(group)
pages.RegisterRoutesAuthz(group)
admin.RegisterRoutesAuthz(group)
}

View File

@@ -127,4 +127,6 @@ type CustomPage struct {
Path string
// 是否显示在导航栏, 如 true
ShowInNav bool
// 是否嵌入, 如 true
IsEmbed bool
}