✨ feat: add support for giscus & utterances comments
This commit is contained in:
parent
93c8b577b8
commit
19d120019b
53
config.toml
53
config.toml
@ -179,41 +179,28 @@ allowed_domains = [
|
|||||||
custom_subset = true
|
custom_subset = true
|
||||||
|
|
||||||
# giscus support for comments. https://giscus.app
|
# giscus support for comments. https://giscus.app
|
||||||
# TODO: make sure giscus / utterances are added to the Custom security headers when enabled
|
|
||||||
# TODO: Mention this fact in the docs
|
|
||||||
[extra.giscus]
|
[extra.giscus]
|
||||||
enabled_for_all_posts = false # Enables utterances on all posts. You can also do it on a post-per-post basis by setting `utterances = true` in the [extra] section of the post's front matter.
|
enabled_for_all_posts = false # Enables giscus on all posts. It can be enabled on individual posts by setting `giscus = true` in the [extra] section of the post's front matter.
|
||||||
repo = "yourname/yourrepository"
|
repo = "welpo/test-utterances"
|
||||||
|
repo_id = "R_kgDOJ59Urw"
|
||||||
|
category = "Announcements"
|
||||||
enable_reactions = true
|
category_id = "DIC_kwDOJ59Ur84CX0QG"
|
||||||
|
mapping = "slug" # Available: pathname; url; title; slug. "slug" will use the post's filename (slug); this is the only way to share comments between languages.
|
||||||
|
strict_title_matching = 1 # 1 to enable, 0 to disable. https://github.com/giscus/giscus/blob/main/ADVANCED-USAGE.md#data-strict
|
||||||
|
enable_reactions = 1 # 1 to enable, 0 to disable.
|
||||||
comment_box_above_comments = true
|
comment_box_above_comments = true
|
||||||
lazy_loading = true
|
|
||||||
light_theme = "noborder_light"
|
light_theme = "noborder_light"
|
||||||
dark_theme = "noborder_dark"
|
dark_theme = "noborder_dark"
|
||||||
# TODO: Set data-lang to page's language
|
lang = "" # Leave blank to set it based on the page's language.
|
||||||
|
lazy_loading = true
|
||||||
# <script src="https://giscus.app/client.js"
|
automatic_loading = true # If set to false, a "Show comments" button will be shown.
|
||||||
# data-repo-id="[REPOSITORI ID]"
|
|
||||||
# data-category="[NOM CATEGORIA]"
|
# utterances support for comments. https://utteranc.es
|
||||||
# data-category-id="[ID CATEGORIA]"
|
[extra.utterances]
|
||||||
# data-mapping="pathname"
|
enabled_for_all_posts = false # Enables utterances on all posts. It can be enabled on individual posts by setting `utterances = true` in the [extra] section of the post's front matter.
|
||||||
# data-strict="0"
|
repo = "yourgithubuser/yourrepo" # https://utteranc.es/#heading-repository
|
||||||
# data-lang="ca"
|
issue_term = "slug" # Available: pathname; url; title; slug. "slug" will use the post's filename (slug); this is the only way to share comments between languages. https://utteranc.es/#heading-mapping
|
||||||
# crossorigin="anonymous"
|
label = "💬" # https://utteranc.es/#heading-issue-label
|
||||||
# async>
|
light_theme = "github-light" # https://utteranc.es/#heading-theme
|
||||||
# </script>
|
dark_theme = "github-dark" # https://utteranc.es/#heading-theme
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Utterances support for comments. https://utteranc.es
|
|
||||||
[extra.utterances]
|
|
||||||
enabled_for_all_posts = false # Enables utterances on all posts. You can also do it on a post-per-post basis by setting `utterances = true` in the [extra] section of the post's front matter.
|
|
||||||
repo = "welpo/test-utterances" # https://utteranc.es/#heading-repository
|
|
||||||
issue_term = "pathname" # Available: pathname; url; title. More info: https://utteranc.es/#heading-mapping
|
|
||||||
label = "💬" # https://utteranc.es/#heading-issue-label
|
|
||||||
theme = "preferred-color-scheme" # https://utteranc.es/#heading-theme. If you use the theme switcher, it's probably best to use "preferred-color-scheme"
|
|
||||||
lazy_loading = true
|
lazy_loading = true
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
+++
|
+++
|
||||||
title = "Secure by default"
|
title = "Secure by default"
|
||||||
date = 2023-02-22
|
date = 2023-02-22
|
||||||
updated = 2023-05-22
|
updated = 2023-07-12
|
||||||
description = "tabi has an easily customizable Content Security Policy (CSP) with safe defaults. Get peace of mind and an A+ on Mozilla Observatory."
|
description = "tabi has an easily customizable Content Security Policy (CSP) with safe defaults. Get peace of mind and an A+ on Mozilla Observatory."
|
||||||
|
|
||||||
[taxonomies]
|
[taxonomies]
|
||||||
@ -27,4 +27,6 @@ The `allowed_domains` list specifies the URLs that the website should be able to
|
|||||||
|
|
||||||
This feature allows you to easily customize the website's security headers to allow for specific use cases, such as embedding YouTube videos, loading scripts or remote fonts ([not recommended](https://www.albertovarela.net/blog/2022/11/stop-using-google-fonts/)).
|
This feature allows you to easily customize the website's security headers to allow for specific use cases, such as embedding YouTube videos, loading scripts or remote fonts ([not recommended](https://www.albertovarela.net/blog/2022/11/stop-using-google-fonts/)).
|
||||||
|
|
||||||
|
**Note**: enabling comments automatically allows scripts and frames from either utterances/giscus, as well as unsafe-inline styles when using utterances (required so that the widget can adjust its size based on the number of comments).
|
||||||
|
|
||||||
[^1]: Requires proper webserver configuration (e.g. redirecting HTTP traffic to HTTPS).
|
[^1]: Requires proper webserver configuration (e.g. redirecting HTTP traffic to HTTPS).
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
.utterances-frame {
|
.utterances-frame {
|
||||||
min-height: 18rem;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments {
|
.comments {
|
||||||
padding-top: 5vmin;
|
border-top: var(--divider-color) solid 0.5px;
|
||||||
|
margin-top: 2rem;
|
||||||
|
padding-top: 2rem;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
|
||||||
iframe {
|
iframe {
|
||||||
border: none;
|
border: none;
|
||||||
|
81
static/js/giscus.js
Normal file
81
static/js/giscus.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
function setGiscusTheme(newTheme) {
|
||||||
|
// Get the giscus iframe.
|
||||||
|
const frame = document.querySelector('iframe.giscus-frame');
|
||||||
|
|
||||||
|
if (frame) {
|
||||||
|
// If the iframe exists, send a message to set the theme.
|
||||||
|
frame.contentWindow.postMessage(
|
||||||
|
{ giscus: { setConfig: { theme: newTheme } } },
|
||||||
|
'https://giscus.app'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to initialize Giscus. This function is run when the window loads.
|
||||||
|
function initGiscus() {
|
||||||
|
// Get the div that will contain the comments.
|
||||||
|
const commentsDiv = document.querySelector('.comments');
|
||||||
|
if (commentsDiv) {
|
||||||
|
// Get the various settings from data attributes on the div.
|
||||||
|
const repo = commentsDiv.getAttribute('data-repo');
|
||||||
|
const repoId = commentsDiv.getAttribute('data-repo-id');
|
||||||
|
const category = commentsDiv.getAttribute('data-category');
|
||||||
|
const categoryId = commentsDiv.getAttribute('data-category-id');
|
||||||
|
const strictTitleMatching = commentsDiv.getAttribute('data-strict');
|
||||||
|
const term = commentsDiv.getAttribute('data-term');
|
||||||
|
const reactionsEnabled = commentsDiv.getAttribute('data-reactions-enabled');
|
||||||
|
const inputPosition = commentsDiv.getAttribute('data-input-position');
|
||||||
|
const lightTheme = commentsDiv.getAttribute('data-light-theme');
|
||||||
|
const darkTheme = commentsDiv.getAttribute('data-dark-theme');
|
||||||
|
const lang = commentsDiv.getAttribute('data-lang');
|
||||||
|
const lazyLoading = commentsDiv.getAttribute('data-lazy-loading');
|
||||||
|
|
||||||
|
// Create a new script tag that will load the Giscus script.
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = 'https://giscus.app/client.js';
|
||||||
|
script.async = true;
|
||||||
|
|
||||||
|
// Set the various settings as data attributes on the script tag.
|
||||||
|
script.setAttribute('data-repo', repo);
|
||||||
|
script.setAttribute('data-repo-id', repoId);
|
||||||
|
script.setAttribute('data-category', category);
|
||||||
|
script.setAttribute('data-category-id', categoryId);
|
||||||
|
script.setAttribute('data-term', term);
|
||||||
|
script.setAttribute('data-strict', strictTitleMatching);
|
||||||
|
script.setAttribute('data-reactions-enabled', reactionsEnabled);
|
||||||
|
script.setAttribute('data-emit-metadata', '0');
|
||||||
|
script.setAttribute('data-input-position', inputPosition);
|
||||||
|
script.setAttribute('data-lang', lang);
|
||||||
|
script.setAttribute('crossorigin', 'anonymous');
|
||||||
|
|
||||||
|
// Set the mapping if it is provided.
|
||||||
|
const mapping = commentsDiv.getAttribute('data-mapping');
|
||||||
|
if (mapping) {
|
||||||
|
script.setAttribute('data-mapping', mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose the correct theme based on the current theme of the document.
|
||||||
|
const currentTheme = document.documentElement.getAttribute('data-theme') || 'light';
|
||||||
|
const selectedTheme = currentTheme === 'dark' ? darkTheme : lightTheme;
|
||||||
|
script.setAttribute('data-theme', selectedTheme);
|
||||||
|
|
||||||
|
// Set the loading attribute if lazy loading is enabled.
|
||||||
|
if (lazyLoading === 'true') {
|
||||||
|
script.setAttribute('data-loading', 'lazy');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the script tag to the div.
|
||||||
|
commentsDiv.appendChild(script);
|
||||||
|
|
||||||
|
// Listen for theme changes and update the Giscus theme when they occur.
|
||||||
|
window.addEventListener('themeChanged', (event) => {
|
||||||
|
const selectedTheme = event.detail.theme === 'dark' ? darkTheme : lightTheme;
|
||||||
|
setGiscusTheme(selectedTheme);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize Giscus when the window loads.
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
initGiscus();
|
||||||
|
});
|
1
static/js/giscus_min.js
Normal file
1
static/js/giscus_min.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
function setGiscusTheme(t){var e=document.querySelector("iframe.giscus-frame");e&&e.contentWindow.postMessage({giscus:{setConfig:{theme:t}}},"https://giscus.app")}function initGiscus(){var t=document.querySelector(".comments");if(t){var e=t.getAttribute("data-repo"),a=t.getAttribute("data-repo-id"),i=t.getAttribute("data-category"),r=t.getAttribute("data-category-id"),d=t.getAttribute("data-strict"),s=t.getAttribute("data-term"),u=t.getAttribute("data-reactions-enabled"),n=t.getAttribute("data-input-position");const b=t.getAttribute("data-light-theme"),A=t.getAttribute("data-dark-theme");var o=t.getAttribute("data-lang"),c=t.getAttribute("data-lazy-loading"),g=document.createElement("script"),e=(g.src="https://giscus.app/client.js",g.async=!0,g.setAttribute("data-repo",e),g.setAttribute("data-repo-id",a),g.setAttribute("data-category",i),g.setAttribute("data-category-id",r),g.setAttribute("data-term",s),g.setAttribute("data-strict",d),g.setAttribute("data-reactions-enabled",u),g.setAttribute("data-emit-metadata","0"),g.setAttribute("data-input-position",n),g.setAttribute("data-lang",o),g.setAttribute("crossorigin","anonymous"),t.getAttribute("data-mapping")),a=(e&&g.setAttribute("data-mapping",e),document.documentElement.getAttribute("data-theme")||"light"),i="dark"===a?A:b;g.setAttribute("data-theme",i),"true"===c&&g.setAttribute("data-loading","lazy"),t.appendChild(g),window.addEventListener("themeChanged",t=>{setGiscusTheme("dark"===t.detail.theme?A:b)})}}window.addEventListener("load",()=>{initGiscus()});
|
@ -1,37 +0,0 @@
|
|||||||
// Get the theme switcher button element.
|
|
||||||
const themeSwitcher = document.querySelector(".theme-switcher");
|
|
||||||
|
|
||||||
// Retrieve theme from localStorage.
|
|
||||||
let currentTheme = localStorage.getItem("theme");
|
|
||||||
|
|
||||||
// Function to switch between dark and light themes.
|
|
||||||
function switchTheme() {
|
|
||||||
// Set the new theme based on the current theme.
|
|
||||||
currentTheme = currentTheme === "dark" ? "light" : "dark";
|
|
||||||
document.documentElement.setAttribute("data-theme", currentTheme);
|
|
||||||
localStorage.setItem("theme", currentTheme);
|
|
||||||
|
|
||||||
// Send a message to the Utterances iframe to change its theme.
|
|
||||||
document.querySelectorAll(".utterances-frame").forEach((frame) => {
|
|
||||||
frame.contentWindow.postMessage(
|
|
||||||
{ type: 'set-theme', theme: `github-${currentTheme}` },
|
|
||||||
'*'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the theme switcher button.
|
|
||||||
themeSwitcher.addEventListener("click", switchTheme, false);
|
|
||||||
|
|
||||||
// Update the theme based on system preference if the user hasn't manually changed the theme.
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", e => {
|
|
||||||
if (!localStorage.getItem("theme")) {
|
|
||||||
currentTheme = e.matches ? "dark" : "light";
|
|
||||||
document.documentElement.setAttribute("data-theme", currentTheme);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fix the theme switcher button not working on the first click by updating currentTheme.
|
|
||||||
if (!currentTheme) {
|
|
||||||
currentTheme = document.documentElement.getAttribute("data-theme");
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
const themeSwitcher=document.querySelector(".theme-switcher");let currentTheme=localStorage.getItem("theme");function switchTheme(){currentTheme="dark"===currentTheme?"light":"dark",document.documentElement.setAttribute("data-theme",currentTheme),localStorage.setItem("theme",currentTheme),document.querySelectorAll(".utterances-frame").forEach(e=>{e.contentWindow.postMessage({type:"set-theme",theme:`github-${currentTheme}`},"*")})}themeSwitcher.addEventListener("click",switchTheme,!1),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{localStorage.getItem("theme")||(currentTheme=e.matches?"dark":"light",document.documentElement.setAttribute("data-theme",currentTheme))}),currentTheme||(currentTheme=document.documentElement.getAttribute("data-theme"));
|
|
33
static/js/themeSwitcher.js
Normal file
33
static/js/themeSwitcher.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Get the theme switcher button element.
|
||||||
|
const themeSwitcher = document.querySelector(".theme-switcher");
|
||||||
|
|
||||||
|
// Retrieve theme from localStorage.
|
||||||
|
let currentTheme = localStorage.getItem("theme");
|
||||||
|
|
||||||
|
// Function to switch between dark and light themes.
|
||||||
|
function setTheme(theme) {
|
||||||
|
document.documentElement.setAttribute("data-theme", theme);
|
||||||
|
localStorage.setItem("theme", theme);
|
||||||
|
|
||||||
|
// Dispatch a custom event for utterances and giscus.
|
||||||
|
const event = new CustomEvent("themeChanged", {
|
||||||
|
detail: { theme: theme }
|
||||||
|
});
|
||||||
|
window.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchTheme() {
|
||||||
|
// Set the new theme based on the current theme.
|
||||||
|
const newTheme = currentTheme === "dark" ? "light" : "dark";
|
||||||
|
setTheme(newTheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
themeSwitcher.addEventListener("click", switchTheme, false);
|
||||||
|
|
||||||
|
// Update the theme based on system preference if the user hasn't manually changed the theme.
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", e => {
|
||||||
|
if (!localStorage.getItem("theme")) {
|
||||||
|
const newTheme = e.matches ? "dark" : "light";
|
||||||
|
setTheme(newTheme);
|
||||||
|
}
|
||||||
|
});
|
37
static/js/themeSwitcher_min.js
Normal file
37
static/js/themeSwitcher_min.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Get the theme switcher button element.
|
||||||
|
const themeSwitcher = document.querySelector(".theme-switcher");
|
||||||
|
|
||||||
|
// Retrieve theme from localStorage.
|
||||||
|
let currentTheme = localStorage.getItem("theme");
|
||||||
|
|
||||||
|
// Function to set theme
|
||||||
|
function setTheme(theme, saveToLocalStorage = false) {
|
||||||
|
document.documentElement.setAttribute("data-theme", theme);
|
||||||
|
currentTheme = theme;
|
||||||
|
|
||||||
|
if (saveToLocalStorage) {
|
||||||
|
localStorage.setItem("theme", theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatch a custom event for utterances and giscus.
|
||||||
|
const event = new CustomEvent("themeChanged", {
|
||||||
|
detail: { theme: theme }
|
||||||
|
});
|
||||||
|
window.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to switch between dark and light themes.
|
||||||
|
function switchTheme() {
|
||||||
|
// Set the new theme based on the current theme.
|
||||||
|
const newTheme = currentTheme === "dark" ? "light" : "dark";
|
||||||
|
setTheme(newTheme, true); // Save the theme to localStorage when the user changes it.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the theme switcher button.
|
||||||
|
themeSwitcher.addEventListener("click", switchTheme, false);
|
||||||
|
|
||||||
|
// Update the theme based on system preference if the user hasn't manually changed the theme.
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", e => {
|
||||||
|
const newTheme = e.matches ? "dark" : "light";
|
||||||
|
setTheme(newTheme);
|
||||||
|
});
|
64
static/js/utterances.js
Normal file
64
static/js/utterances.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
function setUtterancesTheme(newTheme) {
|
||||||
|
// Get the frame with class "utterances-frame".
|
||||||
|
const frame = document.querySelector(".utterances-frame");
|
||||||
|
|
||||||
|
if (frame) {
|
||||||
|
// If the iframe exists, send a message to set the theme.
|
||||||
|
frame.contentWindow.postMessage(
|
||||||
|
{ type: 'set-theme', theme: newTheme },
|
||||||
|
'https://utteranc.es'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initUtterances() {
|
||||||
|
// Get the comments div.
|
||||||
|
const commentsDiv = document.querySelector('.comments');
|
||||||
|
|
||||||
|
// Check if the comments div exists.
|
||||||
|
if (commentsDiv) {
|
||||||
|
// Get all necessary attributes for initializing Utterances.
|
||||||
|
const repo = commentsDiv.getAttribute('data-repo');
|
||||||
|
const issueTerm = commentsDiv.getAttribute('data-issue-term');
|
||||||
|
const label = commentsDiv.getAttribute('data-label');
|
||||||
|
const lightTheme = commentsDiv.getAttribute('data-light-theme');
|
||||||
|
const darkTheme = commentsDiv.getAttribute('data-dark-theme');
|
||||||
|
const lazyLoading = commentsDiv.getAttribute('data-lazy-loading');
|
||||||
|
|
||||||
|
// Create a new script element.
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = 'https://utteranc.es/client.js';
|
||||||
|
script.async = true;
|
||||||
|
script.setAttribute('repo', repo);
|
||||||
|
script.setAttribute('issue-term', issueTerm);
|
||||||
|
script.setAttribute('label', label);
|
||||||
|
|
||||||
|
// Set the initial theme.
|
||||||
|
const currentTheme = document.documentElement.getAttribute('data-theme') || 'light';
|
||||||
|
const selectedTheme = currentTheme === 'dark' ? darkTheme : lightTheme;
|
||||||
|
script.setAttribute('theme', selectedTheme);
|
||||||
|
|
||||||
|
script.setAttribute('crossorigin', 'anonymous');
|
||||||
|
|
||||||
|
// Enable lazy loading if specified.
|
||||||
|
if (lazyLoading === 'true') {
|
||||||
|
script.setAttribute('data-loading', 'lazy');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the script to the comments div.
|
||||||
|
commentsDiv.appendChild(script);
|
||||||
|
|
||||||
|
// Listen for themeChanged event to update the theme.
|
||||||
|
window.addEventListener('themeChanged', (event) => {
|
||||||
|
// Determine the new theme based on the event detail.
|
||||||
|
const selectedTheme = event.detail.theme === 'dark' ? darkTheme : lightTheme;
|
||||||
|
// Set the new theme.
|
||||||
|
setUtterancesTheme(selectedTheme);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize Utterances once the window has loaded.
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
initUtterances();
|
||||||
|
});
|
1
static/js/utterances_min.js
Normal file
1
static/js/utterances_min.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
function setUtterancesTheme(t){const e=document.querySelector(".utterances-frame");e&&e.contentWindow.postMessage({type:"set-theme",theme:t},"https://utteranc.es")}function initUtterances(){const t=document.querySelector(".comments");if(t){var e=t.getAttribute("data-repo"),a=t.getAttribute("data-issue-term"),r=t.getAttribute("data-label");const s=t.getAttribute("data-light-theme"),d=t.getAttribute("data-dark-theme");var n=t.getAttribute("data-lazy-loading"),i=document.createElement("script"),e=(i.src="https://utteranc.es/client.js",i.async=!0,i.setAttribute("repo",e),i.setAttribute("issue-term",a),i.setAttribute("label",r),document.documentElement.getAttribute("data-theme")||"light"),a="dark"===e?d:s;i.setAttribute("theme",a),i.setAttribute("crossorigin","anonymous"),"true"===n&&i.setAttribute("data-loading","lazy"),t.appendChild(i),window.addEventListener("themeChanged",t=>{setUtterancesTheme("dark"===t.detail.theme?d:s)})}}window.addEventListener("load",()=>{initUtterances()});
|
@ -6,6 +6,7 @@
|
|||||||
{% import "macros/set_title.html" as macros_set_title %}
|
{% import "macros/set_title.html" as macros_set_title %}
|
||||||
{% import "macros/paginate.html" as macros_paginate %}
|
{% import "macros/paginate.html" as macros_paginate %}
|
||||||
{% import "macros/format_date.html" as macros_format_date %}
|
{% import "macros/format_date.html" as macros_format_date %}
|
||||||
|
{% import "macros/add_comments.html" as macros_add_comments %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{{ lang }}">
|
<html lang="{{ lang }}">
|
||||||
|
64
templates/macros/add_comments.html
Normal file
64
templates/macros/add_comments.html
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
{%- macro add_comments() -%}
|
||||||
|
|
||||||
|
{% set giscus_enabled = config.extra.giscus.enabled_for_all_posts or page.extra.giscus %}
|
||||||
|
{% set utterances_enabled = config.extra.utterances.enabled_for_all_posts or page.extra.utterances %}
|
||||||
|
|
||||||
|
{# Ensure only one comment system is enabled #}
|
||||||
|
{% if giscus_enabled and utterances_enabled %}
|
||||||
|
{{ throw(message="ERROR: Multiple comment systems have been enabled for the same page. Check your config.toml and individual page settings to ensure only one comment system is activated at a time.") }}
|
||||||
|
|
||||||
|
{% elif giscus_enabled %}
|
||||||
|
{# Create a div to host giscus comments #}
|
||||||
|
<div class="comments"
|
||||||
|
{# Store required giscus data attributes in the div #}
|
||||||
|
data-repo="{{ config.extra.giscus.repo }}"
|
||||||
|
data-repo-id="{{ config.extra.giscus.repo_id }}"
|
||||||
|
data-category="{{ config.extra.giscus.category }}"
|
||||||
|
data-category-id="{{ config.extra.giscus.category_id }}"
|
||||||
|
{% if config.extra.giscus.mapping == "slug" %}
|
||||||
|
data-mapping="specific"
|
||||||
|
data-term="{{ page.slug }}"
|
||||||
|
{% else %}
|
||||||
|
data-mapping="{{ config.extra.giscus.mapping }}"
|
||||||
|
{% endif %}
|
||||||
|
data-strict="{{ config.extra.giscus.strict_title_matching }}"
|
||||||
|
data-reactions-enabled="{{ config.extra.giscus.enable_reactions }}"
|
||||||
|
{% if config.extra.giscus.comment_box_above_comments %}
|
||||||
|
data-input-position="top"
|
||||||
|
{% else %}
|
||||||
|
data-input-position="bottom"
|
||||||
|
{% endif %}
|
||||||
|
data-light-theme="{{ config.extra.giscus.light_theme }}"
|
||||||
|
data-dark-theme="{{ config.extra.giscus.dark_theme }}"
|
||||||
|
{% if config.extra.giscus.lang %}
|
||||||
|
data-lang="{{ config.extra.giscus.lang }}"
|
||||||
|
{% else %}
|
||||||
|
data-lang="{{ lang }}"
|
||||||
|
{% endif %}
|
||||||
|
data-lazy-loading="{{ config.extra.giscus.lazy_loading | default(value=true) }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# giscus script to load the widget #}
|
||||||
|
<script src="{{ get_url(path='js/giscus_min.js', trailing_slash=false) | safe }}"/></script>
|
||||||
|
|
||||||
|
{% elif utterances_enabled %}
|
||||||
|
{# Create a div to host utterances comments #}
|
||||||
|
<div class="comments"
|
||||||
|
{# Store required utterances data attributes in the div #}
|
||||||
|
data-repo="{{ config.extra.utterances.repo }}"
|
||||||
|
{% if config.extra.utterances.issue_term == "slug" %}
|
||||||
|
data-issue-term="{{ page.slug }}"
|
||||||
|
{% else %}
|
||||||
|
data-issue-term="{{ config.extra.utterances.issue_term }}"
|
||||||
|
{% endif %}
|
||||||
|
data-label="{{ config.extra.utterances.label }}"
|
||||||
|
data-light-theme="{{ config.extra.utterances.light_theme }}"
|
||||||
|
data-dark-theme="{{ config.extra.utterances.dark_theme }}"
|
||||||
|
data-lazy-loading="{{ config.extra.utterances.lazy_loading | default(value=true) }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# utterances script to load the widget #}
|
||||||
|
<script src="{{ get_url(path='js/utterances_min.js', trailing_slash=false) | safe }}"/></script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{%- endmacro add_comments -%}
|
@ -80,26 +80,9 @@
|
|||||||
{{ page.content | safe }}
|
{{ page.content | safe }}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
{# Add comments if they are enabled #}
|
||||||
|
{{ macros_add_comments::add_comments() }}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
{# giscus / utterances comments #}
|
|
||||||
{% if config.extra.giscus.enabled_for_all_posts or page.extra.giscus %}
|
|
||||||
{# TODO: HERE GOES GISCUS SUPPORT #}
|
|
||||||
{% elif config.extra.utterances.enabled_for_all_posts or page.extra.utterances %}
|
|
||||||
<div class="comments">
|
|
||||||
<script src="https://utteranc.es/client.js"
|
|
||||||
repo="{{ config.extra.utterances.repo }}"
|
|
||||||
issue-term="{{ config.extra.utterances.issue_term }}"
|
|
||||||
label="{{ config.extra.utterances.label }}"
|
|
||||||
theme="{{ config.extra.utterances.theme }}"
|
|
||||||
{%- if config.extra.utterances.lazy_loading -%}
|
|
||||||
data-loading="lazy"
|
|
||||||
{%- endif -%}
|
|
||||||
crossorigin="anonymous"
|
|
||||||
async>
|
|
||||||
</script>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{% endmacro content %}
|
{% endmacro content %}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<link rel=icon href='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg" viewBox="0 0 105 55"><text y=".7em" font-size="90">{{ config.extra.favicon_emoji }}</text></svg>'>
|
<link rel=icon href='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg" viewBox="0 0 105 55"><text y=".7em" font-size="90">{{ config.extra.favicon_emoji }}</text></svg>'>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# RSS #}
|
{# Feed #}
|
||||||
<link rel="alternate" type="application/atom+xml" title="{{ config.title }}" href="{{ get_url(path="atom.xml",
|
<link rel="alternate" type="application/atom+xml" title="{{ config.title }}" href="{{ get_url(path="atom.xml",
|
||||||
trailing_slash=false) }}">
|
trailing_slash=false) }}">
|
||||||
|
|
||||||
@ -36,7 +36,16 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<meta name="description" content="{{ config.description }}">
|
<meta name="color-scheme" content="light dark">
|
||||||
|
|
||||||
|
{%- if page.description %}
|
||||||
|
<meta name="description" content="{{ page.description }}" />
|
||||||
|
{%- elif page.summary %}
|
||||||
|
<meta name="description" content="{{ page.summary }}" />
|
||||||
|
{%- else %}
|
||||||
|
<meta name="description" content="{{ config.description }}" />
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
{% if is_404 %}
|
{% if is_404 %}
|
||||||
<meta name="robots" content="noindex, follow">
|
<meta name="robots" content="noindex, follow">
|
||||||
{% else %}
|
{% else %}
|
||||||
@ -61,11 +70,18 @@
|
|||||||
content="default-src 'self'
|
content="default-src 'self'
|
||||||
{%- if config.extra.allowed_domains -%}
|
{%- if config.extra.allowed_domains -%}
|
||||||
;
|
;
|
||||||
|
{%- set utterances_enabled = config.extra.utterances.enabled_for_all_posts or page.extra.utterances -%}
|
||||||
|
{%- set giscus_enabled = config.extra.giscus.enabled_for_all_posts or page.extra.giscus -%}
|
||||||
{%- for domain in config.extra.allowed_domains -%}
|
{%- for domain in config.extra.allowed_domains -%}
|
||||||
{{ domain.directive }} {{ domain.domains | join(sep=' ') }}
|
{{ domain.directive }} {{ domain.domains | join(sep=' ') -}}
|
||||||
|
|
||||||
|
{% if utterances_enabled -%}
|
||||||
|
{%- if domain.directive == "style-src" %} 'unsafe-inline'
|
||||||
|
{%- endif -%}
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
{# Automatically allow giscus/utterances, if enabled #}
|
{# Automatically allow giscus/utterances, if enabled #}
|
||||||
{%- if domain.directive == "script-src" or domain.directive == "frame-src" or domain.directive == "style-src" -%}
|
{%- if domain.directive == "script-src" or domain.directive == "frame-src" -%}
|
||||||
{%- if config.extra.giscus.enabled_for_all_posts or page.extra.giscus %} giscus.app
|
{%- if config.extra.giscus.enabled_for_all_posts or page.extra.giscus %} giscus.app
|
||||||
{%- elif config.extra.utterances.enabled_for_all_posts or page.extra.utterances%} utteranc.es
|
{%- elif config.extra.utterances.enabled_for_all_posts or page.extra.utterances%} utteranc.es
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
@ -77,8 +93,8 @@
|
|||||||
{%- endif -%}">
|
{%- endif -%}">
|
||||||
|
|
||||||
{%- if config.extra.theme_switcher and config.extra.theme_switcher == true -%}
|
{%- if config.extra.theme_switcher and config.extra.theme_switcher == true -%}
|
||||||
<script type="text/javascript" src="{{ get_url(path='js/initialize_theme_min.js') | safe }}"></script>
|
<script type="text/javascript" src="{{ get_url(path='js/initializeTheme_min.js') | safe }}"></script>
|
||||||
<script defer src="{{ get_url(path='js/main_min.js', trailing_slash=false) | safe }}"/></script>
|
<script defer src="{{ get_url(path='js/themeSwitcher_min.js', trailing_slash=false) | safe }}"/></script>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user