From d4797238140d9a6aa2c863c41708f5fe2b6f04f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Jul 2026 02:27:18 +0800 Subject: [PATCH] feat(forum): multi-tab topic widget lazy REST load SSR first tab; other tabs fetch /forum/frontend/widgets/topics on switch, with shared list markup and styles. --- assets/css/frontend/widget-batch5.css | 58 +++++++ src/AKSRT/Widgets/WidgetForumTabTopics.php | 172 ++++++++++----------- 2 files changed, 142 insertions(+), 88 deletions(-) diff --git a/assets/css/frontend/widget-batch5.css b/assets/css/frontend/widget-batch5.css index 7c8fded0..a8c0a29e 100644 --- a/assets/css/frontend/widget-batch5.css +++ b/assets/css/frontend/widget-batch5.css @@ -718,3 +718,61 @@ .aksrt-badge-modal__card { padding: 12px 8px 8px; } .aksrt-badge-modal__actions { margin-top: 12px; } .aksrt-author-hero__badges { margin-top: 8px; } + +/* Forum tab topics (batch6) */ +.aksrt-ftab__nav { + display: flex; + gap: 6px; + list-style: none; + margin: 0 0 10px; + padding: 0; + overflow-x: auto; +} +.aksrt-ftab__btn { + border: 0; + background: var(--surface-2, #f3f4f6); + border-radius: 999px; + padding: 5px 12px; + font-size: 13px; + cursor: pointer; + color: inherit; +} +.aksrt-ftab__btn.is-active { + background: var(--color-primary, #3b82f6); + color: #fff; +} +.aksrt-ftab__panel { display: none; } +.aksrt-ftab__panel.is-active { display: block; } +.aksrt-ftab__empty { font-size: 13px; color: var(--muted-2-color, #999); padding: 8px 0; } +.aksrt-ftopic-list { list-style: none; margin: 0; padding: 0; } +.aksrt-ftopic-list__item { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 7px 0; + border-bottom: 1px dashed var(--color-line, #eee); + font-size: 13px; +} +.aksrt-ftopic-list__item:last-child { border-bottom: 0; } +.aksrt-ftopic-list__link { + color: inherit; + text-decoration: none; + flex: 1; + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.aksrt-ftopic-list__views { color: var(--muted-2-color, #999); font-size: 12px; flex-shrink: 0; } +.aksrt-ftopic-list__meta { + display: flex; + gap: 8px; + font-size: 11px; + color: var(--muted-2-color, #999); + margin-top: 4px; +} +.aksrt-ftopic-list.is-detail .aksrt-ftopic-list__item { + flex-direction: column; + align-items: flex-start; +} diff --git a/src/AKSRT/Widgets/WidgetForumTabTopics.php b/src/AKSRT/Widgets/WidgetForumTabTopics.php index 1ffbfb60..c96212b6 100644 --- a/src/AKSRT/Widgets/WidgetForumTabTopics.php +++ b/src/AKSRT/Widgets/WidgetForumTabTopics.php @@ -1,6 +1,6 @@ esc_html__('热门/最新/精华等栏目切换的帖子列表。', 'aksrt'), + 'description' => esc_html__('热门/最新/精华等栏目切换的帖子列表(懒加载)。', 'aksrt'), 'classname' => 'widget_aksrt_forum_tab_topics', ] ); @@ -36,6 +36,7 @@ class WidgetForumTabTopics extends \WP_Widget { } $count = max(1, min(20, (int) ($instance['count'] ?? 6))); $uid = 'aksrt-ftab-' . esc_attr($this->id); + $rest = rest_url('aksrt/v1/forum/frontend/widgets/topics'); echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped $title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base); @@ -43,32 +44,60 @@ class WidgetForumTabTopics extends \WP_Widget { echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } - echo '
'; + echo '
'; echo '
    '; foreach ($tabs as $i => $tab) { $cls = $i === 0 ? ' is-active' : ''; - echo '
  • '; + echo '
  • '; } echo '
'; foreach ($tabs as $i => $tab) { $cls = $i === 0 ? ' is-active' : ''; - echo '
'; - $this->render_list($tab, $count); + $loaded = $i === 0 ? '1' : '0'; + echo '
'; + if ($i === 0) { + $payload = WidgetForumTopicLists::query_payload([ + 'count' => $count, + 'orderby' => $tab['orderby'], + 'style' => 'mini', + 'paginate' => 'none', + ], 1); + echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } else { + echo '
'; + } echo '
'; } echo '
'; - ?>