Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/rmaguiar/hugo-theme-color-your-world.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphael Aguiar <rmaguiar@tuta.io>2020-06-22 21:17:46 +0300
committerRaphael Aguiar <rmaguiar@tuta.io>2020-06-22 21:17:46 +0300
commit8f8de1e97b3ffc5a5818742961158564f7f19b1e (patch)
treecc3d70f9f9917304d73501d0301850cb5d55430b /layouts
Initial commit
Diffstat (limited to 'layouts')
-rw-r--r--layouts/404.html8
-rw-r--r--layouts/_default/_markup/render-heading.html18
-rw-r--r--layouts/_default/_markup/render-image.html69
-rw-r--r--layouts/_default/baseof.html54
-rw-r--r--layouts/_default/index.xml44
-rw-r--r--layouts/_default/list.html50
-rw-r--r--layouts/_default/single.html100
-rw-r--r--layouts/_default/sitemap.xml27
-rw-r--r--layouts/index.html32
-rw-r--r--layouts/partials/categories.html5
-rw-r--r--layouts/partials/cover.html45
-rw-r--r--layouts/partials/footer.html40
-rw-r--r--layouts/partials/head.html394
-rw-r--r--layouts/partials/header.html21
-rw-r--r--layouts/partials/katex.html45
-rw-r--r--layouts/partials/pagination.html133
-rw-r--r--layouts/partials/tags.html5
-rw-r--r--layouts/shortcodes/abbr.html8
-rw-r--r--layouts/shortcodes/contact-form.html47
-rw-r--r--layouts/shortcodes/figure.html60
-rw-r--r--layouts/shortcodes/gifoid.html41
-rw-r--r--layouts/shortcodes/img.html51
-rw-r--r--layouts/shortcodes/kbd.html21
-rw-r--r--layouts/shortcodes/social.html257
24 files changed, 1575 insertions, 0 deletions
diff --git a/layouts/404.html b/layouts/404.html
new file mode 100644
index 0000000..44e7d29
--- /dev/null
+++ b/layouts/404.html
@@ -0,0 +1,8 @@
+{{ define "main" }}
+
+ <main>
+ <h1>{{ .Site.Params.notFound.title }}</h1>
+ <p>{{ .Site.Params.notFound.text }}</p>
+ </main>
+
+{{ end }}
diff --git a/layouts/_default/_markup/render-heading.html b/layouts/_default/_markup/render-heading.html
new file mode 100644
index 0000000..85e04c9
--- /dev/null
+++ b/layouts/_default/_markup/render-heading.html
@@ -0,0 +1,18 @@
+<!--
+ Anchor links will be only set with level 2 and 3 headings
+
+ TODO
+ It looks weird when the heading is also a link,
+ but then that's also true for links in ToCs
+ Would like to test a few more things
+-->
+
+{{ $svgBundle := ($.Page.Scratch.Get "svgBundle").RelPermalink }}
+
+{{ $anchoredLinkLevels := slice 2 3 }}
+
+{{ if in $anchoredLinkLevels .Level }}
+ <h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }} {{ printf "<a class=\"anchor\" href=\"#%s\" title='%s \"%s\".'><svg aria-hidden=\"true\"><use xlink:href=\"%s#hashtag\"/></svg></a>" (.Anchor | safeURL) (T "anchor_for") (.Text | plainify | safeHTML) $svgBundle | safeHTML }}</h{{ .Level }}>
+{{ else }}
+ <h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }}</h{{ .Level }}>
+{{ end }}
diff --git a/layouts/_default/_markup/render-image.html b/layouts/_default/_markup/render-image.html
new file mode 100644
index 0000000..25bac7f
--- /dev/null
+++ b/layouts/_default/_markup/render-image.html
@@ -0,0 +1,69 @@
+<!--
+ It always expects the image is inside a folder called "img".
+ File will be converted into 3 versions: 500w, 800w and 1200w.
+
+ Usage:
+ img "weird_cat.jpg" "Something that can (or not) be a cat."
+ img file="weird_cat.jpg" alt="Something that can (or not) be a cat."
+-->
+
+{{ $file := .Destination }}
+{{ $altText := .Text }}
+
+{{ $class := .Page.Param "markupImgClass" | default "borderless" }}
+
+
+{{ $imgPath := .Page.Param "imgPath" }}
+
+{{ if $imgPath }}
+ {{ $file = path.Join $imgPath $file }}
+{{ end }}
+
+{{ $encodedPixel := "image/gif;base64,R0lGODdhAQABAIABAICAgP///ywAAAAAAQABAAACAkQBADs=" }}
+
+<!-- Assume file is local -->
+{{ with $.Page.Resources.GetMatch $file }}
+
+ {{ $placeholder := (.Resize "800x png") | images.Filter (images.Contrast -100) }}
+ {{ $encodedPlaceholder := printf "image/png;base64,%s" ($placeholder.Content | base64Encode) }}
+
+ <img
+ class="lazyload {{ $class }}"
+ loading="lazy"
+ data-srcset="{{ (.Resize "1200x").RelPermalink }} 1200w, {{ (.Resize "800x").RelPermalink }} 800w, {{ (.Resize "500x q90").RelPermalink }} 500w"
+ src="data:{{ $encodedPlaceholder }}"
+ data-src="{{ (.Resize "800x").RelPermalink }}"
+ {{ with $altText }}alt="{{ . }}"{{ end }}
+ />
+
+ <noscript>
+ <img
+ {{ with $class }}class="{{ . }}"{{ end }}
+ loading="lazy"
+ srcset="{{ (.Resize "1200x").RelPermalink }} 1200w, {{ (.Resize "800x").RelPermalink }} 800w, {{ (.Resize "500x q90").RelPermalink }} 500w"
+ src="data:{{ $encodedPlaceholder }}"
+ {{ with $altText }}alt="{{ . }}"{{ end }}
+ />
+ </noscript>
+{{ else }}
+ {{ with (.Destination | safeURL) }}
+ <!-- If local file isn't found, assume it's a remote file -->
+ <img
+ class="lazyload {{ $class }}"
+ loading="lazy"
+ src="data:{{ $encodedPixel }}"
+ data-src="{{ . }}"
+ {{ with $altText }}alt="{{ . }}"{{ end }}
+ />
+
+ <noscript>
+ <img
+ {{ with $class }}class="{{ . }}"{{ end }}
+ loading="lazy"
+ src="{{ . }}"
+ {{ with $altText }}alt="{{ . }}"{{ end }}
+ />
+ </noscript>
+
+ {{ end }}
+{{ end }}
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
new file mode 100644
index 0000000..74f0a26
--- /dev/null
+++ b/layouts/_default/baseof.html
@@ -0,0 +1,54 @@
+<!--
+ Generate and set SVG bundle
+ Currently here to avoid certain priority issues...
+-->
+
+{{- $svgBundle := resources.Get "bundle.svg" | resources.ExecuteAsTemplate "img/bundle.svg" . | minify | resources.Fingerprint "md5" -}}
+{{- $.Page.Scratch.Set "svgBundle" $svgBundle -}}
+
+<!DOCTYPE html>
+<html lang="{{ .Site.Language.Lang }}" data-mode="{{ if .Site.Params.Style.isDark }}dark{{ else }}light{{ end }}">
+ <head prefix="og: http://ogp.me/ns#">
+ {{ partial "head" . }}
+ </head>
+
+ <body>
+
+ <header>
+ {{ partial "header" . }}
+ </header>
+
+ <div class="filler">
+ {{ block "main" . }}
+ <!-- Stuff -->
+ {{ end }}
+ </div>
+
+ <footer>
+ {{ partial "footer" . }}
+ </footer>
+
+ <!--
+ Remnant JavaScript
+ If not using Hugo server, remove every "console.log()"
+ -->
+
+ {{ with resources.Get "js/postpone.js" | resources.ExecuteAsTemplate .Page . | minify }}
+
+ <script>
+ {{ if $.Site.IsServer }}
+ {{ .Content | safeJS }}
+ {{ else }}
+ {{ .Content | replaceRE "console.log(.*?);" "" | safeJS }}
+ {{ end }}
+ </script>
+
+ {{ end }}
+
+ <!-- KaTeX -->
+ {{ if or .Params.katex .Site.Params.katex .Params.math .Site.Params.math }}
+ {{ partial "katex.html" . }}
+ {{ end }}
+
+ </body>
+</html>
diff --git a/layouts/_default/index.xml b/layouts/_default/index.xml
new file mode 100644
index 0000000..2f83faf
--- /dev/null
+++ b/layouts/_default/index.xml
@@ -0,0 +1,44 @@
+{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" | safeHTML }}
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+ <channel>
+ <title>{{ .Site.Title }}</title>
+ <link>{{ .Permalink }}</link>
+ <description>{{ .Site.Params.description }}</description>
+ <generator>Hugo -- gohugo.io</generator>
+
+ {{ with .Site.Language }}
+ <language>{{ . }}</language>
+ {{end}}
+
+ {{ with .Site.Author.email }}
+ <managingEditor>{{ . }}{{ with $.Site.Author.name }} ({{ . }}){{ end }}</managingEditor>
+ {{end}}
+
+ {{ with .Site.Author.email }}
+ <webMaster>{{ . }}{{ with $.Site.Author.name }} ({{ . }}){{ end }}</webMaster>
+ {{end}}
+
+ {{ with .Site.Copyright }}
+ <copyright>{{ . | markdownify | plainify }}</copyright>
+ {{end}}
+
+ {{ if not .Date.IsZero }}
+ <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>
+ {{ end }}
+
+ {{ with .OutputFormats.Get "RSS" }}
+ {{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
+ {{ end }}
+
+ {{ range (where .Site.RegularPages ".Params.sitemap_exclude" "!=" "true") }}
+ <item>
+ <title>{{ .Title | emojify }}</title>
+ <link>{{ .Permalink }}</link>
+ <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
+ {{ with .Site.Author.email }}<author>{{ . }}{{ with $.Site.Author.name }} ({{ . }}){{ end }}</author>{{ end }}
+ <guid>{{ .Permalink }}</guid>
+ <description>{{ if .Description }}{{ .Description | emojify }}{{ else }}{{ .Summary | plainify | truncate 140 }}{{ end }}</description>
+ </item>
+ {{ end }}
+ </channel>
+</rss>
diff --git a/layouts/_default/list.html b/layouts/_default/list.html
new file mode 100644
index 0000000..1ea0aa3
--- /dev/null
+++ b/layouts/_default/list.html
@@ -0,0 +1,50 @@
+{{ define "main" }}
+
+ {{ $currentTitle := .Scratch.Get "currentTitle" }}
+
+ <main class="list">
+
+ <h1>{{ $currentTitle }}</h1>
+
+ {{ if eq .Kind "taxonomyTerm" }}
+ {{ if eq .Type "categories" }}
+ {{ partial "categories" . }}
+ {{ else if eq .Type "tags" }}
+ {{ partial "tags" . }}
+ {{ end }}
+ {{ else }}
+
+ <!--
+ range last 9
+ .Format "2006-01-02"
+ | dateFormat "Jan 02"
+ -->
+
+ {{ $pages := where site.RegularPages "Type" "in" .Site.Params.mainSections }}
+
+ {{ $paginator := .Paginate .Pages }}
+
+ <ul class="posts">
+ {{ range $paginator.Pages }}
+ <li>
+ <a class="btn" href="{{ .RelPermalink }}">
+ <p>{{ .Title | emojify }}</p>
+ {{ if not .Date.IsZero }}<time datetime="{{ .Date | dateFormat "2006-01-02" }}">{{ .Date.Format "2006-01-02" }}</time>{{ end }}
+ </a>
+ </li>
+ {{ end }}
+ </ul>
+
+ {{ partial "pagination" . }}
+
+ {{ if and (gt (len .Site.Taxonomies.tags) 1) (ne .Section "categories") }}
+ <hr>
+ <h2>{{ T "tags" }}</h2>
+ {{ partial "tags" . }}
+ {{ end }}
+
+ {{ end }}
+
+ </main>
+
+{{ end }} \ No newline at end of file
diff --git a/layouts/_default/single.html b/layouts/_default/single.html
new file mode 100644
index 0000000..33dd41e
--- /dev/null
+++ b/layouts/_default/single.html
@@ -0,0 +1,100 @@
+{{ define "main" }}
+
+ {{ $svgBundle := ($.Page.Scratch.Get "svgBundle").RelPermalink }}
+
+ <main>
+ <article>
+ <header>
+
+ <h1>{{ .Title }}</h1>
+
+ {{ if or .Params.categories .Params.tags }}
+ <aside class="tags">
+ <ul>
+ {{- with .Params.categories -}}
+ {{- range sort . -}}
+ <li class="cats"><a class="btn" href="/categories/{{ . | urlize }}">{{ . }}</a></li>
+ {{- end -}}
+ {{- end -}}
+ {{- with .Params.tags -}}
+ {{- range sort . -}}
+ <li><a class="btn" href="/tags/{{ . | urlize }}">{{ . }}</a></li>
+ {{- end -}}
+ {{ end }}
+ </aside>
+ {{- end -}}
+
+ {{ if not .Date.IsZero }}
+ <p>
+ {{ if eq .PublishDate .Lastmod }}
+ {{ T "published_on" }} <time datetime="{{ .PublishDate.Format "2006-01-02" }}">{{ .PublishDate.Format "2006-01-02" }}</time>
+ {{ else }}
+ {{ T "last_updated_on" }} <time datetime="{{ .Lastmod.Format "2006-01-02" }}">{{ .Lastmod.Format "2006-01-02" }}</time>
+ {{ end }}
+ </p>
+ {{ end }}
+
+ {{ if .Params.cover }}
+ {{ partial "cover" . }}
+ {{ end }}
+
+ </header>
+
+ {{ if and .Params.toc (gt (len .Page.TableOfContents) 32) }}
+ <details class="toc" open>
+ <summary>{{ T "table_of_contents" }}</summary>
+ {{ .Page.TableOfContents }}
+ </details>
+ {{ end }}
+
+ <!--
+ For some reason, Chrome will ignore some elements when using TAB
+ (while Firefox will not). Since Chrome is used by the majority,
+ I feel like I need to "fix" this.
+
+ For now, I'll be using "tabindex=0" (but then it makes Firefox
+ complain about accessibility). OH, THIS GONNA BE GREAT.
+
+ Also, sorry for my REGEX skills.
+ -->
+
+ <!-- i18n -->
+ {{ $references := (printf "${1}<h2>%s</h2>" (T "references")) }}
+ {{ $seeFootnotes := (printf "${1} title=\"%s\"" (T "see_footnotes")) }}
+ {{ $returnToText := (printf "${1} title=\"%s\"" (T "return_to_text")) }}
+
+ <!-- a11y, kind of (probably useless) -->
+ {{ $highlightLabel := (printf "${1} aria-label=\"%s\" tabindex=0${2}" (T "box_containing_code")) }}
+
+ <!-- Wrapped to make use of overflow-x property (plus the tabindex thing) -->
+ {{ $improvedTable := printf "<section class=scroll tabindex=0> ${1} </section>" }}
+
+ <!-- Replace the footnote return links with a text label -->
+ {{ $footnoteReturnLink := ( printf "${1}%s${2}" (T "return")) }}
+
+ <!-- OR replace the footnote return links with a SVG icon -->
+ {{ if .Site.Params.Style.hasIconAsFootnoteReturnLink }}
+ {{ $footnoteReturnLink = ( printf "${1}<svg transform=\"rotate(180) translate(0 -1)\" aria-hidden=\"true\" ><use xlink:href=\"%s#caret-down\"/></svg>${2}" $svgBundle) }}
+ {{ end }}
+
+ <!--
+ This is doing 4 things right now (or is it):
+
+ * Adding "tabindex=0" to native table and code fences;
+ * Making tables scrollable;
+ * Localizing some text;
+ * Adding a "h2" to footnotes.
+ -->
+
+ <!--
+ For some reason, I don't seem to be able to capture the "↩" (not even using \x{21A9}).
+ To bypass this, I basically captured everything but the "↩"...
+ -->
+
+ {{ .Content | replaceRE "(<table>(?:.|\n)+?</table>)" $improvedTable | replaceRE "(<div class=\"highlight\"><(?:pre|div) class=\"chroma\")(>)" $highlightLabel | replaceRE "(class=\"footnote-ref\")" $seeFootnotes | replaceRE "(class=\"footnote-backref\")" $returnToText | replaceRE "(<section class=\"footnotes\" role=\"doc-endnotes\">)" $references | replaceRE "(<a (?:.*) class=\"footnote-backref\" (?:.*)>)(?:.*)(</a>)" $footnoteReturnLink | safeHTML }}
+
+ </article>
+
+ </main>
+
+{{ end }}
diff --git a/layouts/_default/sitemap.xml b/layouts/_default/sitemap.xml
new file mode 100644
index 0000000..d3fecaa
--- /dev/null
+++ b/layouts/_default/sitemap.xml
@@ -0,0 +1,27 @@
+{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" | safeHTML }}
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml">
+ {{ range (where .Site.RegularPages ".Params.sitemap_exclude" "!=" "true") }}
+ <url>
+ <loc>{{ .Permalink }}</loc>
+
+ {{ if not .Lastmod.IsZero }}
+ <lastmod>{{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>
+ {{ end }}
+
+ {{ with .Sitemap.ChangeFreq }}
+ <changefreq>{{ . }}</changefreq>
+ {{ end }}
+
+ {{ if ge .Sitemap.Priority 0.0 }}
+ <priority>{{ .Sitemap.Priority }}</priority>
+ {{ end }}
+
+ {{ if .IsTranslated }}
+ {{ range .Translations }}
+ <xhtml:link rel="alternate" hreflang="{{ .Lang }}" href="{{ .Permalink }}" />
+ {{ end }}
+ {{ end }}
+ </url>
+ {{ end }}
+</urlset> \ No newline at end of file
diff --git a/layouts/index.html b/layouts/index.html
new file mode 100644
index 0000000..62c2b9e
--- /dev/null
+++ b/layouts/index.html
@@ -0,0 +1,32 @@
+{{ define "main" }}
+
+ {{ $pages := where site.RegularPages "Type" "in" .Site.Params.mainSections }}
+
+ <main class="index">
+ {{ if .Content }}
+ <h1>{{ .Title | emojify }}</h1>
+ {{ .Content }}
+ {{ else }}
+
+ {{ $paginator := .Paginate $pages }}
+
+ <h1>{{ T "posts" }}</h1>
+
+ <ul class="posts">
+ {{ range $paginator.Pages }}
+ <li>
+ <a class="btn" href="{{ .Permalink }}">
+ <p>{{ .Title | emojify }}</p>
+ {{ if not .Date.IsZero }}<time datetime="{{ .Date | dateFormat "2006-01-02" }}">{{ .Date.Format "2006-01-02" }}</time>{{ end }}
+ </a>
+ </li>
+ {{ end }}
+ </ul>
+
+ {{ partial "pagination" . }}
+
+ {{ end }}
+
+ </main>
+
+{{ end }}
diff --git a/layouts/partials/categories.html b/layouts/partials/categories.html
new file mode 100644
index 0000000..965b291
--- /dev/null
+++ b/layouts/partials/categories.html
@@ -0,0 +1,5 @@
+<ul class="labels">
+ {{ range .Site.Taxonomies.categories }}
+ <li><a class="btn" href="{{ .Page.RelPermalink }}" aria-label="{{ .Page.Title }} ({{ .Count }})">{{ .Page.Title }}</a></li>
+ {{ end }}
+</ul>
diff --git a/layouts/partials/cover.html b/layouts/partials/cover.html
new file mode 100644
index 0000000..047dd39
--- /dev/null
+++ b/layouts/partials/cover.html
@@ -0,0 +1,45 @@
+{{ $file := (.Params.cover) }}
+{{ $altText := (.Params.coverAlt) }}
+
+<!-- https://discourse.gohugo.io/t/ability-to-access-site-params-in-the-front-matter-of-archetypes/9744/6 -->
+{{ $imgPath := .Page.Param "imgPath" }}
+
+{{ if $imgPath }}
+ {{ $file = path.Join $imgPath $file }}
+{{ end }}
+
+{{ with $.Page.Resources.GetMatch $file }}
+
+ {{ $placeholder := (.Resize "800x png") | images.Filter (images.Contrast -100) }}
+ {{ $encodedPlaceholder := printf "image/png;base64,%s" ($placeholder.Content | base64Encode) }}
+
+ {{ $encodedPixel := "image/gif;base64,R0lGODdhAQABAIABAICAgP///ywAAAAAAQABAAACAkQBADs=" }}
+
+ <!--
+ WARNING
+ For some reason I'm not able to printf the whole data URI
+ The ":" seems to be the culprit
+ Trying to escape it didn't work, for now I'm out of ideas
+ so I'll be simply using "data:[printf]" for now
+ -->
+ {{ $testEncodedPlaceholder := printf "data%cimage/png;base64,%s" "\u003A" ($placeholder.Content | base64Encode) }}
+
+ <img
+ class="lazyload cover"
+ loading="lazy"
+ data-srcset="{{ (.Resize "1200x").RelPermalink }} 1200w, {{ (.Resize "800x").RelPermalink }} 800w, {{ (.Resize "500x q90").RelPermalink }} 500w"
+ src="data:{{ $encodedPlaceholder }}"
+ data-src="{{ (.Resize "800x").RelPermalink }}"
+ {{ with $altText }}alt="{{ . }}"{{ end }}
+ />
+
+ <noscript>
+ <img
+ class="cover"
+ loading="lazy"
+ srcset="{{ (.Resize "1200x").RelPermalink }} 1200w, {{ (.Resize "800x").RelPermalink }} 800w, {{ (.Resize "500x q90").RelPermalink }} 500w"
+ src="data:{{ $encodedPlaceholder }}"
+ {{ with $altText }}alt="{{ . }}"{{ end }}
+ />
+ </noscript>
+{{ end }}
diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html
new file mode 100644
index 0000000..6462b80
--- /dev/null
+++ b/layouts/partials/footer.html
@@ -0,0 +1,40 @@
+<!-- Set SVG bundle -->
+{{ $icons := (.Scratch.Get "svgBundle").RelPermalink }}
+
+<!-- Custom footer or default copyright -->
+{{ if or (templates.Exists "partials/custom/footer") (templates.Exists "partials/custom/footer.html") }}
+ {{ partialCached "custom/footer" . }}
+{{ else }}
+ <p>{{ .Site.Copyright | markdownify | emojify }}</p>
+{{ end }}
+
+<!--
+ TODO
+ Maybe I should rethink this
+-->
+
+{{ if gt (len .Translations) 0 }}
+
+ {{ $processedKeys := slice }}
+
+ {{ range .Translations }}
+ {{ $currentKey := printf "<a rel=\"alternate\" hreflang=\"%s\" href=\"%s\">%s</a>" .Language.Lang .RelPermalink .Language.LanguageName }}
+ {{ $processedKeys = $processedKeys | append $currentKey }}
+ {{ end }}
+
+ <p>{{ T "also_available" }}: {{ delimit $processedKeys ", " (T "and") }}.</p>
+
+{{ end }}
+
+
+<!-- Fancy stuff -->
+<aside class="js">
+ <button title="{{ T "change_mode" }}"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><use xlink:href="{{ $icons }}#adjust"/></svg></button><input type="color" list="presets" value="{{ if .Site.Params.Style.isDark }}{{ .Site.Params.style.darkAccent }}{{ else }}{{ .Site.Params.style.lightAccent }}{{ end }}" title="{{ T "change_accent" }}"><datalist id="presets"><option value="{{ .Site.Params.style.lightAccent }}"><option value="{{ .Site.Params.style.darkAccent }}"><!-- Extra colors -->{{- range .Site.Params.style.presets -}}<option value="{{ . }}">{{ end }}</datalist>
+</aside>
+
+<!-- noscript notice -->
+{{ if .Site.Params.hasNoscriptNotice }}
+ <noscript>
+ <p class="noscript">{{ T "noscript" }}</p>
+ </noscript>
+{{ end }}
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
new file mode 100644
index 0000000..fe89a10
--- /dev/null
+++ b/layouts/partials/head.html
@@ -0,0 +1,394 @@
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
+<!-- I'm 99% sure there's a smarter way of doing it but whatever -->
+{{ $currentTitle := (.Title | emojify) }}
+{{ $mainTitle := .Params.mainTitle }}
+
+
+{{ $titleSeparator := .Site.Params.titleSeparator }}
+
+
+{{ if (eq .Kind "404") }}
+
+ <!-- If 404 page -->
+ {{ $currentTitle = .Site.Params.notFound.title }}
+
+{{ else if (eq .Kind "section") }}
+
+ <!-- If it's a post list -->
+ {{ if gt .Paginator.TotalPages 1 }}
+ {{ $mainTitle = printf "%s, %s %s %s %s" .Title (T "page") (string .Paginator.PageNumber) (T "of") (string .Paginator.TotalPages) }}
+ {{ end }}
+
+{{ else if (and (ne .Kind "taxonomyTerm") (eq .Type "tags")) }}
+
+ <!-- If it's a post list for a tag -->
+ {{ $currentTitle = printf "%s: \"%s\"" (T "tag") .Title }}
+
+ {{ if gt .Paginator.TotalPages 1 }}
+ {{ $mainTitle = printf "%s: \"%s\", %s %s %s %s" (T "tag") .Title (T "page") (string .Paginator.PageNumber) (T "of") (string .Paginator.TotalPages) }}
+ {{ else }}
+ {{ $mainTitle = printf "%s: \"%s\"" (T "tag") .Title }}
+ {{ end }}
+
+{{ else if (and (eq .Kind "taxonomyTerm") (eq .Type "tags")) }}
+
+ <!-- /categories/ page -->
+ {{ $currentTitle = (T "tags") }}
+
+{{ else if (and (eq .Kind "taxonomyTerm") (eq .Type "categories")) }}
+
+ <!-- /tags/ page -->
+ {{ $currentTitle = (T "categories") }}
+
+{{ else if and (.IsHome) (not .Content) }}
+
+ <!-- If it's the home page without content -->
+ {{ $currentTitle = (.Site.Title | emojify) }}
+
+{{ end }}
+
+
+{{ $currentDesc := (.Params.Description | emojify) }}
+
+{{ if .IsHome }}
+ {{ $currentDesc = (.Site.Params.description | emojify) }}
+{{ else if and (ne .Kind "taxonomyTerm") (eq .Type "tags") (not .Params.description) }}
+ {{ $currentDesc = (T "posts_under_tag" .) }}
+{{ else if and (ne .Kind "taxonomyTerm") (eq .Type "categories") (not .Params.description) }}
+ {{ $currentDesc = (T "posts_under_category" .) }}
+{{ else if eq .Kind "taxonomyTerm" }}
+ {{ $currentDesc = printf "%s %s." (T "page_containing") ($currentTitle | lower) }}
+{{ else if (eq .Kind "404") }}
+ {{ $currentDesc = .Site.Params.notFound.description }}
+{{ end }}
+
+
+<!-- Scratch -->
+{{ $.Scratch.Set "currentTitle" $currentTitle }}
+
+
+
+<!-- Beginning of the SEO madness -->
+
+<title>
+ {{- if and $titleSeparator (not .Params.disableTitleSeparator ) -}}
+ {{ if $mainTitle }}
+ {{- $mainTitle = printf "%s %s %s" $mainTitle $titleSeparator .Site.Title -}}
+ {{ else }}
+ {{- $mainTitle = printf "%s %s %s" $currentTitle $titleSeparator .Site.Title -}}
+ {{ end }}
+ {{- end -}}
+
+ {{- if $mainTitle -}}
+ {{- $mainTitle -}}
+ {{ else }}
+ {{- $currentTitle -}}
+ {{- end -}}
+</title>
+
+
+{{ with .Site.Params.author }}<meta name="author" content="{{ . }}">{{ end }}
+{{ with $currentDesc }}<meta name="description" content="{{ . }}">{{ end }}
+
+
+<meta name="robots" content="{{ if and (ne .Kind "404") (ne .Params.noindex true) }}index follow{{ else }}noindex follow{{ end }}">
+<meta name="referrer" content="no-referrer-when-downgrade">
+
+
+<!-- Canon -->
+{{ if and (.IsPage) (not .Params.sitemap_exclude) }}
+ {{ if .Params.canonicalURL }}
+ <link rel="canonical" href="{{ .Params.canonicalURL }}">
+ {{ else if and (ne .Kind "404") (ne .Params.sitemap_exclude true) }}
+ <link rel="canonical" href="{{ .Permalink }}">
+ {{ end }}
+{{ else if (eq .Kind "section") }}
+ <link rel="canonical" href="{{ .Paginator.URL | absURL }}">
+
+ {{ if .Paginator.HasPrev }}
+ <link rel="prev" href="{{ .Paginator.Prev.URL | absURL }}">
+ {{ end }}
+
+ {{ if .Paginator.HasNext }}
+ <link rel="next" href="{{ .Paginator.Next.URL | absURL }}">
+ {{ end }}
+{{ end }}
+
+
+
+<!-- Reserved -->
+{{ if or (templates.Exists "partials/custom/head") (templates.Exists "partials/custom/head.html") }}
+ {{ partial "custom/head" . }}
+{{ end }}
+
+
+
+<!-- Open Graph / Twitter Card -->
+<meta property="og:site_name" content="{{ .Site.Title }}">
+<meta property="og:title" content="{{ $currentTitle }}">
+{{ with $currentDesc }}<meta property="og:description" content="{{ . }}">{{ end }}
+
+{{- if ne .Kind "404" }}
+ <meta property="og:url" content="{{ .Permalink }}">
+{{ end -}}
+
+
+<!-- Generated images for Open Graph, Twitter Cards and also Schema.org -->
+
+{{ $imgPath := .Page.Param "imgPath" }}
+
+{{- if .Params.cover }}
+
+ {{ $file := .Params.cover }}
+
+ {{ if $imgPath }}
+ {{ $file = path.Join $imgPath $file }}
+ {{ end }}
+
+ {{- with .Resources.GetMatch $file }}
+ <meta property="og:image" content="{{ (.Fill "1200x630").Permalink }}">
+ <meta property="og:image:width" content="1200">
+ <meta property="og:image:height" content="630">
+ {{ with $.Params.coverAlt }}
+ <meta property="og:image:alt" content="{{ . }}">
+ {{ end }}
+ <meta name="twitter:card" content="summary_large_image">
+ <meta name="twitter:image" content="{{ (.Fill "1280x640").Permalink }}">
+
+ {{ $.Scratch.Set "schemaCover" (.Fill "960x540").Permalink }}
+ {{ end -}}
+{{ else if .Site.Params.cover }}
+ {{ with resources.Get (.Site.Params.cover | default "img/cover.jpg") }}
+ <meta property="og:image" content="{{ (.Fill "1200x630 center").Permalink }}">
+ <meta property="og:image:width" content="1200">
+ <meta property="og:image:height" content="630">
+ {{ with $.Site.Params.coverAlt }}
+ <meta property="og:image:alt" content="{{ . }}">
+ {{ end }}
+ <meta name="twitter:card" content="summary_large_image">
+ <meta name="twitter:image" content="{{ (.Fill "1280x640 center").Permalink }}">
+
+ {{ $.Scratch.Set "schemaCover" (.Fill "960x540").Permalink }}
+ {{ end }}
+{{ end -}}
+
+<!-- More social crap -->
+{{ if and (.IsPage) (not .Params.sitemap_exclude) }}
+ <meta property="og:type" content="article">
+
+ {{ if not .Date.IsZero }}
+ <meta property="article:published_time" content="{{ .PublishDate.Format "2006-01-02" | safeHTML }}">
+ <meta property="article:modified_time" content="{{ .Lastmod.Format "2006-01-02" | safeHTML }}">
+ <meta property="og:updated_time" content="{{ .Lastmod.Format "2006-01-02" | safeHTML }}">
+ {{ end }}
+
+ {{ with .Params.author }}
+ <meta property="article:author" content="{{ . }}">
+ {{ end }}
+
+ {{ with .Site.Params.Social.Centralized.twitter }}
+ <meta name="twitter:creator" content="{{ (urls.Parse (index . 0)).Path | replaceRE "/" "@" }}">
+ {{ end}}
+
+{{ else }}
+ <meta property="og:type" content="website">
+{{ end -}}
+
+{{ with .Site.Params.Social.Centralized.twitter }}
+ <meta name="twitter:site" content="{{ (urls.Parse (index . 0)).Path | replaceRE "/" "@" }}">
+{{ end }}
+
+
+
+{{ with .Site.Params.locale }}
+ <meta property="og:locale" content="{{ . }}">
+{{ end }}
+
+{{ if .Site.Config.Privacy.Twitter.EnableDNT }}
+ <meta name="twitter:dnt" content="on">
+{{ end }}
+
+<!-- Feed -->
+<link rel="alternate" type="application/rss+xml" href="{{ "index.xml" | relURL }}" title="{{ .Site.Title }}">
+
+<!-- i18n -->
+{{ if .IsTranslated }}
+ {{ range .Translations }}
+ <link rel="alternate" hreflang="{{ .Language.Lang }}" href="{{ .Permalink }}" title="{{ .Language.LanguageName }}">
+ {{ end }}
+{{ end }}
+
+
+<!-- Will be replaced by JS anyway -->
+<meta name="theme-color" content="#222">
+
+<meta name="apple-mobile-web-app-capable" content="yes">
+<meta name="apple-mobile-web-app-status-bar-style" content="default">
+
+
+<!-- Social on Schema.org -->
+{{ $sameAs := slice }}
+
+{{ range .Site.Params.Social.Centralized }}
+ {{ $sameAs = $sameAs | append (index . 0) }}
+{{ end }}
+
+{{ range .Site.Params.Social.Decentralized }}
+ {{ range . }}
+ {{ $sameAs = $sameAs | append (index . 0) }}
+ {{ end }}
+{{ end }}
+
+
+
+<!-- Schema Markup / Structured Data -->
+
+<!--
+ TODO
+ The lack of "datePublished" will throw an error,
+ but I don't know if leaving it as "0001-01-01" is any better.
+
+ Also, there's something wrong with the Google's validation tool. It's ignoring the "Person" type for https://schema.org/publisher.
+
+ Reference: https://www.drupal.org/project/schema_metatag/issues/3097526
+-->
+
+{{ if and (in .Site.Params.mainSections .Section) (not .Params.sitemap_exclude) }}
+ <script type="application/ld+json">
+ {
+ "@context": "https://schema.org",
+ "@type": "Article",
+ "mainEntityOfPage": {
+ "@type": "WebSite",
+ "@id": "{{ .Site.BaseURL }}"
+ },
+ "headline": {{ $currentTitle }},
+ "description": {{ $currentDesc }},
+ {{ with $.Scratch.Get "schemaCover" }}"image": "{{ . }}",{{ end }}
+ "url": "{{ .Permalink }}",
+ "inLanguage": "{{ .Site.Language.Lang }}",
+ "datePublished": "{{ .PublishDate.Format "2006-01-02" | safeHTML }}",
+ {{ with .Lastmod }}"dateModified": "{{ .Format "2006-01-02" | safeHTML }}",{{ end }}
+ "wordCount" : "{{ .WordCount }}",
+ "publisher": {
+ "@type": "Person",
+ "name": "{{ .Site.Params.author }}"
+ },
+ "author": {
+ "@type": "Person",
+ "name": "{{ .Site.Params.author }}",
+ {{ with .Site.Params.authorDesc }}"description": {{ . }},{{ end }}
+ {{ if gt (len $sameAs) 0 }}"sameAs": {{ $sameAs }}{{ end }}
+ }
+ }
+ </script>
+{{ else }}
+ <script type="application/ld+json">
+ {
+ "@context": "https://schema.org",
+ "@type": "WebSite",
+ "url": "{{ .Site.BaseURL }}",
+ "inLanguage": "{{ .Site.Language.Lang }}",
+ "name": {{ .Site.Title }},
+ "description": {{ .Site.Params.description | emojify }},
+ "publisher": "{{ .Site.Params.author }}"
+ }
+ </script>
+{{ end }}
+
+
+
+<!-- Main CSS -->
+{{ $main := resources.Get "scss/main.scss" | resources.ExecuteAsTemplate "css/main.scss" . | toCSS | minify | resources.Fingerprint "sha512" }}
+<link rel="stylesheet" href="{{ $main.RelPermalink }}" integrity="{{ $main.Data.Integrity }}">
+
+
+<!-- If JS is disabled -->
+<noscript>
+
+ <!-- Not properly tested? -->
+ <meta name="theme-color" content="{{ .Site.Params.Style.lightAccent }}" {{ if .Site.Params.Style.isDark }}media="(prefers-color-scheme: light)"{{ end }}>
+ <meta name="theme-color" content="{{ .Site.Params.Style.darkAccent }}" {{ if not .Site.Params.Style.isDark }}media="(prefers-color-scheme: dark)"{{ end }}>
+
+ <style>
+
+ html {
+ --accent: {{ if .Site.Params.Style.isDark }}{{ .Site.Params.Style.darkAccent }}{{ else }}{{ .Site.Params.Style.lightAccent }}{{ end }};
+ }
+
+ .js,
+ img.lazyload {
+ display: none;
+ }
+
+ </style>
+</noscript>
+
+
+<!-- Exclusive CSS / CSS that "ideally" should appear once -->
+{{ if or (.HasShortcode "contact-form") (.HasShortcode "social") }}
+ <style>
+ {{ if .HasShortcode "contact-form" }}
+ {{ with resources.Get "scss/exclusive/contact-form.scss" | resources.ExecuteAsTemplate .Layout . | toCSS | minify }}
+ {{ .Content | safeCSS }}
+ {{ end }}
+ {{ end }}
+
+ {{ if .HasShortcode "social" }}
+ {{ with resources.Get "scss/exclusive/social.scss" | resources.ExecuteAsTemplate .Layout . | toCSS | minify }}
+ {{ .Content | safeCSS }}
+ {{ end }}
+ {{ end }}
+ </style>
+{{ end }}
+
+
+<!-- Should be loaded even if browser has native lazy load support -->
+
+{{ $lazysizes := resources.Get "lazysizes@5.2.2/lazysizes.min.js" | resources.ExecuteAsTemplate "js/lazysizes.min.js" . | minify | resources.Fingerprint "sha512" }}
+
+<script defer src="{{ $lazysizes.RelPermalink }}" integrity="{{ $lazysizes.Data.Integrity }}" crossorigin="anonymous"></script>
+
+
+<!-- KaTeX -->
+{{ if or .Params.katex .Site.Params.katex .Params.math .Site.Params.math }}
+ <!-- Preconnect -->
+ <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
+{{ end }}
+
+
+<!--
+ rel="me"
+ Not even sure how useful is this nowdays,
+ but since it's easy to implement...
+-->
+
+{{ range .Site.Params.Social.Centralized }}
+ <link rel="me" href="{{ index . 0 }}"/>
+{{ end }}
+
+{{ range .Site.Params.Social.Decentralized }}
+ {{ range . }}
+ <link rel="me" href="{{ index . 0 }}"/>
+ {{ end }}
+{{ end }}
+
+
+<!--
+ Priority JavaScript
+ If not using Hugo server, remove every "console.log()"
+-->
+
+{{ with resources.Get "js/prepone.js" | resources.ExecuteAsTemplate .Page . | minify }}
+
+ <script>
+ {{ if $.Site.IsServer }}
+ {{ .Content | safeJS }}
+ {{ else }}
+ {{ .Content | replaceRE "console.log(.*?);" "" | safeJS }}
+ {{ end }}
+ </script>
+
+{{ end }}
diff --git a/layouts/partials/header.html b/layouts/partials/header.html
new file mode 100644
index 0000000..413b592
--- /dev/null
+++ b/layouts/partials/header.html
@@ -0,0 +1,21 @@
+<!-- Site title -->
+{{ if or (templates.Exists "partials/custom/header") (templates.Exists "partials/custom/header.html") }}
+ {{ partialCached "custom/header" . }}
+{{ else }}
+ <a href="{{ .Site.BaseURL | relLangURL }}">{{ .Site.Title }}</a>
+{{ end }}
+
+<!-- Menu -->
+{{ if .Site.Menus.main }}
+ {{ with .Site.Menus.main }}
+ <nav>
+ <ul>
+ {{ range . }}
+ <li>
+ <a class="btn" href="{{ .URL | relLangURL }}">{{ .Name }}</a>
+ </li>
+ {{ end }}
+ </ul>
+ </nav>
+ {{ end }}
+{{ end }}
diff --git a/layouts/partials/katex.html b/layouts/partials/katex.html
new file mode 100644
index 0000000..64b9a37
--- /dev/null
+++ b/layouts/partials/katex.html
@@ -0,0 +1,45 @@
+<!-- KaTeX -->
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha512-SBL9R0mkYbWGuy/0DLHNxYHPScUMar9Y55t8vrnN42ZYfLZ4SnjXqCFfEhPTnj9pedAs5F+WZkzjq1qGS8+VGg==" crossorigin="anonymous">
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js" integrity="sha512-2k+W+3OGhtd3whnGt33ek/oA1M/aqB6Mir+WIcCrSuIC2yD6iTX6IuPf5q1oEJGQT06jma5K6ca7Xqb4u7Urow==" crossorigin="anonymous"></script>
+
+<!-- mchem extension -->
+{{ if or (in .Params.katexExtensions "mchem") (in .Site.Params.katexExtensions "mchem") }}
+ <script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/contrib/mhchem.min.js" integrity="sha512-B4sSu3isYYpaurfStmXsh1wL71s8xKFZyNjCCuUHw8feCh9RlpG03x8+a3egFiZ1VuCoj6463IY18VnrDBbKuA==" crossorigin="anonymous"></script>
+{{ end }}
+
+<!-- copy-tex extension -->
+{{ if or (in .Params.katexExtensions "copy-tex") (in .Site.Params.katexExtensions "copy-tex") }}
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/contrib/copy-tex.css" integrity="sha512-gLOBccbZVR13Jvu/EZJAGz9C6P8CGD10sCGt/EdH5xHMKU3S9m43i6BX0ZqWIKeRo0JYXJiLi3Lv0gCAxFqz+Q==" crossorigin="anonymous">
+ <script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/contrib/copy-tex.min.js" integrity="sha512-DJT2Gf9zoglFWNuxgFcMZ3zi9Ra9GPDxpw9/8kyQ6cji+SOaLlV1A49Its53eLZlGfb4WjwRCptEUdNju6Wxgw==" crossorigin="anonymous"></script>
+{{ end }}
+
+<!-- auto-render extension + tabIndex HACK (see below) -->
+<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/contrib/auto-render.min.js" integrity="sha512-GicGrbLBXJh2kbF+DYD+sCW5hPavoOfVAKSOE7+qgYCgVTcwe+/D4LXegS9JVTY72ovc5Ung4Fml+i1uD3uOyQ==" crossorigin="anonymous" onload="renderMathInElement(document.body);addTabIndex()"></script>
+
+<!--
+ HACK
+ Google Chrome will ignore "scroll" elements while navigating via keyboard
+ I could "fix" such behavior by using "tabindex=0"
+ But since KaTeX stuff here is being injected with JS, it seems I need to fight JS with JS
+
+ (what a BS...)
+-->
+
+<script>
+
+ function addTabIndex() {
+
+ const $katexBlocks = getAll('span.katex-display');
+
+ // While we are at it... Some a11y
+ const $katexLabel = {{ T "box_containing_expression" }};
+
+ $katexBlocks.forEach(function ($el) {
+ $el.tabIndex = 0;
+
+ $el.setAttribute('aria-label', $katexLabel);
+ })
+
+ }
+
+</script>
diff --git a/layouts/partials/pagination.html b/layouts/partials/pagination.html
new file mode 100644
index 0000000..4434645
--- /dev/null
+++ b/layouts/partials/pagination.html
@@ -0,0 +1,133 @@
+{{ $icons := (.Scratch.Get "svgBundle").RelPermalink }}
+
+{{ $pag := $.Paginator }}
+
+
+<!--
+ Blatantly copied from Glenn McComb
+ Source: https://glennmccomb.com/articles/how-to-build-custom-hugo-pagination/
+-->
+
+<!-- Number of links either side of the current page. Default value is 2 -->
+{{ $adjacent_links := 1 }}
+
+<!-- $max_links = ($adjacent_links * 2) + 1 -->
+{{ $max_links := (add (mul $adjacent_links 2) 1) }}
+
+<!-- $lower_limit = $adjacent_links + 1 -->
+{{ $lower_limit := (add $adjacent_links 1) }}
+
+<!-- $upper_limit = $pag.TotalPages - $adjacent_links -->
+{{ $upper_limit := (sub $pag.TotalPages $adjacent_links) }}
+
+<!-- If there's more than one page. -->
+{{ if gt $pag.TotalPages 1 }}
+
+ <nav>
+ <ul class="pagination">
+
+ <!-- First page. -->
+ {{ if ne $pag.PageNumber 1 }}
+ <li>
+ <a class="btn" href="{{ $pag.First.URL }}" aria-label="{{ T "go_to_first" }}">
+ <svg aria-hidden="true">
+ <use transform="rotate(180) translate(-18 -18)" xlink:href="{{ $icons }}#angle-double-right"/>
+ </svg>
+ </a>
+ </li>
+ {{ end }}
+
+ <!-- Previous page. -->
+ {{ if $pag.HasPrev }}
+ <li>
+ <a class="btn" href="{{ $pag.Prev.URL }}" aria-label="{{ T "go_to_prev" }}">
+ <svg transform="rotate(180)" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#angle-right"/>
+ </svg>
+ </a>
+ </li>
+ {{ end }}
+
+ <!-- Page numbers. -->
+ {{ range $pag.Pagers }}
+
+ {{ $.Scratch.Set "page_number_flag" false }}
+
+ <!-- Advanced page numbers. -->
+ {{ if gt $pag.TotalPages $max_links }}
+
+ <!-- Lower limit pages. -->
+ <!-- If the user is on a page which is in the lower limit. -->
+ {{ if le $pag.PageNumber $lower_limit }}
+
+ <!-- If the current loop page is less than max_links. -->
+ {{ if le .PageNumber $max_links }}
+ {{ $.Scratch.Set "page_number_flag" true }}
+ {{ end }}
+
+
+ <!-- Upper limit pages. -->
+ <!-- If the user is on a page which is in the upper limit. -->
+ {{ else if ge $pag.PageNumber $upper_limit }}
+
+ <!-- If the current loop page is greater than total pages minus $max_links -->
+ {{ if gt .PageNumber (sub $pag.TotalPages $max_links) }}
+ {{ $.Scratch.Set "page_number_flag" true }}
+ {{ end }}
+
+
+ <!-- Middle pages. -->
+ {{ else }}
+
+ {{ if and ( ge .PageNumber (sub $pag.PageNumber $adjacent_links) ) ( le .PageNumber (add $pag.PageNumber $adjacent_links) ) }}
+ {{ $.Scratch.Set "page_number_flag" true }}
+ {{ end }}
+
+ {{ end }}
+
+
+ <!-- Simple page numbers. -->
+ {{ else }}
+
+ {{ $.Scratch.Set "page_number_flag" true }}
+
+ {{ end }}
+
+ <!-- Output page numbers. -->
+ {{ if eq ($.Scratch.Get "page_number_flag") true }}
+ <li {{ if eq . $pag }}class="current"{{ end }}>
+ {{ if eq . $pag }}
+ <p>{{ .PageNumber }}</p>
+ {{ else }}
+ <a class="btn" href="{{ .URL }}" aria-label="{{ T "go_to_pag" . }}" >{{ .PageNumber }}</a>
+ {{ end }}
+ </li>
+ {{ end }}
+
+ {{ end }}
+
+ <!-- Next page. -->
+ {{ if $pag.HasNext }}
+ <li>
+ <a class="btn" href="{{ $pag.Next.URL }}" aria-label="{{ T "go_to_next" }}">
+ <svg aria-hidden="true">
+ <use xlink:href="{{ $icons }}#angle-right"/>
+ </svg>
+ </a>
+ </li>
+ {{ end }}
+
+ <!-- Last page. -->
+ {{ if ne $pag.PageNumber $pag.TotalPages }}
+ <li>
+ <a class="btn" href="{{ $pag.Last.URL }}" aria-label="{{ T "go_to_last" }}">
+ <svg aria-hidden="true">
+ <use xlink:href="{{ $icons }}#angle-double-right"/>
+ </svg>
+ </a>
+ </li>
+ {{ end }}
+
+ </ul>
+ </nav>
+{{ end }}
diff --git a/layouts/partials/tags.html b/layouts/partials/tags.html
new file mode 100644
index 0000000..c750c3a
--- /dev/null
+++ b/layouts/partials/tags.html
@@ -0,0 +1,5 @@
+<ul class="tags">
+ {{ range .Site.Taxonomies.tags }}
+ <li><a class="btn" href="{{ .Page.RelPermalink }}" aria-label="{{ .Page.Title }} ({{ .Count }})">{{ .Page.Title }} <span>{{ .Count }}</span></a></li>
+ {{ end }}
+</ul>
diff --git a/layouts/shortcodes/abbr.html b/layouts/shortcodes/abbr.html
new file mode 100644
index 0000000..7884531
--- /dev/null
+++ b/layouts/shortcodes/abbr.html
@@ -0,0 +1,8 @@
+<!--
+ abbr "idk" "I don't know"
+-->
+
+{{ $abbr := (.Get 0) }}
+{{ $title := (.Get 1) }}
+
+<abbr title="{{ $title }}">{{ $abbr }}</abbr>
diff --git a/layouts/shortcodes/contact-form.html b/layouts/shortcodes/contact-form.html
new file mode 100644
index 0000000..8e841d9
--- /dev/null
+++ b/layouts/shortcodes/contact-form.html
@@ -0,0 +1,47 @@
+{{ $autoComplete := "off" }}
+
+{{ if or .Page.Params.Contact.autoComplete .Site.Params.Contact.autoComplete }}
+ {{ $autoComplete = "on" }}
+{{ end }}
+
+
+<form id="contact" action="https://formspree.io/{{ or .Page.Params.Contact.formspreeFormId .Site.Params.Contact.formspreeFormId }}" method="post" accept-charset="utf-8">
+ <label>{{ T "name" }}
+ <input aria-label="{{ T "name" }}" type="text" name="name" minlength="3" {{ with or .Page.Params.Contact.Placeholder.name .Site.Params.Contact.Placeholder.name }}placeholder="{{ . }}"{{ end }} autocomplete="{{ $autoComplete }}" required>
+ </label>
+
+ <label>Email<input aria-label="Email" type="email" name="_replyto" {{ with or .Page.Params.Contact.Placeholder.email .Site.Params.Contact.Placeholder.email }}placeholder="{{ . }}"{{ end }} autocomplete="{{ $autoComplete }}" required></label>
+
+ {{ with or .Page.Params.Contact.subject .Site.Params.Contact.subject }}
+ {{ if gt (len .) 1 }}
+ <label>{{ T "subject" }}
+ <select aria-label="{{ T "subject" }}" name="_subject">
+
+ {{ range . }}
+ <option>{{ . }}</option>
+ {{ end }}
+
+ </select>
+ </label>
+ {{ else }}
+ <input type="hidden" name="_subject" value="{{ index . 0 }}" />
+ {{ end }}
+ {{ else }}
+
+ {{ with or .Page.Params.Contact.Placeholder.subject .Site.Params.Contact.Placeholder.subject }}
+ <label>{{ T "subject" }}
+ <input aria-label="{{ T "subject" }}" type="text" name="_subject" minlength="6" placeholder="{{ . }}" autocomplete="{{ $autoComplete }}" required>
+ </label>
+ {{ end }}
+
+ {{ end }}
+
+
+ <label>{{ T "message" }}<textarea id="message" aria-label="{{ T "message" }}" rows="6" name="message" {{ with or .Page.Params.Contact.messageMinLength .Site.Params.Contact.messageMinLength }}minlength="{{ . }}"{{ end }} {{ with or .Page.Params.Contact.Placeholder.message .Site.Params.Contact.Placeholder.message }}placeholder="{{ . }}"{{ end }} required></textarea></label>
+
+ <input type="text" name="_gotcha" style="display:none">
+
+ <input type="submit" value="{{ T "submit" }}">
+
+</form>
+ \ No newline at end of file
diff --git a/layouts/shortcodes/figure.html b/layouts/shortcodes/figure.html
new file mode 100644
index 0000000..8c6a85e
--- /dev/null
+++ b/layouts/shortcodes/figure.html
@@ -0,0 +1,60 @@
+<!--
+ It always expects the image is inside a folder called "img".
+ File will be converted into 3 versions: 500w, 800w and 1200w.
+
+ Usage:
+ figure "weird_cat.jpg" "Something that can (or not) be a cat."
+ figure file="weird_cat.jpg" alt="Something that can (or not) be a cat."
+ figure class="border" file="weird_cat.jpg" alt="Something that can (or not) be a cat."
+ figure "weird_cat.jpg" "Something that can (or not) be a cat." "border"
+ figure class="border" file="weird_cat.jpg" caption="Something that can (or not) be a cat." alt="Ask someone blind if a caption and alt text are the same thing."
+
+ Default classes:
+ border
+ borderless
+-->
+
+{{ $file := .Get "file" | default (.Get 0) }}
+{{ $caption := .Get "caption" | default (.Get 1) | markdownify }}
+{{ $class := .Get "class" | default (.Get 2) }}
+{{ $alt := .Get "alt" | default $caption }}
+
+
+{{ $imgPath := .Page.Param "imgPath" }}
+
+{{ if $imgPath }}
+ {{ $file = path.Join $imgPath $file }}
+{{ end }}
+
+{{ with $.Page.Resources.GetMatch $file }}
+
+ {{ $placeholder := (.Resize "800x png") | images.Filter (images.Contrast -100) }}
+ {{ $encodedPlaceholder := printf "image/png;base64,%s" ($placeholder.Content | base64Encode) }}
+ {{ $encodedPixel := "image/gif;base64,R0lGODdhAQABAIABAICAgP///ywAAAAAAQABAAACAkQBADs=" }}
+
+ <figure>
+ <img
+ class="lazyload {{ $class }}"
+ loading="lazy"
+ data-srcset="{{ (.Resize "1200x").RelPermalink }} 1200w, {{ (.Resize "800x").RelPermalink }} 800w, {{ (.Resize "500x q90").RelPermalink }} 500w"
+ src="data:{{ $encodedPlaceholder }}"
+ data-src="{{ (.Resize "800x").RelPermalink }}"
+ {{ with $alt }}alt="{{ . }}"{{ end }}
+ />
+
+ <noscript>
+ <img
+ {{ with $class }}class="{{ . }}"{{ end }}
+ loading="lazy"
+ srcset="{{ (.Resize "1200x").RelPermalink }} 1200w, {{ (.Resize "800x").RelPermalink }} 800w, {{ (.Resize "500x q90").RelPermalink }} 500w"
+ src="data:{{ $encodedPlaceholder }}"
+ {{ with $alt }}alt="{{ . }}"{{ end }}
+ />
+ </noscript>
+
+ {{ with $caption }}
+ <figcaption>{{ . }}</figcaption>
+ {{ end }}
+
+ </figure>
+{{ end }}
diff --git a/layouts/shortcodes/gifoid.html b/layouts/shortcodes/gifoid.html
new file mode 100644
index 0000000..715f20d
--- /dev/null
+++ b/layouts/shortcodes/gifoid.html
@@ -0,0 +1,41 @@
+<!--
+ Using videos as "GIFs"
+
+ Convert them to video using ffmpeg or whatever, place them in a
+ folder named "video" (can be changed via params "videoPath"),
+ then use this shortcode.
+
+ For reference:
+ https://web.dev/replace-gifs-with-videos/
+
+ More references:
+ ffmpeg -i "cat_n_laser.gif" -b:v 0 -crf 25 "cat_n_laser.mp4"
+ ffmpeg -i "cat_n_laser.gif" -c vp9 -b:v 0 -crf 41 "cat_n_laser.webm"
+ ffmpeg -i "cat_n_laser.mp4" -vframes 1 -q:v 2 "cat_n_laser.jpg"
+
+ Usage:
+ gifoid "cat_n_laser" "It's your standard internet cat chasing a laser pointer." border
+
+ Default classes:
+ border
+ borderless
+
+ TODO
+ * Write a routine (using os.Stat?) that places the smallest file
+ at the top of the video tag, as it's apparently important.
+ * Allow the user to use the full filename and the shortcode will
+ strip its extension.
+-->
+
+{{ $fileName := (.Get 0) }}
+{{ $title := (.Get 1) }}
+{{ $class := (.Get 2) }}
+
+{{ $videoPath := .Page.Params.videoPath | default "video" }}
+{{ $filePath := path.Join $videoPath $fileName }}
+
+<video class="gifoid {{ $class }}" autoplay loop muted playsinline {{ with $title }}title="{{ . }}"{{ end }}>
+ <source src="{{ $filePath }}.mp4" type="video/mp4">
+ <source src="{{ $filePath }}.webm" type="video/webm">
+ <p class="error">{{ T "missing_codec" }}</p>
+</video>
diff --git a/layouts/shortcodes/img.html b/layouts/shortcodes/img.html
new file mode 100644
index 0000000..0c4bd7a
--- /dev/null
+++ b/layouts/shortcodes/img.html
@@ -0,0 +1,51 @@
+<!--
+ It always expects the image is inside a folder called "img".
+ File will be converted into 3 versions: 500w, 800w and 1200w.
+
+ Usage examples:
+ img "weird_cat.jpg" "Something that can (or not) be a cat."
+ img file="weird_cat.jpg" alt="Something that can (or not) be a cat."
+ img class="border" file="weird_cat.jpg" alt="Something that can (or not) be a cat."
+ img "weird_cat.jpg" "Something that can (or not) be a cat." "border"
+
+ Default classes:
+ border
+ borderless
+-->
+
+{{ $file := .Get "file" | default (.Get 0) }}
+{{ $altText := .Get "alt" | default (.Get 1) }}
+{{ $class := .Get "class" | default (.Get 2) }}
+
+
+{{ $imgPath := .Page.Param "imgPath" }}
+
+{{ if $imgPath }}
+ {{ $file = path.Join $imgPath $file }}
+{{ end }}
+
+{{ with $.Page.Resources.GetMatch $file }}
+
+ {{ $placeholder := (.Resize "800x png") | images.Filter (images.Contrast -100) }}
+ {{ $encodedPlaceholder := printf "image/png;base64,%s" ($placeholder.Content | base64Encode) }}
+ {{ $encodedPixel := "image/gif;base64,R0lGODdhAQABAIABAICAgP///ywAAAAAAQABAAACAkQBADs=" }}
+
+ <img
+ class="lazyload {{ $class }}"
+ loading="lazy"
+ data-srcset="{{ (.Resize "1200x").RelPermalink }} 1200w, {{ (.Resize "800x").RelPermalink }} 800w, {{ (.Resize "500x q90").RelPermalink }} 500w"
+ src="data:{{ $encodedPlaceholder }}"
+ data-src="{{ (.Resize "800x").RelPermalink }}"
+ {{ with $altText }}alt="{{ . }}"{{ end }}
+ />
+
+ <noscript>
+ <img
+ {{ with $class }}class="{{ . }}"{{ end }}
+ loading="lazy"
+ srcset="{{ (.Resize "1200x").RelPermalink }} 1200w, {{ (.Resize "800x").RelPermalink }} 800w, {{ (.Resize "500x q90").RelPermalink }} 500w"
+ src="data:{{ $encodedPlaceholder }}"
+ {{ with $altText }}alt="{{ . }}"{{ end }}
+ />
+ </noscript>
+{{ end }}
diff --git a/layouts/shortcodes/kbd.html b/layouts/shortcodes/kbd.html
new file mode 100644
index 0000000..e6421b3
--- /dev/null
+++ b/layouts/shortcodes/kbd.html
@@ -0,0 +1,21 @@
+<!--
+ usage:
+ kdb "Ctrl" "Shift" "i"
+
+ output:
+ Ctrl + Shift + i
+-->
+
+{{ $semanticKeyboardKeys := slice }}
+
+{{ range .Params }}
+ {{ $currentKey := printf "<kbd>%s</kbd>" . }}
+
+ {{ $semanticKeyboardKeys = $semanticKeyboardKeys | append $currentKey }}
+{{ end }}
+
+{{ if gt $semanticKeyboardKeys 1 }}
+ <kbd>{{- delimit $semanticKeyboardKeys "+" -}}</kbd>
+{{ else }}
+ {{- delimit $semanticKeyboardKeys "+" -}}
+{{ end }} \ No newline at end of file
diff --git a/layouts/shortcodes/social.html b/layouts/shortcodes/social.html
new file mode 100644
index 0000000..a27a962
--- /dev/null
+++ b/layouts/shortcodes/social.html
@@ -0,0 +1,257 @@
+{{ $svgBundle := resources.Get "bundle.svg" | resources.ExecuteAsTemplate "img/bundle.svg" . | minify | resources.Fingerprint "md5" }}
+{{ $icons := $svgBundle.RelPermalink }}
+
+<section class="social">
+
+ {{ with or .Page.Params.Social.Centralized.facebook .Site.Params.Social.Centralized.facebook }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "Facebook" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#facebook"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+ {{ with or .Page.Params.Social.Centralized.github .Site.Params.Social.Centralized.github }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "GitHub" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#github"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+ {{ with or .Page.Params.Social.Centralized.gitlab .Site.Params.Social.Centralized.gitlab }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "GitLab" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#gitlab"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+ {{ with or .Page.Params.Social.Centralized.instagram .Site.Params.Social.Centralized.instagram }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "Instagram" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#instagram"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+ {{ with or .Page.Params.Social.Centralized.keybase .Site.Params.Social.Centralized.keybase }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "Keybase" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#keybase"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+ {{ with or .Page.Params.Social.Centralized.linkedin .Site.Params.Social.Centralized.linkedin }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "LinkedIn" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#linkedin"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+
+
+
+
+
+
+
+
+ {{ if or .Page.Params.Social.Decentralized.mastodon .Site.Params.Social.Decentralized.mastodon }}
+
+ {{ range or .Page.Params.Social.Decentralized.mastodon .Site.Params.Social.Decentralized.mastodon }}
+
+ <a rel="me nofollow" href="{{ index . 0 }}" title="{{ index . 1 }} (Mastodon)">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#mastodon"/>
+ </svg>
+
+ <p>{{ index . 1 | truncate 15 }}</p>
+ </a>
+
+ {{ end }}
+
+ {{ end }}
+
+ {{ if or .Page.Params.Social.Decentralized.matrix .Site.Params.Social.Decentralized.matrix }}
+
+ {{ range or .Page.Params.Social.Decentralized.matrix .Site.Params.Social.Decentralized.matrix }}
+ <a rel="me nofollow" href="{{ index . 0 }}" title="{{ index . 1 }} (Matrix)">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#matrix"/>
+ </svg>
+
+ <p>{{ index . 1 | truncate 15 }}</p>
+ </a>
+ {{ end }}
+
+ {{ end }}
+
+
+ {{ with or .Page.Params.Social.Centralized.medium .Site.Params.Social.Centralized.medium }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "Medium" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#medium"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+
+ {{ with or .Page.Params.Social.Centralized.stackOverflow .Site.Params.Social.Centralized.stackOverflow }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "Stack Overflow" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#stack-overflow"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+
+ {{ with or .Page.Params.Social.Centralized.reddit .Site.Params.Social.Centralized.reddit }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "Reddit" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#reddit"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+
+ {{ with or .Page.Params.Social.Centralized.telegram .Site.Params.Social.Centralized.telegram }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "Telegram" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#telegram"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+ {{ with or .Page.Params.Social.Centralized.twitter .Site.Params.Social.Centralized.twitter }}
+
+ {{ $url := (index . 0) }}
+ {{ $label := "Twitter" }}
+
+ {{ with (index . 1) }}
+ {{ $label = . }}
+ {{ end }}
+
+ <a rel="me nofollow" href="{{ $url }}" title="{{ $label }}">
+ <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
+ <use xlink:href="{{ $icons }}#twitter"/>
+ </svg>
+
+ <p>{{ $label }}</p>
+ </a>
+
+ {{ end }}
+
+</section> \ No newline at end of file