Skip to content

Commit

Permalink
opengraph optimisation (#436)
Browse files Browse the repository at this point in the history
* add opengraph control to repo

* resize opengraph image

* add full res option for webp viewers

* add article-link and change to show webp images

* change picture to loop over a slice of resolutions

* change author to use picture partial

* change profile page to use partial as well

* increase timeout

* add back json as it broke search (#437)

* increase timeout again

* add back alt to article link image

* add imaging defaults

* add default quality

* I think this should inline critical css

* Revert "I think this should inline critical css"

This reverts commit 5a8e631.

* inline appearance js
  • Loading branch information
jamesjarvis authored Apr 6, 2024
1 parent 6217aa6 commit 1aeb48f
Show file tree
Hide file tree
Showing 7 changed files with 387 additions and 47 deletions.
6 changes: 5 additions & 1 deletion config/_default/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ paginate = 20
summaryLength = 10
colorScheme = "ocean"

timeout = '500s'
timeout = '3000s'

[outputs]
home = ["HTML", "RSS", "JSON"]
Expand Down Expand Up @@ -36,3 +36,7 @@ disable = true
[privacy.youtube]
disable = false
privacyEnhanced = true

[imaging]
quality = 75
disableDate = true
87 changes: 87 additions & 0 deletions layouts/partials/article-link.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<article class="mt-6 flex max-w-prose flex-row">
{{- $images := $.Resources.ByType "image" }}
{{- $thumbnail := $images.GetMatch (.Params.thumbnail | default "*thumb*") }}
{{- $feature := $images.GetMatch (.Params.feature | default "*feature*") | default $thumbnail }}
{{- $lazy := $.Site.Params.enableImageLazyLoading | default true }}
{{- $webp := $.Site.Params.enableImageWebp | default true }}
{{- with $feature }}
<div class="flex-none pe-4 sm:pe-6 ">
<a
href="{{ with $.Params.externalUrl }}
{{ . }}
{{ else }}
{{ $.RelPermalink }}
{{ end }}"
aria-label="{{ $.Title | emojify }}"
>
{{- $alt := $.Params.featureAlt | default $.Params.thumbnailAlt | default $.Title }}
{{- $class := "w-24 rounded-md sm:w-40" }}
<picture
{{ with $class }}class="{{ . }}"{{ end }}
{{ with $alt }}alt="{{ . }}"{{ end }}
>
{{ if $webp }}
<source
type="image/webp"
srcset="{{- (.Fill "160x120 Center webp").RelPermalink }}
,{{- (.Fill "320x240 Center webp").RelPermalink }} 2x"
/>
{{ end }}
<img
{{ with $alt }}alt="{{ . }}"{{ end }}
{{ with $class }}class="{{ . }}"{{ end }}
{{ with $lazy }}loading="lazy" decoding="async"{{ end }}
width="160" height="120"
srcset="{{- (.Fill "160x120 Center").RelPermalink }}
,{{- (.Fill "320x240 Center").RelPermalink }} 2x"
src="{{- (.Fill "320x240 Center").RelPermalink }}"
/>
</picture>
</a>
</div>
{{- end }}
<div>
<h3 class="flex items-center text-xl font-semibold">
{{ with .Params.externalUrl }}
<div>
<a
class="text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral"
href="{{ . }}"
target="_blank"
rel="external"
>{{ $.Title | emojify }}</a
>
<span
class="cursor-default align-top text-xs text-neutral-400 dark:text-neutral-500"
title="{{ i18n "list.externalurl_title" }}"
>
<span class="rtl:hidden">&#8599;</span>
<span class="ltr:hidden">&#8598;</span>
</span>
</div>
{{ else }}
<a
class="text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral"
href="{{ .RelPermalink }}"
>{{ .Title | emojify }}</a
>
{{ end }}
{{ if and .Draft .Site.Params.article.showDraftLabel }}
<div class="ms-2">
{{ partial "badge.html" (i18n "article.draft" | emojify) }}
</div>
{{ end }}
{{ if templates.Exists "partials/extend-article-link.html" }}
{{ partial "extend-article-link.html" . }}
{{ end }}
</h3>
<div class="text-sm text-neutral-500 dark:text-neutral-400">
{{ partial "article-meta.html" . }}
</div>
{{ if .Params.showSummary | default (.Site.Params.list.showSummary | default false) }}
<div class="prose py-1 dark:prose-invert">
{{ .Summary | emojify }}
</div>
{{ end }}
</div>
</article>
25 changes: 25 additions & 0 deletions layouts/partials/author.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{{ if .Params.showAuthor | default (.Site.Params.article.showAuthor | default true) }}
<div class="flex">
{{ with .Site.Language.Params.Author.image }}
{{ $authorImage := resources.Get . }}
{{ if $authorImage }}
{{- $altText := $.Site.Language.Params.Author.name | default "Author" }}
{{ partial "picture.html" (dict "img" $authorImage "alt" $altText "class" "!mb-0 !mt-0 me-4 h-24 w-24 rounded-full" "maxSize" 192 ) }}
{{ end }}
{{ end }}
<div class="place-self-center">
{{ with .Site.Language.Params.Author.name | markdownify | emojify }}
<div class="text-[0.6rem] uppercase leading-3 text-neutral-500 dark:text-neutral-400">
{{ i18n "author.byline_title" | markdownify | emojify }}
</div>
<div class="font-semibold leading-6 text-neutral-800 dark:text-neutral-300">
{{ . }}
</div>
{{ end }}
{{ with .Site.Language.Params.Author.bio | markdownify | emojify }}
<div class="text-sm text-neutral-700 dark:text-neutral-400">{{ . }}</div>
{{ end }}
<div class="text-2xl sm:text-lg">{{ partialCached "author-links.html" . }}</div>
</div>
</div>
{{ end }}
144 changes: 144 additions & 0 deletions layouts/partials/head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="rgb(255,255,255)" />
{{/* Title */}}
{{ if .IsHome -}}
<title>{{ .Site.Title | emojify }}</title>
<meta name="title" content="{{ .Site.Title | emojify }}" />
{{- else -}}
<title>{{ .Title | emojify }} &middot; {{ .Site.Title | emojify }}</title>
<meta name="title" content="{{ .Title | emojify }} &middot; {{ .Site.Title | emojify }}" />
{{- end }}
{{/* Asset bundles */}}
{{ $assets := newScratch }}
{{ $algorithm := .Site.Params.fingerprintAlgorithm | default "sha256" }}
{{ $jsAppearance := resources.Get "js/appearance.js" }}
{{ $jsAppearance = $jsAppearance | resources.Minify | resources.Fingerprint $algorithm }}
<script
type="text/javascript"
integrity="{{ $jsAppearance.Data.Integrity }}"
>
{{ $jsAppearance.Content }}
</script>
{{ $cssScheme := resources.Get (printf "css/schemes/%s.css" (lower .Site.Params.colorScheme | default "congo")) }}
{{ if not $cssScheme }}
{{ $cssScheme = resources.Get "css/schemes/congo.css" }}
{{ end }}
{{ $assets.Add "css" (slice $cssScheme) }}
{{ $cssMain := resources.Get "css/compiled/main.css" }}
{{ $assets.Add "css" (slice $cssMain) }}
{{ $cssCustom := resources.Get "css/custom.css" }}
{{ if $cssCustom }}
{{ $assets.Add "css" (slice $cssCustom) }}
{{ end }}
{{ $bundleCSS := $assets.Get "css" | resources.Concat "css/main.bundle.css" | resources.Minify | resources.Fingerprint $algorithm }}
<link
type="text/css"
rel="stylesheet"
href="{{ $bundleCSS.RelPermalink }}"
integrity="{{ $bundleCSS.Data.Integrity }}"
/>
{{ if .Site.Params.enableSearch | default false }}
{{ $jsFuse := resources.Get "lib/fuse/fuse.min.js" }}
{{ $jsSearch := resources.Get "js/search.js" }}
{{ $assets.Add "js" (slice $jsFuse $jsSearch) }}
{{ end }}
{{ if .Site.Params.enableQuicklink | default false }}
{{ $jsQuicklink := resources.Get "lib/quicklink/quicklink.umd.js" }}
{{ $jsQuicklinkInit := resources.Get "js/quicklink.js" }}
{{ $assets.Add "js" (slice $jsQuicklink $jsQuicklinkInit) }}
{{ end }}
{{ if .Site.Params.enableCodeCopy | default false }}
{{ $jsCode := resources.Get "js/code.js" }}
{{ $assets.Add "js" (slice $jsCode) }}
{{ end }}
{{ if or (eq .Site.Params.header.layout "hamburger") (eq .Site.Params.header.layout "hybrid") }}
{{ $jsMenu := resources.Get "js/menu.js" }}
{{ $assets.Add "js" (slice $jsMenu) }}
{{ end }}
{{ if eq (site.Language.LanguageDirection | default "ltr") "rtl" }}
{{ $jsRTL := resources.Get "js/rtl.js" }}
{{ $assets.Add "js" (slice $jsRTL) }}
{{ end }}
{{ if $assets.Get "js" }}
{{ $bundleJS := $assets.Get "js" | resources.Concat "js/main.bundle.js" | resources.Minify | resources.Fingerprint $algorithm }}
<script
defer
type="text/javascript"
id="script-bundle"
src="{{ $bundleJS.RelPermalink }}"
integrity="{{ $bundleJS.Data.Integrity }}"
data-copy="{{ i18n "code.copy" }}"
data-copied="{{ i18n "code.copied" }}"
></script>
{{ end }}
{{/* Metadata */}}
<meta
name="description"
content="{{ with .Description }}
{{ . }}
{{ else }}
{{ if .IsPage }}
{{ .Summary }}
{{ else }}
{{ with .Site.Params.description }}{{ . }}{{ end }}
{{ end }}
{{ end }}"
/>
{{ with union .Site.Params.keywords .Params.keywords -}}
<meta name="keywords" content="{{ delimit . `, ` }}" />
{{- end }}
{{ with .Site.Params.robots }}
<meta name="robots" content="{{ . }}" />
{{ end }}
{{ with .Params.robots }}
<meta name="robots" content="{{ . }}" />
{{ end }}
<link rel="canonical" href="{{ .Permalink }}" />
{{ range .AlternativeOutputFormats -}}
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .RelPermalink ($.Site.Title | emojify) | safeHTML }}
{{ end -}}
{{/* Icons */}}
{{ if templates.Exists "partials/favicons.html" }}
{{ partialCached "favicons.html" .Site }}
{{ else }}
<link rel="apple-touch-icon" sizes="180x180" href="{{ "apple-touch-icon.png" | relURL }}" />
<link rel="icon" type="image/png" sizes="32x32" href="{{ "favicon-32x32.png" | relURL }}" />
<link rel="icon" type="image/png" sizes="16x16" href="{{ "favicon-16x16.png" | relURL }}" />
<link rel="manifest" href="{{ "site.webmanifest" | relURL }}" />
{{ end }}
{{/* Site Verification */}}
{{ with .Site.Params.verification.google }}
<meta name="google-site-verification" content="{{ . }}" />
{{ end }}
{{ with .Site.Params.verification.bing }}
<meta name="msvalidate.01" content="{{ . }}" />
{{ end }}
{{ with .Site.Params.verification.pinterest }}
<meta name="p:domain_verify" content="{{ . }}" />
{{ end }}
{{ with .Site.Params.verification.yandex }}
<meta name="yandex-verification" content="{{ . }}" />
{{ end }}
{{/* Social */}}
{{ partial "opengraph.html" . }}
{{ template "_internal/twitter_cards.html" . }}
{{/* Schema */}}
{{ partial "schema.html" . }}
{{/* Me */}}
{{ with .Site.Language.Params.Author.name }}<meta name="author" content="{{ . }}" />{{ end }}
{{ with .Site.Language.Params.Author.links }}
{{ range $links := . }}
{{ range $name, $url := $links }}<link href="{{ $url }}" rel="me" />{{ end }}
{{ end }}
{{ end }}
{{/* Vendor */}}
{{ partial "vendor.html" . }}
{{/* Analytics */}}
{{ partial "analytics.html" . }}
{{/* Extend head - eg. for custom analytics scripts, etc. */}}
{{ if templates.Exists "partials/extend-head.html" }}
{{ partial "extend-head.html" . }}
{{ end }}
</head>
30 changes: 30 additions & 0 deletions layouts/partials/home/profile.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<article
class="{{ if not .Site.Params.homepage.showRecent }}
h-full
{{ end }} flex flex-col items-center justify-center text-center"
>
<header class="mb-3 flex flex-col items-center">
{{ with .Site.Language.Params.Author.image }}
{{ $authorImage := resources.Get . }}
{{ if $authorImage }}
{{- $altText := $.Site.Language.Params.Author.name | default "Author" }}
{{ partial "picture.html" (dict "img" $authorImage "alt" $altText "class" "mb-2 h-36 w-36 rounded-full" "maxSize" 288 ) }}
{{ end }}
{{ end }}
<h1 class="text-4xl font-extrabold">
{{ .Site.Language.Params.Author.name | default .Site.Title }}
</h1>
{{ with .Site.Language.Params.Author.headline }}
<h2 class="text-xl text-neutral-500 dark:text-neutral-400">
{{ . | markdownify | emojify }}
</h2>
{{ end }}
<div class="mt-1 text-2xl">
{{ partialCached "author-links.html" . }}
</div>
</header>
<section class="prose dark:prose-invert">{{ .Content | emojify }}</section>
</article>
<section>
{{ partial "recent-articles.html" . }}
</section>
72 changes: 72 additions & 0 deletions layouts/partials/opengraph.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<meta property="og:url" content="{{ .Permalink }}">

{{- with or site.Title site.Params.title | plainify }}
<meta property="og:site_name" content="{{ . }}">
{{- end }}

{{- with or .Title site.Title site.Params.title | plainify}}
<meta property="og:title" content="{{ . }}">
{{- end }}

{{- with or .Description .Summary site.Params.description | plainify }}
<meta property="og:description" content="{{ . }}">
{{- end }}

{{- with or .Params.locale site.Language.LanguageCode site.Language.Lang }}
<meta property="og:locale" content="{{ . }}">
{{- end }}

{{- if .IsPage }}
<meta property="og:type" content="article">
<meta property="article:section" content="{{ .Section }}">
{{- $ISO8601 := "2006-01-02T15:04:05-07:00" }}
{{- with .PublishDate }}
<meta property="article:published_time" {{ .Format $ISO8601 | printf "content=%q" | safeHTMLAttr }}>
{{- end }}
{{- with .Lastmod }}
<meta property="article:modified_time" {{ .Format $ISO8601 | printf "content=%q" | safeHTMLAttr }}>
{{- end }}
{{- range .GetTerms "tags" | first 6 }}
<meta property="article:tag" content="{{ .Page.Title | plainify }}">
{{- end }}
{{- else }}
<meta property="og:type" content="website">
{{- end }}

{{- with partial "_funcs/get-page-images" . }}
{{- range . | first 6 }}
<meta property="og:image" content="{{ (.Image.Resize "1320x webp").RelPermalink }}">
{{- end }}
{{- end }}

{{- with .Params.audio }}
{{- range . | first 6 }}
<meta property="og:audio" content="{{ . | absURL }}">
{{- end }}
{{- end }}

{{- with .Params.videos }}
{{- range . | first 6 }}
<meta property="og:video" content="{{ . | absURL }}">
{{- end }}
{{- end }}

{{- range .GetTerms "series" }}
{{- range .Pages | first 7 }}
{{- if ne $ . }}
<meta property="og:see_also" content="{{ .Permalink }}">
{{- end }}
{{- end }}
{{- end }}

{{- with site.Params.social }}
{{- if reflect.IsMap . }}
{{- with .facebook_app_id }}
<meta property="fb:app_id" content="{{ . }}">
{{- else }}
{{- with .facebook_admin }}
<meta property="fb:admins" content="{{ . }}">
{{- end }}
{{- end }}
{{- end }}
{{- end }}
Loading

0 comments on commit 1aeb48f

Please sign in to comment.