Skip to content

Commit f8be04f

Browse files
authored
Merge pull request #526 from goblogplatform/feature/shared-head-template
Extract shared head template from themes
2 parents 1fa7e76 + 90594a6 commit f8be04f

7 files changed

Lines changed: 99 additions & 246 deletions

File tree

blog/blog_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,11 @@ func TestBlogWorkflow(t *testing.T) {
175175
router.SetFuncMap(template.FuncMap{
176176
"rawHTML": func(s string) template.HTML { return template.HTML(s) },
177177
})
178-
router.LoadHTMLGlob("../themes/default/templates/*")
178+
tmpl := template.Must(template.New("").Funcs(template.FuncMap{
179+
"rawHTML": func(s string) template.HTML { return template.HTML(s) },
180+
}).ParseGlob("../templates/shared/*.html"))
181+
template.Must(tmpl.ParseGlob("../themes/default/templates/*.html"))
182+
router.SetHTMLTemplate(tmpl)
179183
a.On("IsAdmin", mock.Anything).Return(false).Once()
180184
a.On("IsLoggedIn", mock.Anything).Return(false)
181185
jsonValue, _ = json.Marshal("")

goblog.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,12 +374,17 @@ func main() {
374374
}
375375
themePath := filepath.Join("themes", theme) + "/"
376376
log.Println("Loading theme: " + theme)
377-
tmpl, err := template.New("").Funcs(funcMap).ParseGlob(themePath + "templates/*.html")
377+
// Load shared templates first, then theme templates
378+
tmpl, err := template.New("").Funcs(funcMap).ParseGlob("templates/shared/*.html")
379+
if err != nil {
380+
log.Fatalf("Failed to load shared templates: %v", err)
381+
}
382+
tmpl, err = tmpl.ParseGlob(themePath + "templates/*.html")
378383
if err != nil {
379384
log.Printf("Warning: failed to load theme %q: %v — falling back to default", theme, err)
380385
theme = "default"
381386
themePath = "themes/default/"
382-
tmpl = template.Must(template.New("").Funcs(funcMap).ParseGlob(themePath + "templates/*.html"))
387+
tmpl = template.Must(template.Must(template.New("").Funcs(funcMap).ParseGlob("templates/shared/*.html")).ParseGlob(themePath + "templates/*.html"))
383388
}
384389
router.SetHTMLTemplate(tmpl)
385390
activeTheme = theme

templates/shared/_head.html

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{{ define "_head" }}
2+
<!DOCTYPE html>
3+
<html lang="en">
4+
<head>
5+
<meta charset="utf-8"/>
6+
<meta name="keywords" content="{{ .settings.site_title.Value }}{{range .post.Tags}}, {{.Name}}{{end}}">
7+
<meta name="author" content="{{ .settings.site_title.Value }}">
8+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
9+
<meta name="robots" content="{{ with index .settings "robots_tag" }}{{ if .Value }}{{ .Value }}{{ else }}index, follow{{ end }}{{ else }}index, follow{{ end }}" />
10+
<meta property="og:site_name" content="{{ .settings.site_title.Value }}">
11+
{{ if .post }}
12+
<meta name="description" content="{{ .post.PlainTextPreview 155 }}">
13+
<meta property="og:title" content="{{ .settings.site_title.Value }}: {{ .post.Title }}">
14+
<meta property="og:type" content="article">
15+
<meta property="og:url" content="{{ with index .settings "site_url" }}{{ .Value }}{{ end }}{{ .post.Permalink }}">
16+
<meta property="og:updated_time" content="{{ .post.UpdatedAt }}">
17+
<meta property="og:locale" content="en_US">
18+
<meta property="article:published_time" content="{{ .post.CreatedAt }}">
19+
<meta property="article:modified_time" content="{{ .post.UpdatedAt }}">
20+
<meta property="article:author" content="{{ .settings.site_title.Value }}">
21+
{{ range .post.Tags }}
22+
<meta property="article:tag" content="{{ .Name }}">
23+
{{ end }}
24+
<title>{{ .settings.site_title.Value }}: {{ .post.Title }}</title>
25+
<script type="application/ld+json">
26+
{
27+
"@context": "https://schema.org",
28+
"@type": "BlogPosting",
29+
"headline": "{{ .post.Title }}",
30+
"image": [
31+
{{range .post.ExtractImages}}
32+
"{{ with index $.settings "site_url" }}{{ .Value }}{{ end }}{{.}}",
33+
{{end}}
34+
"{{ with index .settings "site_url" }}{{ .Value }}{{ end }}/img/jason.jpg"
35+
],
36+
"datePublished": "{{ .post.CreatedAt }}",
37+
"dateModified": "{{ .post.UpdatedAt }}",
38+
"author": [{
39+
"@type": "Person",
40+
"name": "{{ .settings.site_title.Value }}",
41+
"url": "{{ with index .settings "site_url" }}{{ .Value }}{{ end }}"
42+
}]
43+
}
44+
</script>
45+
{{ else }}
46+
<meta name="description" content="{{ .settings.site_title.Value }}'s blog, code, projects and publications">
47+
<title>{{ .settings.site_title.Value }}: {{ .title }}</title>
48+
{{ end }}
49+
<link rel="icon" type="image/png" href="{{ .settings.favicon.Value }}">
50+
<link rel="manifest" href="/site.webmanifest">
51+
{{ if .admin_page }}
52+
<script src="/js/inline-attachment.js"></script>
53+
<script src="/js/codemirror-4.inline-attachment.js"></script>
54+
<script src="https://cdnjs.cloudflare.com/ajax/libs/simplemde/1.11.2/simplemde.min.js" integrity="sha512-ksSfTk6JIdsze75yZ8c+yDVLu09SNefa9IicxEE+HZvWo9kLPY1vrRlmucEMHQReWmEdKqusQWaDMpkTb3M2ug==" crossorigin="anonymous"></script>
55+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/simplemde/1.11.2/simplemde.min.css" integrity="sha512-lB03MbtC3LxImQ+BKnZIyvVHTQ8SSmQ15AhVh5U/+CCp4wKtZMvgLGXbZIjIBBbnKsmk3/6n2vcF8a9CtVVSfA==" crossorigin="anonymous" />
56+
{{ end }}
57+
{{ if or .admin_page .post }}
58+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js" integrity="sha512-EBLzUL8XLl+va/zAsmXwS7Z2B1F9HUHkZwyS/VKwh3S7T/U0nF4BaU29EP/ZSf6zgiIxYAnKLu6bJ8dqpmX5uw==" crossorigin="anonymous"></script>
59+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css" integrity="sha512-hasIneQUHlh06VNBe7f6ZcHmeRTLIaQWFd43YriJ0UND19bvYRauxthDg8E4eVNPm9bRUhr5JGeqH7FRFXQu5g==" crossorigin="anonymous" />
60+
{{ end }}
61+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous"></script>
62+
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.8/js/bootstrap.min.js" integrity="sha512-nKXmKvJyiGQy343jatQlzDprflyB5c+tKCzGP3Uq67v+lmzfnZUi/ZT+fc6ITZfSC5HhaBKUIvr/nTLCV+7F+Q==" crossorigin="anonymous"></script>
63+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.8/css/bootstrap.min.css" integrity="sha512-2bBQCjcnw658Lho4nlXJcc6WkV/UxpE/sAokbXPxQNGqmNdQrWqtw26Ns9kFF/yG792pKR1Sx8/Y1Lf1XN4GKA==" crossorigin="anonymous" />
64+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-social/5.1.1/bootstrap-social.min.css" integrity="sha512-f8mUMCRNrJxPBDzPJx3n+Y5TC5xp6SmStstEfgsDXZJTcxBakoB5hvPLhAfJKa9rCvH+n3xpJ2vQByxLk4WP2g==" crossorigin="anonymous" />
65+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css" integrity="sha512-2SwdPD6INVrV/lHTZbO2nodKhrnDdJK9/kg2XD1r9uGqPo1cUbujc+IYdlYdEErWNu69gVcYgdxlmVmzTWnetw==" crossorigin="anonymous" />
66+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tachyons/4.11.1/tachyons.min.css" integrity="sha512-d0v474klOFSF7qD9WDvyRxAvXaWSxCHDZdnBSZQjo8BpVr6vpjwAgqetpqkKP38DzlOzdVPaLVnzzW1Ba8wB9w==" crossorigin="anonymous" />
67+
{{ if .admin_page }}
68+
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js" integrity="sha512-QoJS4DOhdmG8kbbHkxmB/rtPdN62cGWXAdAFWWJPvUFF1/zxcPSdAnn4HhYZSIlVoLVEJ0LesfNlusgm2bPfnA==" crossorigin="anonymous"></script>
69+
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.6.0/moment-timezone-with-data.min.js" integrity="sha512-+FcC+reETRqrbKDor++Otoek++yhj4Q1pu/VjNTYHywub+2uoKV+0o0C+yLDun7b+MzAQ0qz9G5ShZUUJpxN1Q==" crossorigin="anonymous"></script>
70+
<script src="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.39.0/js/tempusdominus-bootstrap-4.min.js" integrity="sha512-k6/Bkb8Fxf/c1Tkyl39yJwcOZ1P4cRrJu77p83zJjN2Z55prbFHxPs9vN7q3l3+tSMGPDdoH51AEU8Vgo1cgAA==" crossorigin="anonymous"></script>
71+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.39.0/css/tempusdominus-bootstrap-4.min.css" integrity="sha512-3JRrEUwaCkFUBLK1N8HehwQgu8e23jTH4np5NHOmQOobuC4ROQxFwFgBLTnhcnQRMs84muMh0PnnwXlPq5MGjg==" crossorigin="anonymous" />
72+
{{ end }}
73+
<link rel="stylesheet" href="/theme/css/goblog.css"/>
74+
{{ with index .settings "custom_header_code" }}{{ if .Value }}
75+
{{ .Value | rawHTML }}
76+
{{ end }}{{ end }}
77+
{{ with .plugin_head_html }}{{ . | rawHTML }}{{ end }}
78+
</head>
79+
{{ end }}
Lines changed: 2 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,4 @@
1-
<!DOCTYPE html>
2-
<html lang="en">
3-
<head>
4-
<meta charset="utf-8"/>
5-
<meta name="keywords" content="{{ .settings.site_title.Value }}, software engineer, computer science, {{range .post.Tags}} {{.Name}},{{end}}">
6-
<meta name="author" content="{{ .settings.site_title.Value }}">
7-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8-
<meta name="robots" content="index, follow" />
9-
<meta property="og:site_name" content="{{ .settings.site_title.Value }}">
10-
{{ if .post }}
11-
<meta name="description" content="{{ .post.PlainTextPreview 155 }}">
12-
<meta property="og:title" content="{{ .settings.site_title.Value }}: {{ .post.Title }}">
13-
<meta property="og:type" content="article">
14-
<meta property="og:url" content="https://www.jasonernst.com{{ .post.Permalink }}">
15-
<meta property="og:updated_time" content="{{ .post.UpdatedAt }}">
16-
<meta property="og:locale" content="en_US">
17-
<meta property="article:published_time" content="{{ .post.CreatedAt }}">
18-
<meta property="article:modified_time" content="{{ .post.UpdatedAt }}">
19-
<meta property="article:author" content="{{ .settings.site_title.Value }}">
20-
{{ range .post.Tags }}
21-
<meta property="article:tag" content="{{ .Name }}">
22-
{{ end }}
23-
<title>{{ .settings.site_title.Value }}: {{ .post.Title }}</title>
24-
<script type="application/ld+json">
25-
{
26-
"@context": "https://schema.org",
27-
"@type": "BlogPosting",
28-
"headline": "{{ .post.Title }}",
29-
"image": [
30-
{{range .post.ExtractImages}}
31-
"https://www.jasonernst.com{{.}}",
32-
{{end}}
33-
"https://www.jasonernst.com/img/jason.jpg"
34-
],
35-
"datePublished": "{{ .post.CreatedAt }}",
36-
"dateModified": "{{ .post.UpdatedAt }}",
37-
"author": [{
38-
"@type": "Person",
39-
"name": "Jason Ernst",
40-
"url": "https://www.jasonernst.com"
41-
}]
42-
}
43-
</script>
44-
{{ else }}
45-
<meta name="description" content="{{ .settings.site_title.Value }}'s blog, code, projects and publications">
46-
<title>{{ .settings.site_title.Value }}: {{ .title }}</title>
47-
{{ end }}
48-
<!-- favicon generated with https://favicon.io/favicon-generator/ -->
49-
<link rel="icon" type="image/png" href="{{ .settings.favicon.Value }}">
50-
<link rel="manifest" href="/site.webmanifest">
51-
<!-- imports for code highlighting, datetime picker, editor, etc -->
52-
{{ if .admin_page }}
53-
<script src="/js/inline-attachment.js"></script>
54-
<script src="/js/codemirror-4.inline-attachment.js"></script>
55-
<script src="https://cdnjs.cloudflare.com/ajax/libs/simplemde/1.11.2/simplemde.min.js" integrity="sha512-ksSfTk6JIdsze75yZ8c+yDVLu09SNefa9IicxEE+HZvWo9kLPY1vrRlmucEMHQReWmEdKqusQWaDMpkTb3M2ug==" crossorigin="anonymous"></script>
56-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/simplemde/1.11.2/simplemde.min.css" integrity="sha512-lB03MbtC3LxImQ+BKnZIyvVHTQ8SSmQ15AhVh5U/+CCp4wKtZMvgLGXbZIjIBBbnKsmk3/6n2vcF8a9CtVVSfA==" crossorigin="anonymous" />
57-
{{ end }}
58-
{{ if or .admin_page .post }}
59-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js" integrity="sha512-EBLzUL8XLl+va/zAsmXwS7Z2B1F9HUHkZwyS/VKwh3S7T/U0nF4BaU29EP/ZSf6zgiIxYAnKLu6bJ8dqpmX5uw==" crossorigin="anonymous"></script>
60-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css" integrity="sha512-hasIneQUHlh06VNBe7f6ZcHmeRTLIaQWFd43YriJ0UND19bvYRauxthDg8E4eVNPm9bRUhr5JGeqH7FRFXQu5g==" crossorigin="anonymous" />
61-
{{ end }}
62-
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous"></script>
63-
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.8/js/bootstrap.min.js" integrity="sha512-nKXmKvJyiGQy343jatQlzDprflyB5c+tKCzGP3Uq67v+lmzfnZUi/ZT+fc6ITZfSC5HhaBKUIvr/nTLCV+7F+Q==" crossorigin="anonymous"></script>
64-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.8/css/bootstrap.min.css" integrity="sha512-2bBQCjcnw658Lho4nlXJcc6WkV/UxpE/sAokbXPxQNGqmNdQrWqtw26Ns9kFF/yG792pKR1Sx8/Y1Lf1XN4GKA==" crossorigin="anonymous" />
65-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-social/5.1.1/bootstrap-social.min.css" integrity="sha512-f8mUMCRNrJxPBDzPJx3n+Y5TC5xp6SmStstEfgsDXZJTcxBakoB5hvPLhAfJKa9rCvH+n3xpJ2vQByxLk4WP2g==" crossorigin="anonymous" />
66-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css" integrity="sha512-2SwdPD6INVrV/lHTZbO2nodKhrnDdJK9/kg2XD1r9uGqPo1cUbujc+IYdlYdEErWNu69gVcYgdxlmVmzTWnetw==" crossorigin="anonymous" />
67-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tachyons/4.11.1/tachyons.min.css" integrity="sha512-d0v474klOFSF7qD9WDvyRxAvXaWSxCHDZdnBSZQjo8BpVr6vpjwAgqetpqkKP38DzlOzdVPaLVnzzW1Ba8wB9w==" crossorigin="anonymous" />
68-
{{ if .admin_page }}
69-
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js" integrity="sha512-QoJS4DOhdmG8kbbHkxmB/rtPdN62cGWXAdAFWWJPvUFF1/zxcPSdAnn4HhYZSIlVoLVEJ0LesfNlusgm2bPfnA==" crossorigin="anonymous"></script>
70-
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.6.0/moment-timezone-with-data.min.js" integrity="sha512-+FcC+reETRqrbKDor++Otoek++yhj4Q1pu/VjNTYHywub+2uoKV+0o0C+yLDun7b+MzAQ0qz9G5ShZUUJpxN1Q==" crossorigin="anonymous"></script>
71-
<script src="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.39.0/js/tempusdominus-bootstrap-4.min.js" integrity="sha512-k6/Bkb8Fxf/c1Tkyl39yJwcOZ1P4cRrJu77p83zJjN2Z55prbFHxPs9vN7q3l3+tSMGPDdoH51AEU8Vgo1cgAA==" crossorigin="anonymous"></script>
72-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.39.0/css/tempusdominus-bootstrap-4.min.css" integrity="sha512-3JRrEUwaCkFUBLK1N8HehwQgu8e23jTH4np5NHOmQOobuC4ROQxFwFgBLTnhcnQRMs84muMh0PnnwXlPq5MGjg==" crossorigin="anonymous" />
73-
{{ end }}
74-
75-
<link rel="stylesheet" href="/theme/css/goblog.css"/>
76-
{{ with index .settings "custom_header_code" }}{{ if .Value }}
77-
{{ .Value | rawHTML }}
78-
{{ end }}{{ end }}
79-
{{ with .plugin_head_html }}{{ . | rawHTML }}{{ end }}
80-
</head>
1+
{{ template "_head" . }}
812
<body>
823
<div id="header" class="text-center">
834
<div class="container">
@@ -101,4 +22,4 @@
10122
</form>
10223
</div>
10324
</div>
104-
<div class="wrapper">
25+
<div class="wrapper">

0 commit comments

Comments
 (0)