Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion blog/blog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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("")
Expand Down
9 changes: 7 additions & 2 deletions goblog.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
79 changes: 79 additions & 0 deletions templates/shared/_head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{{ define "_head" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="keywords" content="{{ .settings.site_title.Value }}{{range .post.Tags}}, {{.Name}}{{end}}">
<meta name="author" content="{{ .settings.site_title.Value }}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="{{ with index .settings "robots_tag" }}{{ if .Value }}{{ .Value }}{{ else }}index, follow{{ end }}{{ else }}index, follow{{ end }}" />
<meta property="og:site_name" content="{{ .settings.site_title.Value }}">
{{ if .post }}
<meta name="description" content="{{ .post.PlainTextPreview 155 }}">
<meta property="og:title" content="{{ .settings.site_title.Value }}: {{ .post.Title }}">
<meta property="og:type" content="article">
<meta property="og:url" content="{{ with index .settings "site_url" }}{{ .Value }}{{ end }}{{ .post.Permalink }}">
<meta property="og:updated_time" content="{{ .post.UpdatedAt }}">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="{{ .post.CreatedAt }}">
<meta property="article:modified_time" content="{{ .post.UpdatedAt }}">
<meta property="article:author" content="{{ .settings.site_title.Value }}">
{{ range .post.Tags }}
<meta property="article:tag" content="{{ .Name }}">
{{ end }}
<title>{{ .settings.site_title.Value }}: {{ .post.Title }}</title>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "{{ .post.Title }}",
"image": [
{{range .post.ExtractImages}}
"{{ with index $.settings "site_url" }}{{ .Value }}{{ end }}{{.}}",
{{end}}
"{{ with index .settings "site_url" }}{{ .Value }}{{ end }}/img/jason.jpg"
],
"datePublished": "{{ .post.CreatedAt }}",
"dateModified": "{{ .post.UpdatedAt }}",
"author": [{
"@type": "Person",
"name": "{{ .settings.site_title.Value }}",
"url": "{{ with index .settings "site_url" }}{{ .Value }}{{ end }}"
}]
}
</script>
{{ else }}
<meta name="description" content="{{ .settings.site_title.Value }}'s blog, code, projects and publications">
<title>{{ .settings.site_title.Value }}: {{ .title }}</title>
{{ end }}
<link rel="icon" type="image/png" href="{{ .settings.favicon.Value }}">
<link rel="manifest" href="/site.webmanifest">
{{ if .admin_page }}
<script src="/js/inline-attachment.js"></script>
<script src="/js/codemirror-4.inline-attachment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/simplemde/1.11.2/simplemde.min.js" integrity="sha512-ksSfTk6JIdsze75yZ8c+yDVLu09SNefa9IicxEE+HZvWo9kLPY1vrRlmucEMHQReWmEdKqusQWaDMpkTb3M2ug==" crossorigin="anonymous"></script>
<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" />
{{ end }}
{{ if or .admin_page .post }}
<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>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css" integrity="sha512-hasIneQUHlh06VNBe7f6ZcHmeRTLIaQWFd43YriJ0UND19bvYRauxthDg8E4eVNPm9bRUhr5JGeqH7FRFXQu5g==" crossorigin="anonymous" />
{{ end }}
<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>
<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>
<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" />
<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" />
<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" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tachyons/4.11.1/tachyons.min.css" integrity="sha512-d0v474klOFSF7qD9WDvyRxAvXaWSxCHDZdnBSZQjo8BpVr6vpjwAgqetpqkKP38DzlOzdVPaLVnzzW1Ba8wB9w==" crossorigin="anonymous" />
{{ if .admin_page }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js" integrity="sha512-QoJS4DOhdmG8kbbHkxmB/rtPdN62cGWXAdAFWWJPvUFF1/zxcPSdAnn4HhYZSIlVoLVEJ0LesfNlusgm2bPfnA==" crossorigin="anonymous"></script>
<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>
<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>
<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" />
{{ end }}
<link rel="stylesheet" href="/theme/css/goblog.css"/>
{{ with index .settings "custom_header_code" }}{{ if .Value }}
{{ .Value | rawHTML }}
{{ end }}{{ end }}
{{ with .plugin_head_html }}{{ . | rawHTML }}{{ end }}
</head>
{{ end }}
83 changes: 2 additions & 81 deletions themes/default/templates/header.html
Original file line number Diff line number Diff line change
@@ -1,83 +1,4 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="keywords" content="{{ .settings.site_title.Value }}, software engineer, computer science, {{range .post.Tags}} {{.Name}},{{end}}">
<meta name="author" content="{{ .settings.site_title.Value }}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="index, follow" />
<meta property="og:site_name" content="{{ .settings.site_title.Value }}">
{{ if .post }}
<meta name="description" content="{{ .post.PlainTextPreview 155 }}">
<meta property="og:title" content="{{ .settings.site_title.Value }}: {{ .post.Title }}">
<meta property="og:type" content="article">
<meta property="og:url" content="https://www.jasonernst.com{{ .post.Permalink }}">
<meta property="og:updated_time" content="{{ .post.UpdatedAt }}">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="{{ .post.CreatedAt }}">
<meta property="article:modified_time" content="{{ .post.UpdatedAt }}">
<meta property="article:author" content="{{ .settings.site_title.Value }}">
{{ range .post.Tags }}
<meta property="article:tag" content="{{ .Name }}">
{{ end }}
<title>{{ .settings.site_title.Value }}: {{ .post.Title }}</title>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "{{ .post.Title }}",
"image": [
{{range .post.ExtractImages}}
"https://www.jasonernst.com{{.}}",
{{end}}
"https://www.jasonernst.com/img/jason.jpg"
],
"datePublished": "{{ .post.CreatedAt }}",
"dateModified": "{{ .post.UpdatedAt }}",
"author": [{
"@type": "Person",
"name": "Jason Ernst",
"url": "https://www.jasonernst.com"
}]
}
</script>
{{ else }}
<meta name="description" content="{{ .settings.site_title.Value }}'s blog, code, projects and publications">
<title>{{ .settings.site_title.Value }}: {{ .title }}</title>
{{ end }}
<!-- favicon generated with https://favicon.io/favicon-generator/ -->
<link rel="icon" type="image/png" href="{{ .settings.favicon.Value }}">
<link rel="manifest" href="/site.webmanifest">
<!-- imports for code highlighting, datetime picker, editor, etc -->
{{ if .admin_page }}
<script src="/js/inline-attachment.js"></script>
<script src="/js/codemirror-4.inline-attachment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/simplemde/1.11.2/simplemde.min.js" integrity="sha512-ksSfTk6JIdsze75yZ8c+yDVLu09SNefa9IicxEE+HZvWo9kLPY1vrRlmucEMHQReWmEdKqusQWaDMpkTb3M2ug==" crossorigin="anonymous"></script>
<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" />
{{ end }}
{{ if or .admin_page .post }}
<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>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css" integrity="sha512-hasIneQUHlh06VNBe7f6ZcHmeRTLIaQWFd43YriJ0UND19bvYRauxthDg8E4eVNPm9bRUhr5JGeqH7FRFXQu5g==" crossorigin="anonymous" />
{{ end }}
<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>
<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>
<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" />
<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" />
<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" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tachyons/4.11.1/tachyons.min.css" integrity="sha512-d0v474klOFSF7qD9WDvyRxAvXaWSxCHDZdnBSZQjo8BpVr6vpjwAgqetpqkKP38DzlOzdVPaLVnzzW1Ba8wB9w==" crossorigin="anonymous" />
{{ if .admin_page }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js" integrity="sha512-QoJS4DOhdmG8kbbHkxmB/rtPdN62cGWXAdAFWWJPvUFF1/zxcPSdAnn4HhYZSIlVoLVEJ0LesfNlusgm2bPfnA==" crossorigin="anonymous"></script>
<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>
<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>
<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" />
{{ end }}

<link rel="stylesheet" href="/theme/css/goblog.css"/>
{{ with index .settings "custom_header_code" }}{{ if .Value }}
{{ .Value | rawHTML }}
{{ end }}{{ end }}
{{ with .plugin_head_html }}{{ . | rawHTML }}{{ end }}
</head>
{{ template "_head" . }}
<body>
<div id="header" class="text-center">
<div class="container">
Expand All @@ -101,4 +22,4 @@
</form>
</div>
</div>
<div class="wrapper">
<div class="wrapper">
Loading
Loading