feat(nav): deep-align menu_search panel, pill radius, senior media

- Layout-2 remote-box AJAX panel (history/hot/posts) via aksrt_menu_search
- Live suggestions for post/topic/product; local history for guests
- Publish radius switch (zibll bool pill) mapped to CSS radius class
- Senior menu editor: WP media library image picker
- Active menu underline + panel CSS; acceptance/contract updates
This commit is contained in:
2026-07-22 12:51:56 +08:00
parent 2a11a889c3
commit 159a12c481
14 changed files with 494 additions and 117 deletions
@@ -0,0 +1,141 @@
<?php
/**
* Layout-2 menu search remote panel (zibll menu_search parity subset).
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
if (!function_exists('aksrt_ajax_menu_search')) :
/**
* AJAX: HTML panel for navbar inline search (history + hot + posts).
*/
function aksrt_ajax_menu_search(): void {
// Prefer public nonce; also accept no nonce for same-origin remote-box first paint like zibll.
if (!empty($_REQUEST['nonce'])) {
$nonce = sanitize_text_field(wp_unslash((string) $_REQUEST['nonce']));
if (!wp_verify_nonce($nonce, 'aksrt_public_nonce')) {
wp_die('0');
}
}
$html = aksrt_get_menu_search_panel_html();
if ($html === '') {
wp_die('0');
}
echo '<div class="dropdown-menu hover-show-con navbar-inline-search-panel is-open">' . $html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
wp_die();
}
endif;
if (!function_exists('aksrt_get_menu_search_panel_html')) :
/**
* Build inner search panel HTML (no outer dropdown wrapper).
*/
function aksrt_get_menu_search_panel_html(): string {
$show_keywords = true;
$show_history = true;
$show_posts = true;
if (class_exists('\AKSRT\Settings\Settings')) {
$show_keywords = method_exists('\AKSRT\Settings\Settings', 'hot_search_enabled')
? (bool) \AKSRT\Settings\Settings::hot_search_enabled()
: true;
$show_history = method_exists('\AKSRT\Settings\Settings', 'search_history_enabled')
? (bool) \AKSRT\Settings\Settings::search_history_enabled()
: true;
$show_posts = method_exists('\AKSRT\Settings\Settings', 'search_posts_enabled')
? (bool) \AKSRT\Settings\Settings::search_posts_enabled()
: !empty(\AKSRT\Settings\Settings::get_value('search_posts', true));
}
$out = '';
// History (client may also fill via localStorage; server returns logged-in history).
if ($show_history) {
$hist = [];
if (is_user_logged_in()) {
$saved = get_user_meta(get_current_user_id(), 'aksrt_search_history', true);
if (is_array($saved)) {
foreach (array_slice($saved, 0, 10) as $item) {
if (is_array($item) && !empty($item['keyword'])) {
$hist[] = (string) $item['keyword'];
} elseif (is_string($item) && $item !== '') {
$hist[] = $item;
}
}
}
}
$out .= '<div class="aksrt-menu-search-history" data-aksrt-menu-history="1">';
$out .= '<div class="flex jsb ac mb6"><span class="muted-2-color em09">' . esc_html__('搜索历史', 'aksrt') . '</span>';
$out .= '<a href="javascript:;" class="muted-2-color em09" data-aksrt-clear-menu-history="1">' . esc_html__('清空', 'aksrt') . '</a></div>';
$out .= '<div class="aksrt-menu-search-history__list">';
if ($hist) {
foreach ($hist as $kw) {
$out .= '<a class="but jb-sm" href="' . esc_url(home_url('/?s=' . rawurlencode($kw))) . '">' . esc_html($kw) . '</a> ';
}
} else {
$out .= '<span class="muted-3-color em09" data-empty="1">' . esc_html__('暂无历史', 'aksrt') . '</span>';
}
$out .= '</div></div>';
}
// Hot keywords.
if ($show_keywords) {
$hots = function_exists('aksrt_get_search_hot_keywords') ? aksrt_get_search_hot_keywords() : [];
if ($hots) {
$title = class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'search_popular_title')
? \AKSRT\Settings\Settings::search_popular_title()
: __('热门搜索', 'aksrt');
$out .= '<div class="aksrt-menu-search-hots mt10">';
$out .= '<div class="muted-2-color em09 mb6">' . esc_html($title) . '</div>';
$out .= '<div class="navbar-inline-search-hots">';
foreach ($hots as $kw) {
$kw = trim((string) $kw);
if ($kw === '') {
continue;
}
$out .= '<a class="but jb-sm" href="' . esc_url(home_url('/?s=' . rawurlencode($kw))) . '">' . esc_html($kw) . '</a> ';
}
$out .= '</div></div>';
}
}
// Latest / popular posts (optional).
if ($show_posts) {
$posts = get_posts([
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 6,
'ignore_sticky_posts' => true,
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
]);
if ($posts) {
$out .= '<div class="aksrt-menu-search-posts mt10">';
$out .= '<div class="muted-2-color em09 mb6">' . esc_html__('推荐内容', 'aksrt') . '</div>';
$out .= '<div class="aksrt-menu-search-posts__list">';
foreach ($posts as $p) {
$out .= '<a class="aksrt-menu-search-posts__item" href="' . esc_url(get_permalink($p)) . '">';
$out .= '<span class="title text-ellipsis">' . esc_html(get_the_title($p)) . '</span>';
$out .= '<span class="meta muted-3-color em09">' . esc_html(get_the_date('', $p)) . '</span>';
$out .= '</a>';
}
$out .= '</div></div>';
}
}
// Live suggestions mount point.
$out .= '<div class="aksrt-menu-search-suggest mt10" data-aksrt-menu-suggest="1" hidden></div>';
return $out;
}
endif;
add_action('wp_ajax_aksrt_menu_search', 'aksrt_ajax_menu_search');
add_action('wp_ajax_nopriv_aksrt_menu_search', 'aksrt_ajax_menu_search');
// Alias for zibll-compatible remote-box query action name used in markup.
add_action('wp_ajax_menu_search', 'aksrt_ajax_menu_search');
add_action('wp_ajax_nopriv_menu_search', 'aksrt_ajax_menu_search');
+12 -14
View File
@@ -104,7 +104,14 @@ if (!function_exists('aksrt_get_menu_search')) :
$type = (string) ($state['type'] ?? 'post');
$cat_enabled = !empty($state['category_enabled']);
$cat_id = (int) ($state['category_id'] ?? 0);
$hots = is_array($ctx['search_hot_keywords'] ?? null) ? $ctx['search_hot_keywords'] : [];
// zibll remote-box: panel HTML loaded via ajax action menu_search.
$remote_url = add_query_arg(
[
'action' => 'aksrt_menu_search',
],
admin_url('admin-ajax.php')
);
echo '<form method="get" class="navbar-form navbar-left hover-show" action="' . esc_url(home_url('/')) . '" role="search" data-aksrt-search-form="inline">';
echo '<div class="form-group relative dropdown">';
@@ -116,19 +123,10 @@ if (!function_exists('aksrt_get_menu_search')) :
. esc_attr(get_search_query()) . '" placeholder="' . esc_attr($placeholder) . '" autocomplete="off">';
echo '<div class="abs-right muted-3-color"><button type="submit" class="null" aria-label="'
. esc_attr__('搜索', 'aksrt') . '"><i class="fas fa-search" aria-hidden="true"></i></button></div>';
if ($hots) {
echo '<div class="dropdown-menu hover-show-con navbar-inline-search-panel">';
echo '<div class="muted-2-color em09 mb6">' . esc_html__('热门搜索', 'aksrt') . '</div>';
echo '<div class="navbar-inline-search-hots">';
foreach ($hots as $kw) {
$kw = trim((string) $kw);
if ($kw === '') {
continue;
}
echo '<a class="but jb-sm" href="' . esc_url(home_url('/?s=' . rawurlencode($kw))) . '">' . esc_html($kw) . '</a> ';
}
echo '</div></div>';
}
// Remote panel mount (zibll remote-box / lazyload-action=ias).
echo '<div class="aksrt-remote-box lazyload" remote-box="' . esc_url($remote_url) . '" lazyload-action="ias" data-aksrt-menu-search-remote="1">';
echo '<i class="loading-spot"><i></i></i>';
echo '</div>';
echo '</div></form>';
}
endif;