diff --git a/blog/blog_test.go b/blog/blog_test.go index 32a62b3..41424f5 100644 --- a/blog/blog_test.go +++ b/blog/blog_test.go @@ -175,7 +175,11 @@ func TestBlogWorkflow(t *testing.T) { router.SetFuncMap(template.FuncMap{ "rawHTML": func(s string) template.HTML { return template.HTML(s) }, }) - router.LoadHTMLGlob("../themes/default/templates/*") + tmpl := template.Must(template.New("").Funcs(template.FuncMap{ + "rawHTML": func(s string) template.HTML { return template.HTML(s) }, + }).ParseGlob("../templates/shared/*.html")) + template.Must(tmpl.ParseGlob("../themes/default/templates/*.html")) + router.SetHTMLTemplate(tmpl) a.On("IsAdmin", mock.Anything).Return(false).Once() a.On("IsLoggedIn", mock.Anything).Return(false) jsonValue, _ = json.Marshal("") diff --git a/goblog.go b/goblog.go index 331bc90..8e047ba 100644 --- a/goblog.go +++ b/goblog.go @@ -374,12 +374,17 @@ func main() { } themePath := filepath.Join("themes", theme) + "/" log.Println("Loading theme: " + theme) - tmpl, err := template.New("").Funcs(funcMap).ParseGlob(themePath + "templates/*.html") + // Load shared templates first, then theme templates + tmpl, err := template.New("").Funcs(funcMap).ParseGlob("templates/shared/*.html") + if err != nil { + log.Fatalf("Failed to load shared templates: %v", err) + } + tmpl, err = tmpl.ParseGlob(themePath + "templates/*.html") if err != nil { log.Printf("Warning: failed to load theme %q: %v — falling back to default", theme, err) theme = "default" themePath = "themes/default/" - tmpl = template.Must(template.New("").Funcs(funcMap).ParseGlob(themePath + "templates/*.html")) + tmpl = template.Must(template.Must(template.New("").Funcs(funcMap).ParseGlob("templates/shared/*.html")).ParseGlob(themePath + "templates/*.html")) } router.SetHTMLTemplate(tmpl) activeTheme = theme diff --git a/templates/shared/_head.html b/templates/shared/_head.html new file mode 100644 index 0000000..9a34064 --- /dev/null +++ b/templates/shared/_head.html @@ -0,0 +1,79 @@ +{{ define "_head" }} + + + + + + + + + + {{ if .post }} + + + + + + + + + + {{ range .post.Tags }} + + {{ end }} + {{ .settings.site_title.Value }}: {{ .post.Title }} + + {{ else }} + + {{ .settings.site_title.Value }}: {{ .title }} + {{ end }} + + + {{ if .admin_page }} + + + + + {{ end }} + {{ if or .admin_page .post }} + + + {{ end }} + + + + + + + {{ if .admin_page }} + + + + + {{ end }} + + {{ with index .settings "custom_header_code" }}{{ if .Value }} + {{ .Value | rawHTML }} + {{ end }}{{ end }} + {{ with .plugin_head_html }}{{ . | rawHTML }}{{ end }} + +{{ end }} diff --git a/themes/default/templates/header.html b/themes/default/templates/header.html index 9c29cd6..ffe0ea3 100644 --- a/themes/default/templates/header.html +++ b/themes/default/templates/header.html @@ -1,83 +1,4 @@ - - - - - - - - - - {{ if .post }} - - - - - - - - - - {{ range .post.Tags }} - - {{ end }} - {{ .settings.site_title.Value }}: {{ .post.Title }} - - {{ else }} - - {{ .settings.site_title.Value }}: {{ .title }} - {{ end }} - - - - - {{ if .admin_page }} - - - - - {{ end }} - {{ if or .admin_page .post }} - - - {{ end }} - - - - - - - {{ if .admin_page }} - - - - - {{ end }} - - - {{ with index .settings "custom_header_code" }}{{ if .Value }} - {{ .Value | rawHTML }} - {{ end }}{{ end }} - {{ with .plugin_head_html }}{{ . | rawHTML }}{{ end }} - +{{ template "_head" . }} -
\ No newline at end of file +
diff --git a/themes/forest/templates/header.html b/themes/forest/templates/header.html index 5d33b88..20153bb 100644 --- a/themes/forest/templates/header.html +++ b/themes/forest/templates/header.html @@ -1,83 +1,4 @@ - - - - - - - - - - {{ if .post }} - - - - - - - - - - {{ range .post.Tags }} - - {{ end }} - {{ .settings.site_title.Value }}: {{ .post.Title }} - - {{ else }} - - {{ .settings.site_title.Value }}: {{ .title }} - {{ end }} - - - - - {{ if .admin_page }} - - - - - {{ end }} - {{ if or .admin_page .post }} - - - {{ end }} - - - - - - - {{ if .admin_page }} - - - - - {{ end }} - - - {{ with index .settings "custom_header_code" }}{{ if .Value }} - {{ .Value | rawHTML }} - {{ end }}{{ end }} - {{ with .plugin_head_html }}{{ . | rawHTML }}{{ end }} - +{{ template "_head" . }}
-
\ No newline at end of file +
diff --git a/themes/minimal/templates/header.html b/themes/minimal/templates/header.html index 5191bbf..a27c7d0 100644 --- a/themes/minimal/templates/header.html +++ b/themes/minimal/templates/header.html @@ -1,83 +1,4 @@ - - - - - - - - - - {{ if .post }} - - - - - - - - - - {{ range .post.Tags }} - - {{ end }} - {{ .settings.site_title.Value }}: {{ .post.Title }} - - {{ else }} - - {{ .settings.site_title.Value }}: {{ .title }} - {{ end }} - - - - - {{ if .admin_page }} - - - - - {{ end }} - {{ if or .admin_page .post }} - - - {{ end }} - - - - - - - {{ if .admin_page }} - - - - - {{ end }} - - - {{ with index .settings "custom_header_code" }}{{ if .Value }} - {{ .Value | rawHTML }} - {{ end }}{{ end }} - {{ with .plugin_head_html }}{{ . | rawHTML }}{{ end }} - +{{ template "_head" . }}
-
\ No newline at end of file +
diff --git a/tools/migrate.go b/tools/migrate.go index 7369a81..aea8c3f 100644 --- a/tools/migrate.go +++ b/tools/migrate.go @@ -276,6 +276,8 @@ func seedDefaultSettings(db *gorm.DB) { {Key: "custom_header_code", Type: "textarea", Value: ""}, {Key: "custom_footer_code", Type: "textarea", Value: ""}, {Key: "theme", Type: "text", Value: "default"}, + {Key: "robots_tag", Type: "text", Value: "index, follow"}, + {Key: "site_url", Type: "text", Value: "https://www.example.com"}, } for _, s := range defaults { db.Where("key = ?", s.Key).FirstOrCreate(&s)