没发现有类似的插件或者组件,自己捣鼓的话坑太深,干脆召唤 AI 写 JS 实现了,异常简陋,但感觉效果还行,记录分享下
在论坛帖子列表顶部插入一个随机帖子金句,点击可以进入帖子
金句和对应帖子标题链接是手动写入 JS 的……
没发现有类似的插件或者组件,自己捣鼓的话坑太深,干脆召唤 AI 写 JS 实现了,异常简陋,但感觉效果还行,记录分享下
在论坛帖子列表顶部插入一个随机帖子金句,点击可以进入帖子
金句和对应帖子标题链接是手动写入 JS 的……
emmmm 感觉好像没什么意义 或许应该弄一个签到的按钮 点击后谈一个悬浮UI里面写这个感觉会不错
挺有趣,可以放到discourse meta上,我去装一下
github 小号被标记了 (可能是上次提 issue 连续回复然后解决问题以后 issue 被整个删了导致的……)
解封需要国外手机号验证,用 sms-activate 第一个号没收到短信,第二个就一直 「You’ve reached your request limit, please try again later.」……
直接发这好了,暂时也不会迭代
Discourse 随机帖子金句脚本
简介
一个简陋但能用的 Discourse 脚本,在帖子列表顶部插入一个随机帖子金句,并提供跳转到对应帖子的链接。
该脚本由 AI 生成,仅供参考,如需优化请自行调整。功能
- 在论坛帖子列表顶部随机显示一条帖子金句。
- 点击金句可以跳转到对应帖子。
- 通过手动更新 JS 文件,维护需要展示的金句。
安装方法
编辑 Discourse 主题或组件
- 进入
管理
>自定义
>主题
。- 选择一个主题或创建一个新组件。
- 在
自定义 CSS/HTML
选项卡中,找到通用
>head
。- 在
head
部分粘贴完整的脚本代码。修改金句数据
在脚本内找到
_postsData
变量。按照格式添加或修改金句:
// 初始化原始帖子数据(只定义一次) if (!window._postsData) { window._postsData = [ { postId: "demoid1", title: "demotitle1", quotes: [ "demoquote11", "demoquote12", ] }, { postId: "demoid2", title: "demotitle2", quotes: [ "demoquote21", "demoquote22", ] }, ]; }
postId
:对应帖子 ID(用于跳转)。
title
:帖子标题(用于显示和链接)。
quotes
:该帖子的多个可选金句。保存并应用
- 点击
保存
。- 刷新页面,随机帖子金句会出现在帖子列表顶部。
<script type="text/discourse-plugin" version="0.8">
// 全局定义 shuffle 函数,确保后续调用时可用
function shuffle(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function insertRandomProverb() {
console.log("insertRandomProverb 被调用");
var panel = document.querySelector('.topic-list-body');
if (!panel) {
console.log("未找到 .topic-list-body 元素,延时重试");
setTimeout(insertRandomProverb, 300);
return;
}
console.log("找到了 panel:", panel);
// 移除已存在的金句,避免重复插入
var existing = panel.querySelector('.random-proverb');
if (existing) {
existing.remove();
console.log("已移除旧的金句");
}
// 初始化原始帖子数据(只定义一次)
if (!window._postsData) {
window._postsData = [
{
postId: "demoid1",
title: "demotitle1",
quotes: [
"demoquote11",
"demoquote12",
]
},
{
postId: "demoid2",
title: "demotitle2",
quotes: [
"demoquote21",
"demoquote22",
]
},
];
}
// 如果洗牌数组不存在或为空,则生成洗牌后的金句数组
if (!window._shuffledQuotes || window._shuffledQuotes.length === 0) {
var combined = [];
window._postsData.forEach(function(post) {
post.quotes.forEach(function(q) {
combined.push({
postId: post.postId,
title: post.title,
quote: q
});
});
});
window._shuffledQuotes = shuffle(combined.slice());
console.log("已生成洗牌金句数组:", window._shuffledQuotes);
}
function getNextQuote() {
var data = window._shuffledQuotes.shift();
if (!data) {
var combined = [];
window._postsData.forEach(function(post) {
post.quotes.forEach(function(q) {
combined.push({
postId: post.postId,
title: post.title,
quote: q
});
});
});
window._shuffledQuotes = shuffle(combined.slice());
data = window._shuffledQuotes.shift();
}
return data;
}
var quoteData = getNextQuote();
var isMobile = window.innerWidth <= 1024;
// 构造公共部分(链接部分)
var commonLink = '<a href="/t/' + quoteData.postId + '" class="title raw-link raw-topic-link">' +
quoteData.quote + '……<br><small>✨ ' + quoteData.title + '</small>' +
'</a>';
var commonCell = '<td class="main-link clearfix topic-list-data" colspan="1">' +
'<span class="link-top-line" role="heading" aria-level="2">' +
'<span class="topic-statuses"></span>' +
commonLink +
'</span>' +
'</td>';
// 如果是 PC 版,则附加额外的单元格;移动版则只用公共单元格
var extraCells = "";
if (!isMobile) {
extraCells =
'<td class="posters topic-list-data theme-avatar-small">' +
'<a href="/u/system" data-user-card="system" class="latest single">' +
'<img alt="" width="24" height="24" src="/" class="avatar latest single" title="system - 原始发帖人、最新发帖人">' +
'</a>' +
'</td>' +
'<td class="num posts-map posts topic-list-data">' +
'<a href="/t/' + quoteData.postId + '" class="badge-posts"><span class="number">0</span></a>' +
'</td>' +
'<td class="num views topic-list-data"><span class="number">0</span></td>' +
'<td class="activity num topic-list-data age">' +
'<a href="/t/' + quoteData.postId + '" class="post-activity"><span class="relative-date" data-time="1738932033887" data-format="tiny">0m</span></a>' +
'</td>';
}
var rowHTML = '<tr class="random-proverb topic-list-item ' + (isMobile ? '' : 'pc-template') + '">' +
commonCell + extraCells +
'</tr>';
panel.insertAdjacentHTML('afterbegin', rowHTML);
console.log("金句行已插入");
}
// 初次加载时执行
if (document.readyState === 'complete' || document.readyState === 'interactive') {
insertRandomProverb();
} else {
document.addEventListener('DOMContentLoaded', insertRandomProverb);
}
// 尝试使用 MutationObserver 监听较稳定的容器
// 这里优先尝试 data-test-id="topic-list",若找不到则退回 document.body
var stableContainer = document.querySelector('[data-test-id="topic-list"]');
if (!stableContainer) {
console.log("未找到稳定容器 [data-test-id='topic-list'],使用 document.body 作为备用");
stableContainer = document.body;
}
var observer = new MutationObserver(function(mutationsList, observer) {
// 检查 .topic-list-body 是否存在且包含金句
var panel = document.querySelector('.topic-list-body');
if (panel && !panel.querySelector('.random-proverb')) {
console.log("MutationObserver 检测到金句缺失,重新插入");
insertRandomProverb();
}
});
observer.observe(stableContainer, { childList: true, subtree: true });
console.log("MutationObserver 已启动,在稳定容器:", stableContainer);
</script>
<style>
.random-proverb {
opacity: 1;
text-align: left;
margin-top: 10px;
padding: 5px;
}
.random-proverb br {
line-height: 1px !important;
}
.random-proverb .title {
opacity: 0.5;
}
.random-proverb small {
margin-top: 0.5em;
opacity: 0.7;
}
/* 移动版:调整单元格内边距 */
@media screen and (max-width: 1024px) {
.random-proverb > td {
padding: 20px 0 !important;
}
.random-proverb small {
float: right;
}
}
/* PC版:取消 <small> 的浮动,保持帖子标题左对齐 */
.pc-template small {
float: none !important;
}
</style>
好吧。
Github 还有小号的呀。
我就一个号,一直就没有变过,反而是换个公司换个号,其实也挺麻烦的。
github repo discourse-random-quote 已经能访问了
原来是因为个人资料信息不像个人账户而是组织/项目信息的原因被限制的,修改以后就解封了
另外接码方面,开始随手选的印尼的号码一直提示「You’ve reached your request limit, please try again later」,换了个美国号码搞定
@hex 代码盲,所谓的大号也只是放了个 blog ……
汗,这次是真忘了私有转公开了
现在好了……