就像短博文里说的那样,使用 giscus 配合 Planet 批量设置评论区还是有一点麻烦的。
其实主要问题是用户可能通过不同的 IPFS 网关访问,这就导致了不管是 URL 还是 pathname 都不可靠。帖子的标题确实可行,但可能出现没有标题的短博文这种情况。
一开始的选择是如果没有标题那么就用 JS 把 og:title
写入成发帖时间,可以实现功能,但会有两个问题,如果后期加上了标题、或者发帖时间被修改(Planet 似乎有一个 bug 是编辑帖子的时候时间有概率会变成现在),而手动设置时间则无法设置“秒”,出现这两种情况的话,之前的评论就不会显示了。
使用标题还有另一个需要处理的问题就是标题本身发生变化的情况。
所以最终还是决定用 JS 将所有文章的 Open Graph Title 全部动态替换成 Post ID(反正读取这玩意的服务都不会去跑 JS),最终代码如下,似乎只能放在 header 的 Custom Code 里才能生效:
适用于 Plain 模板:
<script>
(function() {
// --- Step 1: Compare og:site_name to the actual page title
const siteNameTag = document.querySelector('meta[property="og:site_name"]');
const siteName = siteNameTag ? siteNameTag.getAttribute('content').trim() : '';
const pageTitle = document.title.trim();
// --- Step 2: If they differ, update og:title with the last part of the pathname
if (siteName !== pageTitle) {
let path = window.location.pathname;
// Remove trailing slash if any
if (path.endsWith('/')) {
path = path.slice(0, -1);
}
// Extract the last segment of the path
const lastPart = path.substring(path.lastIndexOf('/') + 1);
// Update <meta property="og:title" ...>
const ogTitleTag = document.querySelector('meta[property="og:title"]');
if (ogTitleTag) {
ogTitleTag.setAttribute('content', lastPart);
console.log(`Updated og:title to "${lastPart}"`);
}
}
// --- Step 3: Create the wrapper <div> elements
const outerDiv = document.createElement('div');
outerDiv.style.display = 'flex';
outerDiv.style.alignItems = 'center';
outerDiv.style.padding = '0px 20px';
const innerDiv = document.createElement('div');
innerDiv.style.flex = '1';
innerDiv.style.width = '100%';
innerDiv.style.maxWidth = '700px';
innerDiv.style.margin = '20px auto';
// --- Step 4: Load the Giscus script
const giscusScript = document.createElement('script');
giscusScript.src = "https://giscus.app/client.js";
giscusScript.setAttribute('data-repo', "extrawdw-code/blog-giscus");
giscusScript.setAttribute('data-repo-id', "R_kgDONkfVTg");
giscusScript.setAttribute('data-category', "General");
giscusScript.setAttribute('data-category-id', "DIC_kwDONkfVTs4ClpWU");
giscusScript.setAttribute('data-mapping', "og:title");
giscusScript.setAttribute('data-strict', "1");
giscusScript.setAttribute('data-reactions-enabled', "1");
giscusScript.setAttribute('data-emit-metadata', "0");
giscusScript.setAttribute('data-input-position', "top");
giscusScript.setAttribute('data-theme', "preferred_color_scheme");
giscusScript.setAttribute('data-lang', "en");
giscusScript.setAttribute('data-loading', "lazy");
giscusScript.setAttribute('crossorigin', "anonymous");
giscusScript.async = true;
// Append script inside the inner div
innerDiv.appendChild(giscusScript);
// Then append the inner div to the outer div
outerDiv.appendChild(innerDiv);
// Insert the wrapper into <head> or near end of <body>
document.addEventListener('DOMContentLoaded', function() {
document.body.appendChild(outerDiv);
});
})();
</script>
适用于 Sepia 模板:
<script>
(function() {
// --- Step 1: Compare og:site_name to the actual page title
const siteNameTag = document.querySelector('meta[property="og:site_name"]');
const siteName = siteNameTag ? siteNameTag.getAttribute('content').trim() : '';
const pageTitle = document.title.trim();
// --- Step 2: If they differ, update og:title with the last part of the pathname
if (siteName !== pageTitle) {
let path = window.location.pathname;
// Remove trailing slash if any
if (path.endsWith('/')) {
path = path.slice(0, -1);
}
// Extract the last segment of the path
const lastPart = path.substring(path.lastIndexOf('/') + 1);
// Update <meta property="og:title" ...>
const ogTitleTag = document.querySelector('meta[property="og:title"]');
if (ogTitleTag) {
ogTitleTag.setAttribute('content', lastPart);
console.log(`Updated og:title to "${lastPart}"`);
}
}
// --- Step 3: Create the wrapper <div> elements
const outerDiv = document.createElement('div');
outerDiv.style.display = 'flex';
outerDiv.style.alignItems = 'center';
outerDiv.style.padding = '0px 20px';
const innerDiv = document.createElement('div');
innerDiv.style.flex = '1';
innerDiv.style.width = '100%';
innerDiv.style.maxWidth = '700px';
innerDiv.style.margin = '20px auto';
// --- Step 4: Load the Giscus script
const giscusScript = document.createElement('script');
giscusScript.src = "https://giscus.app/client.js";
giscusScript.setAttribute('data-repo', "extrawdw-code/blog-giscus");
giscusScript.setAttribute('data-repo-id', "R_kgDONkfVTg");
giscusScript.setAttribute('data-category', "General");
giscusScript.setAttribute('data-category-id', "DIC_kwDONkfVTs4ClpWU");
giscusScript.setAttribute('data-mapping', "og:title");
giscusScript.setAttribute('data-strict', "1");
giscusScript.setAttribute('data-reactions-enabled', "1");
giscusScript.setAttribute('data-emit-metadata', "0");
giscusScript.setAttribute('data-input-position', "top");
giscusScript.setAttribute('data-theme', "preferred_color_scheme");
giscusScript.setAttribute('data-lang', "en");
giscusScript.setAttribute('data-loading', "lazy");
giscusScript.setAttribute('crossorigin', "anonymous");
giscusScript.async = true;
// Append script inside the inner div
innerDiv.appendChild(giscusScript);
// Then append the inner div to the outer div
outerDiv.appendChild(innerDiv);
// Finally, place this wrapper inside the div with id="main-container"
document.addEventListener('DOMContentLoaded', function() {
const container = document.getElementById("main-container");
if (container) {
container.appendChild(outerDiv);
} else {
console.warn('Could not find a container with id="main-container".');
}
});
})();
</script>
外边套的俩 div 是参考的站长的网站设计。
最终效果如下:
在聚合站点的时候,只要打开“重用原始ID”的选项就可以让评论也“同步”过去。
p.s.:Planet 在聚合站点且保留 ID 的情况下,Bug 太多了……经常出现原帖被当成聚合过来的帖子,然后无法编辑需要重启的情况。