Update to current version
All checks were successful
Building & Deploying Website / Deploy-Website (push) Successful in 12s

This commit is contained in:
2025-11-05 23:14:41 +01:00
parent a8304db3e2
commit 05f0b104d4
300 changed files with 40464 additions and 6492 deletions

View File

@@ -0,0 +1,4 @@
{{- if and (isset .Site.Params "commentourl") (not (eq .Site.Params.commentoURL "" )) (eq (.Params.disableComments | default false) false) -}}
<div id="commento"></div>
<script src="{{ .Site.Params.commentoURL }}/js/commento.js"></script>
{{- end -}}

View File

@@ -0,0 +1,16 @@
{{- if isset .Site.Params "cusdis" -}}
{{- if and (isset .Site.Params.cusdis "data_app_id") (eq (.Params.disableComments | default false) false) -}}
<div class="comments">
<h4>Comments:</h4>
<div id="cusdis_thread"
data-host="https://cusdis.com"
data-app-id="{{ .Site.Params.cusdis.data_app_id }}"
data-page-id="{{ .File.UniqueID }}"
data-page-url="{{ .Permalink }}"
data-page-title="{{ .Title }}">
</div>
<script async defer src="https://cusdis.com/js/cusdis.es.js"></script>
</div>
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,26 @@
{{- if and (not (eq (.Site.Config.Services.Disqus.Shortname | default "") "")) (eq (.Params.disableComments | default false) false) -}}
<div id="disqus_thread"></div>
<script>
window.disqus_config = function () {
{{with .Params.disqus_identifier }}this.page.identifier = '{{ . }}';{{end}}
{{with .Params.disqus_title }}this.page.title = '{{ . }}';{{end}}
{{with .Params.disqus_url }}this.page.url = '{{ . | html }}';{{end}}
};
(function() {
if (["localhost", "127.0.0.1"].indexOf(window.location.hostname) != -1) {
document.getElementById('disqus_thread').innerHTML = 'Disqus comments not available by default when the website is previewed locally.';
return;
}
var d = document, s = d.createElement('script'); s.async = true;
s.src = '//' + {{ .Site.Config.Services.Disqus.Shortname }} + '.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
// Disqus theme switching
document.addEventListener('themeChanged', function (e) {
if (document.readyState == 'complete') {
DISQUS.reset({ reload: true, config: disqus_config });
}
});
</script>
{{- end -}}

View File

@@ -0,0 +1,33 @@
{{- if isset .Site.Params "giscus" -}}
{{- if and (isset .Site.Params.giscus "repo") (not (eq .Site.Params.giscus.repo "" )) (eq (.Params.disableComments | default false) false) -}}
<div class="comments">
<script>
let getTheme = window.localStorage && window.localStorage.getItem("colorscheme");
getTheme = getTheme == null ? '{{$.Site.Params.giscus.theme}}' : getTheme;
let s = document.createElement('script');
s.src = 'https://giscus.app/client.js';
s.setAttribute('data-repo', '{{ .Site.Params.giscus.repo }}');
s.setAttribute('data-repo-id', '{{ .Site.Params.giscus.repoID }}');
s.setAttribute('data-category', '{{ .Site.Params.giscus.category }}');
s.setAttribute('data-category-id', '{{ .Site.Params.giscus.categoryID }}');
s.setAttribute('data-mapping', '{{ default "pathname" .Site.Params.giscus.mapping }}');
s.setAttribute('data-term', '{{ .Site.Params.giscus.term }}');
s.setAttribute('data-strict', '{{ default "0" .Site.Params.giscus.strict }}');
s.setAttribute('data-reactions-enabled', '{{ default "1" .Site.Params.giscus.reactionsEnabled }}');
s.setAttribute('data-emit-metadata', '{{ default "0" .Site.Params.giscus.emitMetadata }}');
s.setAttribute('data-input-position', '{{ default "bottom" .Site.Params.giscus.inputPosition }}');
s.setAttribute('data-theme', getTheme);
s.setAttribute('data-lang', '{{ default "en" .Site.Params.giscus.lang }}');
s.setAttribute('data-loading', '{{ .Site.Params.giscus.loading }}');
s.setAttribute('crossorigin', 'anonymous');
s.setAttribute('async', '');
document.querySelector('div.comments').innerHTML = '';
document.querySelector('div.comments').appendChild(s);
</script>
</div>
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,108 @@
{{- if isset .Site.Params "mastodon" -}}
{{- with .Site.Params.mastodon -}}
<div class="article-content">
<h2>Comments</h2>
<p>You can use your Mastodon account to reply to this <a class="link" href="https://{{ .host }}/@{{ .username }}/{{ .statusID }}">post</a>. Learn how this is implemented <a class="link" href="https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/">here.</a></p>
<p><button id="replyButton" href="https://{{ .host }}/@{{ .username }}/{{ .statusID }}">Reply</button></p>
<p id="mastodon-comments-list"><button id="load-comment">Load comments</button></p>
<dialog id="toot-reply" class="mastodon" data-component="dialog">
<h3>Reply to {{ .username }}'s post</h3>
<p>
With an account on the Fediverse or Mastodon, you can respond to this post.
Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.
</p>
<p>Copy and paste this URL into the search field of your favourite Fediverse app or the web interface of your Mastodon server.</p>
<div class="copypaste">
<input type="text" readonly="" value="https://{{ .host }}/@{{ .username }}/{{ .statusID }}">
<button class="button" id="copyButton">Copy</button>
<button class="button" id="cancelButton">Close</button>
</div>
</dialog>
<noscript>You need JavaScript to view the comments.</noscript>
<script src="{{ .purifyCDN }}"></script>
<script type="text/javascript">
const dialog = document.querySelector('dialog');
document.getElementById('replyButton').addEventListener('click', () => {
dialog.showModal();
});
document.getElementById('copyButton').addEventListener('click', () => {
navigator.clipboard.writeText('https://{{ .host }}/@{{ .username }}/{{ .statusID }}');
});
document.getElementById('cancelButton').addEventListener('click', () => {
dialog.close();
});
dialog.addEventListener('keydown', e => {
if (e.key === 'Escape') dialog.close();
});
const dateOptions = {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
};
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
document.getElementById("load-comment").addEventListener("click", function() {
document.getElementById("load-comment").innerHTML = "Loading";
fetch('https://{{ .host }}/api/v1/statuses/{{ .statusID }}/context')
.then(function(response) {
return response.json();
})
.then(function(data) {
if(data['descendants'] &&
Array.isArray(data['descendants']) &&
data['descendants'].length > 0) {
document.getElementById('mastodon-comments-list').innerHTML = "";
data['descendants'].forEach(function(reply) {
reply.account.display_name = escapeHtml(reply.account.display_name);
reply.account.reply_class = reply.in_reply_to_id == "{{ .statusID }}" ? "reply-original" : "reply-child";
reply.created_date = new Date(reply.created_at);
reply.account.emojis.forEach(emoji => {
reply.account.display_name = reply.account.display_name.replace(`:${emoji.shortcode}:`,
`<img src="${escapeHtml(emoji.static_url)}" alt="Emoji ${emoji.shortcode}" height="20" width="20" />`);
});
mastodonComment =
`
<div class="mastodon-wrapper">
<div class="comment-level ${reply.account.reply_class}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" stroke="currentColor" d="m 307,477.17986 c -11.5,-5.1 -19,-16.6 -19,-29.2 v -64 H 176 C 78.8,383.97986 -4.6936293e-8,305.17986 -4.6936293e-8,207.97986 -4.6936293e-8,94.679854 81.5,44.079854 100.2,33.879854 c 2.5,-1.4 5.3,-1.9 8.1,-1.9 10.9,0 19.7,8.9 19.7,19.7 0,7.5 -4.3,14.4 -9.8,19.5 -9.4,8.8 -22.2,26.4 -22.2,56.700006 0,53 43,96 96,96 h 96 v -64 c 0,-12.6 7.4,-24.1 19,-29.2 11.6,-5.1 25,-3 34.4,5.4 l 160,144 c 6.7,6.2 10.6,14.8 10.6,23.9 0,9.1 -3.9,17.7 -10.6,23.8 l -160,144 c -9.4,8.5 -22.9,10.6 -34.4,5.4 z" />
</svg></div>
<div class="mastodon-comment">
<div class="comment">
<div class="comment-avatar"><img src="${escapeHtml(reply.account.avatar_static)}" alt=""></div>
<div class="comment-author">
<div class="comment-author-name"><a href="${reply.account.url}" rel="nofollow">${reply.account.display_name}</a></div>
<div class="comment-author-reply"><a href="${reply.account.url}" rel="nofollow">${escapeHtml(reply.account.acct)}</a></div>
</div>
<div class="comment-author-date">${reply.created_date.toLocaleString(navigator.language, dateOptions)}</div>
</div>
<div class="comment-content">${reply.content}</div>
</div>
</div>
`;
document.getElementById('mastodon-comments-list').appendChild(DOMPurify.sanitize(mastodonComment, {'RETURN_DOM_FRAGMENT': true}));
});
} else {
document.getElementById('mastodon-comments-list').innerHTML = "<p>Not comments found</p>";
}
});
});
</script>
</div>
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,19 @@
{{- if or (.Params.math) (.Site.Params.math) (.Params.katex) (.Site.Params.katex) -}}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css"
integrity="sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0" crossorigin="anonymous">
{{/* The loading of KaTeX is deferred to speed up page rendering */}}
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js"
integrity="sha384-PwRUT/YqbnEjkZO0zZxNqcxACrXe+j766U2amXcgMg5457rve2Y7I6ZJSm2A0mS4" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/contrib/auto-render.min.js"
integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"
onload="renderMathInElement(document.body,
{
delimiters: [
{left: '$$', right: '$$', display:true},
{left: '$', right: '$', display:false},
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true}
]
}
);"></script>
{{- end -}}

View File

@@ -0,0 +1,30 @@
{{ $currentPageUrl := .RelPermalink }}
{{ if .Params.series }}
<section class="see-also">
{{ range .Params.series }}
{{ $name := . | anchorize }}
{{ $series := index $.Site.Taxonomies.series $name }}
{{ if gt (len $series.Pages) 1 }}
<h3 id="{{ i18n "see_also" | default "See also in" | anchorize }}-{{ anchorize . | safeURL }}">
{{ i18n "see_also" | default "See also in" }} {{ . }}
<a class="heading-link" href="#{{ i18n "see_also" | default "See also in" | anchorize }}-{{ anchorize . | safeURL }}">
<i class="fa-solid fa-link" aria-hidden="true" title="{{ i18n "link_to_heading" | default "Link to heading" }}"></i>
<span class="sr-only">{{ i18n "link_to_heading" | default "Link to heading" }}</span>
</a>
</h3>
<nav>
<ul>
{{ $maxItems := $.Site.Params.maxSeeAlsoItems | default 5 }}
{{ range first (add $maxItems 1) $series.Pages }}
{{ if ne .RelPermalink $currentPageUrl }}
<li>
<a href="{{ .Params.externalLink | default .RelPermalink }}">{{ .Title }}</a>
</li>
{{ end }}
{{ end }}
</ul>
</nav>
{{ end }}
{{ end }}
</section>
{{ end }}

View File

@@ -0,0 +1,22 @@
{{- if isset .Site.Params "telegram" -}}
{{- if and (isset .Site.Params.telegram "siteid") (not (eq .Site.Params.telegram.siteID "" )) (eq (.Params.disableComments | default false) false) -}}
<div class="comments">
<script>
let s = document.createElement('script');
s.src = 'https://comments.app/js/widget.js?3';
s.setAttribute('data-comments-app-website', '{{ .Site.Params.telegram.siteID }}');
s.setAttribute('data-limit', '{{ .Site.Params.telegram.limit }}');
s.setAttribute('data-height', '{{ .Site.Params.telegram.height }}');
s.setAttribute('data-color', '{{ .Site.Params.telegram.color }}');
s.setAttribute('data-dislikes', '{{ .Site.Params.telegram.dislikes }}');
s.setAttribute('data-outlined', '{{ .Site.Params.telegram.outlined }}');
s.setAttribute('data-colorful', '{{ .Site.Params.telegram.colorful }}');
s.setAttribute('data-dark', '{{ .Site.Params.telegram.dark }}');
document.querySelector('div.comments').innerHTML = '';
document.querySelector('div.comments').appendChild(s);
</script>
</div>
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,32 @@
{{- if isset .Site.Params "utterances" -}}
{{- if and (isset .Site.Params.utterances "repo") (not (eq .Site.Params.utterances.repo "" )) (eq (.Params.disableComments | default false) false) -}}
<div class="comments">
<script>
let getTheme = window.localStorage && window.localStorage.getItem("colorscheme");
let themeInParams = '{{$.Site.Params.utterances.theme}}';
if (getTheme == null) {
if (themeInParams !== '' && themeInParams !== 'auto') {
getTheme = themeInParams;
}
else {
getTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? "dark" : "light";
}
}
let theme = getTheme === 'dark' ? 'github-dark' : 'github-light';
let s = document.createElement('script');
s.src = 'https://utteranc.es/client.js';
s.setAttribute('repo', '{{ .Site.Params.utterances.repo }}');
s.setAttribute('issue-term', '{{ default "title" .Site.Params.utterances.issueTerm }}');
s.setAttribute('theme', theme);
s.setAttribute('crossorigin', 'anonymous');
s.setAttribute('async', '');
document.querySelector('div.comments').innerHTML = '';
document.querySelector('div.comments').appendChild(s);
</script>
</div>
{{- end -}}
{{- end -}}