From 616beb8c03504a2fc8b0d789140fd3fe71c2665f Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 23 Aug 2026 18:01:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAJAX=20=E5=BC=95=E6=93=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/css/routes/user-home.css | 8 ++--- inc/helpers/aksrt-archive.php | 25 ++++++--------- inc/helpers/posts-renderer/config.php | 8 ++--- src/Admin/Admin.php | 3 ++ src/Admin/GlobalController.php | 5 ++- templates/parts/user-home/panel-favorites.php | 1 - templates/parts/user-home/panel-posts.php | 1 - .../post-visual-contract.test.cjs | 31 ++++++++++++++++--- 8 files changed, 50 insertions(+), 32 deletions(-) diff --git a/assets/css/routes/user-home.css b/assets/css/routes/user-home.css index 6a049d7e..6f3228ad 100644 --- a/assets/css/routes/user-home.css +++ b/assets/css/routes/user-home.css @@ -430,7 +430,7 @@ /* Public author posts/favorites follow Zibll's author-tab list * (zibll css/main.css: .author-tab .posts-item + the ≥992px no-sidebar * two-column rule .site-layout-1 .posts-item:not(.card)). */ -.aksrt-user-home .aksrt-user-home__post-list .posts-item { +.aksrt-user-home .aksrt-user-home__post-list[data-view="list"] .posts-item { background: transparent; box-shadow: none; } @@ -438,7 +438,7 @@ /* 宽屏双列:无侧边栏全文宽时文章卡片并排两列,视觉同 zibll site-layout-1 * (zibll 用 inline-flex+calc(50%),对标记空白敏感,此处用等几何的 grid) */ @media (min-width: 992px) { - .aksrt-user-home .aksrt-user-home__post-list { + .aksrt-user-home .aksrt-user-home__post-list[data-view="list"] { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; @@ -447,14 +447,14 @@ margin-left: 0; } - .aksrt-user-home .aksrt-user-home__post-list > .posts-item { + .aksrt-user-home .aksrt-user-home__post-list[data-view="list"] > .posts-item { width: auto; /* 覆盖 vendored site-layout-1 的 width: calc(50% - 16px),让卡片填满网格单元 */ margin: 0 !important; /* 抵消 vendored .posts-row > * 的 8px !important 边距 */ } } @media (max-width: 767px) { - .aksrt-user-home .aksrt-user-home__post-list .posts-item { + .aksrt-user-home .aksrt-user-home__post-list[data-view="list"] .posts-item { padding: 10px 0; } } diff --git a/inc/helpers/aksrt-archive.php b/inc/helpers/aksrt-archive.php index 181308e0..3b22df34 100644 --- a/inc/helpers/aksrt-archive.php +++ b/inc/helpers/aksrt-archive.php @@ -9,19 +9,6 @@ defined('ABSPATH') || exit; -if (!function_exists('aksrt_archive_get_list_style_settings')) : - /** - * Shared list style defaults for archive surfaces. - * - * @return array - */ - function aksrt_archive_get_list_style_settings(): array { - return class_exists('\AKSRT\Settings\Settings') - ? \AKSRT\Settings\Settings::get_post_list_style_settings() - : []; - } -endif; - if (!function_exists('aksrt_resolve_post_list_render_config')) : /** * Build the legacy-shaped arguments used by every list surface. @@ -34,11 +21,14 @@ if (!function_exists('aksrt_resolve_post_list_render_config')) : * @return array */ function aksrt_resolve_post_list_render_config(array $args = []): array { + $has_top_level_term_id = array_key_exists('term_id', $args); $args = wp_parse_args($args, [ 'context' => '', + 'term_id' => 0, 'overrides' => [], ]); $overrides = is_array($args['overrides']) ? $args['overrides'] : []; + $has_override_term_id = array_key_exists('term_id', $overrides); $context = sanitize_key((string) ($args['context'] ?: ($overrides['context'] ?? ''))); if ($context === '') { if (function_exists('is_front_page') && (is_front_page() || is_home())) { @@ -55,17 +45,22 @@ if (!function_exists('aksrt_resolve_post_list_render_config')) : $context = 'archive'; } } + $term_id = $has_override_term_id ? absint($overrides['term_id']) : absint($args['term_id']); + if ($context === 'category' && !$has_top_level_term_id && !$has_override_term_id) { + $term_id = absint(get_queried_object_id()); + } $config = [ 'context' => $context, + 'term_id' => $term_id, 'is_home' => $context === 'home', 'is_category' => $context === 'category', 'is_tag' => $context === 'tag', 'is_author' => $context === 'author', 'is_search' => $context === 'search', ]; - foreach (['type', 'no_author', 'no_margin', 'is_mult_thumb', 'is_no_thumb', 'is_card', 'highlight_query', 'wrapper_class', 'skip_wrapper'] as $key) { + foreach (['type', 'term_id', 'no_author', 'no_margin', 'is_mult_thumb', 'is_no_thumb', 'is_card', 'highlight_query', 'wrapper_class', 'skip_wrapper'] as $key) { if (array_key_exists($key, $overrides)) { - $config[$key] = $overrides[$key]; + $config[$key] = $key === 'term_id' ? absint($overrides[$key]) : $overrides[$key]; } } return aksrt_renderer_config($config); diff --git a/inc/helpers/posts-renderer/config.php b/inc/helpers/posts-renderer/config.php index dfb904f0..fcd76c3e 100644 --- a/inc/helpers/posts-renderer/config.php +++ b/inc/helpers/posts-renderer/config.php @@ -17,6 +17,7 @@ if (!function_exists('aksrt_renderer_defaults')) { 'is_mult_thumb' => false, 'is_no_thumb' => false, 'is_card' => false, + 'term_id' => 0, 'is_category' => is_category(), 'is_search' => is_search(), 'is_home' => is_home() || is_front_page(), @@ -57,8 +58,8 @@ if (!function_exists('aksrt_renderer_config')) { || (!empty($args['is_home']) && !empty($list['list_card_home'])) || (!empty($args['is_author']) && !empty($list['list_card_author'])); } - if (!$is_forced && !$is_card) { - $term_id = (int) get_queried_object_id(); + if (!$is_forced && !$is_card && !empty($args['is_category'])) { + $term_id = absint($args['term_id']); $is_card = $term_id > 0 && in_array($term_id, (array) ($list['list_card_cat'] ?? []), true); } @@ -73,8 +74,6 @@ if (!function_exists('aksrt_renderer_config')) { $args['list_type'] = $list_type; $args['style'] = $style; $args['img_position'] = sanitize_key((string) ($list_option['img_position'] ?? 'left')) === 'right' ? 'right' : 'left'; - $args['list_scale'] = max(50, min(200, (int) ($list_option['scale'] ?? 70))); - $args['card_scale'] = max(20, min(200, (int) ($card_option['scale'] ?? 70))); $args['no_margin'] = !empty($args['no_margin']) || (($list['list_show_type'] ?? 'separate') === 'no_margin'); $args['no_author'] = !empty($args['no_author']) || !empty($args['is_author']); $args['target_blank'] = !empty($list['target_blank']); @@ -83,7 +82,6 @@ if (!function_exists('aksrt_renderer_config')) { $args['show_time'] = !empty($list['post_list_time']); $args['time_source'] = (string) ($list['post_time_source'] ?? 'modified'); $args['list_orderby'] = (string) ($list['list_orderby'] ?? 'modified'); - $args['mobile_meta'] = (string) ($list['list_meta_show'] ?? 'like'); $args['badge_types'] = (array) ($list['list_badge_show'] ?? ['pay', 'cat', 'tag']); $args['mult_thumb_cat'] = (array) ($list['mult_thumb_cat'] ?? []); $args['thumb'] = $thumb; diff --git a/src/Admin/Admin.php b/src/Admin/Admin.php index 93543f81..bb8ffa19 100644 --- a/src/Admin/Admin.php +++ b/src/Admin/Admin.php @@ -255,6 +255,9 @@ class Admin { if (isset($config['query_context'])) { $clean['query_context'] = sanitize_key((string) $config['query_context']); } + if (isset($config['term_id'])) { + $clean['term_id'] = absint($config['term_id']); + } foreach (['no_author', 'no_margin', 'is_card', 'skip_wrapper'] as $bool_key) { if (array_key_exists($bool_key, $config)) { $clean[$bool_key] = !empty($config[$bool_key]); diff --git a/src/Admin/GlobalController.php b/src/Admin/GlobalController.php index 77a87157..5b1d280e 100644 --- a/src/Admin/GlobalController.php +++ b/src/Admin/GlobalController.php @@ -335,7 +335,10 @@ class GlobalController extends ControllerBase { } $query = new \WP_Query($args); - $render_config = aksrt_resolve_post_list_render_config(['context' => $archive_type]); + $render_config = aksrt_resolve_post_list_render_config([ + 'context' => $archive_type, + 'term_id' => $archive_type === 'category' ? $term_id : 0, + ]); $render_config['skip_wrapper'] = true; $html = aksrt_render_post_list($render_config, $query, false); diff --git a/templates/parts/user-home/panel-favorites.php b/templates/parts/user-home/panel-favorites.php index 613166e2..a1d68504 100644 --- a/templates/parts/user-home/panel-favorites.php +++ b/templates/parts/user-home/panel-favorites.php @@ -18,7 +18,6 @@ if (!empty($favorite_post_ids)) : $user_home_render_config = aksrt_resolve_post_list_render_config([ 'context' => 'author', 'overrides' => [ - 'type' => 'list', 'no_author' => true, 'no_margin' => true, ], diff --git a/templates/parts/user-home/panel-posts.php b/templates/parts/user-home/panel-posts.php index 98344c36..819efc72 100644 --- a/templates/parts/user-home/panel-posts.php +++ b/templates/parts/user-home/panel-posts.php @@ -17,7 +17,6 @@ extract($args, EXTR_SKIP); // phpcs:ignore WordPress.PHP.DontExtract.extract_ext $user_home_render_config = aksrt_resolve_post_list_render_config([ 'context' => 'author', 'overrides' => [ - 'type' => 'list', 'no_author' => true, 'no_margin' => true, ], diff --git a/tests/widget-system/post-visual-contract.test.cjs b/tests/widget-system/post-visual-contract.test.cjs index e10a7953..fd73f2f2 100644 --- a/tests/widget-system/post-visual-contract.test.cjs +++ b/tests/widget-system/post-visual-contract.test.cjs @@ -105,6 +105,24 @@ test('forced mode wins and thumb_if_has ignores spare and lazy placeholders', () assert.match(data, /has_post_format\(\['image', 'gallery'\]/); }); +test('category card mode carries its term id through archive, AJAX and REST rendering', () => { + const resolver = read('inc/helpers/aksrt-archive.php'); + const config = read('inc/helpers/posts-renderer/config.php'); + const admin = read('src/Admin/Admin.php'); + const global = read('src/Admin/GlobalController.php'); + + assert.match(resolver, /'term_id'\s*=>\s*0/); + assert.match(resolver, /foreach \(\['type', 'term_id'/); + assert.match(resolver, /\$context === 'category' && !\$has_top_level_term_id && !\$has_override_term_id/); + assert.match(config, /!\$is_forced && !\$is_card && !empty\(\$args\['is_category'\]\)/); + assert.match(config, /\$term_id = absint\(\$args\['term_id'\]\)/); + assert.doesNotMatch(config, /get_queried_object_id/); + assert.match(admin, /\$clean\['term_id'\]\s*=\s*absint\(\$config\['term_id'\]\)/); + assert.match(global, /aksrt_resolve_post_list_render_config\(\[\s*'context'\s*=>\s*\$archive_type,\s*'term_id'\s*=>\s*\$archive_type === 'category' \? \$term_id : 0,/); + assert.doesNotMatch(config, /\b(?:list_scale|card_scale|mobile_meta)\b/); + assert.doesNotMatch(resolver, /aksrt_archive_get_list_style_settings/); +}); + test('image resolution counts only content images and applies the configured WordPress size', () => { const config = read('inc/helpers/posts-renderer/config.php'); const data = read('inc/helpers/posts-renderer/post-data.php'); @@ -216,7 +234,8 @@ test('related posts, author page and widgets use their dedicated renderers', () assert.match(resourceRelated, /aksrt_render_related_graphic_card/); assert.doesNotMatch(resourceRelated, /aksrt_render_post_list/); assert.match(author, /aksrt_render_post_list/); - assert.match(author, /'type'\s*=>\s*'list'/); + assert.doesNotMatch(author, /'type'\s*=>\s*'list'/); + assert.match(author, /'context'\s*=>\s*'author'/); assert.match(author, /'no_author'\s*=>\s*true/); assert.match(author, /'no_margin'\s*=>\s*true/); assert.match(author, /'wrapper_class'\s*=>\s*'aksrt-user-home__post-list'/); @@ -322,11 +341,13 @@ test('profile routes load versioned leaf styles and keep dialogs hidden initiall assert.match(accountModals, /id="email-modal" class="aksrt-modal" hidden/); assert.match(userCenterJs, /function closeModal\(m\)[\s\S]*?m\.hidden = true;/); assert.match(userHomeCss, /\.aksrt-profile-details-modal\[hidden\]\s*\{\s*display:\s*none\s*!important;\s*\}/); - assert.match(userHomeCss, /\.aksrt-user-home \.aksrt-user-home__post-list \.posts-item\s*\{[^}]*background:\s*transparent;[^}]*box-shadow:\s*none;/); - assert.match(userHomeCss, /@media \(min-width: 992px\)\s*\{[\s\S]*?\.aksrt-user-home \.aksrt-user-home__post-list\s*\{[^}]*display:\s*grid;[^}]*grid-template-columns:\s*repeat\(2,\s*minmax\(0,\s*1fr\)\);/); - assert.match(userHomeCss, /@media \(min-width: 992px\)\s*\{[\s\S]*?\.aksrt-user-home \.aksrt-user-home__post-list > \.posts-item\s*\{[^}]*width:\s*auto;[^}]*margin:\s*0 !important;/); - assert.match(userHomeCss, /@media \(max-width: 767px\)\s*\{[\s\S]*?\.aksrt-user-home \.aksrt-user-home__post-list \.posts-item\s*\{[^}]*padding:\s*10px 0;/); + assert.match(userHomeCss, /\.aksrt-user-home \.aksrt-user-home__post-list\[data-view="list"\] \.posts-item\s*\{[^}]*background:\s*transparent;[^}]*box-shadow:\s*none;/); + assert.match(userHomeCss, /@media \(min-width: 992px\)\s*\{[\s\S]*?\.aksrt-user-home \.aksrt-user-home__post-list\[data-view="list"\]\s*\{[^}]*display:\s*grid;[^}]*grid-template-columns:\s*repeat\(2,\s*minmax\(0,\s*1fr\)\);/); + assert.match(userHomeCss, /@media \(min-width: 992px\)\s*\{[\s\S]*?\.aksrt-user-home \.aksrt-user-home__post-list\[data-view="list"\] > \.posts-item\s*\{[^}]*width:\s*auto;[^}]*margin:\s*0 !important;/); + assert.match(userHomeCss, /@media \(max-width: 767px\)\s*\{[\s\S]*?\.aksrt-user-home \.aksrt-user-home__post-list\[data-view="list"\] \.posts-item\s*\{[^}]*padding:\s*10px 0;/); const panelFavorites = read('templates/parts/user-home/panel-favorites.php'); + assert.doesNotMatch(panelFavorites, /'type'\s*=>\s*'list'/); + assert.match(panelFavorites, /'context'\s*=>\s*'author'/); assert.match(panelFavorites, /aksrt_render_user_home_pagination\(\(int\) \$favorites_query->max_num_pages, \(int\) \$favorites_page\)/); assert.match(panelFavorites, /array_merge\(\$user_home_render_config, \['wrapper_class' => 'aksrt-user-home__post-list'\]\), \$favorites_query\)/); assert.doesNotMatch(panelFavorites, /profile-list-item|\$_GET|add_query_arg/);