前言与简介
经过对Xiuno BBS 4核心机制的深度研究,我成功实现了HTMX 的深度集成。以清爽蓝色主题 为基底,在不破坏原生逻辑的前提下,为纯原装Xiuno BBS带来现代化近乎SPA的体验。
这意味着什么?
意味着更流畅、更现代的用户体验,同时保持 Xiuno 一贯的简洁和高效。
技术实现亮点
非侵入式改造
零核心代码修改,完全通过Hook机制实现
原生功能100%覆盖(目前仅限于此,插件兼容性保留)
渐进式增强:未改动验证码/附件上传等复杂交互
核心交互升级
无刷新全局导航
所有GET请求保持原URL结构,但实现内容动态替换
增加 `updatePagination` 事件解决分页器兼容问题
新增 `setActive` 函数替代jQuery依赖
纯HTMX表单处理
主题帖回帖:彻底脱离jQuery,通过 updatePostCount 事件同步计数,与HTMX本身的功能配合提供流畅体验
密码交互:属性自动生成加密字段,告别jQuery-MD5
管理功能:基于Pico CSS重构模态框(这部分不依赖Bootstrap功能,但暂时依赖Bootstrap样式),删除回帖时触发 removePost 等事件实现原子化更新(普通管理操作则全页刷新确保没有奇怪的副作用)
改造后的 message.htm 成为事件中枢
大多数操作的(文字)反馈都会通过模态框和吐司框呈现。
新增事件:
showModalSimple:显示模态框
closeModal:关闭模态框
showToast:右上角轻量吐司框通知
智能路由识别
通过全局变量精准控制渲染逻辑
/**
* @var bool 是HTMX发起的请求吗?
*/
$IS_HTMX = isset($_SERVER['HTTP_HX_REQUEST']) || (isset($_SERVER['HTTP_HX_REQUEST']) && $_SERVER['HTTP_HX_REQUEST'] == 'true');
/**
* @var bool 是通过翻页器访问的吗?
*/
$IS_IN_PAGINATION = isset($_REQUEST['IS_IN_PAGINATION']) && boolval($_REQUEST['IS_IN_PAGINATION']);
.
技术选型思考
HTMX的声明式特性与Xiuno的AOP架构完美契合 :
后端仅需微调输出HTML片段(通过现有Hook点)
前端交互复杂度降低60%+(移除大量jQuery回调)
传输体积减少约40%(局部更新优势)
已知注意事项
插件页面(例如通知、排行榜、积分等页面)可能出现双重嵌套(HTMX正常工作的副作用)
你看到的,是未来
这不是一个简单的“去 jQuery”项目,而是一次对传统论坛架构的重新思考:
我们不需要抛弃成熟的后端系统,也能拥有现代交互体验。
HTMX 让服务端渲染应用焕发新生,而 Xiuno BBS 凭借其清晰的 Hook 机制和插件生态,完美适配这一理念。
更新记录
1.2(2025年9月3日)
【新增】:解决了覆盖其他hook的最大难点。本插件会覆盖其他插件的更多内容,目的主要是添加HTMX支持
修复:解决了process_pagination_to_htmx_trigger在特定情况下出错
新增:用原生JS+HTMX实现了$('[data-modal-title]').each(function () {...}
的弹窗显示属性
必须拥有data-modal-url属性,这会让HTMX往这里发送GET请求
可选data-modal-title属性,替代原来的弹窗标题
可选data-modal-arg属性,约等于hx-include属性值,但如果你没有在这个属性里写input或textarea或select的话,会自动加上来保证可用性和兼容性
推荐使用data-modal-url直接作用于按钮等控件上来打开弹窗
修改:用HTMX实现了$.ajax_modal
的弹窗部分功能
移除:大约是xiuno bbs 3.0时期的旧函数:xn_position
、xn_menu
、xn_dropdown
、xn_toggle
,因为完全没有插件使用
移除:“点击响应整行”.tap
功能
新增:应当使用“fullpage”参数来获取全页(不含页眉页脚)
插件兼容
art_signature 适配完成
ax_comment 直接可用
ax_notice_sx 适配完成
fox_prison 适配完成
fox_search 适配完成
xn_digest 适配完成
haya_post_like 25%
huux_notice 适配完成
独立消息页面 √
但是在当前的个人中心里是加载到右侧,因为其他的都确定了
在导航栏里的是加载到页面内容
消息分类切换 √
翻页 √
标记已读 √
点击a标签设置已读 √
删除单条 √
全部已读 √
删除本页信息 √
无限滚动 ×
其他
$.fn.button
的第一个参数的取值有
loading:将按钮变为不可点击,然后将按钮原来的文字设置到按钮的default-text属性里,然后将按钮的文字设置为按钮的data-loading-text属性值
disabled:将按钮变为不可点击
enable:将按钮变为可点击(去掉disabled状态)
reset:将按钮变为可点击,然后检查是否有default-text属性,如果有,则将按钮的文字设置为default-text属性值
其他字符串:直接将按钮的文字设置为该值
message函数的第一个参数:
-101 ,目前具体表现为显示toast 类型为info
发掘到的未使用部分
$.ajax_modal
函数中提到了if (code == -101)
,
这会让该函数解析JSON里的HTML\CSS\JS然后隐藏 modal-footer
class=xn-dropdown
的元素会变成xiuno的dropdown,所有插件都没使用
用法:
<div class ="xn-dropdown" data-pos="5" data-hidearrow="0" >
<div class ="dropdown-toggle" >显示dropdown</div >
<div class ="dropdown-menu" >dropdown内容</div >
</div >
点击“显示dropdown”后,会根据data-pos的值定位“dropdown内容”的位置并显示出来,并且“dropdown内容”会附带一个小三角,这个小三角则是根据data-hidearrow
的值决定是否显示,如果data-hidearrow
是1或其他表示true的值则不会显示
data-pos
的值:
11 12 1
--------------------
10 | | 2
| |
9 | 0 | 3
| |
8 | | 4
--------------------
7 6 5
class=xn-toggle
的元素会变成xiuno的toggle开关,所有插件都没使用
用法:
<div class ="xn-toggle" data-target="#toggle_demo" >toggle按钮</div >
<div id ="toggle_demo" >toggle内容</div >
点击“toggle按钮”后,data-target属性指定的“toggle内容”会滑动显示出来,然后再次点击屏幕任何位置,“toggle内容”会滑动隐藏
如何使用fullpage参数
当链接是HTMX发起的时候,$IS_HTMX
会优先响应,然后根据携带的额外参数来提供HTML片段,但有时候我们确实需要返回页面本体,但如果对该链接不使用HTMX的话就失去了用HTMX的意义。那么后端插件在写链接地址的时候这样写:
<a href ="<?= url('my-notice');?>" > 消息</a >
<a href ="<?= url('my-notice',['fullpage'=>1]);?>" hx-boost ="true" hx-trigger ="click" hx-target ="#body" hx-swap ="innerHTML" hx-push-url ="true" > 消息</a >
然后在插件本身提供的页面里写:
<?php
if ($IS_HTMX && boolval(param('fullpage' ,0 )) === false ){
include _include(APP_PATH.'plugin/huux_notice/view/htm/my_notice_list.inc.htm' );
} elseif (!$IS_HTMX || ($IS_HTMX && boolval(param('fullpage' ,0 )))) { ?>
<?php if (!$IS_HTMX) {include _include(APP_PATH . 'view/htm/header.inc.htm' );} ?>
<?php include _include(APP_PATH.'plugin/huux_notice/view/htm/my_notice_list.inc.htm' ); ?>
<?php if (!$IS_HTMX) {include _include(APP_PATH . 'view/htm/footer.inc.htm' );} ?>
<?php } ?>
这样就可以兼顾HTMX的片段输出和全页输出。
1.1.0(2025年7月27日)
新增:主页、论坛版块页面、个人中心、用户页面 里的“帖子列表”的无限滚动加载
新增:帖子页面、个人中心、用户页面 里的“回帖列表”的无限滚动加载
修改:process_pagination_to_htmx_trigger函数增肌了第二个参数,用来指示给前台的翻页器添加什么参数,为后续精细化控制打下基础。目前是写死的thread(代表threadlist,在前台会增加IS_IN_THREADLIST)和post(代表postlist,在前台会增加IS_IN_POSTLIST)
新增:兼容了xiuno第一方插件“我的回帖”
外观没有变化。有人说“ui不好看”,那确实。这个的外观和原装xiuno相差无几。但从一个熟悉的起点出发可以更容易理解。
1.0.0(2025年7月24日)
初次发布。实现核心 HTMX 集成: 无刷新导航、HTMX 表单提交、事件中枢、新版Pico CSS 弹窗、替代JQuery的自动 MD5 等。
截图
源码获取
见附件。
这只是一个开始。
当 HTMX 遇见 Xiuno BBS,
老树开新花,原味生未来。
最后于 4天前
被Tillreetree编辑
,原因:
上传的附件: