fix(header): full zibll 1:1 for top multifunc search/cards/admin

Wire hero search through aksrt_get_search_box, device-gated cards/blur (zib_m_pc_is_show), expanded admin schema, and keyword/type UI styles matching zibll header-slider.
This commit is contained in:
2026-07-24 10:43:29 +08:00
parent e35011f2c0
commit 96bd9d949d
7 changed files with 256 additions and 151 deletions
+119 -103
View File
@@ -22,29 +22,94 @@ $hero_banners = function_exists('aksrt_get_banners') ? aksrt_get_banners(8, 'her
$settings = function_exists('aksrt_get_all_settings') ? aksrt_get_all_settings() : [];
$search_cfg = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_header_components_search_config() : [
'pc' => false,
'mobile' => false,
'show' => false,
'keywords' => [],
'categories' => [],
'type_options' => [],
'before_html' => '',
'after_html' => '',
'show_keywords' => false,
'popular_limit' => 6,
'show_input_cat' => false,
'show_type' => false,
'in_cat' => '',
'in_type' => 'post',
'more_cats' => [],
'before_html' => '',
'after_html' => '',
];
$show_search = !empty($search_cfg['show']) || !empty($cfg['with_search']);
$show_cards = !empty($settings['header_components_cards_enabled']);
// zibll zib_m_pc_is_show: checkbox arrays with pc_s / m_s.
$is_mobile_req = function_exists('wp_is_mobile') && wp_is_mobile();
$m_pc_show = static function ($opt) use ($is_mobile_req): bool {
$opt = (array) $opt;
return ($is_mobile_req && in_array('m_s', $opt, true)) || (!$is_mobile_req && in_array('pc_s', $opt, true));
};
// Search device gate (zibll header_slider_search_s).
$search_opt = [];
if (!empty($search_cfg['pc'])) {
$search_opt[] = 'pc_s';
}
if (!empty($search_cfg['mobile'])) {
$search_opt[] = 'm_s';
}
// Fallback: master enabled without explicit devices = both (legacy).
if (!$search_opt && !empty($search_cfg['show'])) {
$search_opt = ['pc_s', 'm_s'];
}
$show_search = $m_pc_show($search_opt) || !empty($cfg['with_search']);
// Cards device gate (zibll header_slider_card_s).
$cards_master = !empty($settings['header_components_cards_enabled']);
$card_show_devices = isset($settings['header_components_card_show_devices'])
? (array) $settings['header_components_card_show_devices']
: ['pc', 'mobile'];
$card_opt = [];
if (in_array('pc', $card_show_devices, true)) {
$card_opt[] = 'pc_s';
}
if (in_array('mobile', $card_show_devices, true)) {
$card_opt[] = 'm_s';
}
if (!$card_opt && $cards_master) {
$card_opt = ['pc_s', 'm_s'];
}
$show_cards = $cards_master && $m_pc_show($card_opt);
$icon_cards = isset($settings['header_components_icon_cards']) ? (array) $settings['header_components_icon_cards'] : [];
$card_bg_mode = !empty($settings['header_components_card_shared_bg']) ? 'shared' : 'individual';
$card_blur = !empty($settings['header_components_card_blur']);
$filter_blur_devices = isset($settings['header_components_filter_blur_devices']) ? (array) $settings['header_components_filter_blur_devices'] : ($card_blur ? ['pc', 'mobile'] : []);
$card_show_devices = isset($settings['header_components_card_show_devices']) ? (array) $settings['header_components_card_show_devices'] : ['pc', 'mobile'];
$card_icon_shape = $settings['header_components_card_icon_shape'] ?? 'circle';
// Filter blur (zibll header_slider_filter_blur) — independent of cards.
$filter_blur_devices = isset($settings['header_components_filter_blur_devices'])
? (array) $settings['header_components_filter_blur_devices']
: [];
// Legacy: header_components_card_blur true without devices → both.
if (!$filter_blur_devices && !empty($settings['header_components_card_blur'])) {
$filter_blur_devices = ['pc', 'mobile'];
}
$filter_opt = [];
if (in_array('pc', $filter_blur_devices, true)) {
$filter_opt[] = 'pc_s';
}
if (in_array('mobile', $filter_blur_devices, true)) {
$filter_opt[] = 'm_s';
}
$filter_blur_on = $m_pc_show($filter_opt);
$slide_count = count($hero_banners);
$visible_card_count = ($show_cards && !empty($icon_cards)) ? count($icon_cards) : 0;
// card-N only counts cards actually rendered on this device (zibll parity).
$visible_card_count = 0;
if ($show_cards) {
foreach ($icon_cards as $_c) {
if (is_array($_c) && (trim((string) ($_c['icon'] ?? '')) !== '' || trim((string) ($_c['custom_icon'] ?? '')) !== '' || trim((string) ($_c['customize_icon'] ?? '')) !== '')) {
$visible_card_count++;
} elseif (is_array($_c) && trim((string) ($_c['title'] ?? '')) !== '') {
// Count entries even if icon missing so layout still allocates.
$visible_card_count++;
}
}
}
$container_classes = ['header-slider-container', 'header-components-container', 'relative', 'mb20', 'card-' . $visible_card_count];
if (in_array('pc', $filter_blur_devices, true) || in_array('mobile', $filter_blur_devices, true)) {
if ($filter_blur_on) {
$container_classes[] = 'filter-blur';
}
if (in_array('pc', $filter_blur_devices, true)) {
@@ -53,99 +118,50 @@ if (in_array('pc', $filter_blur_devices, true)) {
if (in_array('mobile', $filter_blur_devices, true)) {
$container_classes[] = 'has-blur-mobile';
}
if (!in_array('pc', $card_show_devices, true)) {
$container_classes[] = 'hide-cards-pc';
}
if (!in_array('mobile', $card_show_devices, true)) {
$container_classes[] = 'hide-cards-mobile';
}
$search_placeholder = function_exists('aksrt_get_search_placeholder') ? aksrt_get_search_placeholder() : __('开启精彩搜索', 'aksrt');
$search_value = trim((string) get_search_query());
$search_type = function_exists('aksrt_get_search_form_type') ? aksrt_get_search_form_type() : 'post';
/**
* Search overlay = zibll .header-slider-search.abs-center
* Uses aksrt_get_search_box() (zib_get_search_box parity) for form / keywords / type / cat.
* Title/subtitle live in before_html (same flow stack as the form).
*/
$render_hero_search = static function (string $search_id) use ($search_placeholder, $search_value, $search_type, $search_cfg): void {
$_kw = $search_cfg['keywords'] ?? [];
$_cats = $search_cfg['categories'] ?? [];
$_types = $search_cfg['type_options'] ?? [];
$_show_cat = !empty($search_cfg['show_input_cat']) && !empty($_cats);
$_show_type = !empty($search_cfg['show_type']) && !empty($_types);
$_before = isset($search_cfg['before_html']) ? (string) $search_cfg['before_html'] : '';
$_after = isset($search_cfg['after_html']) ? (string) $search_cfg['after_html'] : '';
?>
<div class="header-slider-search header-components-search abs-center">
<?php if (trim($_before) !== '') : ?>
<div class="header-slider-search-more text-center before">
<?php echo wp_kses_post($_before); ?>
</div>
<?php endif; ?>
<div class="search-input">
<form role="search" method="get" action="<?php echo esc_url(home_url('/')); ?>" class="search-form" data-aksrt-search-form="hero">
<input type="hidden" name="aksrt_search_type" value="<?php echo esc_attr($search_type); ?>">
<div class="line-form<?php echo ($_show_cat || $_show_type) ? ' has-addons' : ''; ?>">
<?php if ($_show_cat) : ?>
<select name="cat" class="header-components-search__cat" aria-label="<?php esc_attr_e('选择分类', 'aksrt'); ?>">
<option value=""><?php esc_html_e('全部分类', 'aksrt'); ?></option>
<?php foreach ($_cats as $_c) : ?>
<option value="<?php echo esc_attr($_c['id']); ?>"><?php echo esc_html($_c['name']); ?></option>
<?php endforeach; ?>
</select>
<?php endif; ?>
<?php if ($_show_type) : ?>
<div class="header-components-search__types">
<?php foreach ($_types as $_idx => $_t) : ?>
<label class="header-components-search__type-label">
<input type="radio" name="aksrt_search_type" value="<?php echo esc_attr($_t['key']); ?>"<?php echo $_idx === 0 ? ' checked' : ''; ?> class="header-components-search__type-radio">
<span class="header-components-search__type-text"><?php echo esc_html($_t['label']); ?></span>
</label>
<?php endforeach; ?>
</div>
<?php endif; ?>
<div class="search-input-text">
<label class="screen-reader-text" for="<?php echo esc_attr($search_id); ?>"><?php esc_html_e('搜索', 'aksrt'); ?></label>
<input
type="search"
id="<?php echo esc_attr($search_id); ?>"
name="s"
class="line-form-input"
value="<?php echo esc_attr($search_value); ?>"
placeholder=" "
autocomplete="off"
>
<i class="line-form-line"></i>
<div class="scale-placeholder<?php echo $search_value !== '' ? ' is-focus' : ''; ?>" default="<?php echo esc_attr($search_placeholder); ?>">
<?php echo esc_html($search_placeholder); ?>
</div>
<div class="abs-right">
<button type="submit" class="null header-components-search__submit" aria-label="<?php echo esc_attr__('搜索', 'aksrt'); ?>">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<circle cx="11" cy="11" r="8"></circle>
<path d="m21 21-4.3-4.3"></path>
</svg>
</button>
</div>
</div>
</div>
</form>
<?php if (!empty($_kw)) : ?>
<div class="header-components-search__keywords search-keywords">
<?php foreach ($_kw as $_kw_text) : ?>
<a href="<?php echo esc_url(add_query_arg('s', rawurlencode($_kw_text), home_url('/'))); ?>" class="header-components-search__kw-tag search_keywords"><?php echo esc_html($_kw_text); ?></a>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php if (trim($_after) !== '') : ?>
<div class="header-slider-search-more text-center after">
<?php echo wp_kses_post($_after); ?>
</div>
<?php endif; ?>
</div>
<?php
$render_hero_search = static function () use ($search_cfg, $is_mobile_req): void {
$_before = isset($search_cfg['before_html']) ? (string) $search_cfg['before_html'] : '';
$_after = isset($search_cfg['after_html']) ? (string) $search_cfg['after_html'] : '';
$search_args = [
'class' => '',
'show_keywords' => !empty($search_cfg['show_keywords']),
'popular_limit' => max(0, (int) ($search_cfg['popular_limit'] ?? 6)),
'show_history' => false,
'show_posts' => false,
'show_input_cat' => !empty($search_cfg['show_input_cat']),
'more_cats' => !empty($search_cfg['more_cats']) ? (array) $search_cfg['more_cats'] : [],
'in_cat' => (string) ($search_cfg['in_cat'] ?? ''),
'show_type' => !empty($search_cfg['show_type']),
'in_type' => (string) ($search_cfg['in_type'] ?? 'post'),
'in_user' => '',
's' => is_search() ? (string) get_search_query() : '',
];
// Mobile: never show hot keywords (zibll).
if ($is_mobile_req) {
$search_args['show_keywords'] = false;
}
$search_html = function_exists('aksrt_get_search_box')
? (string) aksrt_get_search_box($search_args)
: '';
$before_html = trim($_before) !== ''
? '<div class="header-slider-search-more text-center before">' . wp_kses_post($_before) . '</div>'
: '';
$after_html = trim($_after) !== ''
? '<div class="header-slider-search-more after">' . wp_kses_post($_after) . '</div>'
: '';
echo '<div class="header-slider-search header-components-search abs-center">'
. $before_html
. $search_html
. $after_html
. '</div>';
};
$render_icon_cards = static function () use ($show_cards, $icon_cards, $card_bg_mode, $card_icon_shape): void {
@@ -206,7 +222,7 @@ if (!empty($hero_banners)) :
$slider_cfg = function_exists('aksrt_get_slider_config') ? aksrt_get_slider_config() : [];
$_nav_color_for_header = sanitize_hex_color((string) ($slider_cfg['nav_color'] ?? '')) ?: '';
if ($_nav_color_for_header !== '' && strtolower($_nav_color_for_header) !== '#ffffff') {
echo '<style id="aksrt-header-slider-nav-color">.header.show-slide{--header-color:' . esc_attr($_nav_color_for_header) . ';}</style>';
echo '<style id="aksrt-header-slider-nav-color">body.nav-fixed:not(.body-scroll):not(.mobile-navbar-show) .header.show-slide{--header-color:' . esc_attr($_nav_color_for_header) . ';}</style>';
}
$swiper_config = [
@@ -345,7 +361,7 @@ if (!empty($hero_banners)) :
</div>
<?php if ($show_search) : ?>
<?php $render_hero_search('header-search-input'); ?>
<?php $render_hero_search(); ?>
<?php endif; ?>
<?php $render_icon_cards(); ?>
@@ -381,7 +397,7 @@ if (!empty($hero_banners)) :
</div>
<?php if ($show_search) : ?>
<?php $render_hero_search('header-search-input-fallback'); ?>
<?php $render_hero_search(); ?>
<?php endif; ?>
<?php $render_icon_cards(); ?>