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:
1 parent
ea3c987695
commit
322060bd15
2 files changed
+90
-40
No files matched your search
@@ -70,48 +70,83 @@ class HotPostsWidget extends \WP_Widget {
|
|||||||
if (!$query->have_posts()) {
|
if (!$query->have_posts()) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
$show_thumb = !empty($instance['show_thumb']);
|
$show_thumb = !isset($instance['show_thumb']) || !empty($instance['show_thumb']);
|
||||||
$order_by = sanitize_key((string) ($instance['order_by'] ?? 'views'));
|
$order_by = sanitize_key((string) ($instance['order_by'] ?? 'views'));
|
||||||
$placeholder = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
$placeholder = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
||||||
|
$top_tones = ['jb-red', 'jb-yellow', 'b-gray'];
|
||||||
ob_start();
|
ob_start();
|
||||||
$index = $start;
|
$index = $start;
|
||||||
while ($query->have_posts()) {
|
while ($query->have_posts()) {
|
||||||
$query->the_post();
|
$query->the_post();
|
||||||
$index++;
|
$index++;
|
||||||
$rank_class = $index <= 3 ? ' rank-top' : '';
|
$pid = (int) get_the_ID();
|
||||||
$pid = get_the_ID();
|
if ($order_by === 'comments') {
|
||||||
if ($order_by === 'comments') {
|
$metric = (int) get_comments_number($pid);
|
||||||
$metric = (int) get_comments_number($pid);
|
$metric_icon = 'fa-comment-o';
|
||||||
$metric_icon = 'fa-comment-o';
|
$metric_label = __('条评论', 'aksrt');
|
||||||
} elseif ($order_by === 'likes') {
|
} 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 = 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_icon = 'fa-heart';
|
||||||
} elseif ($order_by === 'favorites') {
|
$metric_label = __('人点赞', 'aksrt');
|
||||||
$metric = (int) get_post_meta($pid, '_aksrt_favorite_count', true);
|
} elseif ($order_by === 'favorites') {
|
||||||
$metric_icon = 'fa-star';
|
$metric = (int) get_post_meta($pid, '_aksrt_favorite_count', true);
|
||||||
} elseif ($order_by === 'downloads') {
|
$metric_icon = 'fa-star';
|
||||||
$metric = (int) get_post_meta($pid, '_aksrt_res_download_count', true);
|
$metric_label = __('人收藏', 'aksrt');
|
||||||
$metric_icon = 'fa-download';
|
} elseif ($order_by === 'downloads') {
|
||||||
} else {
|
$metric = (int) get_post_meta($pid, '_aksrt_res_download_count', true);
|
||||||
$metric = (int) get_post_meta($pid, 'aksrt_post_views', true);
|
$metric_icon = 'fa-download';
|
||||||
$metric_icon = 'fa-eye';
|
$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); ?>">
|
<div class="hot-post-item flex mt15 relative hover-zoom-img ajax-item <?php echo esc_attr($rank_class); ?>">
|
||||||
<span class="hot-post-item__rank"><?php echo esc_html((string) $index); ?></span>
|
<?php echo $top_badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
<?php if ($show_thumb) :
|
<?php if ($show_thumb) : ?>
|
||||||
$thumb = get_the_post_thumbnail_url($pid, 'thumbnail');
|
<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 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; ?>
|
|
||||||
</a>
|
</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<div class="hot-post-item__info">
|
<div class="hot-post-item__info term-title ml10 flex xx flex1 jsb">
|
||||||
<a href="<?php the_permalink(); ?>" class="hot-post-item__title"><?php the_title(); ?></a>
|
<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="hot-post-item__meta">
|
<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><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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -121,16 +156,14 @@ class HotPostsWidget extends \WP_Widget {
|
|||||||
return (string) ob_get_clean();
|
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 {
|
public static function query_payload(array $instance, int $page = 1): array {
|
||||||
$page = max(1, $page);
|
$page = max(1, $page);
|
||||||
$count = max(1, min(20, (int) ($instance['count'] ?? 5)));
|
$count = max(1, min(20, (int) ($instance['count'] ?? 5)));
|
||||||
$paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
$paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
||||||
$q = new \WP_Query(self::build_query_args($instance, $page));
|
$q = new \WP_Query(self::build_query_args($instance, $page));
|
||||||
$items = self::render_items_html($q, $instance, ($page - 1) * $count);
|
$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) {
|
if ($html === '' && $page === 1) {
|
||||||
$html = function_exists('aksrt_get_widget_null')
|
$html = function_exists('aksrt_get_widget_null')
|
||||||
? aksrt_get_widget_null(__('暂无热门文章', 'aksrt'))
|
? aksrt_get_widget_null(__('暂无热门文章', 'aksrt'))
|
||||||
|
|||||||
@@ -61,6 +61,14 @@ class WidgetPaidPosts extends \WP_Widget {
|
|||||||
} else {
|
} else {
|
||||||
$query['orderby'] = 'date';
|
$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;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,9 +165,6 @@ class WidgetPaidPosts extends \WP_Widget {
|
|||||||
$paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
$paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
|
||||||
$instance['paginate'] = $paginate;
|
$instance['paginate'] = $paginate;
|
||||||
$payload = self::query_payload($instance, 1);
|
$payload = self::query_payload($instance, 1);
|
||||||
if ($payload['html'] === '' && empty($payload['total'])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
$title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base);
|
$title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base);
|
||||||
@@ -206,6 +211,16 @@ class WidgetPaidPosts extends \WP_Widget {
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</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
|
<?php
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +232,9 @@ class WidgetPaidPosts extends \WP_Widget {
|
|||||||
return [
|
return [
|
||||||
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
||||||
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 6))),
|
'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',
|
'paginate' => sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) === 'none' ? 'none' : 'ajax',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user