feat(nav): rewrite top header to zibll 1:1 DOM/CSS/JS contract
Replace hybrid site-nav/drawer shell with zibll navbar-top layouts 1/2/3, body.mobile-navbar-show drawer, wired NavWalker + aksrt_menu_options meta, nav_folding/chevron, VIP switches, and SPA/PHP schema parity. No dual-class compat paths.
This commit is contained in:
@@ -47,6 +47,9 @@ require_once AKSRT_DIR . '/inc/helpers/aksrt-ajax-list.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-links.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-header-userbox.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-header-menu-buttons.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/header/aksrt-header-render.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/header/aksrt-header-navbar.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/header/aksrt-header-mobile.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-runtime-win.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-identity.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-graphic-card.php';
|
||||
|
||||
@@ -14,19 +14,14 @@ if (!function_exists('aksrt_get_header_newposts_config')) :
|
||||
function aksrt_get_header_newposts_config(): array {
|
||||
$cfg = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_header_newposts_config()
|
||||
: ['enabled' => true, 'text' => __('发布', 'aksrt'), 'radius' => 20, 'class' => ''];
|
||||
$all = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_all() : [];
|
||||
// Prefer publish_btn from header nav when newposts not explicitly set.
|
||||
: ['enabled' => true, 'text' => __('发布', 'aksrt'), 'radius' => 20, 'class' => '', 'types' => []];
|
||||
$nav = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_header_nav_settings()
|
||||
: ['publish_btn' => true];
|
||||
if (empty($cfg['enabled']) && !empty($nav['publish_btn'])) {
|
||||
$cfg['enabled'] = true;
|
||||
}
|
||||
$types = [];
|
||||
if (!empty($all['header_newposts_types']) && is_array($all['header_newposts_types'])) {
|
||||
$types = array_values(array_filter(array_map('sanitize_key', $all['header_newposts_types'])));
|
||||
}
|
||||
// Single source: newposts enabled AND header publish switch.
|
||||
$cfg['enabled'] = !empty($cfg['enabled']) && !empty($nav['publish_btn']);
|
||||
|
||||
$types = is_array($cfg['types'] ?? null) ? $cfg['types'] : [];
|
||||
if (!$types) {
|
||||
$types = ['post'];
|
||||
if (class_exists('\AKSRT\Settings\Settings')) {
|
||||
@@ -229,7 +224,7 @@ if (!function_exists('aksrt_render_header_menu_buttons')) :
|
||||
$show_vip = false;
|
||||
if (class_exists('\AKSRT\Settings\Settings')) {
|
||||
$vs = \AKSRT\Settings\Settings::get_payment_vip_settings();
|
||||
$show_vip = !empty($vs['enabled']);
|
||||
$show_vip = !empty($vs['enabled']) && !empty(\AKSRT\Settings\Settings::get_header_nav_settings()['nav_pay_vip']);
|
||||
}
|
||||
if ($show_vip) {
|
||||
$is_vip = false;
|
||||
|
||||
@@ -117,6 +117,10 @@ if (!function_exists('aksrt_header_payvip_bar')) :
|
||||
return '';
|
||||
}
|
||||
|
||||
$nav = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_header_nav_settings()
|
||||
: ['nav_user_pay_vip' => true];
|
||||
|
||||
$level = function_exists('aksrt_get_user_vip_level') ? (int) aksrt_get_user_vip_level($user_id) : 0;
|
||||
if ($level > 0) {
|
||||
$levels = is_array($vip['levels'] ?? null) ? $vip['levels'] : [];
|
||||
@@ -139,6 +143,11 @@ if (!function_exists('aksrt_header_payvip_bar')) :
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Open-VIP CTA only when user-box switch is on (zibll nav_user_pay_vip).
|
||||
if (empty($nav['nav_user_pay_vip'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '<div class="mt10 em09 aksrt-header-payvip">'
|
||||
. '<a class="pay-vip but radius4 payvip-icon btn-block navbar-cta" href="javascript:;" vip-level="1">'
|
||||
. '<i class="fas fa-gem" aria-hidden="true"></i>'
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* Mobile drawer (zibll zib_nav_mobile + mobile-header shell).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_nav_mobile_shell')) :
|
||||
/**
|
||||
* Full mobile header drawer + fixed-body.
|
||||
*
|
||||
* @param array<string,mixed> $ctx
|
||||
*/
|
||||
function aksrt_nav_mobile_shell(array $ctx): void {
|
||||
$align = (string) ($ctx['mobile_align'] ?? 'left');
|
||||
if (!in_array($align, ['top', 'left', 'right'], true)) {
|
||||
$align = 'left';
|
||||
}
|
||||
$m_layout = (string) ($ctx['mobile_layout'] ?? 'center');
|
||||
$fixed = !empty($ctx['fixed']);
|
||||
|
||||
$touch_attr = '';
|
||||
if ($align !== 'top') {
|
||||
// mini-touch.js reads data-mini-touch; direction via data-touch-direction.
|
||||
$touch_attr = ' data-mini-touch="mobile-nav" data-touch-direction="' . esc_attr($align) . '"';
|
||||
}
|
||||
|
||||
echo '<div class="mobile-header">';
|
||||
echo '<nav' . $touch_attr . ' class="mobile-navbar visible-xs-block scroll-y mini-scrollbar '
|
||||
. esc_attr($align) . '">';
|
||||
|
||||
if (!$fixed) {
|
||||
aksrt_navbar_header($ctx);
|
||||
}
|
||||
|
||||
$brand_name = (string) ($ctx['brand_name'] ?? get_bloginfo('name'));
|
||||
$logo_inner = !empty($ctx['logo_html'])
|
||||
? $ctx['logo_html']
|
||||
: '<span class="navbar-logo-text">' . esc_html($brand_name) . '</span>';
|
||||
|
||||
echo '<div class="flex jsb ac mb20">';
|
||||
echo '<div class="navbar-logo"><a href="' . esc_url(home_url('/')) . '">' . $logo_inner . '</a></div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '<button type="button" data-toggle-class="mobile-navbar-show" data-target="body" class="close" aria-label="'
|
||||
. esc_attr__('关闭菜单', 'aksrt') . '"><i class="fas fa-times" aria-hidden="true"></i></button>';
|
||||
echo '</div>';
|
||||
|
||||
aksrt_nav_mobile_content($ctx, $m_layout);
|
||||
|
||||
if (is_active_sidebar('mobile_nav_fluid')) {
|
||||
echo '<div class="mobile-nav-widget">';
|
||||
dynamic_sidebar('mobile_nav_fluid');
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
echo '</nav>';
|
||||
echo '<div class="fixed-body" data-toggle-class="mobile-navbar-show" data-target="body"></div>';
|
||||
echo '</div>';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_nav_mobile_content')) :
|
||||
/**
|
||||
* Mobile menu list + top toggles + user box.
|
||||
*
|
||||
* @param array<string,mixed> $ctx
|
||||
* @param string $m_layout center|left
|
||||
*/
|
||||
function aksrt_nav_mobile_content(array $ctx, string $m_layout = 'center'): void {
|
||||
$top_btns = '';
|
||||
if (in_array('m_menu', (array) ($ctx['theme_positions'] ?? []), true)) {
|
||||
$top_btns .= '<a href="javascript:;" class="toggle-theme toggle-radius" id="theme-toggle-mobile" title="'
|
||||
. esc_attr__('切换亮暗色', 'aksrt') . '">';
|
||||
$top_btns .= '<i class="fas fa-moon theme-icon-moon" aria-hidden="true"></i>';
|
||||
$top_btns .= '<i class="fas fa-sun theme-icon-sun" aria-hidden="true" style="display:none"></i>';
|
||||
$top_btns .= '</a>';
|
||||
}
|
||||
if ($m_layout !== 'center' && !empty($ctx['search_enabled'])) {
|
||||
$top_btns .= '<a href="javascript:;" class="toggle-radius main-search-btn" data-toggle-class data-target=".navbar-search" aria-label="'
|
||||
. esc_attr__('打开搜索', 'aksrt') . '"><i class="fas fa-search" aria-hidden="true"></i></a>';
|
||||
}
|
||||
if ($top_btns !== '') {
|
||||
echo '<div class="flex ac pull-right" style="margin-right: -3px;">' . $top_btns . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
$location = has_nav_menu('mobile') ? 'mobile' : 'primary';
|
||||
$walker = class_exists('\AKSRT\Frontend\NavWalker')
|
||||
? new \AKSRT\Frontend\NavWalker(
|
||||
function_exists('aksrt_get_menu_decoration_settings')
|
||||
? aksrt_get_menu_decoration_settings()
|
||||
: []
|
||||
)
|
||||
: null;
|
||||
|
||||
$args = [
|
||||
'container' => false,
|
||||
'echo' => false,
|
||||
'fallback_cb' => false,
|
||||
'depth' => 2,
|
||||
'items_wrap' => '<ul class="mobile-menus theme-box">%3$s</ul>',
|
||||
'theme_location' => $location,
|
||||
];
|
||||
if ($walker) {
|
||||
$args['walker'] = $walker;
|
||||
}
|
||||
|
||||
$menu = has_nav_menu($location) ? (string) wp_nav_menu($args) : '';
|
||||
if ($menu === '' && $location !== 'primary' && has_nav_menu('primary')) {
|
||||
$args['theme_location'] = 'primary';
|
||||
$menu = (string) wp_nav_menu($args);
|
||||
}
|
||||
if ($menu === '' && is_super_admin()) {
|
||||
$menu = '<ul class="mobile-menus theme-box"><li><a href="' . esc_url(admin_url('nav-menus.php')) . '">'
|
||||
. esc_html__('添加导航菜单', 'aksrt') . '</a></li></ul>';
|
||||
}
|
||||
echo $menu; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
|
||||
// User box at bottom of drawer.
|
||||
if (!empty($ctx['user_menu'])) {
|
||||
echo aksrt_header_user_box_html($ctx); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
}
|
||||
endif;
|
||||
@@ -0,0 +1,344 @@
|
||||
<?php
|
||||
/**
|
||||
* Desktop navbar pieces (zibll navbar header / menu / buttons).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_menu_items')) :
|
||||
/**
|
||||
* PC top menu (zibll zib_menu_items).
|
||||
*
|
||||
* @param string $location Menu location.
|
||||
* @param bool $echo Echo or return.
|
||||
* @return string|void
|
||||
*/
|
||||
function aksrt_menu_items(string $location = 'primary', bool $echo = true) {
|
||||
$walker = class_exists('\AKSRT\Frontend\NavWalker')
|
||||
? new \AKSRT\Frontend\NavWalker(
|
||||
function_exists('aksrt_get_menu_decoration_settings')
|
||||
? aksrt_get_menu_decoration_settings()
|
||||
: []
|
||||
)
|
||||
: null;
|
||||
|
||||
$args = [
|
||||
'container' => false,
|
||||
'echo' => false,
|
||||
'fallback_cb' => false,
|
||||
'items_wrap' => '<ul class="nav navbar-nav">%3$s</ul>',
|
||||
'theme_location' => $location,
|
||||
];
|
||||
if ($walker) {
|
||||
$args['walker'] = $walker;
|
||||
}
|
||||
if (!wp_is_mobile()) {
|
||||
$args['depth'] = 0;
|
||||
} else {
|
||||
$args['depth'] = 3;
|
||||
}
|
||||
|
||||
$menu = '';
|
||||
if (has_nav_menu($location)) {
|
||||
$menu = (string) wp_nav_menu($args);
|
||||
}
|
||||
|
||||
if ($menu === '' && is_super_admin()) {
|
||||
$menu = '<ul class="nav navbar-nav"><li><a href="' . esc_url(admin_url('nav-menus.php')) . '">'
|
||||
. esc_html__('添加导航菜单', 'aksrt') . '</a></li></ul>';
|
||||
}
|
||||
|
||||
if ($echo) {
|
||||
echo $menu; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
return;
|
||||
}
|
||||
return $menu;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_navbar_header')) :
|
||||
/**
|
||||
* Logo + mobile toggles (zibll zib_navbar_header).
|
||||
*
|
||||
* @param array<string,mixed> $ctx
|
||||
*/
|
||||
function aksrt_navbar_header(array $ctx): void {
|
||||
$brand_name = (string) ($ctx['brand_name'] ?? get_bloginfo('name'));
|
||||
$logo_inner = !empty($ctx['logo_html'])
|
||||
? $ctx['logo_html']
|
||||
: '<span class="navbar-logo-text">' . esc_html($brand_name) . '</span>';
|
||||
|
||||
$logo = '<a class="navbar-logo" href="' . esc_url(home_url('/')) . '">' . $logo_inner . '</a>';
|
||||
|
||||
$button = '<button type="button" data-toggle-class="mobile-navbar-show" data-target="body" class="navbar-toggle" aria-label="'
|
||||
. esc_attr__('打开菜单', 'aksrt') . '">';
|
||||
$button .= '<i class="em12 css-icon i-menu"><i></i></i></button>';
|
||||
|
||||
if (($ctx['mobile_layout'] ?? 'center') === 'center' && !empty($ctx['search_enabled'])) {
|
||||
$button .= '<button type="button" class="navbar-toggle main-search-btn nav-search-btn" data-toggle-class data-target=".navbar-search" aria-label="'
|
||||
. esc_attr__('打开搜索', 'aksrt') . '">';
|
||||
$button .= '<i class="fas fa-search" aria-hidden="true"></i></button>';
|
||||
}
|
||||
|
||||
echo '<div class="navbar-header">';
|
||||
echo '<div class="navbar-brand">' . $logo . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo $button; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '</div>';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_menu_search')) :
|
||||
/**
|
||||
* Layout-2 inline search form (zibll zib_get_menu_search simplified).
|
||||
*
|
||||
* @param array<string,mixed> $ctx
|
||||
*/
|
||||
function aksrt_get_menu_search(array $ctx): void {
|
||||
if (is_search()) {
|
||||
return;
|
||||
}
|
||||
$placeholder = (string) ($ctx['search_placeholder'] ?? __('搜索内容', 'aksrt'));
|
||||
$state = is_array($ctx['search_state'] ?? null) ? $ctx['search_state'] : [];
|
||||
$type = (string) ($state['type'] ?? 'post');
|
||||
$cat_enabled = !empty($state['category_enabled']);
|
||||
$cat_id = (int) ($state['category_id'] ?? 0);
|
||||
|
||||
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">';
|
||||
echo '<input type="hidden" name="aksrt_search_type" value="' . esc_attr($type) . '">';
|
||||
if ($cat_enabled) {
|
||||
echo '<input type="hidden" name="aksrt_category" value="' . esc_attr((string) $cat_id) . '">';
|
||||
}
|
||||
echo '<input type="text" class="form-control search-input focus-show" name="s" value="'
|
||||
. esc_attr(get_search_query()) . '" placeholder="' . esc_attr($placeholder) . '">';
|
||||
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>';
|
||||
echo '</div></form>';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_header_user_box_html')) :
|
||||
/**
|
||||
* User dropdown inner content for nav sub-menu (logged-in / guest).
|
||||
*
|
||||
* @param array<string,mixed> $ctx
|
||||
*/
|
||||
function aksrt_header_user_box_html(array $ctx): string {
|
||||
static $html = null;
|
||||
if ($html !== null) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
if (empty($ctx['user_menu'])) {
|
||||
$html = '';
|
||||
return $html;
|
||||
}
|
||||
|
||||
$user_id = (int) ($ctx['user_id'] ?? 0);
|
||||
$con = '';
|
||||
|
||||
if ($user_id > 0) {
|
||||
$user = $ctx['current_user'] instanceof WP_User ? $ctx['current_user'] : wp_get_current_user();
|
||||
$display_name = $user->display_name ?: $user->user_login;
|
||||
$avatar = get_avatar($user_id, 44, '', esc_attr($display_name), ['loading' => 'lazy']);
|
||||
$desc = (string) ($ctx['user_desc'] ?? '');
|
||||
$vip_badge = function_exists('aksrt_render_vip_badge') ? aksrt_render_vip_badge($user_id, 'sm') : '';
|
||||
$payvip = function_exists('aksrt_header_payvip_bar') ? aksrt_header_payvip_bar($user_id) : '';
|
||||
// nav_user_pay_vip gate: empty payvip when switch off for non-VIP CTA only — helper already handles VIP status.
|
||||
if (empty($ctx['nav_user_pay_vip']) && $payvip !== '' && strpos($payvip, 'is-vip') === false) {
|
||||
$payvip = '';
|
||||
}
|
||||
$checkin = function_exists('aksrt_header_user_checkin_btn') ? aksrt_header_user_checkin_btn($user_id) : '';
|
||||
$wallet = function_exists('aksrt_header_user_wallet_mini') ? aksrt_header_user_wallet_mini($user_id) : '';
|
||||
$badges = function_exists('aksrt_header_user_badges_row') ? aksrt_header_user_badges_row($user_id) : '';
|
||||
$unread = (int) ($ctx['unread_count'] ?? 0);
|
||||
$msg_url = (string) ($ctx['messages_url'] ?? '');
|
||||
|
||||
$msg_icon = '';
|
||||
if ($msg_url !== '') {
|
||||
$msg_icon = '<a class="abs-right" href="' . esc_url($msg_url) . '" title="' . esc_attr__('消息中心', 'aksrt') . '">';
|
||||
$msg_icon .= '<i class="fas fa-bell" aria-hidden="true"></i>';
|
||||
if ($unread > 0) {
|
||||
$msg_icon .= '<span class="aksrt-notification-badge">' . esc_html((string) min(99, $unread)) . '</span>';
|
||||
}
|
||||
$msg_icon .= '</a>';
|
||||
}
|
||||
|
||||
$href = '<div class="flex jsa header-user-href">';
|
||||
$href .= '<a rel="nofollow" href="' . esc_url(function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url() : home_url('/')) . '">';
|
||||
$href .= '<div class="badg mb6 toggle-radius c-blue"><i class="fas fa-user" aria-hidden="true"></i></div>';
|
||||
$href .= '<div class="c-blue">' . esc_html__('用户中心', 'aksrt') . '</div></a>';
|
||||
|
||||
$orders = (string) ($ctx['orders_url'] ?? '');
|
||||
if ($orders !== '') {
|
||||
$href .= '<a rel="nofollow" href="' . esc_url($orders) . '">';
|
||||
$href .= '<div class="badg mb6 toggle-radius c-purple"><i class="fas fa-shopping-bag" aria-hidden="true"></i></div>';
|
||||
$href .= '<div class="c-purple">' . esc_html__('我的订单', 'aksrt') . '</div></a>';
|
||||
}
|
||||
|
||||
if (!empty($ctx['can_publish'])) {
|
||||
$pub_text = class_exists('\AKSRT\Settings\Settings')
|
||||
? (string) (\AKSRT\Settings\Settings::get_all()['header_user_newposts_text'] ?? '')
|
||||
: '';
|
||||
if ($pub_text === '') {
|
||||
$pub_text = __('发布内容', 'aksrt');
|
||||
}
|
||||
$href .= '<a rel="nofollow" href="' . esc_url((string) $ctx['publish_url']) . '">';
|
||||
$href .= '<div class="badg mb6 toggle-radius c-green"><i class="fas fa-pen" aria-hidden="true"></i></div>';
|
||||
$href .= '<div class="c-green">' . esc_html($pub_text) . '</div></a>';
|
||||
}
|
||||
|
||||
$href .= '<a href="javascript:;" data-toggle="modal" data-target="#modal_signout">';
|
||||
$href .= '<div class="badg mb6 toggle-radius c-red"><i class="fas fa-sign-out-alt" aria-hidden="true"></i></div>';
|
||||
$href .= '<div class="c-red">' . esc_html__('退出登录', 'aksrt') . '</div></a>';
|
||||
$href .= '</div>';
|
||||
|
||||
if (is_super_admin()) {
|
||||
$href .= '<div class="flex jsa header-user-href">';
|
||||
$href .= '<a rel="nofollow" target="_blank" href="' . esc_url((string) $ctx['theme_settings_url']) . '">';
|
||||
$href .= '<div class="badg mb6 toggle-radius c-yellow"><i class="fas fa-sliders-h" aria-hidden="true"></i></div>';
|
||||
$href .= '<div class="c-yellow">' . esc_html__('主题设置', 'aksrt') . '</div></a>';
|
||||
$href .= '<a rel="nofollow" target="_blank" href="' . esc_url(admin_url()) . '">';
|
||||
$href .= '<div class="badg mb6 toggle-radius c-yellow"><i class="fas fa-cog" aria-hidden="true"></i></div>';
|
||||
$href .= '<div class="c-yellow">' . esc_html__('后台管理', 'aksrt') . '</div></a>';
|
||||
$href .= '</div>';
|
||||
}
|
||||
|
||||
$con = '<div class="user-info flex ac relative">';
|
||||
$con .= $avatar;
|
||||
$con .= '<div class="user-right flex flex1 ac jsb ml10">';
|
||||
$con .= '<div class="flex1" style="max-width: calc(100% - 40px);"><b>'
|
||||
. esc_html($display_name) . $vip_badge
|
||||
. '</b><div class="px12 muted-2-color text-ellipsis">' . esc_html($desc) . '</div></div>';
|
||||
$con .= '</div>';
|
||||
$con .= $msg_icon;
|
||||
$con .= '</div>';
|
||||
$con .= $payvip ? $payvip : '';
|
||||
$con .= $checkin ? '<div class="mt6 em09" style="padding:2px;">' . $checkin . '</div>' : '';
|
||||
$con .= $wallet ? '<div class="mt6" style="padding:2px;">' . $wallet . '</div>' : '';
|
||||
$con .= $badges;
|
||||
$con .= '<div class="relative opacity5"><i class="line-form-line"></i></div>';
|
||||
$con .= '<div class="mt10 text-center">' . $href . '</div>';
|
||||
} else {
|
||||
$vip_guest = '';
|
||||
if (!empty($ctx['nav_user_pay_vip']) && class_exists('\AKSRT\Settings\Settings')) {
|
||||
$vs = \AKSRT\Settings\Settings::get_payment_vip_settings();
|
||||
if (!empty($vs['enabled'])) {
|
||||
$vip_guest = '<div><a class="em09 signin-loader but jb-red radius4 payvip-icon btn-block mt10" href="javascript:;">'
|
||||
. '<i class="fas fa-gem" aria-hidden="true"></i> '
|
||||
. esc_html__('开通会员 尊享会员权益', 'aksrt') . '</a></div>';
|
||||
}
|
||||
}
|
||||
|
||||
$href = $vip_guest;
|
||||
$href .= '<div class="flex jsa header-user-href">';
|
||||
$href .= '<a href="javascript:;" class="signin-loader"><div class="badg mb6 toggle-radius c-blue"><i class="fas fa-sign-in-alt" aria-hidden="true"></i></div><div class="c-blue">'
|
||||
. esc_html__('登录', 'aksrt') . '</div></a>';
|
||||
if (get_option('users_can_register')) {
|
||||
$href .= '<a href="javascript:;" class="signup-loader"><div class="badg mb6 toggle-radius c-green"><i class="fas fa-user-plus" aria-hidden="true"></i></div><div class="c-green">'
|
||||
. esc_html__('注册', 'aksrt') . '</div></a>';
|
||||
}
|
||||
$href .= '<a rel="nofollow" href="' . esc_url(wp_lostpassword_url(home_url('/'))) . '"><div class="badg mb6 toggle-radius c-purple"><i class="fas fa-key" aria-hidden="true"></i></div><div class="c-purple">'
|
||||
. esc_html__('找回密码', 'aksrt') . '</div></a>';
|
||||
$href .= '</div>';
|
||||
|
||||
$con = '<div class="text-center">' . $href . '</div>';
|
||||
if (class_exists('\AKSRT\Auth\OAuth') && method_exists(\AKSRT\Auth\OAuth::get_instance(), 'render_social_buttons')) {
|
||||
$oauth_html = (string) \AKSRT\Auth\OAuth::get_instance()->render_social_buttons(__('快速登录', 'aksrt'));
|
||||
if ($oauth_html !== '') {
|
||||
$con .= '<p class="social-separator separator muted-3-color em09 mt10">' . esc_html__('快速登录', 'aksrt') . '</p>';
|
||||
$con .= '<div class="social_loginbar">' . $oauth_html . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$html = '<div class="sub-user-box">' . $con . '</div>';
|
||||
return $html;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_menu_button')) :
|
||||
/**
|
||||
* Right cluster: fold, publish/VIP, theme, user, search (zibll zib_menu_button).
|
||||
*
|
||||
* @param array<string,mixed> $ctx
|
||||
*/
|
||||
function aksrt_menu_button(array $ctx): void {
|
||||
$layout = (string) ($ctx['layout'] ?? '1');
|
||||
$user_id = (int) ($ctx['user_id'] ?? 0);
|
||||
$button = '';
|
||||
|
||||
// Publish + VIP (respect nav_pay_vip).
|
||||
if (function_exists('aksrt_render_header_menu_buttons')) {
|
||||
$button .= aksrt_render_header_menu_buttons();
|
||||
}
|
||||
|
||||
// Theme toggle.
|
||||
$radius_but = '';
|
||||
if (in_array('pc_nav', (array) ($ctx['theme_positions'] ?? []), true)) {
|
||||
$radius_but .= '<a href="javascript:;" class="toggle-theme toggle-radius" id="theme-toggle-desktop" title="'
|
||||
. esc_attr__('切换亮暗色', 'aksrt') . '">';
|
||||
$radius_but .= '<i class="fas fa-moon theme-icon-moon" aria-hidden="true"></i>';
|
||||
$radius_but .= '<i class="fas fa-sun theme-icon-sun" aria-hidden="true" style="display:none"></i>';
|
||||
$radius_but .= '</a>';
|
||||
}
|
||||
if ($radius_but !== '') {
|
||||
$button .= '<div class="navbar-form navbar-right flex ac">' . $radius_but . '</div>';
|
||||
}
|
||||
|
||||
// User + search.
|
||||
$sign_but = '';
|
||||
$user_sub = '';
|
||||
if (!empty($ctx['user_menu'])) {
|
||||
$user_sub = '<div class="padding-10">' . aksrt_header_user_box_html($ctx) . '</div>';
|
||||
if ('2' === $layout) {
|
||||
if ($user_id > 0) {
|
||||
$avatar = get_avatar($user_id, 36, '', '', ['loading' => 'lazy', 'class' => 'avatar']);
|
||||
$sign_but = '<li><a href="javascript:;" class="navbar-avatar">' . $avatar . '</a><ul class="sub-menu">'
|
||||
. $user_sub . '</ul></li>';
|
||||
} else {
|
||||
$sign_but = '<li><a href="javascript:;" class="signin-loader">' . esc_html__('登录', 'aksrt') . '</a></li>';
|
||||
if (get_option('users_can_register')) {
|
||||
$sign_but .= '<li><a href="javascript:;" class="signup-loader">' . esc_html__('注册', 'aksrt') . '</a></li>';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$trigger = $user_id > 0
|
||||
? get_avatar($user_id, 36, '', '', ['loading' => 'lazy'])
|
||||
: '<i class="fas fa-user" aria-hidden="true"></i>';
|
||||
$cls = $user_id > 0 ? 'navbar-avatar' : 'btn signin-loader';
|
||||
$dot = ($user_id > 0 && (int) ($ctx['unread_count'] ?? 0) > 0)
|
||||
? '<span class="nav-user__dot" aria-hidden="true"></span>'
|
||||
: '';
|
||||
$sign_but = '<li class="relative"><a href="javascript:;" class="' . esc_attr($cls) . '">'
|
||||
. $trigger . $dot . '</a><ul class="sub-menu">' . $user_sub . '</ul></li>';
|
||||
}
|
||||
}
|
||||
|
||||
$search_but = '';
|
||||
if ('2' !== $layout && !empty($ctx['search_enabled'])) {
|
||||
$search_but = '<li class="relative"><a href="javascript:;" class="btn nav-search-btn main-search-btn" data-toggle-class data-target=".navbar-search" aria-label="'
|
||||
. esc_attr__('打开搜索', 'aksrt') . '"><i class="fas fa-search" aria-hidden="true"></i></a></li>';
|
||||
}
|
||||
|
||||
$right_but = '<div class="navbar-form navbar-right'
|
||||
. ($user_id <= 0 && '2' === $layout ? ' navbar-text' : '') . '">';
|
||||
$right_but .= '<ul class="list-inline splitters relative">'
|
||||
. $sign_but . $search_but . '</ul></div>';
|
||||
|
||||
$fold = '<div class="navbar-form navbar-right hide show-nav-but" style="margin-right:-10px;">'
|
||||
. '<a data-toggle-class data-target=".nav.navbar-nav" href="javascript:;" class="but" aria-label="'
|
||||
. esc_attr__('展开菜单', 'aksrt') . '"><i class="fas fa-bars" aria-hidden="true"></i></a></div>';
|
||||
|
||||
$html = $fold;
|
||||
if ('3' === $layout) {
|
||||
$html .= $right_but . $button;
|
||||
} else {
|
||||
$html .= $button . $right_but;
|
||||
}
|
||||
|
||||
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
endif;
|
||||
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/**
|
||||
* Header shell orchestration (zibll zib_header contract).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_get_header_nav_context')) :
|
||||
/**
|
||||
* Shared header render context (settings + brand + user flags).
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
function aksrt_get_header_nav_context(): array {
|
||||
static $ctx = null;
|
||||
if ($ctx !== null) {
|
||||
return $ctx;
|
||||
}
|
||||
|
||||
$settings = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_header_nav_settings()
|
||||
: [
|
||||
'fixed' => true,
|
||||
'search_enabled' => true,
|
||||
'user_menu' => true,
|
||||
'publish_btn' => true,
|
||||
'mobile_drawer' => true,
|
||||
'nav_style' => 'default',
|
||||
'max_width' => 1200,
|
||||
'scroll_down_hide' => true,
|
||||
'layout' => '1',
|
||||
'mobile_layout' => 'center',
|
||||
'mobile_align' => 'left',
|
||||
'nav_pay_vip' => true,
|
||||
'nav_user_pay_vip' => true,
|
||||
];
|
||||
|
||||
$site_name = get_bloginfo('name');
|
||||
$brand_name = function_exists('aksrt_get_site_logo_text') ? aksrt_get_site_logo_text() : $site_name;
|
||||
$brand_name = $brand_name !== '' ? $brand_name : $site_name;
|
||||
$logo_url = function_exists('aksrt_get_site_logo_url') ? trim((string) aksrt_get_site_logo_url()) : '';
|
||||
$logo_dark = function_exists('aksrt_get_site_logo_dark_url') ? trim((string) aksrt_get_site_logo_dark_url()) : '';
|
||||
$logo_width = function_exists('aksrt_get_site_logo_width') ? aksrt_get_site_logo_width() : 150;
|
||||
$logo_more = $logo_width > 0
|
||||
? 'style="height:36px;width:auto;max-width:' . max(36, (int) $logo_width) . 'px"'
|
||||
: 'style="height:36px;width:auto"';
|
||||
$logo_html = '';
|
||||
if ($logo_url !== '' || $logo_dark !== '') {
|
||||
$logo_html = function_exists('aksrt_get_adaptive_theme_img')
|
||||
? aksrt_get_adaptive_theme_img($logo_url, $logo_dark, $brand_name, $logo_more)
|
||||
: '';
|
||||
}
|
||||
|
||||
$theme_positions = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_theme_mode_button_positions()
|
||||
: ['pc_nav', 'm_menu'];
|
||||
|
||||
$can_publish = !empty($settings['publish_btn']) && (
|
||||
current_user_can('manage_options')
|
||||
|| (class_exists('\AKSRT\Core\FrontSubmit') && \AKSRT\Core\FrontSubmit::get_instance()->can_submit())
|
||||
);
|
||||
|
||||
$show_slide = function_exists('aksrt_header_slide_is_show')
|
||||
? aksrt_header_slide_is_show()
|
||||
: false;
|
||||
|
||||
$current_user = wp_get_current_user();
|
||||
$user_id = (int) $current_user->ID;
|
||||
$user_desc = $user_id > 0 ? (string) get_user_meta($user_id, 'description', true) : '';
|
||||
if ($user_desc === '' && $user_id > 0) {
|
||||
$user_desc = (string) $current_user->user_email;
|
||||
}
|
||||
|
||||
$ctx = [
|
||||
'settings' => $settings,
|
||||
'layout' => (string) ($settings['layout'] ?? '1'),
|
||||
'mobile_layout' => (string) ($settings['mobile_layout'] ?? 'center'),
|
||||
'mobile_align' => (string) ($settings['mobile_align'] ?? 'left'),
|
||||
'fixed' => !empty($settings['fixed']),
|
||||
'scroll_down_hide' => !empty($settings['scroll_down_hide']) && !empty($settings['fixed']),
|
||||
'search_enabled' => !empty($settings['search_enabled']),
|
||||
'user_menu' => !empty($settings['user_menu']),
|
||||
'mobile_drawer' => !empty($settings['mobile_drawer']),
|
||||
'nav_pay_vip' => !isset($settings['nav_pay_vip']) || !empty($settings['nav_pay_vip']),
|
||||
'nav_user_pay_vip' => !isset($settings['nav_user_pay_vip']) || !empty($settings['nav_user_pay_vip']),
|
||||
'max_width' => (int) ($settings['max_width'] ?? 1200),
|
||||
'brand_name' => $brand_name,
|
||||
'logo_html' => $logo_html,
|
||||
'has_logo' => $logo_html !== '',
|
||||
'theme_positions' => is_array($theme_positions) ? $theme_positions : [],
|
||||
'can_publish' => $can_publish,
|
||||
'show_slide' => $show_slide,
|
||||
'current_user' => $current_user,
|
||||
'user_id' => $user_id,
|
||||
'user_desc' => $user_desc,
|
||||
'unread_count' => ($user_id > 0 && function_exists('aksrt_get_user_unread_notification_count'))
|
||||
? (int) aksrt_get_user_unread_notification_count($user_id)
|
||||
: 0,
|
||||
'messages_url' => function_exists('aksrt_get_messages_page_url') ? aksrt_get_messages_page_url() : '',
|
||||
'orders_url' => function_exists('aksrt_get_orders_page_url') ? aksrt_get_orders_page_url() : '',
|
||||
'publish_url' => function_exists('aksrt_get_new_post_url') ? aksrt_get_new_post_url() : admin_url('post-new.php'),
|
||||
'theme_settings_url' => function_exists('aksrt_get_admin_settings_url')
|
||||
? aksrt_get_admin_settings_url('')
|
||||
: admin_url('admin.php?page=aksrt-settings'),
|
||||
'search_state' => function_exists('aksrt_get_search_form_state')
|
||||
? aksrt_get_search_form_state()
|
||||
: [
|
||||
'type' => 'post',
|
||||
'types' => ['post' => __('文章', 'aksrt')],
|
||||
'category_id' => 0,
|
||||
'category_enabled' => false,
|
||||
'categories' => [],
|
||||
],
|
||||
'search_placeholder' => function_exists('aksrt_get_search_placeholder')
|
||||
? aksrt_get_search_placeholder()
|
||||
: __('开启精彩搜索', 'aksrt'),
|
||||
'search_hot_keywords' => function_exists('aksrt_get_search_hot_keywords')
|
||||
? aksrt_get_search_hot_keywords()
|
||||
: [],
|
||||
];
|
||||
|
||||
if ($ctx['publish_url'] === '') {
|
||||
$ctx['publish_url'] = admin_url('post-new.php');
|
||||
}
|
||||
|
||||
return $ctx;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_header')) :
|
||||
/**
|
||||
* Render top header + mobile drawer (+ optional slide after caller).
|
||||
*/
|
||||
function aksrt_header(): void {
|
||||
$ctx = aksrt_get_header_nav_context();
|
||||
$layout = $ctx['layout'];
|
||||
$header_class = [
|
||||
'header',
|
||||
'header-layout-' . $layout,
|
||||
];
|
||||
if (!empty($ctx['show_slide'])) {
|
||||
$header_class[] = 'show-slide';
|
||||
}
|
||||
if (!empty($ctx['scroll_down_hide'])) {
|
||||
$header_class[] = 'scroll-down-hide';
|
||||
}
|
||||
|
||||
$nav_class = [
|
||||
'navbar',
|
||||
'navbar-top',
|
||||
$ctx['mobile_layout'],
|
||||
];
|
||||
|
||||
$nav_style = '';
|
||||
if ((int) $ctx['max_width'] > 0) {
|
||||
$nav_style = ' style="--nav-max-width:' . (int) $ctx['max_width'] . 'px"';
|
||||
}
|
||||
|
||||
echo '<header class="' . esc_attr(implode(' ', array_map('sanitize_html_class', $header_class))) . '">';
|
||||
echo '<nav class="' . esc_attr(implode(' ', array_map('sanitize_html_class', $nav_class))) . '"' . $nav_style . '>';
|
||||
echo '<div class="container-fluid container-header">';
|
||||
|
||||
aksrt_navbar_header($ctx);
|
||||
|
||||
echo '<div class="collapse navbar-collapse">';
|
||||
if ('3' !== $layout) {
|
||||
aksrt_menu_items('primary', true);
|
||||
}
|
||||
if ('2' === $layout && !empty($ctx['search_enabled'])) {
|
||||
aksrt_get_menu_search($ctx);
|
||||
}
|
||||
aksrt_menu_button($ctx);
|
||||
if ('3' === $layout) {
|
||||
echo '<div class="navbar-right">';
|
||||
aksrt_menu_items('primary', true);
|
||||
echo '</div>';
|
||||
}
|
||||
echo '</div></div></nav></header>';
|
||||
|
||||
if (!empty($ctx['mobile_drawer'])) {
|
||||
aksrt_nav_mobile_shell($ctx);
|
||||
}
|
||||
|
||||
if (function_exists('aksrt_render_signout_modal')) {
|
||||
aksrt_render_signout_modal();
|
||||
}
|
||||
}
|
||||
endif;
|
||||
+65
-128
@@ -1,9 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Menu Decoration Helpers
|
||||
*
|
||||
* Helper functions for reading menu item meta (icons, badges, submenu styles)
|
||||
* and rendering decorated menu items.
|
||||
* Menu decoration helpers — aksrt_menu_options meta only (zibll zib_menu_pz).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -11,151 +8,91 @@
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Get menu decoration settings from \AKSRT\Settings\Settings.
|
||||
* Global decoration switches (SPA). Per-item data is always from meta.
|
||||
*
|
||||
* @return array
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
function aksrt_get_menu_decoration_settings(): array {
|
||||
static $cache = null;
|
||||
if ($cache !== null) {
|
||||
return $cache;
|
||||
}
|
||||
static $cache = null;
|
||||
if ($cache !== null) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
if (class_exists('\AKSRT\Settings\Settings')) {
|
||||
$all = \AKSRT\Settings\Settings::get_all();
|
||||
} else {
|
||||
$all = [];
|
||||
}
|
||||
$all = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_all()
|
||||
: [];
|
||||
|
||||
$cache = [
|
||||
'icon_enabled' => !empty($all['menu_icon_enabled']),
|
||||
'badge_enabled' => !empty($all['menu_badge_enabled']),
|
||||
'submenu_style' => in_array($all['menu_submenu_style'] ?? '', ['dropdown', 'mega', 'cards'], true)
|
||||
? $all['menu_submenu_style']
|
||||
: 'dropdown',
|
||||
'submenu_columns' => max(1, min(5, (int) ($all['menu_submenu_columns'] ?? 1))),
|
||||
'submenu_width' => max(160, min(800, (int) ($all['menu_submenu_width'] ?? 220))),
|
||||
'hover_effect' => in_array($all['menu_hover_effect'] ?? '', ['underline', 'background', 'color', 'none'], true)
|
||||
? $all['menu_hover_effect']
|
||||
: 'underline',
|
||||
'item_padding' => max(4, min(32, (int) ($all['menu_item_padding'] ?? 12))),
|
||||
'mobile_style' => in_array($all['menu_mobile_style'] ?? '', ['drawer', 'fullscreen', 'dropdown'], true)
|
||||
? $all['menu_mobile_style']
|
||||
: 'drawer',
|
||||
];
|
||||
$cache = [
|
||||
'icon_enabled' => !isset($all['menu_icon_enabled']) || !empty($all['menu_icon_enabled']),
|
||||
'badge_enabled' => !isset($all['menu_badge_enabled']) || !empty($all['menu_badge_enabled']),
|
||||
];
|
||||
|
||||
return $cache;
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get decoration meta for a specific menu item.
|
||||
* Read one menu item option from post meta aksrt_menu_options.
|
||||
*
|
||||
* Reads CSS class and title attribute from the menu item to extract:
|
||||
* - icon: FA5 class (e.g. "fas fa-home")
|
||||
* - badge_text: badge label (e.g. "新", "热")
|
||||
* - badge_type: badge color type (e.g. "new", "hot", "info")
|
||||
* - submenu_style: override for this item's submenu
|
||||
* @param int $id Menu item ID.
|
||||
* @param string $key Option key.
|
||||
* @param mixed $default Default.
|
||||
* @return mixed
|
||||
*/
|
||||
function aksrt_menu_pz(int $id, string $key = '', $default = '') {
|
||||
static $options = [];
|
||||
if (!isset($options[$id])) {
|
||||
$raw = get_post_meta($id, 'aksrt_menu_options', true);
|
||||
$options[$id] = is_array($raw) ? $raw : [];
|
||||
}
|
||||
if ($key === '') {
|
||||
return $options[$id];
|
||||
}
|
||||
return $options[$id][$key] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decoration for a menu item (meta only).
|
||||
*
|
||||
* @param WP_Post $menu_item The menu item post object.
|
||||
* @return array
|
||||
* @param WP_Post|object $menu_item Menu item.
|
||||
* @return array{icon:string,badge_text:string,badge_class:string,submenu_s:bool,submenu_type:string}
|
||||
*/
|
||||
function aksrt_get_menu_item_decoration($menu_item): array {
|
||||
$classes = (array) ($menu_item->classes ?? []);
|
||||
$title = (string) ($menu_item->title ?? '');
|
||||
$attr = (string) ($menu_item->attr_title ?? '');
|
||||
|
||||
$result = [
|
||||
'icon' => '',
|
||||
'badge_text' => '',
|
||||
'badge_type' => 'new',
|
||||
'submenu_style' => '',
|
||||
];
|
||||
|
||||
// Extract icon from CSS classes (pattern: icon-* or fa-*)
|
||||
foreach ($classes as $cls) {
|
||||
$cls = trim($cls);
|
||||
if (strpos($cls, 'fa-') === 0 || strpos($cls, 'fas ') === 0 || strpos($cls, 'fab ') === 0 || strpos($cls, 'far ') === 0) {
|
||||
$result['icon'] = $cls;
|
||||
break;
|
||||
}
|
||||
if (strpos($cls, 'icon-') === 0) {
|
||||
$result['icon'] = 'fas fa-' . substr($cls, 5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract badge from title attribute (pattern: [新] or [热:hot])
|
||||
if (preg_match('/^\[([^\]:]+)(?::(\w+))?\]/', $title, $m)) {
|
||||
$result['badge_text'] = $m[1];
|
||||
$result['badge_type'] = $m[2] ?? 'new';
|
||||
// Remove badge markup from display title
|
||||
$menu_item->title = trim(substr($title, strlen($m[0])));
|
||||
}
|
||||
|
||||
// Extract submenu style override from classes
|
||||
foreach ($classes as $cls) {
|
||||
if (strpos($cls, 'submenu-') === 0) {
|
||||
$style = substr($cls, 8);
|
||||
if (in_array($style, ['dropdown', 'mega', 'cards'], true)) {
|
||||
$result['submenu_style'] = $style;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
$id = (int) ($menu_item->ID ?? 0);
|
||||
return [
|
||||
'icon' => (string) aksrt_menu_pz($id, 'icon', ''),
|
||||
'badge_text' => (string) aksrt_menu_pz($id, 'badge', ''),
|
||||
'badge_class' => (string) aksrt_menu_pz($id, 'badge_class', ''),
|
||||
'submenu_s' => !empty(aksrt_menu_pz($id, 'submenu_s', false)),
|
||||
'submenu_type' => sanitize_key((string) aksrt_menu_pz($id, 'submenu_type', '')),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a menu item icon if enabled.
|
||||
*
|
||||
* @param string $icon_class FA5 icon class.
|
||||
* @param bool $enabled Whether icons are enabled globally.
|
||||
* @return string HTML string.
|
||||
* @param string $icon_class FA5 / icon class.
|
||||
* @param bool $enabled Global switch.
|
||||
*/
|
||||
function aksrt_render_menu_icon(string $icon_class, bool $enabled = true): string {
|
||||
if (!$enabled || $icon_class === '') {
|
||||
return '';
|
||||
}
|
||||
return '<i class="' . esc_attr($icon_class) . ' aksrt-nav__icon" aria-hidden="true"></i>';
|
||||
if (!$enabled || $icon_class === '') {
|
||||
return '';
|
||||
}
|
||||
// Allow bare "fa-home" → "fas fa-home".
|
||||
if (strpos($icon_class, 'fa') === false) {
|
||||
$icon_class = 'fas fa-' . ltrim($icon_class, '-');
|
||||
} elseif (strpos($icon_class, 'fa-') === 0 && strpos($icon_class, ' ') === false) {
|
||||
$icon_class = 'fas ' . $icon_class;
|
||||
}
|
||||
return '<i class="' . esc_attr($icon_class) . ' mr3 menu-item-icon" aria-hidden="true"></i>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a menu item badge if enabled.
|
||||
*
|
||||
* @param string $text Badge text.
|
||||
* @param string $type Badge type (new, hot, info, etc.).
|
||||
* @param bool $enabled Whether badges are enabled globally.
|
||||
* @return string HTML string.
|
||||
* @param string $class Extra class (jb-red etc.).
|
||||
* @param bool $enabled Global switch.
|
||||
*/
|
||||
function aksrt_render_menu_badge(string $text, string $type = 'new', bool $enabled = true): string {
|
||||
if (!$enabled || $text === '') {
|
||||
return '';
|
||||
}
|
||||
return '<span class="aksrt-nav__badge aksrt-nav__badge--' . esc_attr($type) . '">' . esc_html($text) . '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSS classes for a menu item based on decoration settings.
|
||||
*
|
||||
* @param array $decoration Decoration meta from aksrt_get_menu_item_decoration().
|
||||
* @param array $settings Global decoration settings.
|
||||
* @return string Space-separated CSS classes.
|
||||
*/
|
||||
function aksrt_get_menu_item_classes(array $decoration, array $settings): string {
|
||||
$classes = ['aksrt-nav__item'];
|
||||
|
||||
if ($settings['hover_effect'] !== 'none') {
|
||||
$classes[] = 'aksrt-nav__item--hover-' . $settings['hover_effect'];
|
||||
}
|
||||
|
||||
if ($decoration['icon'] !== '') {
|
||||
$classes[] = 'aksrt-nav__item--has-icon';
|
||||
}
|
||||
|
||||
if ($decoration['badge_text'] !== '') {
|
||||
$classes[] = 'aksrt-nav__item--has-badge';
|
||||
}
|
||||
|
||||
return implode(' ', $classes);
|
||||
function aksrt_render_menu_badge(string $text, string $class = '', bool $enabled = true): string {
|
||||
if (!$enabled || $text === '') {
|
||||
return '';
|
||||
}
|
||||
$cls = trim('menu-item-badge ' . $class);
|
||||
return ' <badge class="' . esc_attr($cls) . '">' . esc_html($text) . '</badge>';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user