Files
wordpress-theme-aksrt/.specs/plans/zibll-widgets-1to1.md
T
kate522andClaude Fable 5 5061977b72 plan: zibll widgets 1:1 replication
6-phase vertical-slice plan for full 1:1 replication of the Zibll
widget system into AKSRT. Covers pagination fatal fix, card-stacking
CSS fix, unified renderer, shared common-form layer adoption, and
per-category widget alignment (posts/users/slider/marketing/forum/shop)
plus resource migration and registration/block-editor parity.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 18:56:16 +08:00

15 KiB
Raw Blame History

Plan: Zibll 小工具全量 1:1 深度复刻

PRD: .specs/prds/zibll-widgets-1to1.md 参考主题:C:\Users\Xing\Desktop\zibll

Architectural Decisions

跨所有阶段恒定的决策:

  • 表单架构 = 复用现有共享层,不移植 CSF:扩展现有 inc/modules/widgets-register.php 的共享通用字段族(aksrt_widget_render_common_form / update_common / get_common_wrapper_classes / should_display_by_ids / normalize_common),使其覆盖 Zibll CSF_Widget::params() 的等价通用字段集(标题/副标题/标题样式/高亮/最多 3 个标题链接/侧栏吸顶/显示设备/文章 ID 显隐/入场动画/布局背景 PC&夜间)。所有小工具通过共享层,不再各自手写。不引入 Codestar (CSF) 框架。
  • 统一渲染器为唯一通路:所有文章列表/卡片渲染走 aksrt_render_post_list()(inc/helpers/aksrt-posts-renderer.php)。删除 archive-resources.php 等手写 .posts-row.ajaxpager + get_template_part 的重复路径。
  • 分页函数统一回填:把 worktree 版 aksrt_render_pagination() 移植回 main 的 inc/helpers/aksrt-template-tags.php,作为唯一分页实现。
  • 小工具基座 = 单一 trait:新增 src/AKSRT/Widgets/Traits/CommonWidgetFields.php(或等价),封装 form/update/render-common 的共享调用,消除 16 处 in_affix 重复实现。每个小工具 use 该 trait,自身只声明业务字段。
  • 注册 = PSR-4 + inc/modules/widgets-register.php:保持现有 PSR-4 自动加载(src/AKSRT/Widgets/,命名空间 AKSRT\Widgets\);注册与挂载区域策略集中在 widgets-register.php。
  • 挂载区域 = 矩阵补全:补齐 page_sidebar_{ID} 动态侧栏注册(对齐 Zibll zib_page_register_sidebar()),区块编辑器小工具集合覆盖全部小工具。
  • 资源搬运:把 Zibll img/(slider-bg、slider-layer、user-level-、medal/、null.svg、thumbnail*.svg 等)及 CSF 后台选择器缩略图拷入 assets/img/(或 assets/images/),后续逐步替换。不移植 CSF 框架本体。
  • 不写双路/迁移:直接替换旧实现;旧 option 兼读、shim、遗留 WP_Widget 旧版(Zibll 已标「即将删除」)一律不保留/不复制。
  • 文件体量:遵循 CLAUDE.md ≤700 行目标、1000 行硬限;超限即拆 trait / 子文件。
  • 文档对齐:修正 CLAUDE.md 路径漂移(inc/classes/widgets/ → src/AKSRT/Widgets/)。

Phase 1 — 致命错误与卡片堆叠修复 + 渲染统一

User stories: US2(卡片正确布局)、US3(分页无致命)、US5(单一渲染通路)

What to build

修地基:回填 aksrt_render_pagination() 到 main;修复 post-card.css 的 display: block !important 使卡片恢复 inline-block 网格;删除 archive-resources.php 手写卡片循环,改走 aksrt_render_post_list() 统一渲染器。完成后首页/归档/搜索页有文章时不再致命,卡片在 list/card/mini 三模式下正确布局、不堆叠。

Done when

  • inc/helpers/aksrt-template-tags.php 存在 function aksrt_render_pagination(?WP_Query $query = null, array $args = []): void,含 numbered(.pagenav.ajax-pag.aksrt-pagination + paginate_links + 跳转)与 load_more/infinite(.aksrt-pagination-ajax + data-mode/data-query-vars/data-render-config)两分支。
  • grep -n "display: block !important" assets/css/frontend/post-card.css 不再出现在基础 .posts-item 规则块(行 28-46);.posts-item.card 的 display: inline-block 生效,可用浏览器/截图确认 3 列卡片网格(验证命令:grep -A3 '.posts-item.card {' assets/css/frontend/post-card.css 见 display: inline-block)。
  • archive-resources.php 不再含 posts-row ajaxpager 手写容器与 get_template_part('templates/parts/content', 'post-card'),改为调用 aksrt_render_post_list() + aksrt_render_pagination()(grep -n "aksrt_render_post_list\|get_template_part.*post-card" archive-resources.php 确认)。
  • index.php:40、search.php:281、archive-resources.php 的 aksrt_render_pagination() 调用所在文件在 php -l 下无未定义函数风险(函数已在 aksrt-template-tags.php 定义且通过 inc/bootstrap.php 加载链可达)。
  • php tools/audit-admin-contracts.php 退出码 0(无新增 schema/REST 硬不一致)。
  • 全部改动文件 ≤1000 行;超限已拆。

Phase 2 — 通用表单层全链路接入

User stories: US1(统一通用字段)、US5(全链路一致)

What to build

把 Zibll CSF_Widget::params() 的通用字段集等价实现进 AKSRT 共享层,并以单一 trait 让全部小工具接入:扩展 aksrt_widget_render_common_form / update_common / get_common_wrapper_classes / normalize_common 覆盖 标题/副标题/标题样式(简约·居中大标题)/高亮/高亮色/标题链接×3/侧栏吸顶/显示设备/文章 ID 显隐/入场动画/动画重复/布局背景(日间&夜间);新增 CommonWidgetFields trait 封装 form/update 的共享调用;删除 16 处小工具内 in_affix 等重复实现,全部改 use trait。

Done when

  • inc/modules/widgets-register.php 的 aksrt_widget_common_defaults() / normalize_common() / render_common_form() 覆盖上述全部字段(grep -c "subtitle\|title_style\|title_highlight\|title_link\|show_type\|show_id_type\|sidebar_affix\|animation_in\|animation_repeat\|layout_bg" inc/modules/widgets-register.php ≥ 预期命中)。
  • 新增 src/AKSRT/Widgets/Traits/CommonWidgetFields.php(trait),封装 render_common_form_section() + update_common_fields(),php -l 通过。
  • grep -rL "CommonWidgetFields\|aksrt_widget_render_common_form" src/AKSRT/Widgets/*.php 在所有非纯展示/无表单小工具上为空(即全部接入)。
  • grep -rln "in_affix" src/AKSRT/Widgets/*.php 返回的文件数 = 0(局部重复实现已删除,逻辑全部经共享层 sidebar_affix)。
  • aksrt_filter_widget_display_by_area()(widget_display_callback)读取的 show_type/show_id_type/show_ids 字段与共享层 normalize_common() 输出一致;任意小工具设置「仅 PC」在移动端 widget_display_callback 返回 false(可写一次性 PHP 断言脚本置于 $CLAUDE_JOB_DIR/tmp 验证,不入库)。
  • php tools/audit-admin-contracts.php 退出码 0;改动文件 ≤1000 行。

Phase 3 — 文章列表 / 卡片类小工具 1:1 对齐

User stories: US2、US4(文章类)、US5

What to build

对照 Zibll 文章列表类(zib_widget_ui_main_post、zib_widget_ui_tab_post、widget_ui_oneline_posts、zib_widget_ui_hot_posts、zib_widget_ui_posts_pay、zib_widget_ui_term_card、zib_widget_ui_term_lists_card)对齐 AKSRT 对应小工具(WidgetMainPosts、TabPostsWidget、WidgetOnelinePosts、HotPostsWidget、WidgetPostPayBox、WidgetTermCards、WidgetTermAggregation):字段、查询构造(cat/topics/zibpay_type/limit_day/orderby/count/paged)、3 种卡片样式(list/card/mini)、AJAX 懒加载与分页(REST /aksrt/v1/widgets/*)、空态。统一经 aksrt_render_post_list() 渲染。

Done when

  • 上述 7 个小工具各自 form() 业务字段与 Zibll 对齐(对照 C:\Users\Xing\Desktop\zibll\inc\widgets\widget-posts.php 同名 Zib_CFSwidget::create() 的 fields 数组逐项核对,差异记录在阶段说明)。
  • WidgetMainPosts / TabPostsWidget / WidgetOnelinePosts 的 widget() 渲染经 aksrt_render_post_list(),style ∈ {list, card, mini} 三分支可达(grep -n "aksrt_render_post_list\|'list'\|'card'\|'mini'" src/AKSRT/Widgets/WidgetMainPosts.php 确认)。
  • src/AKSRT/Core/WidgetAjax.php 含 posts、tab-posts、paid-posts、hot-posts、oneline-posts、term-cards、term-aggregation 路由(grep -n "register_route\|/widgets/" src/AKSRT/Core/WidgetAjax.php 确认),均带 permission_callback。
  • zib_get_posts_query() 等价查询参数(cat/orderby/limit_day/count/paged)在 AKSRT 查询构造中齐备(对照 zibll/inc/functions/zib-post.php:427 zib_get_posts_query)。
  • 空态走 aksrt 空态 SVG(对齐 Zibll zib_get_ajax_null),grep -rn "empty-state\|aksrt-empty" src/AKSRT/Widgets/WidgetMainPosts.php 确认。
  • php tools/audit-admin-contracts.php 退出码 0;改动文件 ≤1000 行。

Phase 4 — 用户 / 作者 / 幻灯片类小工具 1:1 对齐

User stories: US4(用户/作者/幻灯类)、US5

What to build

对照 Zibll(widget_ui_user 用户信息、widget_ui_avatar 文章作者、zib_widget_ui_user_ranking 排行榜、widget_ui_user_lists 用户列表、zib_widget_ui_slider 幻灯片)对齐 AKSRT(AboutWidget/WidgetUserCard、WidgetAuthorCard、WidgetUserRanking、WidgetUserLists、WidgetSlider):字段、登录态切换、签到/快捷入口、排行维度(签到总天数/连续天数/积分/粉丝)、幻灯片背景/图层视差/文字/链接(对齐 CFS_Module::add_slider() + CFS_Module::slide())。

Done when

  • 5 个小工具业务字段与 Zibll 对齐(对照 zibll/inc/widgets/widget-user.php、widget-slider.php 及 inc/options/options-module.php 的 add_slider/slide)。
  • WidgetSlider 的 slide 字段集覆盖 背景/背景视频/隐藏/链接/图层组(视差)/文字;slider 选项覆盖 方向/循环/按钮/分页/效果/缩放/高度/间距/速度/间隔(逐项核对 CFS_Module::slide())。
  • 用户类小工具登录态分支:未登录→登录/注册卡(含 OAuth),已登录→用户信息卡(对齐 widget_ui_user)。
  • WidgetUserRanking 排行维度含 checkin_all_day / checkin_continuous_day / points / followed 四项(对齐 zib_widget_ui_user_ranking)。
  • 幻灯片前端走共享 Swiper 栈(assets/js/core/slider.js + swiper-bundle),grep -n "swiper\|slider" src/AKSRT/Widgets/WidgetSlider.php 确认。
  • php tools/audit-admin-contracts.php 退出码 0;改动文件 ≤1000 行。

Phase 5 — 营销 / 装饰类小工具 1:1 对齐

User stories: US4(营销/装饰类)、US6(资源视觉一致)、US5

What to build

对照 Zibll 营销类(widget-produck.php:定价/评价/FAQ/统计/亮点/图文亮点/3D交互)与装饰类(widget-more.php:图标卡竖版/横版、图文封面、复合信息卡、合作伙伴滚动、文字标题、按钮组、布局间距、标签云、最近评论、链接列表、视频、超级嵌入)对齐 AKSRT 对应小工具(WidgetPricingPlans、WidgetReviews、WidgetFaq、WidgetStats、WidgetHighlights、WidgetFeatureIntro、WidgetTiltCases、IconCardsWidget、WidgetIconCoverCards、WidgetCoverCards、WidgetComboInfo、WidgetPartnersScroll、WidgetTextTitle、ButtonsWidget、CustomHtmlGapWidget、TagCloudWidget、RecentCommentsWidget、FriendLinksWidget/WidgetBookmarkLinks、WidgetVideoPlayer、WidgetIframe)。同时搬运 Zibll 资源(图片/图标/CSS/JS)入 assets/img。

Done when

  • 上述 20 个小工具业务字段与 Zibll 对齐(对照 zibll/inc/widgets/widget-produck.php、widget-more.php 的 fields 数组逐项核对)。
  • assets/img/ 含搬运资源:slider-bg.jpg、slider-layer-1.png、slider-layer-2.png、user_t.jpg、null*.svg、thumbnail*.svg、user-level-1..10.png、medal/、avatar-default.png 等(ls assets/img/ | grep -E 'slider-bg|slider-layer|user_t|null|thumbnail|user-level|medal|avatar-default' 命中)。
  • 装饰类滚动/轮播(合作伙伴、评价、图标卡)走共享 Swiper 栈;按钮组/文字标题/复合信息卡字段与 Zibll 对齐。
  • 链接类(FriendLinksWidget/WidgetBookmarkLinks)支持 card/bigcard/image/simple 四型(对齐 aksrt_links_box / Zibll widget_ui_links_lists_2)。
  • CustomHtmlGapWidget 双模式(html / gap,PC&移动高度)与 Zibll zib_widget_ui_layout_gap 对齐。
  • php tools/audit-admin-contracts.php 退出码 0;改动文件 ≤1000 行。

Phase 6 — 论坛 + 商城小工具、资源注册、区块编辑器对齐

User stories: US4(论坛/商城)、US7、US5

What to build

对照 Zibll 论坛小工具(inc/functions/bbs/widgets/:版块列表/信息/版主、帖子列表/多栏目、专题/话题列表)与商城小工具(inc/functions/shop/widgets/:商品列表/单行/多TAB)对齐 AKSRT(WidgetForum* 9 个 + WidgetProductList/WidgetProductOneline/WidgetProductTab)。补齐 page_sidebar_{ID} 动态侧栏注册;区块编辑器小工具集合覆盖全部小工具;修正 CLAUDE.md 路径漂移。

Done when

  • 论坛 9 个小工具业务字段与 Zibll 对齐(对照 zibll/inc/functions/bbs/widgets/widgets-plate.php、widgets-posts.php、widgets-term.php)。
  • 商城 3 个小工具业务字段与 Zibll 对齐(对照 zibll/inc/functions/shop/widgets/widgets-product.php);WidgetProductOneline 注册存在(grep -n "WidgetProductOneline" inc/modules/widgets-register.php 命中)。
  • WidgetAjax.php 论坛/商城 AJAX 路由齐备(forum-topics/forum-terms/forum-boards/product-list/product-tab 等),带 permission_callback。
  • page_sidebar_{ID} 动态侧栏已注册(对齐 Zibll zib_page_register_sidebar()),is_active_sidebar('page_sidebar_<ID>') 对启用挂载的页面返回 true(一次性 PHP 断言脚本验证,置于 $CLAUDE_JOB_DIR/tmp)。
  • 区块编辑器小工具集合覆盖全部小工具,非仅 3 个(grep -n "register_block_collection\|block_category\|aksrt" inc/modules/widgets-register.php 核对登记范围)。
  • CLAUDE.md 小工具路径修正为 src/AKSRT/Widgets/(grep -n "inc/classes/widgets" CLAUDE.md 无残留或已注明实际路径)。
  • php tools/audit-admin-contracts.php 退出码 0;全部改动文件 ≤1000 行。

Out of Scope

  • 不新增任何向后兼容 / 数据迁移层(PRD 明确)。
  • 参考图片为临时搬运,后续替换不属于本计划。
  • 不移植 CSF 框架本体。

Open Questions

  • Zibll 9 个旧版 WP_Widget(标记「即将删除」)是否需要在 AKSRT 复刻旧版?默认不复刻(符合「不保留旧实现」),仅以现代对等小工具覆盖。若需保留旧版行为,请在 Phase 3/5 前确认。
  • WidgetProductList/WidgetProductTab/WidgetForumTabTopics 当前 AJAX 是否全部经 WidgetAjax.php?Phase 6 将统一收敛到 REST 路由;若某些小工具刻意只做客户端渲染,请确认。
  • 小工具挂载区域策略(aksrt_widget_allowed_sidebars)当前仅约束 7 个小工具,其余不受限。是否需要对照 Zibll 全量收紧?默认保持现有宽松策略,仅修复明确错误。