site_head.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. {{ $scr := .Scratch }}
  2. <head>
  3. <meta charset="utf-8" />
  4. <meta name="viewport" content="width=device-width, initial-scale=1" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. {{ $is_sponsor := site.Params.i_am_a_sponsor | default false }}
  7. {{ $hide_generator := site.Params.power_ups.hide_generator | default false }}
  8. {{ if not (and $is_sponsor $hide_generator) }}
  9. <meta name="generator" content="Wowchemy {{ site.Data.wowchemy.version }} for Hugo" />
  10. {{ end }}
  11. {{ if .Params.private }}
  12. <meta name="robots" content="noindex" />
  13. {{- end -}}
  14. {{/* Parse theme and font */}}
  15. {{ partial "functions/parse_theme" . }}
  16. {{/* Pre-connect to Google Fonts if the site's Font Theme uses them. */}}
  17. {{ with ($scr.Get "google_fonts") }}
  18. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  19. {{ end }}
  20. {{/* Load Google Fonts if the site's Font Theme uses them. */}}
  21. {{/* Note: we cannot use SRI with Google Fonts because the CSS is dynamically generated according to the user agent. */}}
  22. {{ with ($scr.Get "google_fonts") }}
  23. {{ if hasPrefix . "family=" }}
  24. {{/* If `google_fonts` starts with "family=", use API v2 (https://developers.google.com/fonts/docs/css2) */}}
  25. <link rel="preload" as="style" {{ printf "href=\"https://fonts.googleapis.com/css2?%s&display=swap\"" . | safeHTMLAttr }}>
  26. <link rel="stylesheet" {{ printf "href=\"https://fonts.googleapis.com/css2?%s&display=swap\"" . | safeHTMLAttr }} media="print" onload="this.media='all'">
  27. {{ else }}
  28. {{ errorf "There is a new version of Google Fonts. Learn how to upgrade your font pack at https://wowchemy.com/docs/customization/#custom-font" }}
  29. {{ end }}
  30. {{ end }}
  31. {{ if site.Params.marketing.analytics.google_optimize | and hugo.IsProduction }}
  32. <script src="https://www.googleoptimize.com/optimize.js?id={{ site.Params.marketing.analytics.google_optimize }}"></script>
  33. {{- end -}}
  34. {{ with site.Params.marketing.verification.google }}
  35. <meta name="google-site-verification" content="{{ . }}" />
  36. {{- end -}}
  37. {{ with site.Params.marketing.verification.baidu }}
  38. <meta name="baidu-site-verification" content="{{ . }}" />
  39. {{- end -}}
  40. {{ with site.Params.marketing.verification.bing }}
  41. <meta name="msvalidate.01" content="{{ . }}" />
  42. {{- end -}}
  43. {{/* Attempt to load superuser. */}}
  44. {{ $superuser_name := "" }}
  45. {{ $superuser_username := "" }}
  46. {{ $superuser_role := "" }}
  47. {{ range first 1 (where (where site.Pages "Section" "authors") "Params.superuser" true) }}
  48. {{ $superuser_name = .Title }}
  49. {{ $superuser_username = path.Base (path.Split .Path).Dir }}
  50. {{ $superuser_role = .Params.role }}
  51. {{ end }}
  52. {{ $scr.Set "superuser_username" $superuser_username }}{{/* Set superuser globally for page_author.html. */}}
  53. {{ with $superuser_name }}<meta name="author" content="{{ . }}" />{{ end }}
  54. {{/* Generate page description. */}}
  55. {{ $desc := "" }}
  56. {{ if .Params.summary }}
  57. {{ $desc = .Params.summary }}
  58. {{ else if .Params.abstract }}
  59. {{ $desc = .Params.abstract }}
  60. {{ else if .IsPage }}
  61. {{ $desc = .Summary }}
  62. {{ else if site.Params.marketing.seo.org_name }}
  63. {{ $desc = site.Params.marketing.seo.org_name }}
  64. {{ else }}
  65. {{ $desc = $superuser_role }}
  66. {{ end }}
  67. <meta name="description" content="{{ $desc }}" />
  68. {{ range .Translations }}
  69. <link rel="alternate" hreflang="{{ .Lang }}" href="{{ .Permalink }}" />
  70. {{ end }}
  71. <link rel="alternate" hreflang="{{ site.LanguageCode | default "en-us" }}" href="{{ .Permalink }}" />
  72. {{ $css := site.Data.assets.css }}
  73. {{ $js := site.Data.assets.js }}
  74. {{ if ne ($scr.Get "primary") "#fff" }}
  75. <meta name="theme-color" content="{{ $scr.Get "primary" }}" />
  76. {{ end }}
  77. {{/* Config LaTeX math rendering. */}}
  78. {{ if or .Params.math site.Params.features.math.enable }}
  79. {{ $mathjax_config := resources.Get "js/mathjax-config.js" }}
  80. <script src="{{ $mathjax_config.RelPermalink }}"></script>
  81. {{ end }}
  82. {{/* Attempt to load local vendor CSS, otherwise load from CDN. */}}
  83. {{/* Only load non-essential CSS in this media-swapping way */}}
  84. {{- $stylesheets := slice -}}
  85. {{- $lib_names := slice "fontawesome/all.min" -}}
  86. {{- range $lib_names -}}
  87. {{- $stylesheets = $stylesheets | append (resources.Get (printf "css/libs/%s.css" . ) ) -}}
  88. {{- end -}}
  89. {{ $stylesheets = $stylesheets | resources.Concat "css/vendor-bundle.css" | minify }}
  90. {{- if hugo.IsProduction -}}
  91. {{- $stylesheets = $stylesheets | fingerprint "md5" -}}
  92. {{- end -}}
  93. <link rel="stylesheet" href="{{$stylesheets.RelPermalink}}" media="print" onload="this.media='all'">
  94. {{ $scr.Set "vendor_css_filename" "main.min.css" }}
  95. {{ $scr.Set "vendor_js_filename" "main.min.js" }}
  96. {{ if and (fileExists (printf "static/css/vendor/%s" ($scr.Get "vendor_css_filename"))) (fileExists (printf "static/js/vendor/%s" ($scr.Get "vendor_js_filename"))) }}
  97. {{ $scr.Set "use_cdn" 0 }}
  98. <link rel="stylesheet" href="{{ printf "/css/vendor/%s" ($scr.Get "vendor_css_filename") | relURL }}" />
  99. {{ else }}
  100. {{ $scr.Set "use_cdn" 1 }}
  101. {{ if site.Params.extensions.academicons.enable }}
  102. {{ printf "<link rel=\"stylesheet\" href=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" media=\"print\" onload=\"this.media='all'\">" (printf $css.academicons.url $css.academicons.version) $css.academicons.sri | safeHTML }}
  103. {{ end }}
  104. {{/* Workaround `.HasShortcode "gallery"` not parsing page resources (widget page sections) */}}
  105. {{ $has_gallery := false }}
  106. {{/* Note: unless there is a root `/index.md` with `type: widget_page`, Hugo treats homepage as `page` type. */}}
  107. {{ if (eq .Type "widget_page") | or (and .IsHome (eq .Type "page")) }}
  108. {{/* Check if widget page sections use a gallery */}}
  109. {{ $page := "/home/index.md" }}
  110. {{ $context := cond .IsHome (site.GetPage $page) . }}
  111. {{ range $context.Resources.ByType "page" }}
  112. {{ if .HasShortcode "gallery" }}
  113. {{ $has_gallery = true }}
  114. {{ end }}
  115. {{ end }}
  116. {{ else }}
  117. {{/* Single page */}}
  118. {{ if .HasShortcode "gallery" }}
  119. {{ $has_gallery = true }}
  120. {{ end }}
  121. {{ end }}
  122. {{ $scr.Set "HasNestedGalleryShortcode" $has_gallery }}
  123. {{ if $has_gallery | or site.Params.require_fancybox }}
  124. {{ printf "<link rel=\"stylesheet\" href=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" media=\"print\" onload=\"this.media='all'\">" (printf $css.fancybox.url $css.fancybox.version) $css.fancybox.sri | safeHTML }}
  125. {{ end }}
  126. {{/* Default to disabling highlighting, but allow the user to override it in .Params or site.Params.
  127. Use $scr to store "highlight_enabled", so that we can read it again in footer.html. */}}
  128. {{ $scr.Set "highlight_enabled" false }}
  129. {{ if isset .Params "highlight" }}
  130. {{ $scr.Set "highlight_enabled" .Params.highlight }}
  131. {{ else if isset site.Params.features.syntax_highlighter "enable" }}
  132. {{ $scr.Set "highlight_enabled" site.Params.features.syntax_highlighter.enable }}
  133. {{ end }}
  134. {{ if ($scr.Get "highlight_enabled") }}
  135. {{ $v := $css.highlight.version }}
  136. {{ with site.Params.features.syntax_highlighter.theme }}
  137. {{ printf "<link rel=\"stylesheet\" href=\"%s\" crossorigin=\"anonymous\" title=\"hl-light\" media=\"print\" onload=\"this.media='all'\">" (printf $css.highlight.url $css.highlight.version .) | safeHTML }}
  138. {{ printf "<link rel=\"stylesheet\" href=\"%s\" crossorigin=\"anonymous\" title=\"hl-dark\" media=\"print\" onload=\"this.media='all'\" disabled>" (printf $css.highlight.url $css.highlight.version .) | safeHTML }}
  139. {{ else }}
  140. {{ if eq ($scr.Get "light") true }}
  141. {{ printf "<link rel=\"stylesheet\" href=\"%s\" crossorigin=\"anonymous\" title=\"hl-light\" media=\"print\" onload=\"this.media='all'\">" (printf $css.highlight.url $css.highlight.version "github") | safeHTML }}
  142. {{ printf "<link rel=\"stylesheet\" href=\"%s\" crossorigin=\"anonymous\" title=\"hl-dark\" media=\"print\" onload=\"this.media='all'\" disabled>" (printf $css.highlight.url $css.highlight.version "dracula") | safeHTML }}
  143. {{ else }}
  144. {{ printf "<link rel=\"stylesheet\" href=\"%s\" crossorigin=\"anonymous\" title=\"hl-light\" media=\"print\" onload=\"this.media='all'\" disabled>" (printf $css.highlight.url $css.highlight.version "github") | safeHTML }}
  145. {{ printf "<link rel=\"stylesheet\" href=\"%s\" crossorigin=\"anonymous\" title=\"hl-dark\" media=\"print\" onload=\"this.media='all'\">" (printf $css.highlight.url $css.highlight.version "dracula") | safeHTML }}
  146. {{ end }}
  147. {{ end }}
  148. {{ end }}
  149. {{/* Maps CSS. */}}
  150. {{ $map_provider := lower site.Params.features.map.provider }}
  151. {{ if in (slice "mapnik" "mapbox") $map_provider }}
  152. {{ printf "<link rel=\"stylesheet\" href=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" media=\"print\" onload=\"this.media='all'\">" (printf $css.leaflet.url $css.leaflet.version) $css.leaflet.sri | safeHTML }}
  153. {{ end }}
  154. {{ if eq (lower site.Params.features.search.provider) "algolia" }}
  155. {{ printf "<link rel=\"stylesheet\" href=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\">" (printf $css.instantsearch.url $css.instantsearch.version) $css.instantsearch.sri | safeHTML }}
  156. {{ end }}
  157. {{/* Load async scripts. */}}
  158. {{ range $k, $v := site.Data.assets.js }}
  159. {{/* TODO: investigate why `where ... "async" true` does not work. */}}
  160. {{ $load := $v.async }}
  161. {{/* Only load MathJax if required. */}}
  162. {{ if (eq $k "mathJax") | and (not (or $.Params.math site.Params.features.math.enable)) }}
  163. {{ $load = false }}
  164. {{ end }}
  165. {{ if $load }}
  166. {{ printf "<script src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\" async></script>" (printf $v.url $v.version) $v.sri | safeHTML }}
  167. {{ end }}
  168. {{ end }}
  169. {{ end }}
  170. {{ $license := printf "/*! Wowchemy v%s | https://wowchemy.com/ */\n" site.Data.wowchemy.version }}
  171. {{ $license := $license | printf "%s/*! Copyright 2016-present George Cushen (https://georgecushen.com/) */\n" }}
  172. {{ $license := $license | printf "%s/*! License: https://github.com/wowchemy/wowchemy-hugo-themes/blob/main/LICENSE.md */\n" }}
  173. {{ $css_bundle_head := $license | resources.FromString "css/bundle-head.css" }}
  174. {{ $css_options := dict "targetPath" "css/wowchemy.css" }}
  175. {{- if hugo.IsProduction -}}
  176. {{- $css_options = merge $css_options (dict "outputStyle" "compressed") -}}
  177. {{- end -}}
  178. {{ $sass_template := resources.Get "scss/main.scss" }}
  179. {{ $style := $sass_template | resources.ExecuteAsTemplate "main_parsed.scss" . | toCSS $css_options }}
  180. {{- if hugo.IsProduction -}}
  181. {{- $style = $style | minify -}}
  182. {{- end -}}
  183. {{ $style := slice $css_bundle_head $style | resources.Concat "css/wowchemy.css" }}
  184. {{- if eq (getenv "HUGO_WC_POST_CSS") "true" -}}
  185. {{- $style = $style | postCSS -}}
  186. {{- end -}}
  187. {{- if hugo.IsProduction -}}
  188. {{- $style = $style | fingerprint "md5" -}}
  189. {{- end -}}
  190. {{- if eq (getenv "HUGO_WC_POST_CSS") "true" -}}
  191. {{/* PostProcess must be last action in the pipeline */}}
  192. {{- $style = $style | resources.PostProcess -}}
  193. {{- end -}}
  194. <link rel="stylesheet" href="{{ $style.RelPermalink }}" />
  195. {{ partial "marketing/google_analytics" . }}
  196. {{ partial "marketing/google_tag_manager" . }}
  197. {{ partial "marketing/microsoft_clarity" . }}
  198. {{ partial "marketing/baidu_tongji" . }}
  199. {{/* Netlify Identity integration. */}}
  200. {{ $use_cms := templates.Exists "wowchemycms/single.wowchemycms_config.yml" | default (site.Params.extensions.cms.netlify_cms | default false) }}
  201. {{ if .IsHome | and $use_cms }}
  202. <script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
  203. {{ end }}
  204. {{ with .OutputFormats.Get "RSS" }}
  205. <link rel="alternate" href="{{ .RelPermalink }}" type="application/rss+xml" title="{{ site.Title }}" />
  206. {{ end }}
  207. {{ with site.Home.OutputFormats.Get "WebAppManifest" }}
  208. <link rel="manifest" href="{{ .RelPermalink }}" />
  209. {{ end }}
  210. <link rel="icon" type="image/png" href="{{ (partial "functions/get_icon" 32).RelPermalink }}" />
  211. <link rel="apple-touch-icon" type="image/png" href="{{ (partial "functions/get_icon" 180).RelPermalink }}" />
  212. <link rel="canonical" href="{{ .Permalink }}" />
  213. {{/* Get page image for sharing. */}}
  214. {{ $sharing_image := resources.GetMatch (path.Join "media" "sharing.*") }}
  215. {{ $featured_image := (.Resources.ByType "image").GetMatch "*featured*" }}
  216. {{ $avatar_image := (.Resources.ByType "image").GetMatch "avatar*" }}
  217. {{ $has_logo := fileExists "assets/media/logo.png" | or (fileExists "assets/media/logo.svg") }}
  218. {{ $og_image := "" }}
  219. {{ $twitter_card := "summary_large_image" }}
  220. {{ if (and (eq .Kind "term") $avatar_image) }}
  221. {{/* Match image processing in About widget to prevent generating more images than necessary. */}}
  222. {{ $og_image = ($avatar_image.Fill "270x270 Center").Permalink }}
  223. {{ $twitter_card = "summary" }}
  224. {{ else if $featured_image }}
  225. {{ $og_image = $featured_image.Permalink }}
  226. {{ else if $sharing_image }}
  227. {{ $og_image = $sharing_image.Permalink }}
  228. {{ else if $has_logo }}
  229. {{ $og_image = (partial "functions/get_logo" (dict "constraint" "fit" "size" 300)).Permalink }}
  230. {{ $twitter_card = "summary" }}
  231. {{ else }}
  232. {{ $og_image = (partial "functions/get_icon" 512).Permalink }}
  233. {{ $twitter_card = "summary" }}
  234. {{ end }}
  235. {{ $scr.Set "og_image" $og_image }}{{/* Set `og_image` globally for `rss.xml`. */}}
  236. {{ $title := "" }}
  237. {{ with .Params.seo.title }}
  238. {{ $title = replace . "{brand}" site.Title }}
  239. {{ else }}
  240. {{ $title = .Title | default site.Title }}
  241. {{ if ne $title site.Title }}{{ $title = printf "%s | %s" $title site.Title }}{{ end }}
  242. {{ end }}
  243. <meta property="twitter:card" content="{{ $twitter_card }}" />
  244. {{ with site.Params.marketing.seo.twitter }}
  245. <meta property="twitter:site" content="@{{ . }}" />
  246. <meta property="twitter:creator" content="@{{ . }}" />
  247. {{ end }}
  248. <meta property="og:site_name" content="{{ site.Title }}" />
  249. <meta property="og:url" content="{{ .Permalink }}" />
  250. <meta property="og:title" content="{{ $title }}" />
  251. <meta property="og:description" content="{{ $desc }}" />
  252. {{- with $og_image -}}
  253. <meta property="og:image" content="{{ . }}" />
  254. <meta property="twitter:image" content="{{ . }}" />
  255. {{- end -}}
  256. <meta property="og:locale" content="{{ site.LanguageCode | default "en-us" }}" />
  257. {{ if .IsPage }}
  258. {{ if not .PublishDate.IsZero }}
  259. <meta
  260. property="article:published_time"
  261. content="{{ .PublishDate.Format "2006-01-02T15:04:05-07:00" | safeHTML }}"
  262. />
  263. {{ else if not .Date.IsZero }}
  264. <meta property="article:published_time" content="{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}" />
  265. {{ end }}
  266. {{ if not .Lastmod.IsZero }}<meta property="article:modified_time" content="{{ .Lastmod.Format "2006-01-02T15:04:05-07:00" | safeHTML }}">{{ end }}
  267. {{ else }}
  268. {{ if not .Date.IsZero }}
  269. <meta property="og:updated_time" content="{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}" />
  270. {{ end }}
  271. {{ end }}
  272. {{ partial "jsonld/main" (dict "page" . "summary" $desc) }}
  273. {{ partial "cookie_consent" . }}
  274. {{ partial "custom_head" . }}
  275. <title>{{$title}}</title>
  276. </head>