diff --git a/assets/admin/src/schema/sections/page-display/index.js b/assets/admin/src/schema/sections/page-display/index.js
index 0da1e5a1..cc2b21e6 100644
--- a/assets/admin/src/schema/sections/page-display/index.js
+++ b/assets/admin/src/schema/sections/page-display/index.js
@@ -1010,7 +1010,7 @@ export const pageDisplaySchemas = {
fields: [
{
key: 'homepage_card_style',
- label: '卡片风格',
+ label: '卡片风格(已弃用)',
type: 'radio',
default: 'default',
options: [
@@ -1018,18 +1018,23 @@ export const pageDisplaySchemas = {
{ label: '风格 2', value: 'style2' },
{ label: '风格 3', value: 'style3' },
],
+ help: '已弃用:请改用「文章列表」中的列表/卡片样式设置。',
},
- { key: 'homepage_multi_thumb_enabled', label: '多图卡片', type: 'switch', default: true },
- { key: 'homepage_multi_thumb_min_images', label: '最少图片数', type: 'number', default: 3, min: 2, max: 4, dependsOn: { key: 'homepage_multi_thumb_enabled', value: true } },
+ { key: 'homepage_multi_thumb_enabled', label: '多图卡片(已弃用)', type: 'switch', default: true, help: '请改用文章列表缩略图/多图设置。' },
+ { key: 'homepage_multi_thumb_min_images', label: '最少图片数(已弃用)', type: 'number', default: 3, min: 2, max: 4 },
{
key: 'homepage_default_view',
- label: '默认视图',
+ label: '默认视图(已弃用)',
type: 'radio',
default: 'list',
options: [
{ label: '列表', value: 'list' },
{ label: '卡片', value: 'card' },
],
+ help: 'SSR 以文章列表全局设置为准;此字段仅作兼容保留。',
+ },
+ { label: '卡片', value: 'card' },
+ ],
},
{ key: 'homepage_sidebar_mini_enabled', label: '迷你侧栏列表', type: 'switch', default: true },
{ key: 'homepage_sort_ajax_enabled', label: '排序栏 AJAX', type: 'switch', default: true },
diff --git a/assets/admin/src/schema/sections/post-list/list.js b/assets/admin/src/schema/sections/post-list/list.js
index 208c88dc..9bbd8ad7 100644
--- a/assets/admin/src/schema/sections/post-list/list.js
+++ b/assets/admin/src/schema/sections/post-list/list.js
@@ -166,18 +166,19 @@ export const listSchema = {
fields: [
{
key: 'post_card_style',
- label: '列表卡片样式',
+ label: '默认列表模式',
type: 'select',
default: 'thumb',
options: [
- { label: '标准图文', value: 'thumb' },
- { label: '紧凑卡', value: 'compact' },
- { label: '大图卡', value: 'large_thumb' },
- { label: '多图卡', value: 'multi_thumb' },
- { label: '纯文字', value: 'text' },
- { label: '有图则图文', value: 'thumb_if_has' },
+ { label: '列表图文模式', value: 'thumb' },
+ { label: '列表文字模式', value: 'text' },
+ { label: '列表自动图文', value: 'thumb_if_has' },
{ label: '卡片模式', value: 'card' },
+ { label: '紧凑列表', value: 'compact' },
+ { label: '大图列表', value: 'large_thumb' },
+ { label: '多图列表', value: 'multi_thumb' },
],
+ help: '对齐 Zibll list_type:thumb/text/thumb_if_has 为列表,card 为卡片网格。首页可用下方「首页卡片模式」单独强制卡片。',
},
{ key: 'post_excerpt_length', label: '摘要长度', type: 'number', default: 120, min: 20, max: 500 },
{ key: 'post_list_per_page', label: '每页文章数', type: 'number', default: 12, min: 4, max: 48 },
@@ -223,7 +224,7 @@ export const listSchema = {
],
},
{ key: 'list_card_scale', label: '卡片缩略图比例 (%)', type: 'number', default: 70, min: 20, max: 200 },
- { key: 'list_card_home', label: '首页卡片模式', type: 'switch', default: false },
+ { key: 'list_card_home', label: '首页卡片模式', type: 'switch', default: false, help: '当默认模式不为卡片时,单独将首页列表强制为卡片(Zibll list_card_home)', dependsOn: { key: 'post_card_style', operator: '!=', value: 'card' } },
{
key: 'list_card_cat',
label: '分类卡片模式',
diff --git a/category.php b/category.php
index 9c7f20b3..e4bee932 100644
--- a/category.php
+++ b/category.php
@@ -68,17 +68,20 @@ $custom_dimensions = is_array($cat_filter_config['dimensions'] ?? null) ? $cat_f
$sort_state = function_exists('aksrt_archive_get_sort_state') ? aksrt_archive_get_sort_state() : ['current' => 'latest', 'links' => []];
$current_sort = $sort_state['current'];
$sort_links = $sort_state['links'];
-$render_config = function_exists('aksrt_archive_get_render_config')
- ? aksrt_archive_get_render_config([
- 'context' => 'category',
- 'mode' => $layout_mode,
- 'card_style' => $card_style,
- ])
- : [
- 'context' => 'category',
- 'mode' => $layout_mode,
- 'card_style' => $card_style,
+$render_overrides = [
+ 'context' => 'category',
];
+ // Term meta layout_mode is authoritative only when explicitly set (non-empty preset).
+ $layout_preset = (string) ($archive_settings['layout_preset'] ?? '');
+ if ($layout_preset !== '' && in_array((string) $layout_mode, ['list', 'card', 'mini', 'grid-cms'], true)) {
+ $render_overrides['mode'] = (string) $layout_mode;
+ if (!empty($card_style)) {
+ $render_overrides['card_style'] = (string) $card_style;
+ }
+ }
+ $render_config = function_exists('aksrt_archive_get_render_config')
+ ? aksrt_archive_get_render_config($render_overrides)
+ : array_merge(['context' => 'category', 'mode' => 'list'], $render_overrides);
$filter_terms = [];
$filter_all_url = get_category_link($term->term_id);
diff --git a/inc/classes/admin/class-aksrt-admin-global-controller.php b/inc/classes/admin/class-aksrt-admin-global-controller.php
index 6c270ad3..ef6736e1 100644
--- a/inc/classes/admin/class-aksrt-admin-global-controller.php
+++ b/inc/classes/admin/class-aksrt-admin-global-controller.php
@@ -301,13 +301,20 @@ class AKSRT_Admin_Global_Controller extends AKSRT_Admin_Controller_Base {
$query = new WP_Query($args);
- $mode = in_array($view_mode, ['card', 'list'], true) ? $view_mode : 'list';
+ $mode = in_array($view_mode, ['card', 'list'], true) ? $view_mode : '';
$html = '';
if (function_exists('aksrt_render_post_list')) {
- $html = aksrt_render_post_list($query, [
- 'mode' => $mode,
- 'context' => 'home',
- ], false);
+ $overrides = ['context' => 'home'];
+ if ($mode !== '') {
+ $overrides['mode'] = $mode;
+ }
+ $render_config = function_exists('aksrt_resolve_post_list_render_config')
+ ? aksrt_resolve_post_list_render_config([
+ 'context' => 'home',
+ 'overrides' => $overrides,
+ ])
+ : array_merge(['mode' => ($mode !== '' ? $mode : 'list'), 'context' => 'home'], $overrides);
+ $html = aksrt_render_post_list($query, $render_config, false);
} elseif ($query->have_posts()) {
$html = '';
while ($query->have_posts()) {
diff --git a/inc/classes/admin/schema/post-list/class-aksrt-admin-schema-post-list-list.php b/inc/classes/admin/schema/post-list/class-aksrt-admin-schema-post-list-list.php
index 00b7a1a0..a78903df 100644
--- a/inc/classes/admin/schema/post-list/class-aksrt-admin-schema-post-list-list.php
+++ b/inc/classes/admin/schema/post-list/class-aksrt-admin-schema-post-list-list.php
@@ -159,16 +159,16 @@ class AKSRT_Admin_Schema_Post_List_List {
'fields' => [
[
'key' => 'post_card_style',
- 'label' => '列表卡片样式',
+ 'label' => '默认列表模式',
'type' => 'select',
'default' => 'thumb',
'options' => [
- ['label' => '标准图文', 'value' => 'thumb'],
+ ['label' => '列表图文模式', 'value' => 'thumb'],
['label' => '紧凑卡', 'value' => 'compact'],
['label' => '大图卡', 'value' => 'large_thumb'],
['label' => '多图卡', 'value' => 'multi_thumb'],
- ['label' => '纯文字', 'value' => 'text'],
- ['label' => '有图则图文', 'value' => 'thumb_if_has'],
+ ['label' => '列表文字模式', 'value' => 'text'],
+ ['label' => '列表自动图文', 'value' => 'thumb_if_has'],
['label' => '卡片模式', 'value' => 'card'],
],
],
diff --git a/inc/classes/class-aksrt-admin.php b/inc/classes/class-aksrt-admin.php
index 2549d3c5..960d376e 100644
--- a/inc/classes/class-aksrt-admin.php
+++ b/inc/classes/class-aksrt-admin.php
@@ -226,7 +226,10 @@ class AKSRT_Admin {
public static function sanitize_public_render_config(array $config): array {
$clean = [];
if (isset($config['mode'])) {
- $clean['mode'] = sanitize_key((string) $config['mode']);
+ $mode = sanitize_key((string) $config['mode']);
+ if (in_array($mode, ['list', 'card', 'mini', 'grid-cms'], true)) {
+ $clean['mode'] = $mode;
+ }
}
if (isset($config['context'])) {
$clean['context'] = sanitize_key((string) $config['context']);
@@ -234,9 +237,49 @@ class AKSRT_Admin {
if (isset($config['query_context'])) {
$clean['query_context'] = sanitize_key((string) $config['query_context']);
}
+ if (isset($config['style'])) {
+ $style = sanitize_key((string) $config['style']);
+ if (in_array($style, ['', 'style2', 'style3'], true)) {
+ $clean['style'] = $style;
+ }
+ }
+ if (isset($config['card_style'])) {
+ $card_style = sanitize_key((string) $config['card_style']);
+ $allowed = ['thumb', 'text', 'thumb_if_has', 'card', 'compact', 'large_thumb', 'multi_thumb', 'standard'];
+ if (in_array($card_style, $allowed, true)) {
+ $clean['card_style'] = $card_style;
+ }
+ }
+ if (isset($config['list_show_type'])) {
+ $v = sanitize_key((string) $config['list_show_type']);
+ if (in_array($v, ['separate', 'no_margin'], true)) {
+ $clean['list_show_type'] = $v;
+ }
+ }
+ if (isset($config['list_img_position'])) {
+ $v = sanitize_key((string) $config['list_img_position']);
+ if (in_array($v, ['left', 'right'], true)) {
+ $clean['list_img_position'] = $v;
+ }
+ }
+ foreach (['thumb_if_has', 'show_thumb', 'show_author', 'show_date', 'show_views', 'show_comments', 'show_likes', 'show_excerpt', 'heading_bold', 'target_blank', 'badge_show', 'multi_thumb_enabled', 'skip_wrapper'] as $bool_key) {
+ if (array_key_exists($bool_key, $config)) {
+ $clean[$bool_key] = !empty($config[$bool_key]);
+ }
+ }
+ if (isset($config['multi_thumb_limit'])) {
+ $clean['multi_thumb_limit'] = max(1, min(6, (int) $config['multi_thumb_limit']));
+ }
+ if (isset($config['multi_thumb_min'])) {
+ $clean['multi_thumb_min'] = max(1, min(6, (int) $config['multi_thumb_min']));
+ }
+ if (isset($config['excerpt_words'])) {
+ $clean['excerpt_words'] = max(0, min(200, (int) $config['excerpt_words']));
+ }
return $clean;
}
+
public function ajax_load_more_posts(): void {
check_ajax_referer('aksrt_public_nonce', 'nonce');
$page = max(1, (int) ($_POST['page'] ?? 1));
@@ -244,6 +287,18 @@ class AKSRT_Admin {
$render_config = json_decode(wp_unslash((string) ($_POST['render_config'] ?? '{}')), true);
$query_vars = is_array($query_vars) ? self::sanitize_public_query_vars($query_vars) : [];
$render_config = is_array($render_config) ? self::sanitize_public_render_config($render_config) : [];
+ // Prefer server-side resolution so AJAX matches SSR styles even if client config is slim.
+ if (function_exists('aksrt_resolve_post_list_render_config')) {
+ $context = sanitize_key((string) ($render_config['context'] ?? 'archive'));
+ if ($context === '') {
+ $context = 'archive';
+ }
+ $resolved = aksrt_resolve_post_list_render_config([
+ 'context' => $context,
+ 'overrides' => $render_config,
+ ]);
+ $render_config = array_merge($resolved, $render_config);
+ }
$query_vars['paged'] = $page;
$query = new WP_Query($query_vars);
diff --git a/inc/classes/class-aksrt-term-meta.php b/inc/classes/class-aksrt-term-meta.php
index a626b793..4718dbd3 100644
--- a/inc/classes/class-aksrt-term-meta.php
+++ b/inc/classes/class-aksrt-term-meta.php
@@ -84,19 +84,24 @@ class AKSRT_Term_Meta {
$saved = [];
}
- $layout_mode = isset($saved['layout_mode']) && $saved['layout_mode'] !== ''
- ? sanitize_key((string) $saved['layout_mode'])
- : (string) ($global['list_mode'] ?? 'grid');
-
- $layout_map = [
- 'grid' => ['mode' => 'card', 'card_style' => 'standard'],
- 'card' => ['mode' => 'card', 'card_style' => 'standard'],
- 'list' => ['mode' => 'list', 'card_style' => 'standard'],
- 'compact' => ['mode' => 'list', 'card_style' => 'compact'],
- 'mini' => ['mode' => 'mini', 'card_style' => 'standard'],
- 'grid-cms' => ['mode' => 'grid-cms', 'card_style' => 'standard'],
- ];
- $resolved_layout = $layout_map[$layout_mode] ?? ['mode' => 'card', 'card_style' => 'standard'];
+ // Empty term layout_mode means follow global post-list settings (Zibll).
+ // Do not fall back to page-display list_mode=grid which forced card everywhere.
+ $layout_preset = isset($saved['layout_mode']) ? sanitize_key((string) $saved['layout_mode']) : '';
+ if ($layout_preset === '') {
+ $resolved_layout = ['mode' => '', 'card_style' => ''];
+ $layout_mode = '';
+ } else {
+ $layout_mode = $layout_preset;
+ $layout_map = [
+ 'grid' => ['mode' => 'card', 'card_style' => 'thumb'],
+ 'card' => ['mode' => 'card', 'card_style' => 'thumb'],
+ 'list' => ['mode' => 'list', 'card_style' => 'thumb'],
+ 'compact' => ['mode' => 'list', 'card_style' => 'compact'],
+ 'mini' => ['mode' => 'mini', 'card_style' => 'thumb'],
+ 'grid-cms' => ['mode' => 'grid-cms', 'card_style' => 'thumb'],
+ ];
+ $resolved_layout = $layout_map[$layout_mode] ?? ['mode' => 'list', 'card_style' => 'thumb'];
+ }
$header_style = (string) ($global['header_style'] ?? 'simple');
if (!in_array($header_style, ['cover', 'simple', 'none'], true)) {
diff --git a/inc/classes/settings/class-aksrt-settings-display-page-groups.php b/inc/classes/settings/class-aksrt-settings-display-page-groups.php
index 955e02a0..ea16285a 100644
--- a/inc/classes/settings/class-aksrt-settings-display-page-groups.php
+++ b/inc/classes/settings/class-aksrt-settings-display-page-groups.php
@@ -161,7 +161,7 @@ trait AKSRT_Settings_Display_Page_Groups {
return [
'list' => [
- 'post_card_style' => $list['card_style'],
+ 'post_card_style' => $list['list_type'] ?? $list['card_style'] ?? 'thumb',
'post_list_author' => $list['show_author'],
'post_show_date' => $list['show_date'],
'post_show_views' => $list['show_views'],
@@ -188,10 +188,10 @@ trait AKSRT_Settings_Display_Page_Groups {
'list_list_style' => $list['list_style'],
'list_list_img_position' => $list['list_img_position'],
'list_list_scale' => $list['list_scale'],
- 'list_card_style' => $list['card_style'],
+ 'list_card_style' => $list['card_variant'] ?? '',
'list_card_scale' => $list['card_scale'],
'list_card_home' => $list['card_home'],
- 'list_card_cat' => $list['card_cat'],
+ 'list_card_cat' => $list['card_cat_ids'] ?? [],
'list_card_tag' => $list['card_tag'],
'list_card_topics' => $list['card_topics'],
'list_card_author' => $list['card_author'],
diff --git a/inc/classes/settings/class-aksrt-settings-post-display.php b/inc/classes/settings/class-aksrt-settings-post-display.php
index 1c544c56..eb601a28 100644
--- a/inc/classes/settings/class-aksrt-settings-post-display.php
+++ b/inc/classes/settings/class-aksrt-settings-post-display.php
@@ -11,19 +11,26 @@ class AKSRT_Settings_Post_Display {
public static function get_post_list_style_settings(): array {
$settings = AKSRT_Settings::get_all();
- $card_style = sanitize_key((string) ($settings['post_card_style'] ?? 'thumb'));
- $allowed_styles = ['thumb', 'compact', 'large_thumb', 'multi_thumb', 'text', 'thumb_if_has', 'card', 'standard'];
- if (!in_array($card_style, $allowed_styles, true)) {
- $card_style = 'thumb';
+ // post_card_style storage key mirrors Zibll list_type.
+ $list_type = sanitize_key((string) ($settings['post_card_style'] ?? 'thumb'));
+ $allowed_list_types = ['thumb', 'compact', 'large_thumb', 'multi_thumb', 'text', 'thumb_if_has', 'card', 'standard'];
+
+ if (!in_array($list_type, $allowed_list_types, true)) {
+ $list_type = 'thumb';
}
- // historical alias
- if ($card_style === 'standard') {
- $card_style = 'thumb';
+ // Historical aliases → Zibll list_type tokens.
+ if ($list_type === 'standard') {
+ $list_type = 'thumb';
+ }
+ // Non-Zibll extras stay list-mode variants (never force card grid).
+ if (in_array($list_type, ['compact', 'large_thumb', 'multi_thumb'], true)) {
+ // Keep token for CSS hooks; render as list.
}
+ // Zibll: only list_type=card is card mode; thumb/text/thumb_if_has are list.
$render_mode_map = [
- 'thumb' => 'card',
+ 'thumb' => 'list',
'compact' => 'list',
'large_thumb' => 'list',
'multi_thumb' => 'list',
@@ -74,9 +81,34 @@ class AKSRT_Settings_Post_Display {
$ajax_nomore = sanitize_text_field((string) $settings['ajax_nomore_text']);
}
+ $list_style = sanitize_key((string) ($settings['list_list_style'] ?? ''));
+ if (!in_array($list_style, ['', 'style2'], true)) {
+ $list_style = '';
+ }
+
+ $card_variant = sanitize_key((string) ($settings['list_card_style'] ?? ''));
+ if (!in_array($card_variant, ['', 'style3'], true)) {
+ $card_variant = '';
+ }
+
+ $card_cat_ids = [];
+ if (is_array($settings['list_card_cat'] ?? null)) {
+ $card_cat_ids = array_values(array_filter(array_map('intval', $settings['list_card_cat'])));
+ }
+
return [
- 'card_style' => in_array(sanitize_key((string) ($settings['list_card_style'] ?? '')), ['', 'style3'], true) ? sanitize_key((string) ($settings['list_card_style'] ?? '')) : '',
- 'render_mode' => $render_mode_map[$card_style] ?? 'card',
+ // Zibll list_type (storage: post_card_style).
+ 'list_type' => $list_type,
+ // Base mode from list_type only (surface card overrides applied by resolver).
+ 'render_mode' => $render_mode_map[$list_type] ?? 'list',
+ // List item subtype token for text/thumb_if_has class hooks (not card variant).
+ 'list_type_token' => $list_type,
+ // List mode visual variant (Zibll list_list_option.style).
+ 'list_style' => $list_style,
+ // Card mode visual variant (Zibll list_card_option.style).
+ 'card_variant' => $card_variant,
+ // Back-compat aliases used by older callers (prefer list_type / card_variant).
+ 'card_style' => $list_type,
'show_author' => $show_author,
'show_date' => $show_date,
'show_views' => !isset($settings['post_show_views']) || !empty($settings['post_show_views']),
@@ -100,13 +132,12 @@ class AKSRT_Settings_Post_Display {
'list_orderby' => in_array(sanitize_key((string) ($settings['list_orderby'] ?? 'modified')), ['modified', 'date', 'default'], true) ? sanitize_key((string) ($settings['list_orderby'] ?? 'modified')) : 'modified',
'columns' => max(1, min(3, (int) ($settings['post_list_columns'] ?? 1))),
'per_page' => max(4, min(48, (int) ($settings['post_list_per_page'] ?? 12))),
- 'list_style' => in_array(sanitize_key((string) ($settings['list_list_style'] ?? '')), ['', 'style2'], true) ? sanitize_key((string) ($settings['list_list_style'] ?? '')) : '',
'list_img_position' => in_array(sanitize_key((string) ($settings['list_list_img_position'] ?? 'left')), ['left', 'right'], true) ? sanitize_key((string) ($settings['list_list_img_position'] ?? 'left')) : 'left',
'list_scale' => max(50, min(200, (int) ($settings['list_list_scale'] ?? 70))),
'card_scale' => max(20, min(200, (int) ($settings['list_card_scale'] ?? 70))),
'card_home' => !empty($settings['list_card_home']),
- 'card_cat' => !empty($settings['list_card_cat']),
- 'card_cat_ids' => is_array($settings['list_card_cat'] ?? null) ? array_map('intval', $settings['list_card_cat']) : [],
+ 'card_cat' => !empty($card_cat_ids),
+ 'card_cat_ids' => $card_cat_ids,
'card_tag' => !empty($settings['list_card_tag']),
'card_topics' => !empty($settings['list_card_topics']),
'card_author' => !empty($settings['list_card_author']),
diff --git a/inc/helpers/aksrt-archive.php b/inc/helpers/aksrt-archive.php
index bdeac772..65952891 100644
--- a/inc/helpers/aksrt-archive.php
+++ b/inc/helpers/aksrt-archive.php
@@ -13,7 +13,7 @@ if (!function_exists('aksrt_archive_get_list_style_settings')) :
/**
* Shared list style defaults for archive surfaces.
*
- * @return array{render_mode:string,card_style:string,card_cat_ids:array}
+ * @return array
*/
function aksrt_archive_get_list_style_settings(): array {
$settings = class_exists('AKSRT_Settings')
@@ -21,13 +21,203 @@ if (!function_exists('aksrt_archive_get_list_style_settings')) :
: [];
return [
- 'render_mode' => (string) ($settings['render_mode'] ?? 'card'),
- 'card_style' => (string) ($settings['card_style'] ?? 'standard'),
- 'card_cat_ids' => is_array($settings['card_cat_ids'] ?? null) ? array_map('intval', $settings['card_cat_ids']) : [],
+ 'list_type' => (string) ($settings['list_type'] ?? 'thumb'),
+ 'render_mode' => (string) ($settings['render_mode'] ?? 'list'),
+ 'list_type_token' => (string) ($settings['list_type_token'] ?? ($settings['list_type'] ?? 'thumb')),
+ 'list_style' => (string) ($settings['list_style'] ?? ''),
+ 'card_variant' => (string) ($settings['card_variant'] ?? ''),
+ // Back-compat: older callers expected card_style as list_type token.
+ 'card_style' => (string) ($settings['list_type'] ?? ($settings['card_style'] ?? 'thumb')),
+ 'card_cat_ids' => is_array($settings['card_cat_ids'] ?? null) ? array_map('intval', $settings['card_cat_ids']) : [],
+ 'card_home' => !empty($settings['card_home']),
+ 'card_tag' => !empty($settings['card_tag']),
+ 'card_topics' => !empty($settings['card_topics']),
+ 'card_author' => !empty($settings['card_author']),
+ 'list_show_type' => (string) ($settings['list_show_type'] ?? 'separate'),
+ 'list_img_position'=> (string) ($settings['list_img_position'] ?? 'left'),
+ 'show_author' => !isset($settings['show_author']) || !empty($settings['show_author']),
+ 'show_date' => !isset($settings['show_date']) || !empty($settings['show_date']),
+ 'show_views' => !isset($settings['show_views']) || !empty($settings['show_views']),
+ 'show_comments' => !empty($settings['show_comments']),
+ 'show_likes' => !empty($settings['show_likes']),
+ 'target_blank' => !empty($settings['target_blank']),
+ 'heading_bold' => !empty($settings['heading_bold']),
+ 'badge_show' => !isset($settings['badge_show']) || !empty($settings['badge_show']),
+ 'excerpt_length' => (int) ($settings['excerpt_length'] ?? 120),
];
}
endif;
+if (!function_exists('aksrt_resolve_post_list_render_config')) :
+ /**
+ * Zibll-aligned list/card resolver for all surfaces.
+ *
+ * Decision order mirrors zib_mian_posts_while():
+ * 1) explicit override mode/type
+ * 2) global list_type (post_card_style): only "card" is card grid; thumb/text/thumb_if_has are list
+ * 3) surface card switches (home/tag/topics/author/cat IDs)
+ *
+ * @param array $args {
+ * @type string $context home|category|tag|topics|author|search|archive
+ * @type int $term_id Optional term id for list_card_cat
+ * @type array $overrides Optional renderer overrides (mode, style, …)
+ * }
+ * @return array
+ */
+ function aksrt_resolve_post_list_render_config(array $args = []): array {
+ $args = wp_parse_args($args, [
+ 'context' => '',
+ 'term_id' => 0,
+ 'overrides' => [],
+ ]);
+
+ $overrides = is_array($args['overrides']) ? $args['overrides'] : [];
+ if (!empty($args['context']) && empty($overrides['context'])) {
+ // keep context on root for merge below
+ }
+
+ $context = sanitize_key((string) ($args['context'] !== '' ? $args['context'] : ($overrides['context'] ?? '')));
+ if ($context === '') {
+ if (function_exists('is_front_page') && (is_front_page() || is_home())) {
+ $context = 'home';
+ } elseif (is_category()) {
+ $context = 'category';
+ } elseif (is_tag()) {
+ $context = 'tag';
+ } elseif (is_tax('topics')) {
+ $context = 'topics';
+ } elseif (is_author()) {
+ $context = 'author';
+ } elseif (is_search()) {
+ $context = 'search';
+ } else {
+ $context = 'archive';
+ }
+ }
+
+ $term_id = (int) ($args['term_id'] ?? 0);
+ if ($term_id <= 0) {
+ $term_id = (int) get_queried_object_id();
+ }
+
+ $list = aksrt_archive_get_list_style_settings();
+ $list_type = sanitize_key((string) ($list['list_type'] ?? 'thumb'));
+ if ($list_type === '' || $list_type === 'standard') {
+ $list_type = 'thumb';
+ }
+
+ // Explicit caller mode wins (term meta, AJAX view toggle, etc.).
+ $forced_mode = '';
+ if (isset($overrides['mode']) && is_string($overrides['mode']) && $overrides['mode'] !== '') {
+ $forced_mode = sanitize_key($overrides['mode']);
+ } elseif (isset($overrides['type']) && sanitize_key((string) $overrides['type']) === 'card') {
+ $forced_mode = 'card';
+ } elseif (!empty($overrides['is_card'])) {
+ $forced_mode = 'card';
+ }
+
+ $mode = $forced_mode !== ''
+ ? $forced_mode
+ : (($list_type === 'card') ? 'card' : 'list');
+
+ // Surface card overrides (only when not already card from list_type / force).
+ if ($mode !== 'card' && $forced_mode === '') {
+ if ($context === 'home' && !empty($list['card_home'])) {
+ $mode = 'card';
+ } elseif ($context === 'tag' && !empty($list['card_tag'])) {
+ $mode = 'card';
+ } elseif ($context === 'topics' && !empty($list['card_topics'])) {
+ $mode = 'card';
+ } elseif ($context === 'author' && !empty($list['card_author'])) {
+ $mode = 'card';
+ } elseif ($term_id > 0 && !empty($list['card_cat_ids']) && in_array($term_id, array_map('intval', (array) $list['card_cat_ids']), true)) {
+ $mode = 'card';
+ }
+ }
+
+ if (!in_array($mode, ['list', 'card', 'mini', 'grid-cms'], true)) {
+ $mode = 'list';
+ }
+
+ // Visual variant: list → style2; card → style3 (Zibll fieldsets).
+ $style = '';
+ if ($mode === 'card') {
+ $style = sanitize_key((string) ($list['card_variant'] ?? ''));
+ if (!in_array($style, ['', 'style3'], true)) {
+ $style = '';
+ }
+ } else {
+ $style = sanitize_key((string) ($list['list_style'] ?? ''));
+ if (!in_array($style, ['', 'style2'], true)) {
+ $style = '';
+ }
+ }
+ if (isset($overrides['style']) && is_string($overrides['style'])) {
+ $style = sanitize_key($overrides['style']);
+ if (in_array($style, ['default', 'null'], true)) {
+ $style = '';
+ }
+ }
+
+ $excerpt_words = max(8, (int) round(((int) ($list['excerpt_length'] ?? 120)) / 4));
+
+ $config = [
+ 'context' => $context,
+ 'mode' => $mode,
+ // list_type token for text / thumb_if_has hooks (renderer card_style key).
+ 'card_style' => $list_type,
+ 'style' => $style === 'default' ? '' : $style,
+ 'list_show_type' => (string) ($list['list_show_type'] ?? 'separate'),
+ 'list_img_position' => (string) ($list['list_img_position'] ?? 'left'),
+ 'thumb_if_has' => ($list_type === 'thumb_if_has'),
+ 'show_thumb' => ($list_type !== 'text'),
+ 'show_author' => !empty($list['show_author']),
+ 'show_date' => !empty($list['show_date']),
+ 'show_views' => !empty($list['show_views']),
+ 'show_comments' => !empty($list['show_comments']),
+ 'show_likes' => !empty($list['show_likes']),
+ 'target_blank' => !empty($list['target_blank']),
+ 'heading_bold' => !empty($list['heading_bold']),
+ 'badge_show' => !empty($list['badge_show']),
+ 'show_excerpt' => $mode !== 'card',
+ 'excerpt_words' => $excerpt_words,
+ ];
+
+ // Multi-thumb from global thumb settings + category allowlist.
+ if (class_exists('AKSRT_Settings')) {
+ $thumb_settings = AKSRT_Settings::get_post_thumb_settings();
+ if (!empty($thumb_settings['multi_enabled'])) {
+ $config['multi_thumb_enabled'] = true;
+ $config['multi_thumb_limit'] = (int) ($thumb_settings['multi_count'] ?? 4);
+ $config['multi_thumb_min'] = 3;
+ }
+ if (($context === 'category' || $context === 'topics') && !empty($thumb_settings['mult_thumb_cat_ids']) && $term_id > 0) {
+ if (in_array($term_id, array_map('intval', (array) $thumb_settings['mult_thumb_cat_ids']), true)) {
+ $config['multi_thumb_enabled'] = true;
+ $config['multi_thumb_limit'] = (int) ($thumb_settings['multi_count'] ?? 4);
+ $config['multi_thumb_min'] = 3;
+ }
+ }
+ }
+
+ // Merge remaining overrides last (except mode/style already handled carefully).
+ foreach ($overrides as $key => $value) {
+ if (in_array($key, ['mode', 'type', 'is_card', 'style', 'context'], true)) {
+ continue;
+ }
+ $config[$key] = $value;
+ }
+ // Re-apply forced mode after merge if present.
+ if ($forced_mode !== '' && in_array($forced_mode, ['list', 'card', 'mini', 'grid-cms'], true)) {
+ $config['mode'] = $forced_mode;
+ }
+ $config['context'] = $context;
+ $config['style'] = $style === 'default' ? '' : $style;
+
+ return $config;
+ }
+endif;
+
if (!function_exists('aksrt_archive_get_render_config')) :
/**
* Build render config for archive-like pages.
@@ -36,32 +226,20 @@ if (!function_exists('aksrt_archive_get_render_config')) :
* @return array
*/
function aksrt_archive_get_render_config(array $overrides = []): array {
- $list = aksrt_archive_get_list_style_settings();
- $config = array_merge([
- 'context' => 'archive',
- 'mode' => $list['render_mode'],
- 'card_style' => $list['card_style'],
- ], $overrides);
+ $context = sanitize_key((string) ($overrides['context'] ?? ''));
+ $term_id = isset($overrides['term_id']) ? (int) $overrides['term_id'] : 0;
- if (is_category() && !empty($list['card_cat_ids'])) {
- $current_cat_id = (int) get_queried_object_id();
- if (in_array($current_cat_id, $list['card_cat_ids'], true)) {
- $config['mode'] = 'card';
- }
+ // Only treat explicit mode as override; empty string means follow global resolver.
+ $resolver_overrides = $overrides;
+ if (isset($resolver_overrides['mode']) && $resolver_overrides['mode'] === '') {
+ unset($resolver_overrides['mode']);
}
- if (is_category() && class_exists('AKSRT_Settings')) {
- $thumb_settings = AKSRT_Settings::get_post_thumb_settings();
- if (!empty($thumb_settings['mult_thumb_cat_ids'])) {
- $current_cat_id = (int) get_queried_object_id();
- if (in_array($current_cat_id, array_map('intval', (array) $thumb_settings['mult_thumb_cat_ids']), true)) {
- $config['multi_thumb_enabled'] = true;
- $config['multi_thumb_limit'] = (int) ($thumb_settings['multi_count'] ?? 4);
- }
- }
- }
-
- return $config;
+ return aksrt_resolve_post_list_render_config([
+ 'context' => $context,
+ 'term_id' => $term_id,
+ 'overrides' => $resolver_overrides,
+ ]);
}
endif;
diff --git a/inc/helpers/aksrt-homepage.php b/inc/helpers/aksrt-homepage.php
index 9393c127..abf606bb 100644
--- a/inc/helpers/aksrt-homepage.php
+++ b/inc/helpers/aksrt-homepage.php
@@ -384,11 +384,18 @@ if (!function_exists('aksrt_homepage_render_sortbar')) {
+ 'home']);
+ $view_mode = (($home_view_cfg['mode'] ?? 'list') === 'card') ? 'card' : 'list';
+ }
+ ?>
@@ -589,10 +596,12 @@ if (!function_exists('aksrt_homepage_get_latest_panel_contract')) {
unset($query_vars['paged'], $query_vars['page']);
- $render_config = [
- 'mode' => 'list',
- 'context' => 'home',
- ];
+ $render_config = function_exists('aksrt_resolve_post_list_render_config')
+ ? aksrt_resolve_post_list_render_config(['context' => 'home'])
+ : [
+ 'mode' => 'list',
+ 'context' => 'home',
+ ];
return [
'query_context' => 'homepage_latest',
@@ -753,10 +762,12 @@ if (!function_exists('aksrt_homepage_render_post_card')) {
return;
}
- $config = [
- 'mode' => 'list',
- 'context' => 'home',
- ];
+ $config = function_exists('aksrt_resolve_post_list_render_config')
+ ? aksrt_resolve_post_list_render_config(['context' => 'home'])
+ : [
+ 'mode' => 'list',
+ 'context' => 'home',
+ ];
echo aksrt_render_post($config); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
@@ -768,15 +779,23 @@ if (!function_exists('aksrt_homepage_render_posts_grid')) {
*/
function aksrt_homepage_render_posts_grid(?WP_Query $query = null, bool $with_pagination = false): void {
$query = $query instanceof WP_Query ? $query : aksrt_homepage_get_latest_query();
+ $config = function_exists('aksrt_resolve_post_list_render_config')
+ ? aksrt_resolve_post_list_render_config(['context' => 'home'])
+ : [
+ 'mode' => 'list',
+ 'context' => 'home',
+ ];
+ $config['skip_wrapper'] = true;
+ $view = (($config['mode'] ?? 'list') === 'card') ? 'card' : 'list';
if (function_exists('aksrt_render_post_list')) {
// Panel already provides posts-row.ajaxpager; avoid nested wrapper.
- aksrt_render_post_list($query, ['mode' => 'list', 'context' => 'home', 'skip_wrapper' => true], true);
+ aksrt_render_post_list($query, $config, true);
} else {
if (!$query->have_posts()) {
echo '' . esc_html__('暂无文章', 'aksrt') . '
';
} else {
- echo '';
+ echo '
';
while ($query->have_posts()) {
$query->the_post();
aksrt_homepage_render_post_card();
diff --git a/inc/helpers/aksrt-posts-renderer.php b/inc/helpers/aksrt-posts-renderer.php
index 2ff0eda6..c341f5a1 100644
--- a/inc/helpers/aksrt-posts-renderer.php
+++ b/inc/helpers/aksrt-posts-renderer.php
@@ -50,6 +50,7 @@ if (!function_exists('aksrt_renderer_defaults')) {
'multi_thumb_limit' => 4,
'multi_thumb_min' => 2,
'list_show_type' => 'separate',
+ 'list_img_position' => 'left',
'number_offset' => 0,
'show_number' => false,
'extra_class' => '',
@@ -87,9 +88,15 @@ if (!function_exists('aksrt_renderer_config')) {
$cfg['show_comments'] = false;
}
- if ($cfg['mode'] === 'card' || $cfg['mode'] === 'grid-cms') {
- $cfg['style'] = $cfg['style'] === 'default' ? 'style3' : $cfg['style'];
+ if (in_array((string) $cfg['style'], ['default', 'null'], true)) {
+ $cfg['style'] = '';
}
+ $cfg['list_img_position'] = in_array(sanitize_key((string) ($cfg['list_img_position'] ?? 'left')), ['left', 'right'], true)
+ ? sanitize_key((string) ($cfg['list_img_position'] ?? 'left'))
+ : 'left';
+ $cfg['list_show_type'] = in_array(sanitize_key((string) ($cfg['list_show_type'] ?? 'separate')), ['separate', 'no_margin'], true)
+ ? sanitize_key((string) ($cfg['list_show_type'] ?? 'separate'))
+ : 'separate';
return $cfg;
}
@@ -514,7 +521,11 @@ if (!function_exists('aksrt_renderer_thumb')) {
$target_attr = !empty($cfg['target_blank']) ? ' target="_blank"' : '';
if ($cfg['mode'] === 'list') {
- return '