From 4faa990bf4df7c6286863618a171bac838469fb8 Mon Sep 17 00:00:00 2001 From: "zhongyan.feng" Date: Tue, 9 Jun 2026 17:56:11 +0800 Subject: [PATCH] Add Giscus comment support --- layout/_third-party/comments/giscus.njk | 2 ++ scripts/filters/comment/giscus.js | 22 +++++++++++++++++ source/js/third-party/comments/giscus.js | 30 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 layout/_third-party/comments/giscus.njk create mode 100644 scripts/filters/comment/giscus.js create mode 100644 source/js/third-party/comments/giscus.js diff --git a/layout/_third-party/comments/giscus.njk b/layout/_third-party/comments/giscus.njk new file mode 100644 index 0000000000..78c98d950d --- /dev/null +++ b/layout/_third-party/comments/giscus.njk @@ -0,0 +1,2 @@ +{{ next_data('giscus', theme.giscus) }} +{{ next_js('third-party/comments/giscus.js') }} diff --git a/scripts/filters/comment/giscus.js b/scripts/filters/comment/giscus.js new file mode 100644 index 0000000000..6338b0aa39 --- /dev/null +++ b/scripts/filters/comment/giscus.js @@ -0,0 +1,22 @@ +/* global hexo */ + +'use strict'; + +const path = require('path'); + +const REQUIRED_OPTIONS = ['repo', 'repo_id', 'category', 'category_id']; + +// Add Giscus comment support. +hexo.extend.filter.register('theme_inject', injects => { + const config = hexo.theme.config.giscus; + if (!config.enable) return; + + const missingOptions = REQUIRED_OPTIONS.filter(option => !config[option]); + if (missingOptions.length > 0) { + hexo.log.warn(`giscus.${missingOptions.join(', giscus.')} can't be null.`); + return; + } + + injects.comment.raw('giscus', '
', {}, { cache: true }); + injects.bodyEnd.file('giscus', path.join(hexo.theme_dir, 'layout/_third-party/comments/giscus.njk')); +}); diff --git a/source/js/third-party/comments/giscus.js b/source/js/third-party/comments/giscus.js new file mode 100644 index 0000000000..0c699f0eb7 --- /dev/null +++ b/source/js/third-party/comments/giscus.js @@ -0,0 +1,30 @@ +/* global NexT, CONFIG */ + +document.addEventListener('page:loaded', async () => { + if (!CONFIG.page.comments) return; + + const giscusConfig = CONFIG.giscus; + const container = document.querySelector('.giscus-container'); + if (!container || !giscusConfig) return; + + await NexT.utils.loadComments('.giscus-container'); + await NexT.utils.getScript('https://giscus.app/client.js', { + attributes: { + async : true, + crossOrigin : giscusConfig.crossorigin || 'anonymous', + 'data-repo' : giscusConfig.repo, + 'data-repo-id' : giscusConfig.repo_id, + 'data-category' : giscusConfig.category, + 'data-category-id' : giscusConfig.category_id, + 'data-mapping' : giscusConfig.mapping || 'pathname', + 'data-strict' : String(giscusConfig.strict ?? 0), + 'data-reactions-enabled': String(giscusConfig.reactions_enabled ?? 1), + 'data-emit-metadata' : String(giscusConfig.emit_metadata ?? 0), + 'data-input-position' : giscusConfig.input_position || 'top', + 'data-theme' : giscusConfig.theme || 'preferred_color_scheme', + 'data-lang' : giscusConfig.lang || 'zh-CN', + 'data-loading' : giscusConfig.loading || 'lazy' + }, + parentNode: container + }); +});