Files
wordpress-theme-aksrt/templates/parts/user/author-hero.php
T
Claude 4325ce0c1c fix(ui): render user level icon inline beside the name
The level (等级) badge was wrapping to its own line below the username and
rendering at the intrinsic PNG size in most surfaces. Centralize the badge
sizing after zibll's `.img-icon` (height: 1.1em, inline-block) in base.css so
every route gets the same compact inline badge, and keep the name row from
flex-wrapping.

- Add shared `.aksrt-user-level-icon / .aksrt-identity-medal` rule + nowrap name
  rows in base.css (loaded on all routes).
- Header dropdown: append the level icon next to the display name (was a
  separate badges row); constrain the name to ellipsis so the badge never wraps.
- User center profile header & author hero: render the level icon inside the
  <h1> name row; drop the duplicate level chip from the signals row.
- Single article author bar / after-box author card: nowrap the name row and
  size the level icon to 1.2em (was unstyled → intrinsic PNG size).
- Comments: inner <name> nowrap with a name clamp; medal sized to 1em.
- Consolidate the per-route `.aksrt-user-level-icon` duplicates in
  user-center/level.css and profile/layout.css onto the shared rule.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 18:13:41 +08:00

216 lines
9.3 KiB
PHP

<?php
/**
* Author Hero — shared hero section for author archive and public user homepage.
*
* Aligns with Zibll zib_author_header(): cover, avatar, name, identity, desc,
* and header actions. Content stats live in the tab bar, not a body stats row.
*
* Contract: get_template_part(..., null, $args)
* user WP_User
* dashboard array from aksrt_get_user_dashboard_view()
* user_home_settings array
* is_author_page bool
* tab_counts array (optional)
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
$args = is_array($args ?? null) ? $args : [];
$user = $args['user'] ?? null;
$dashboard = is_array($args['dashboard'] ?? null) ? $args['dashboard'] : [];
$settings = is_array($args['user_home_settings'] ?? null) ? $args['user_home_settings'] : [];
$is_author = !empty($args['is_author_page']);
$tab_counts = is_array($args['tab_counts'] ?? null) ? $args['tab_counts'] : [];
if (!($user instanceof WP_User)) {
return;
}
$user_id = (int) $user->ID;
$home_url = function_exists('aksrt_get_user_home_url') ? aksrt_get_user_home_url($user) : home_url('/');
$show_cover = !array_key_exists('cover', $settings) || !empty($settings['cover']);
$show_follow = !array_key_exists('follow', $settings) || !empty($settings['follow']);
$show_avatar = !array_key_exists('avatar', $settings) || !empty($settings['avatar']);
$show_name = !array_key_exists('name', $settings) || !empty($settings['name']);
$show_desc = !array_key_exists('desc', $settings) || !empty($settings['desc']);
$show_social = !array_key_exists('social', $settings) || !empty($settings['social']);
$show_message = !array_key_exists('message', $settings) || !empty($settings['message']);
$contacts = $dashboard['user_contacts'] ?? [];
$social_on = !empty($dashboard['social_links_on']);
$signals = $dashboard['profile_signals'] ?? [];
$notice = $dashboard['profile_notice'] ?? null;
$show_report = !empty($dashboard['show_report']);
$bg_url = $dashboard['background_url'] ?? '';
$is_own = !empty($dashboard['is_own_profile']);
$follower_count = (int) ($tab_counts['follow'] ?? 0);
if ($follower_count <= 0 && class_exists('\AKSRT\User\Follow')) {
$follower_count = (int) \AKSRT\User\Follow::get_instance()->get_follower_count($user_id);
}
$pm_enabled = class_exists('\AKSRT\Settings\Settings') && !empty(\AKSRT\Settings\Settings::private_message_settings()['enabled']);
$messages_url = function_exists('aksrt_get_messages_page_url') ? aksrt_get_messages_page_url() : '';
$pm_url = ($pm_enabled && $messages_url !== '')
? add_query_arg('msg_type', 'conversation', $messages_url)
: '';
?>
<div class="aksrt-author-hero<?php echo $show_cover ? '' : ' aksrt-author-hero--no-cover'; ?>">
<?php if ($show_cover) : ?>
<div class="aksrt-author-hero__cover">
<img class="aksrt-author-hero__cover-img"
src="<?php echo esc_url($bg_url ? $bg_url : get_theme_file_uri('assets/img/person_background.png')); ?>"
alt=""<?php echo function_exists('aksrt_lazy_loading') ? aksrt_lazy_loading('cover') : ' loading="lazy"'; ?>>
<div class="aksrt-author-hero__cover-mask"></div>
<?php if ($follower_count > 0) : ?>
<div class="aksrt-author-hero__cover-metas" aria-label="<?php esc_attr_e('主页数据', 'aksrt'); ?>">
<span class="aksrt-author-hero__cover-meta" title="<?php esc_attr_e('粉丝', 'aksrt'); ?>">
<i class="fas fa-heart" aria-hidden="true"></i>
<?php echo esc_html((string) $follower_count); ?>
</span>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<div class="aksrt-author-hero__body">
<?php if ($show_avatar) : ?>
<div class="aksrt-author-hero__avatar">
<?php
if (function_exists('aksrt_get_avatar_html')) {
echo aksrt_get_avatar_html($user_id, 120, ['loading' => 'lazy']); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
} else {
echo get_avatar($user_id, 120, '', $user->display_name); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
?>
</div>
<?php endif; ?>
<div class="aksrt-author-hero__info">
<?php if ($show_name) : ?>
<h1 class="aksrt-author-hero__name">
<?php echo esc_html($user->display_name); ?>
<?php
$vip_badge = function_exists('aksrt_render_vip_badge') ? aksrt_render_vip_badge($user_id) : '';
if ($vip_badge) {
echo $vip_badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
// Level icon inline to the right of the name (zibll parity).
if (class_exists('\AKSRT\User\Level') && method_exists('\AKSRT\User\Level', 'get_badge_html')) {
echo \AKSRT\User\Level::get_badge_html($user_id); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
?>
</h1>
<?php endif; ?>
<?php
// Badge detail remote-modal (zibll user medal info).
if (class_exists('\AKSRT\User\Badges') && \AKSRT\User\Badges::enabled() && \AKSRT\User\Badges::public_display()) {
$badge_link = \AKSRT\User\Badges::get_info_link($user_id, 'but but-sm jb-blue mt6', __('徽章明细', 'aksrt'));
if ($badge_link !== '') {
echo '<div class="aksrt-author-hero__badges">' . $badge_link . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
?>
<?php
// IP 归属地 (zibll author_header_identity / user_city_s).
$city_badge = function_exists('aksrt_get_user_city_badge_html')
? aksrt_get_user_city_badge_html($user_id, 'user_home', 'badg')
: '';
?>
<?php if ($city_badge !== '' || !empty($signals)) : ?>
<div class="aksrt-author-hero__identity user-identity flex ac hh">
<?php if ($city_badge !== '') : ?>
<?php echo $city_badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php endif; ?>
<?php if (function_exists('aksrt_render_user_identity_chips')) : ?>
<?php
// Level already rendered inline next to the name above; skip it here.
echo aksrt_render_user_identity_chips($user_id, 'author', ['include_vip' => false, 'skip_level' => true]); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ($show_desc && $user->description) : ?>
<p class="aksrt-author-hero__desc"><?php echo esc_html($user->description); ?></p>
<?php endif; ?>
<?php if (!empty($notice) && is_array($notice)) : ?>
<div class="aksrt-author-hero__notice aksrt-author-hero__notice--<?php echo esc_attr((string) ($notice['tone'] ?? 'muted')); ?>">
<?php echo esc_html((string) ($notice['message'] ?? '')); ?>
</div>
<?php endif; ?>
<?php if ($show_social && !empty($contacts) && $social_on) : ?>
<div class="aksrt-author-hero__contacts">
<?php if (function_exists('aksrt_render_social_links')) : ?>
<?php aksrt_render_social_links($contacts); ?>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<div class="aksrt-author-hero__actions">
<?php if ($is_own) : ?>
<a href="<?php echo esc_url(aksrt_get_user_center_url()); ?>" class="btn-primary btn-sm">
<i class="fas fa-user" aria-hidden="true"></i>
<span><?php esc_html_e('用户中心', 'aksrt'); ?></span>
</a>
<?php if ($show_message && $messages_url !== '') : ?>
<a href="<?php echo esc_url($messages_url); ?>" class="btn-ghost btn-sm">
<i class="fas fa-bell" aria-hidden="true"></i>
<span><?php esc_html_e('消息', 'aksrt'); ?></span>
</a>
<?php endif; ?>
<?php else : ?>
<?php if ($show_follow) : ?>
<?php if (is_user_logged_in()) : ?>
<button type="button" class="btn-outline btn-sm aksrt-author-hero__follow-btn" data-aksrt-follow="<?php echo (int) $user_id; ?>" title="<?php esc_attr_e('关注该用户', 'aksrt'); ?>">
<i class="far fa-heart" aria-hidden="true"></i>
<span><?php esc_html_e('关注', 'aksrt'); ?></span>
</button>
<?php else : ?>
<a href="<?php echo esc_url(aksrt_get_login_url($home_url)); ?>" class="btn-outline btn-sm aksrt-author-hero__follow-btn">
<i class="far fa-heart" aria-hidden="true"></i>
<span><?php esc_html_e('登录后关注', 'aksrt'); ?></span>
</a>
<?php endif; ?>
<?php endif; ?>
<?php if ($show_message && $pm_url !== '') : ?>
<?php if (is_user_logged_in()) : ?>
<a href="<?php echo esc_url($pm_url); ?>" class="btn-primary btn-sm">
<i class="fas fa-comment" aria-hidden="true"></i>
<span><?php esc_html_e('私信', 'aksrt'); ?></span>
</a>
<?php else : ?>
<a href="<?php echo esc_url(aksrt_get_login_url($home_url)); ?>" class="btn-primary btn-sm">
<i class="fas fa-comment" aria-hidden="true"></i>
<span><?php esc_html_e('私信', 'aksrt'); ?></span>
</a>
<?php endif; ?>
<?php endif; ?>
<?php endif; ?>
<?php if ($show_report) : ?>
<?php if (is_user_logged_in()) : ?>
<button type="button" class="btn-ghost btn-sm aksrt-author-hero__report-btn" data-aksrt-report='{"target_type":"user","target_id":<?php echo (int) $user_id; ?>}' title="<?php esc_attr_e('举报该用户', 'aksrt'); ?>">
<i class="far fa-flag" aria-hidden="true"></i>
</button>
<?php else : ?>
<a href="<?php echo esc_url(aksrt_get_login_url($home_url)); ?>" class="btn-ghost btn-sm aksrt-author-hero__report-btn">
<i class="far fa-flag" aria-hidden="true"></i>
</a>
<?php endif; ?>
<?php endif; ?>
<?php if ($is_author && function_exists('aksrt_render_admin_quick_link')) { aksrt_render_admin_quick_link('page-display/user-home', __('用户主页设置', 'aksrt')); } ?>
</div>
</div>
</div>