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)