feat(widgets): hot posts graphic TOP1 + paid list filters
Mirror zibll hot posts hero/TOP badges; PaidPosts gains cat/limit_day and always renders empty state instead of silent return.
This commit is contained in:
@@ -70,48 +70,83 @@ class HotPostsWidget extends \WP_Widget {
|
||||
if (!$query->have_posts()) {
|
||||
return '';
|
||||
}
|
||||
$show_thumb = !empty($instance['show_thumb']);
|
||||
$order_by = sanitize_key((string) ($instance['order_by'] ?? 'views'));
|
||||
$placeholder = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
||||
$show_thumb = !isset($instance['show_thumb']) || !empty($instance['show_thumb']);
|
||||
$order_by = sanitize_key((string) ($instance['order_by'] ?? 'views'));
|
||||
$placeholder = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
||||
$top_tones = ['jb-red', 'jb-yellow', 'b-gray'];
|
||||
ob_start();
|
||||
$index = $start;
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
$index++;
|
||||
$rank_class = $index <= 3 ? ' rank-top' : '';
|
||||
$pid = get_the_ID();
|
||||
if ($order_by === 'comments') {
|
||||
$metric = (int) get_comments_number($pid);
|
||||
$metric_icon = 'fa-comment-o';
|
||||
} elseif ($order_by === 'likes') {
|
||||
$metric = function_exists('aksrt_get_post_likes') ? (int) aksrt_get_post_likes($pid) : (int) get_post_meta($pid, '_aksrt_like_count', true);
|
||||
$metric_icon = 'fa-heart';
|
||||
} elseif ($order_by === 'favorites') {
|
||||
$metric = (int) get_post_meta($pid, '_aksrt_favorite_count', true);
|
||||
$metric_icon = 'fa-star';
|
||||
} elseif ($order_by === 'downloads') {
|
||||
$metric = (int) get_post_meta($pid, '_aksrt_res_download_count', true);
|
||||
$metric_icon = 'fa-download';
|
||||
} else {
|
||||
$metric = (int) get_post_meta($pid, 'aksrt_post_views', true);
|
||||
$metric_icon = 'fa-eye';
|
||||
$pid = (int) get_the_ID();
|
||||
if ($order_by === 'comments') {
|
||||
$metric = (int) get_comments_number($pid);
|
||||
$metric_icon = 'fa-comment-o';
|
||||
$metric_label = __('条评论', 'aksrt');
|
||||
} elseif ($order_by === 'likes') {
|
||||
$metric = function_exists('aksrt_get_post_likes') ? (int) aksrt_get_post_likes($pid) : (int) get_post_meta($pid, '_aksrt_like_count', true);
|
||||
$metric_icon = 'fa-heart';
|
||||
$metric_label = __('人点赞', 'aksrt');
|
||||
} elseif ($order_by === 'favorites') {
|
||||
$metric = (int) get_post_meta($pid, '_aksrt_favorite_count', true);
|
||||
$metric_icon = 'fa-star';
|
||||
$metric_label = __('人收藏', 'aksrt');
|
||||
} elseif ($order_by === 'downloads') {
|
||||
$metric = (int) get_post_meta($pid, '_aksrt_res_download_count', true);
|
||||
$metric_icon = 'fa-download';
|
||||
$metric_label = __('次下载', 'aksrt');
|
||||
} else {
|
||||
$metric = (int) get_post_meta($pid, 'aksrt_post_views', true);
|
||||
$metric_icon = 'fa-eye';
|
||||
$metric_label = __('次阅读', 'aksrt');
|
||||
}
|
||||
$metric_txt = function_exists('aksrt_format_number') ? aksrt_format_number($metric) : (string) $metric;
|
||||
$tone = $top_tones[$index - 1] ?? 'b-gray';
|
||||
$top_badge = '<badge class="img-badge left hot ' . ($index === 1 ? 'em12 ' : '') . esc_attr($tone) . '"><i>TOP' . (int) $index . '</i></badge>';
|
||||
$permalink = get_permalink($pid);
|
||||
$title = get_the_title($pid);
|
||||
$time_ago = human_time_diff(get_the_time('U'), current_time('timestamp')) . __('前', 'aksrt');
|
||||
|
||||
// Graphic hero for #1 (zibll zib_hot_posts).
|
||||
if ($index === 1 && $start === 0) {
|
||||
$thumb = get_the_post_thumbnail_url($pid, 'large');
|
||||
if (!$thumb) {
|
||||
$thumb = get_the_post_thumbnail_url($pid, 'medium');
|
||||
}
|
||||
$metric_txt = function_exists('aksrt_format_number') ? aksrt_format_number($metric) : (string) $metric;
|
||||
echo '<div class="hot-posts-graphic relative ajax-item is-top1">';
|
||||
echo '<a href="' . esc_url($permalink) . '">';
|
||||
echo '<div class="graphic hover-zoom-img" style="padding-bottom:60%;">';
|
||||
if ($thumb) {
|
||||
echo '<img class="fit-cover radius8 aksrt-lazy lazyload" data-src="' . esc_url($thumb) . '" src="' . esc_url($placeholder) . '" alt="" loading="lazy" />';
|
||||
} else {
|
||||
echo '<span class="hot-posts-graphic__empty"></span>';
|
||||
}
|
||||
echo '<div class="absolute linear-mask"></div>';
|
||||
echo '<div class="abs-center left-bottom box-body">';
|
||||
echo '<div class="mb6"><span class="badg b-theme badg-sm"><i class="fa ' . esc_attr($metric_icon) . '" aria-hidden="true"></i> ' . esc_html($metric_txt . $metric_label) . '</span></div>';
|
||||
echo '<div class="hot-posts-graphic__title">' . esc_html(wp_html_excerpt($title, 48, '…')) . '</div>';
|
||||
echo '</div></div></a>';
|
||||
echo $top_badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '</div>';
|
||||
continue;
|
||||
}
|
||||
|
||||
$rank_class = $index <= 3 ? ' rank-top' : '';
|
||||
$thumb = $show_thumb ? get_the_post_thumbnail_url($pid, 'thumbnail') : '';
|
||||
?>
|
||||
<div class="hot-post-item ajax-item <?php echo esc_attr($rank_class); ?>">
|
||||
<span class="hot-post-item__rank"><?php echo esc_html((string) $index); ?></span>
|
||||
<?php if ($show_thumb) :
|
||||
$thumb = get_the_post_thumbnail_url($pid, 'thumbnail');
|
||||
?>
|
||||
<a class="hot-post-item__thumb<?php echo $thumb ? '' : ' is-empty'; ?>" href="<?php the_permalink(); ?>">
|
||||
<?php if ($thumb) : ?><img class="aksrt-lazy lazyload" data-src="<?php echo esc_url($thumb); ?>" src="<?php echo esc_url($placeholder); ?>" alt="" loading="lazy" /><?php endif; ?>
|
||||
<div class="hot-post-item flex mt15 relative hover-zoom-img ajax-item <?php echo esc_attr($rank_class); ?>">
|
||||
<?php echo $top_badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php if ($show_thumb) : ?>
|
||||
<a class="hot-post-item__thumb graphic<?php echo $thumb ? '' : ' is-empty'; ?>" href="<?php echo esc_url($permalink); ?>">
|
||||
<?php if ($thumb) : ?><img class="fit-cover radius8 aksrt-lazy lazyload" data-src="<?php echo esc_url($thumb); ?>" src="<?php echo esc_url($placeholder); ?>" alt="" loading="lazy" /><?php endif; ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<div class="hot-post-item__info">
|
||||
<a href="<?php the_permalink(); ?>" class="hot-post-item__title"><?php the_title(); ?></a>
|
||||
<div class="hot-post-item__meta">
|
||||
<div class="hot-post-item__info term-title ml10 flex xx flex1 jsb">
|
||||
<div class="text-ellipsis-2"><a href="<?php echo esc_url($permalink); ?>" class="hot-post-item__title"><?php echo esc_html($title); ?></a></div>
|
||||
<div class="px12 muted-3-color text-ellipsis flex jsb hot-post-item__meta">
|
||||
<span class="hot-post-item__time"><i class="fa fa-clock-o mr3" aria-hidden="true"></i><?php echo esc_html($time_ago); ?></span>
|
||||
<span><i class="fa <?php echo esc_attr($metric_icon); ?>" aria-hidden="true"></i> <?php echo esc_html((string) $metric_txt); ?></span>
|
||||
<span class="hot-post-item__time"><?php echo esc_html(human_time_diff(get_the_time('U'), current_time('timestamp')) . __('前', 'aksrt')); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -121,16 +156,14 @@ class HotPostsWidget extends \WP_Widget {
|
||||
return (string) ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{html:string,paginate_html:string,has_more:bool,page:int,max_pages:int,total:int}
|
||||
*/
|
||||
|
||||
public static function query_payload(array $instance, int $page = 1): array {
|
||||
$page = max(1, $page);
|
||||
$count = max(1, min(20, (int) ($instance['count'] ?? 5)));
|
||||
$paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
||||
$q = new \WP_Query(self::build_query_args($instance, $page));
|
||||
$items = self::render_items_html($q, $instance, ($page - 1) * $count);
|
||||
$html = $items !== '' ? '<div class="widget-hot-posts widget-hot-posts--mini">' . $items . '</div>' : '';
|
||||
$html = $items !== '' ? '<div class="widget-hot-posts widget-hot-posts--graphic zib-widget">' . $items . '</div>' : '';
|
||||
if ($html === '' && $page === 1) {
|
||||
$html = function_exists('aksrt_get_widget_null')
|
||||
? aksrt_get_widget_null(__('暂无热门文章', 'aksrt'))
|
||||
|
||||
@@ -61,6 +61,14 @@ class WidgetPaidPosts extends \WP_Widget {
|
||||
} else {
|
||||
$query['orderby'] = 'date';
|
||||
}
|
||||
$cat = max(0, (int) ($instance['cat'] ?? 0));
|
||||
if ($cat > 0) {
|
||||
$query['cat'] = $cat;
|
||||
}
|
||||
$limit_day = max(0, (int) ($instance['limit_day'] ?? 0));
|
||||
if ($limit_day > 0) {
|
||||
$query['date_query'] = [['after' => $limit_day . ' days ago']];
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
@@ -157,9 +165,6 @@ class WidgetPaidPosts extends \WP_Widget {
|
||||
$paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
||||
$instance['paginate'] = $paginate;
|
||||
$payload = self::query_payload($instance, 1);
|
||||
if ($payload['html'] === '' && empty($payload['total'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
$title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base);
|
||||
@@ -206,6 +211,16 @@ class WidgetPaidPosts extends \WP_Widget {
|
||||
</select>
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php esc_html_e('分类 ID(0=全部)', 'aksrt'); ?>
|
||||
<input class="tiny-text" type="number" min="0" name="<?php echo esc_attr($this->get_field_name('cat')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['cat'] ?? 0))); ?>">
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php esc_html_e('最近 N 天(0=不限)', 'aksrt'); ?>
|
||||
<input class="tiny-text" type="number" min="0" name="<?php echo esc_attr($this->get_field_name('limit_day')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['limit_day'] ?? 0))); ?>">
|
||||
</label>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
@@ -217,7 +232,9 @@ class WidgetPaidPosts extends \WP_Widget {
|
||||
return [
|
||||
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
||||
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 6))),
|
||||
'orderby' => $orderby,
|
||||
'orderby' => $orderby,
|
||||
'cat' => max(0, (int) ($new_instance['cat'] ?? 0)),
|
||||
'limit_day' => max(0, (int) ($new_instance['limit_day'] ?? 0)),
|
||||
'paginate' => sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) === 'none' ? 'none' : 'ajax',
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user