The action bar used a locally invented pill-chip style that overrode the reference theme's 80px icon-over-text columns, and the JS toggled a class no stylesheet targeted — so likes/favorites showed no selected state at all. - restore reference markup: <svg class="icon"> + <text>/<count> and the actived class, with data-stat-count/data-base-count preserved - toggle actived plus a transient action-animation so the lovestar keyframes finally reach the DOM - drop the CSS overrides and now-dead action-btn/.action-btn--reward and .post-actions-card rules; main.css already carried the reference rules the overrides were shadowing
672 lines
26 KiB
PHP
672 lines
26 KiB
PHP
<?php
|
||
/**
|
||
* Single post render helpers (legacy-style composition pieces).
|
||
*
|
||
* @package AKSRT
|
||
*/
|
||
|
||
defined('ABSPATH') || exit;
|
||
|
||
if (!function_exists('aksrt_single_render_cover')) :
|
||
/**
|
||
* Cover / slide / video header (legacy single-head-cover).
|
||
*
|
||
* @param array<string,mixed> $ctx Single context.
|
||
*/
|
||
function aksrt_single_render_cover(array $ctx): void {
|
||
if (empty($ctx['show_cover']) || $ctx['cover_url'] === '') {
|
||
return;
|
||
}
|
||
|
||
$type = (string) $ctx['cover_type'];
|
||
$badge = (string) $ctx['status_badge'];
|
||
$crumbs = (string) $ctx['breadcrumbs_html'];
|
||
// 参考主题 article_image_cover_option.scale:20-200(%),标题预留 50px。
|
||
$img_scale = max(20, min(200, (int) $ctx['img_scale']));
|
||
// 参考主题 article_video_cover_option.scale:0-200,0 = 不固定长宽比 → 16:9 回退。
|
||
$video_scale = max(0, min(200, (int) $ctx['video_scale']));
|
||
$video_padding = $video_scale > 0 ? (string) $video_scale : '56.25';
|
||
$slides = is_array($ctx['slide_images'] ?? null) ? $ctx['slide_images'] : [];
|
||
$poster = (string) ($ctx['video_poster'] ?? '');
|
||
$title_html = (string) ($ctx['title_html'] ?? esc_html(get_the_title()));
|
||
|
||
if ($type === 'video') :
|
||
// 视频封面高度为裸比例(对齐参考主题 .dplayer-scale-height 契约):
|
||
// 标题/面包屑在下方 .single-video-footer,不叠加封面,无 +50px 补偿;
|
||
// 单图/多图封面标题叠加封面,才需要 calc(scale% + 50px)。
|
||
?>
|
||
<div class="single-head-cover">
|
||
<div class="single-video">
|
||
<div class="graphic single-cover single-cover--video imgbox-container" style="padding-bottom:<?php echo esc_attr($video_padding); ?>%;">
|
||
<div class="aksrt-video single-cover__player" data-aksrt-video data-src="<?php echo esc_url($ctx['cover_url']); ?>"<?php echo $poster !== '' ? ' data-poster="' . esc_url($poster) . '"' : ''; ?> style="position:absolute;inset:0;width:100%;height:100%;"></div>
|
||
</div>
|
||
<div class="single-video-footer dplayer-featured">
|
||
<div class="flex jsb at">
|
||
<?php echo $crumbs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
</div>
|
||
<h1 class="article-title">
|
||
<?php
|
||
$episodes = is_array($ctx['video_episodes'] ?? null) ? $ctx['video_episodes'] : [];
|
||
if ($episodes === []) {
|
||
$episodes = [['url' => (string) $ctx['cover_url'], 'title' => '']];
|
||
}
|
||
$ep_count = count($episodes);
|
||
if ($ep_count > 1) : ?>
|
||
<span class="badg badg-sm b-theme mr6"><i class="fa fas fa-play-circle mr3" aria-hidden="true"></i><?php printf(esc_html__('共%d集', 'aksrt'), $ep_count); ?></span>
|
||
<?php else : ?>
|
||
<i class="fa fas fa-play-circle mr6 opacity8" aria-hidden="true"></i>
|
||
<?php endif; ?>
|
||
<?php echo $title_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
</h1>
|
||
<?php echo $badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
<div class="featured-video-episode mt10">
|
||
<?php foreach ($episodes as $idx => $ep) :
|
||
$ep_url = (string) ($ep['url'] ?? '');
|
||
if ($ep_url === '') { continue; }
|
||
$ep_title = trim((string) ($ep['title'] ?? ''));
|
||
if ($ep_title === '') {
|
||
$ep_title = sprintf(__('第%d集', 'aksrt'), $idx + 1);
|
||
}
|
||
?>
|
||
<a href="javascript:;" class="switch-video text-ellipsis<?php echo $idx === 0 ? ' active' : ''; ?>" data-index="<?php echo (int) ($idx + 1); ?>" data-src="<?php echo esc_url($ep_url); ?>">
|
||
<span class="mr6 badg badg-sm"><?php echo (int) ($idx + 1); ?></span><i class="episode-active-icon"></i><?php echo esc_html($ep_title); ?>
|
||
</a>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php
|
||
return;
|
||
endif;
|
||
|
||
if ($type === 'slide' && !empty($slides)) :
|
||
$slide_items = [];
|
||
foreach ($slides as $slide_url) {
|
||
$slide_items[] = [
|
||
'image' => (string) $slide_url,
|
||
'alt' => wp_strip_all_tags(get_the_title()),
|
||
];
|
||
}
|
||
$overlay = '<div class="abs-center left-bottom single-cover-con">'
|
||
. '<h1 class="article-title title-h-left">' . $title_html . '</h1>'
|
||
. ($crumbs !== '' ? $crumbs : '')
|
||
. $badge
|
||
. '</div>';
|
||
// 幻灯片配置(参考主题 CFS_Module::slide 全字段,经 get_post_page_settings 归一化)。
|
||
$slide_option = is_array($ctx['settings']['article_slide_cover_option'] ?? null)
|
||
? $ctx['settings']['article_slide_cover_option']
|
||
: [];
|
||
$single_slide = count($slide_items) === 1;
|
||
$slider_args = [
|
||
'slides' => $slide_items,
|
||
'effect' => (string) ($slide_option['effect'] ?? 'slide'),
|
||
'direction' => (string) ($slide_option['direction'] ?? 'horizontal'),
|
||
'spaceBetween' => (int) ($slide_option['spacebetween'] ?? 15),
|
||
'speed' => (int) ($slide_option['speed'] ?? 0),
|
||
'loop' => !$single_slide && !empty($slide_option['loop']),
|
||
'autoplay' => !$single_slide && !empty($slide_option['autoplay']),
|
||
'interval' => max(1, (int) ($slide_option['interval'] ?? 4)) * 1000,
|
||
'show_nav' => !empty($slide_option['button']),
|
||
'show_pagination' => !empty($slide_option['pagination']),
|
||
'wrapper_class' => 'mb20 single-cover-slide imgbox-container',
|
||
'slider_class' => 'single-cover single-cover--slide',
|
||
'overlay_html' => $overlay,
|
||
];
|
||
if (!empty($slide_option['scale_height'])) {
|
||
// 固定高度模式:PC/移动端分别取 px 高度。
|
||
$slider_args['scale_height'] = false;
|
||
$slider_args['pc_height'] = ((int) ($slide_option['pc_height'] ?? 380)) . 'px';
|
||
$slider_args['m_height'] = ((int) ($slide_option['m_height'] ?? 180)) . 'px';
|
||
} else {
|
||
// 比例高度模式:scale% + 50px(标题预留,与单图封面同公式)。
|
||
$slider_args['scale_height'] = true;
|
||
$slider_args['scale_ratio'] = max(10, (int) ($slide_option['scale'] ?? 35)) / 100;
|
||
$slider_args['scale_extra'] = '50px';
|
||
}
|
||
$slider_html = aksrt_render_slider($slider_args);
|
||
?>
|
||
<div class="single-head-cover">
|
||
<?php echo $slider_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
</div>
|
||
<?php
|
||
return;
|
||
endif;
|
||
|
||
// Image cover (default).
|
||
$img_attrs = aksrt_get_lazy_attr('lazy_cover', (string) $ctx['cover_url'], 'fit-cover', aksrt_get_lazy_thumb('lg'));
|
||
?>
|
||
<div class="single-head-cover">
|
||
<div class="graphic mb20 single-cover imgbox-container" style="padding-bottom:calc(<?php echo esc_attr((string) $img_scale); ?>% + 50px);">
|
||
<img<?php echo $img_attrs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="<?php echo esc_attr(wp_strip_all_tags(get_the_title())); ?>">
|
||
<div class="abs-center left-bottom single-cover-con">
|
||
<h1 class="article-title title-h-left"><?php echo $title_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></h1>
|
||
<?php if ($crumbs !== '') : ?>
|
||
<?php echo $crumbs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
<?php endif; ?>
|
||
<?php echo $badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php
|
||
}
|
||
endif;
|
||
|
||
if (!function_exists('aksrt_single_render_box_header')) :
|
||
/**
|
||
* Title + author bar and the canonical article meta row.
|
||
*
|
||
* @param array<string,mixed> $ctx Single context.
|
||
*/
|
||
function aksrt_single_render_box_header(array $ctx): void {
|
||
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
|
||
?>
|
||
<div class="article-header theme-box clearfix relative">
|
||
<?php if (empty($ctx['show_cover'])) : ?>
|
||
<?php echo (string) $ctx['status_badge']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
<h1 class="article-title"><a href="<?php the_permalink(); ?>"><?php echo (string) ($ctx['title_html'] ?? esc_html(get_the_title())); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></a></h1>
|
||
<?php endif; ?>
|
||
|
||
<?php
|
||
get_template_part('templates/parts/single-author-bar', null, [
|
||
'show_time' => empty($settings['hide_time']),
|
||
'meta_html' => (string) ($ctx['meta_box_html'] ?? ''),
|
||
]);
|
||
?>
|
||
</div>
|
||
<?php
|
||
}
|
||
endif;
|
||
|
||
if (!function_exists('aksrt_single_render_actions')) :
|
||
/**
|
||
* Like / reward / share / favorite row.
|
||
*
|
||
* @param array<string,mixed> $ctx Single context.
|
||
*/
|
||
function aksrt_single_render_actions(array $ctx): void {
|
||
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
|
||
$post_id = (int) $ctx['post_id'];
|
||
$like_count = (int) $ctx['like_count'];
|
||
$favorite_count = (int) $ctx['favorite_count'];
|
||
$is_liked = !empty($ctx['is_liked']);
|
||
$is_favorited = !empty($ctx['is_favorited']);
|
||
?>
|
||
<div class="text-center muted-3-color box-body em09"><?php echo esc_html($settings['button_toptext'] ?? __('喜欢就支持一下吧', 'aksrt')); ?></div>
|
||
<div class="post-actions-wrap relative">
|
||
<div class="text-center post-actions">
|
||
<?php
|
||
$like_icon = function_exists('aksrt_icon_markup') ? aksrt_icon_markup('zibsvg-like') : '';
|
||
if (!empty($settings['like_enabled'])) : ?>
|
||
<button type="button" class="action action-like<?php echo $is_liked ? ' actived' : ''; ?>" id="action-like" data-post-id="<?php echo esc_attr((string) $post_id); ?>" data-initial-active="<?php echo $is_liked ? '1' : '0'; ?>">
|
||
<?php echo $like_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fixed sprite markup. ?>
|
||
<text><?php esc_html_e('点赞', 'aksrt'); ?></text><count data-stat-count="likes" data-base-count="<?php echo esc_attr((string) $like_count); ?>"><?php echo esc_html((string) $like_count); ?></count>
|
||
</button>
|
||
<?php endif; ?>
|
||
|
||
<?php
|
||
$reward_author = (int) get_the_author_meta('ID');
|
||
$reward_btn = ($reward_author > 0 && !empty($settings['rewards_enabled']) && function_exists('aksrt_get_rewards_button'))
|
||
? aksrt_get_rewards_button($reward_author, 'action action-rewards', $post_id)
|
||
: '';
|
||
if ($reward_btn !== '') {
|
||
echo $reward_btn; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||
aksrt_render_rewards_modal_for_user($reward_author, $post_id);
|
||
}
|
||
?>
|
||
|
||
<?php if (!empty($settings['share_enabled']) && function_exists('aksrt_get_post_share_btn')) : ?>
|
||
<?php echo aksrt_get_post_share_btn($post_id, 'action action-share'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
<?php endif; ?>
|
||
|
||
<?php
|
||
$favorite_icon = function_exists('aksrt_icon_markup') ? aksrt_icon_markup('zibsvg-favorite') : '';
|
||
if (!empty($settings['favorite_enabled'])) : ?>
|
||
<button type="button" class="action action-favorite<?php echo $is_favorited ? ' actived' : ''; ?>" id="action-favorite" data-post-id="<?php echo esc_attr((string) $post_id); ?>" data-initial-active="<?php echo $is_favorited ? '1' : '0'; ?>">
|
||
<?php echo $favorite_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fixed sprite markup. ?>
|
||
<text><?php esc_html_e('收藏', 'aksrt'); ?></text><count data-stat-count="favorites" data-base-count="<?php echo esc_attr((string) $favorite_count); ?>"><?php echo esc_html((string) $favorite_count); ?></count>
|
||
</button>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<?php
|
||
}
|
||
endif;
|
||
|
||
if (!function_exists('aksrt_single_render_content_footer')) :
|
||
/**
|
||
* Copyright + THE END + tags.
|
||
*
|
||
* @param array<string,mixed> $ctx Single context.
|
||
*/
|
||
function aksrt_single_render_content_footer(array $ctx): void {
|
||
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
|
||
$post_id = (int) $ctx['post_id'];
|
||
?>
|
||
<?php if (!empty($settings['yiyan_footer'])) : ?>
|
||
<?php
|
||
aksrt_render_yiyan_block([
|
||
'class' => 'article-yiyan yiyan-box aksrt-yiyan yiyan--footer',
|
||
]);
|
||
?>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($settings['copyright_enabled'])) : ?>
|
||
<div class="em09 muted-3-color">
|
||
<div><span>©</span> <?php esc_html_e('版权声明', 'aksrt'); ?></div>
|
||
<div class="posts-copyright"><?php echo esc_html((string) $ctx['copyright_text']); ?></div>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<div class="text-center theme-box muted-3-color box-body separator em09">THE END</div>
|
||
<?php
|
||
if (function_exists('aksrt_get_single_article_tags_html')) {
|
||
echo aksrt_get_single_article_tags_html($post_id); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||
}
|
||
?>
|
||
<?php
|
||
}
|
||
endif;
|
||
|
||
if (!function_exists('aksrt_single_render_author_card')) :
|
||
/**
|
||
* After-article author card (legacy zib_get_user_card_box parity:
|
||
* show_button=false / show_img_bg=false / class="author").
|
||
*
|
||
* @param array<string,mixed> $ctx Single context.
|
||
*/
|
||
function aksrt_single_render_author_card(array $ctx): void {
|
||
$author_id = (int) get_the_author_meta('ID');
|
||
if ($author_id <= 0) {
|
||
return;
|
||
}
|
||
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
|
||
|
||
$avatar_box = aksrt_get_avatar_box($author_id, 'avatar-img avatar-lg');
|
||
$name_html = aksrt_get_user_name([
|
||
'id' => $author_id,
|
||
'class' => 'flex1 flex ac',
|
||
'vip' => false,
|
||
'medal' => true,
|
||
'auth' => true,
|
||
'level' => true,
|
||
'follow' => true,
|
||
]);
|
||
$badges = aksrt_get_user_badges($author_id);
|
||
$desc = aksrt_get_user_description($author_id);
|
||
$card_style = sanitize_key((string) ($settings['author_card_style'] ?? 'card')) === 'card' ? 'card' : 'mini';
|
||
$posts_html = aksrt_render_user_card_posts([
|
||
'user_id' => $author_id,
|
||
'limit' => max(0, min(12, (int) ($settings['author_card_limit'] ?? 6))),
|
||
'orderby' => sanitize_key((string) ($settings['author_card_orderby'] ?? 'views')),
|
||
'post_type' => 'post',
|
||
'post_style' => $card_style,
|
||
'exclude' => (int) get_the_ID(),
|
||
]);
|
||
?>
|
||
<div class="user-card zib-widget author">
|
||
<div class="card-content mt10 relative">
|
||
<div class="user-content">
|
||
<div class="user-avatar"><?php echo $avatar_box; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
|
||
<div class="user-info mt20 mb10">
|
||
<div class="user-name flex jc"><?php echo $name_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
|
||
<div class="author-tag mt10 mini-scrollbar"><?php echo $badges; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
|
||
<div class="user-desc mt10 muted-2-color em09"><?php echo esc_html($desc); ?></div>
|
||
</div>
|
||
</div>
|
||
<?php echo $posts_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||
</div>
|
||
</div>
|
||
<?php
|
||
}
|
||
|
||
endif;
|
||
|
||
if (!function_exists('aksrt_single_render_prevnext')) :
|
||
/**
|
||
* Previous / next navigation (legacy .article-nav).
|
||
*
|
||
* @param array<string,mixed> $ctx Single context.
|
||
*/
|
||
function aksrt_single_render_prevnext(array $ctx = []): void {
|
||
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
|
||
$enabled = array_key_exists('prevnext', $settings)
|
||
? !empty($settings['prevnext'])
|
||
: (!array_key_exists('prevnext_s', $settings) || !empty($settings['prevnext_s']));
|
||
if (!$enabled) {
|
||
return;
|
||
}
|
||
|
||
// legacy: constrain to current category when available.
|
||
$in_same_term = !empty(get_the_category());
|
||
$prev = get_previous_post($in_same_term, '', 'category');
|
||
$next = get_next_post($in_same_term, '', 'category');
|
||
if (!$prev && !$next) {
|
||
// Fallback: any post.
|
||
$prev = get_previous_post();
|
||
$next = get_next_post();
|
||
}
|
||
if (!$prev && !$next) {
|
||
return;
|
||
}
|
||
|
||
$prev_title = $prev ? get_the_title($prev) : __('无更多文章', 'aksrt');
|
||
$next_title = $next ? get_the_title($next) : __('无更多文章', 'aksrt');
|
||
$prev_href = $prev ? get_permalink($prev) : 'javascript:;';
|
||
$next_href = $next ? get_permalink($next) : 'javascript:;';
|
||
?>
|
||
<div class="theme-box" style="height:99px">
|
||
<nav class="article-nav">
|
||
<div class="main-bg box-body radius8 main-shadow">
|
||
<a href="<?php echo $prev ? esc_url($prev_href) : 'javascript:;'; ?>">
|
||
<p class="muted-2-color"><i class="fa fas fa-angle-left em12" aria-hidden="true"></i><i class="fa fas fa-angle-left em12 mr6" aria-hidden="true"></i><?php esc_html_e('上一篇', 'aksrt'); ?></p>
|
||
<div class="text-ellipsis-2"><?php echo esc_html($prev_title); ?></div>
|
||
</a>
|
||
</div>
|
||
<div class="main-bg box-body radius8 main-shadow">
|
||
<a href="<?php echo $next ? esc_url($next_href) : 'javascript:;'; ?>">
|
||
<p class="muted-2-color"><?php esc_html_e('下一篇', 'aksrt'); ?><i class="fa fas fa-angle-right em12 ml6" aria-hidden="true"></i><i class="fa fas fa-angle-right em12" aria-hidden="true"></i></p>
|
||
<div class="text-ellipsis-2"><?php echo esc_html($next_title); ?></div>
|
||
</a>
|
||
</div>
|
||
</nav>
|
||
</div>
|
||
<?php
|
||
}
|
||
endif;
|
||
|
||
if (!function_exists('aksrt_single_related_query_args')) :
|
||
/**
|
||
* Build related-posts WP_Query args (legacy zib_posts_related parity:
|
||
* category/topics/tag OR-terms, no current-post exclusion, meta orderby).
|
||
*
|
||
* @param int $post_id Post ID.
|
||
* @param array<string,mixed> $settings Single display settings.
|
||
* @return array<string,mixed>
|
||
*/
|
||
function aksrt_single_related_query_args(int $post_id, array $settings): array {
|
||
$count = max(1, min(12, (int) ($settings['related_count'] ?? 6)));
|
||
$orderby = sanitize_key((string) ($settings['related_orderby'] ?? 'views'));
|
||
if (!in_array($orderby, ['modified', 'date', 'views', 'like', 'comment_count', 'favorite', 'rand'], true)) {
|
||
$orderby = 'views';
|
||
}
|
||
|
||
$args = [
|
||
'showposts' => $count,
|
||
'ignore_sticky_posts' => true,
|
||
'post_type' => 'post',
|
||
'post_status' => 'publish',
|
||
'order' => 'DESC',
|
||
'no_found_rows' => true,
|
||
];
|
||
|
||
// legacy: all three term clauses are always present (even when empty).
|
||
$tax_query = ['relation' => 'OR'];
|
||
foreach (['category', 'topics', 'post_tag'] as $taxonomy) {
|
||
$term_ids = wp_get_post_terms($post_id, $taxonomy, ['fields' => 'ids']);
|
||
$tax_query[] = [
|
||
'taxonomy' => $taxonomy,
|
||
'field' => 'term_id',
|
||
'terms' => array_map('intval', (array) $term_ids),
|
||
];
|
||
}
|
||
$args['tax_query'] = $tax_query;
|
||
|
||
switch ($orderby) {
|
||
case 'rand':
|
||
$args['orderby'] = 'rand';
|
||
break;
|
||
case 'date':
|
||
$args['orderby'] = 'date';
|
||
break;
|
||
case 'modified':
|
||
$args['orderby'] = 'modified';
|
||
break;
|
||
case 'like':
|
||
$args['meta_key'] = '_aksrt_like_count';
|
||
$args['orderby'] = 'meta_value_num';
|
||
break;
|
||
case 'favorite':
|
||
$args['meta_key'] = '_aksrt_favorite_count';
|
||
$args['orderby'] = 'meta_value_num';
|
||
break;
|
||
case 'comment_count':
|
||
$args['orderby'] = 'comment_count';
|
||
break;
|
||
case 'views':
|
||
default:
|
||
$args['meta_key'] = 'aksrt_post_views';
|
||
$args['orderby'] = 'meta_value_num';
|
||
break;
|
||
}
|
||
|
||
return $args;
|
||
}
|
||
endif;
|
||
|
||
if (!function_exists('aksrt_single_render_related')) :
|
||
/**
|
||
* Related posts — legacy zib_posts_related parity (img/list/text).
|
||
*
|
||
* @param array<string,mixed> $ctx Single context.
|
||
*/
|
||
function aksrt_single_render_related(array $ctx): void {
|
||
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
|
||
if (empty($settings['related_enabled'])) {
|
||
return;
|
||
}
|
||
|
||
$post_id = (int) $ctx['post_id'];
|
||
$title = (string) ($settings['related_title'] ?? '');
|
||
if ($title === '') {
|
||
$title = __('相关推荐', 'aksrt');
|
||
}
|
||
$style = sanitize_key((string) ($settings['related_style'] ?? 'img'));
|
||
if (!in_array($style, ['img', 'list', 'text'], true)) {
|
||
$style = 'img';
|
||
}
|
||
|
||
$args = aksrt_single_related_query_args($post_id, $settings);
|
||
|
||
$query = new WP_Query($args);
|
||
$wrap_class = 'theme-box relates' . ($style === 'img' ? ' relates-thumb' : '');
|
||
$posts_html = '';
|
||
$mini_cfg = aksrt_renderer_config([
|
||
'type' => 'list',
|
||
'show_number' => false,
|
||
]);
|
||
while ($query->have_posts()) {
|
||
$query->the_post();
|
||
$post = get_post();
|
||
if (!($post instanceof WP_Post)) {
|
||
continue;
|
||
}
|
||
if ($style === 'list') {
|
||
$data = aksrt_renderer_collect_post_data($mini_cfg);
|
||
if ($data) {
|
||
$posts_html .= aksrt_renderer_mini($data, $mini_cfg);
|
||
}
|
||
} elseif ($style === 'img') {
|
||
$posts_html .= '<div class="swiper-slide mr10">' . aksrt_render_graphic_card_post($post) . '</div>';
|
||
} else {
|
||
$subtitle = class_exists('\AKSRT\Core\PostMetaBox')
|
||
? (string) \AKSRT\Core\PostMetaBox::get_meta_value($post->ID, 'subtitle', '')
|
||
: '';
|
||
$posts_html .= '<li><a class="icon-circle" href="' . esc_url(get_permalink($post)) . '">' . esc_html(get_the_title($post) . $subtitle) . '</a></li>';
|
||
}
|
||
}
|
||
wp_reset_postdata();
|
||
if ($posts_html === '') {
|
||
$posts_html = '<li>' . esc_html__('暂无相关文章', 'aksrt') . '</li>';
|
||
}
|
||
?>
|
||
<div class="<?php echo esc_attr($wrap_class); ?>">
|
||
<div class="box-body notop">
|
||
<div class="title-theme"><?php echo esc_html($title); ?></div>
|
||
</div>
|
||
<div class="zib-widget">
|
||
<?php if ($style === 'img') : ?>
|
||
<div class="swiper-container swiper-scroll">
|
||
<div class="swiper-wrapper"><?php echo $posts_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
|
||
<div class="swiper-button-prev"></div>
|
||
<div class="swiper-button-next"></div>
|
||
</div>
|
||
<?php else : ?>
|
||
<ul class="no-thumb"><?php echo $posts_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></ul>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
<?php
|
||
}
|
||
endif;
|
||
|
||
|
||
if (!function_exists('aksrt_single_render_pay_box')) :
|
||
/**
|
||
* Unified single pay module (legacy aksrtpay_posts_pay_content equivalent).
|
||
*
|
||
* @param array<string,mixed> $ctx Single context.
|
||
*/
|
||
function aksrt_single_render_pay_box(array $ctx = []): void {
|
||
if ($ctx === []) {
|
||
$ctx = function_exists('aksrt_single_build_context') ? aksrt_single_build_context() : [];
|
||
}
|
||
if (empty($ctx['show_pay_box'])) {
|
||
return;
|
||
}
|
||
$allow = $ctx['allow_view'] ?? null;
|
||
if (is_array($allow) && empty($allow['allow'])) {
|
||
return;
|
||
}
|
||
|
||
$post_id = (int) ($ctx['post_id'] ?? get_the_ID());
|
||
$post = get_post($post_id);
|
||
if (!($post instanceof WP_Post)) {
|
||
return;
|
||
}
|
||
|
||
$pay_type = (string) ($ctx['pay_type'] ?? 'no');
|
||
if (!function_exists('aksrt_get_pay_meta')) {
|
||
return;
|
||
}
|
||
|
||
$has_access = function_exists('aksrt_has_paid_access') ? aksrt_has_paid_access($post) : false;
|
||
if ($has_access) {
|
||
echo aksrt_get_paid_box_html($post); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||
} elseif ($pay_type !== 'reading') {
|
||
echo aksrt_get_paywall_html($post); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||
}
|
||
}
|
||
endif;
|
||
|
||
if (!function_exists('aksrt_single_pay_box_matches')) :
|
||
/**
|
||
* @param array<string,mixed> $ctx
|
||
*/
|
||
function aksrt_single_pay_box_matches(array $ctx, string $slot): bool {
|
||
if (empty($ctx['show_pay_box'])) {
|
||
return false;
|
||
}
|
||
$allow = $ctx['allow_view'] ?? null;
|
||
if (is_array($allow) && empty($allow['allow'])) {
|
||
return false;
|
||
}
|
||
return (string) ($ctx['paid_box_position'] ?? 'top') === $slot;
|
||
}
|
||
endif;
|
||
|
||
if (!function_exists('aksrt_single_render_article')) :
|
||
/**
|
||
* Main article box (legacy order).
|
||
*
|
||
* @param array<string,mixed> $ctx Single context.
|
||
*/
|
||
function aksrt_single_render_article(array $ctx): void {
|
||
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
|
||
$maxheight = (int) $ctx['content_maxheight'];
|
||
// 文章目录树(参考主题 article_nav):全局开关 + 每篇文章「不显示目录树」覆盖。
|
||
$article_nav_on = !isset($settings['article_nav']) || !empty($settings['article_nav']);
|
||
if ($article_nav_on) {
|
||
$extension_meta = get_post_meta(get_the_ID(), \AKSRT\Core\DomainModel::POST_META_KEY, true);
|
||
if (is_array($extension_meta) && !empty($extension_meta['no_article-navs'])) {
|
||
$article_nav_on = false;
|
||
}
|
||
}
|
||
?>
|
||
<article <?php post_class('article main-bg theme-box box-body radius8 main-shadow'); ?>>
|
||
<?php aksrt_single_render_box_header($ctx); ?>
|
||
|
||
<div class="article-content<?php echo $article_nav_on ? '' : ' no-nav'; ?>">
|
||
<?php if (!empty($settings['yiyan_header'])) : ?>
|
||
<?php
|
||
aksrt_render_yiyan_block([
|
||
'class' => 'article-yiyan yiyan-box aksrt-yiyan yiyan--header theme-box text-center radius8 main-shadow',
|
||
]);
|
||
?>
|
||
<?php endif; ?>
|
||
|
||
<?php do_action('aksrt_single_content_before', get_post()); ?>
|
||
|
||
<?php if (function_exists('aksrt_single_pay_box_matches') && aksrt_single_pay_box_matches($ctx, 'top')) : ?>
|
||
<?php aksrt_single_render_pay_box($ctx); ?>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($ctx['front_content'] !== '') : ?>
|
||
<div class="post_front_content theme-box box-body"><?php echo wp_kses_post((string) $ctx['front_content']); ?></div>
|
||
<?php endif; ?>
|
||
|
||
<div class="theme-box wp-posts-content<?php echo $maxheight > 0 ? ' limit-height' : ''; ?><?php echo !empty($settings['p_indent']) ? ' p-indent' : ''; ?>"
|
||
<?php echo $article_nav_on ? 'data-nav="posts"' : ''; ?>
|
||
<?php echo $maxheight > 0 ? ' style="max-height:' . esc_attr((string) $maxheight) . 'px;"' : ''; ?>
|
||
data-maxheight="<?php echo esc_attr((string) ($maxheight > 0 ? max(0, $maxheight - 80) : 0)); ?>">
|
||
<?php the_content(); ?>
|
||
<?php
|
||
wp_link_pages([
|
||
'before' => '<p class="text-center post-nav-links radius8 padding-6">',
|
||
'after' => '</p>',
|
||
]);
|
||
?>
|
||
<?php if ($ctx['after_content'] !== '') : ?>
|
||
<?php echo wp_kses_post((string) $ctx['after_content']); ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php if (function_exists('aksrt_single_pay_box_matches') && aksrt_single_pay_box_matches($ctx, 'bottom')) : ?>
|
||
<?php aksrt_single_render_pay_box($ctx); ?>
|
||
<?php endif; ?>
|
||
|
||
<?php aksrt_single_render_content_footer($ctx); ?>
|
||
</div>
|
||
|
||
<?php aksrt_single_render_actions($ctx); ?>
|
||
</article>
|
||
<?php
|
||
}
|
||
endif;
|
||
|
||
if (!function_exists('aksrt_single_render_after_box')) :
|
||
/**
|
||
* After-article stack: yiyan box / author card / prevnext / related.
|
||
*
|
||
* @param array<string,mixed> $ctx Single context.
|
||
*/
|
||
function aksrt_single_render_after_box(array $ctx): void {
|
||
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
|
||
|
||
if (!empty($settings['yiyan_box'])) {
|
||
aksrt_render_yiyan_block([
|
||
'class' => 'yiyan-box main-bg theme-box text-center box-body radius8 main-shadow aksrt-yiyan',
|
||
]);
|
||
}
|
||
|
||
if (!empty($settings['authordesc'])) {
|
||
aksrt_single_render_author_card($ctx);
|
||
}
|
||
|
||
aksrt_single_render_prevnext($ctx);
|
||
aksrt_single_render_related($ctx);
|
||
}
|
||
endif;
|
||
|