feat(widgets): categories tree/cover + hot metric meta + tag scale
Categories gain hierarchical children, optional thumb/desc; hot posts show orderby-aware metrics with lazy thumbs; tag cloud can scale size.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Categories list (zibll-like options depth).
|
||||
* Categories list (zibll widget categories depth).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -18,6 +18,7 @@ class CategoriesWidget extends \WP_Widget {
|
||||
[
|
||||
'description' => esc_html__('以列表形式展示文章分类', 'aksrt'),
|
||||
'customize_selective_refresh' => true,
|
||||
'classname' => 'widget_aksrt_categories',
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -37,6 +38,9 @@ class CategoriesWidget extends \WP_Widget {
|
||||
return array_values(array_unique($ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $instance
|
||||
*/
|
||||
public static function render_html(array $instance): string {
|
||||
$count = max(1, min(50, (int) ($instance['count'] ?? 8)));
|
||||
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'count'));
|
||||
@@ -48,12 +52,14 @@ class CategoriesWidget extends \WP_Widget {
|
||||
$hierarchical = !empty($instance['hierarchical']);
|
||||
$parent = max(0, (int) ($instance['parent'] ?? 0));
|
||||
$show_count = !isset($instance['show_count']) || !empty($instance['show_count']);
|
||||
$show_desc = !empty($instance['show_desc']);
|
||||
$show_thumb = !empty($instance['show_thumb']);
|
||||
$exclude = self::parse_ids_static((string) ($instance['exclude'] ?? ''));
|
||||
$include = self::parse_ids_static((string) ($instance['include'] ?? ''));
|
||||
|
||||
$term_args = [
|
||||
'taxonomy' => 'category',
|
||||
'number' => $count,
|
||||
'number' => $hierarchical ? 0 : $count,
|
||||
'orderby' => $orderby,
|
||||
'order' => $order,
|
||||
'hide_empty' => $hide_empty,
|
||||
@@ -61,6 +67,8 @@ class CategoriesWidget extends \WP_Widget {
|
||||
];
|
||||
if ($parent > 0) {
|
||||
$term_args['parent'] = $parent;
|
||||
} elseif ($hierarchical) {
|
||||
$term_args['parent'] = 0;
|
||||
}
|
||||
if ($include) {
|
||||
$term_args['include'] = $include;
|
||||
@@ -79,19 +87,88 @@ class CategoriesWidget extends \WP_Widget {
|
||||
}
|
||||
|
||||
ob_start();
|
||||
echo '<ul class="widget-list aksrt-cat-list ajax-item">';
|
||||
$cls = 'widget-list aksrt-cat-list ajax-item' . ($hierarchical ? ' is-tree' : '') . ($show_thumb ? ' has-thumb' : '');
|
||||
echo '<ul class="' . esc_attr($cls) . '">';
|
||||
$n = 0;
|
||||
foreach ($cats as $cat) {
|
||||
echo '<li>';
|
||||
echo '<a href="' . esc_url(get_category_link($cat->term_id)) . '">' . esc_html($cat->name) . '</a>';
|
||||
if ($show_count) {
|
||||
echo '<span class="count">' . (int) $cat->count . '</span>';
|
||||
if (!$hierarchical && $n >= $count) {
|
||||
break;
|
||||
}
|
||||
echo '</li>';
|
||||
echo self::render_cat_item($cat, $show_count, $show_desc, $show_thumb, $hierarchical ? 0 : -1, $count, $n, $hide_empty, $orderby, $order);
|
||||
$n++;
|
||||
}
|
||||
echo '</ul>';
|
||||
return (string) ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_Term $cat
|
||||
*/
|
||||
private static function render_cat_item($cat, bool $show_count, bool $show_desc, bool $show_thumb, int $depth, int $limit, int &$n, bool $hide_empty, string $orderby, string $order): string {
|
||||
if ($n > 0 && $limit > 0 && $n >= $limit && $depth >= 0) {
|
||||
return '';
|
||||
}
|
||||
$html = '<li class="aksrt-cat-list__item depth-' . max(0, $depth) . '">';
|
||||
$html .= '<a class="aksrt-cat-list__link" href="' . esc_url(get_category_link($cat->term_id)) . '">';
|
||||
if ($show_thumb) {
|
||||
$thumb = '';
|
||||
$img_id = (int) get_term_meta($cat->term_id, 'thumbnail_id', true);
|
||||
if (!$img_id) {
|
||||
$img_id = (int) get_term_meta($cat->term_id, '_aksrt_cover', true);
|
||||
}
|
||||
if ($img_id) {
|
||||
$thumb = (string) (wp_get_attachment_image_url($img_id, 'thumbnail') ?: '');
|
||||
}
|
||||
if ($thumb === '') {
|
||||
$thumb = (string) get_term_meta($cat->term_id, '_aksrt_cover_url', true);
|
||||
}
|
||||
if ($thumb !== '') {
|
||||
$ph = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
||||
$html .= '<span class="aksrt-cat-list__thumb"><img class="aksrt-lazy lazyload" data-src="' . esc_url($thumb) . '" src="' . esc_url($ph) . '" alt="" loading="lazy" width="32" height="32" /></span>';
|
||||
} else {
|
||||
$html .= '<span class="aksrt-cat-list__thumb is-empty"><i class="fa fa-folder-o" aria-hidden="true"></i></span>';
|
||||
}
|
||||
}
|
||||
$html .= '<span class="aksrt-cat-list__text">';
|
||||
$html .= '<span class="aksrt-cat-list__name">' . esc_html($cat->name) . '</span>';
|
||||
if ($show_desc && $cat->description !== '') {
|
||||
$desc = wp_trim_words(wp_strip_all_tags((string) $cat->description), 12, '…');
|
||||
$html .= '<span class="aksrt-cat-list__desc muted-2-color em09">' . esc_html($desc) . '</span>';
|
||||
}
|
||||
$html .= '</span>';
|
||||
if ($show_count) {
|
||||
$html .= '<span class="count">' . (int) $cat->count . '</span>';
|
||||
}
|
||||
$html .= '</a>';
|
||||
|
||||
if ($depth >= 0) {
|
||||
$children = get_categories([
|
||||
'taxonomy' => 'category',
|
||||
'parent' => (int) $cat->term_id,
|
||||
'hide_empty' => $hide_empty,
|
||||
'orderby' => $orderby,
|
||||
'order' => $order,
|
||||
]);
|
||||
if ($children) {
|
||||
$html .= '<ul class="aksrt-cat-list__children">';
|
||||
foreach ($children as $child) {
|
||||
$n++;
|
||||
if ($limit > 0 && $n > $limit) {
|
||||
break;
|
||||
}
|
||||
$html .= self::render_cat_item($child, $show_count, $show_desc, $show_thumb, $depth + 1, $limit, $n, $hide_empty, $orderby, $order);
|
||||
}
|
||||
$html .= '</ul>';
|
||||
}
|
||||
}
|
||||
$html .= '</li>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $args
|
||||
* @param array<string,mixed> $instance
|
||||
*/
|
||||
public function widget($args, $instance): void {
|
||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
|
||||
@@ -106,11 +183,9 @@ class CategoriesWidget extends \WP_Widget {
|
||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
/** @return array<int,int> */
|
||||
private function parse_ids(string $raw): array {
|
||||
return self::parse_ids_static($raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $instance
|
||||
*/
|
||||
public function form($instance): void {
|
||||
?>
|
||||
<p>
|
||||
@@ -154,12 +229,19 @@ class CategoriesWidget extends \WP_Widget {
|
||||
</p>
|
||||
<p>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_count')); ?>" value="1" <?php checked(!isset($instance['show_count']) || !empty($instance['show_count'])); ?>> <?php esc_html_e('显示数量', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_desc')); ?>" value="1" <?php checked(!empty($instance['show_desc'])); ?>> <?php esc_html_e('显示描述', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_thumb')); ?>" value="1" <?php checked(!empty($instance['show_thumb'])); ?>> <?php esc_html_e('显示封面', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hide_empty')); ?>" value="1" <?php checked(!isset($instance['hide_empty']) || !empty($instance['hide_empty'])); ?>> <?php esc_html_e('隐藏空分类', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hierarchical')); ?>" value="1" <?php checked(!empty($instance['hierarchical'])); ?>> <?php esc_html_e('层级', 'aksrt'); ?></label>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hierarchical')); ?>" value="1" <?php checked(!empty($instance['hierarchical'])); ?>> <?php esc_html_e('层级树', 'aksrt'); ?></label>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $new_instance
|
||||
* @param array<string,mixed> $old_instance
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function update($new_instance, $old_instance): array {
|
||||
$orderby = sanitize_key((string) ($new_instance['orderby'] ?? 'count'));
|
||||
if (!in_array($orderby, ['count', 'name', 'id', 'slug'], true)) {
|
||||
@@ -174,6 +256,8 @@ class CategoriesWidget extends \WP_Widget {
|
||||
'include' => sanitize_text_field((string) ($new_instance['include'] ?? '')),
|
||||
'exclude' => sanitize_text_field((string) ($new_instance['exclude'] ?? '')),
|
||||
'show_count' => !empty($new_instance['show_count']) ? 1 : 0,
|
||||
'show_desc' => !empty($new_instance['show_desc']) ? 1 : 0,
|
||||
'show_thumb' => !empty($new_instance['show_thumb']) ? 1 : 0,
|
||||
'hide_empty' => !empty($new_instance['hide_empty']) ? 1 : 0,
|
||||
'hierarchical' => !empty($new_instance['hierarchical']) ? 1 : 0,
|
||||
];
|
||||
|
||||
@@ -71,27 +71,46 @@ class HotPostsWidget extends \WP_Widget {
|
||||
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';
|
||||
ob_start();
|
||||
$index = $start;
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
$index++;
|
||||
$rank_class = $index <= 3 ? ' rank-top' : '';
|
||||
$views = (int) get_post_meta(get_the_ID(), 'aksrt_post_views', true);
|
||||
$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';
|
||||
}
|
||||
$metric_txt = function_exists('aksrt_format_number') ? aksrt_format_number($metric) : (string) $metric;
|
||||
?>
|
||||
<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(get_the_ID(), 'thumbnail');
|
||||
$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 src="<?php echo esc_url($thumb); ?>" alt="" loading="lazy" /><?php endif; ?>
|
||||
<?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>
|
||||
<?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">
|
||||
<span><i class="fas fa-eye" aria-hidden="true"></i> <?php echo esc_html(function_exists('aksrt_format_number') ? aksrt_format_number($views) : (string) $views); ?></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>
|
||||
|
||||
@@ -139,7 +139,8 @@ class TagCloudWidget extends \WP_Widget {
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_count')); ?>" value="1" <?php checked(!empty($instance['show_count'])); ?>> <?php esc_html_e('显示数量', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('blank')); ?>" value="1" <?php checked(!empty($instance['blank'])); ?>> <?php esc_html_e('新窗口', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('fixed_width')); ?>" value="1" <?php checked(!empty($instance['fixed_width'])); ?>> <?php esc_html_e('固定宽度', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hide_empty')); ?>" value="1" <?php checked(!empty($instance['hide_empty'])); ?>> <?php esc_html_e('隐藏空标签', 'aksrt'); ?></label>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hide_empty')); ?>" value="1" <?php checked(!empty($instance['hide_empty'])); ?>> <?php esc_html_e('隐藏空标签', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('scale')); ?>" value="1" <?php checked(!empty($instance['scale'])); ?>> <?php esc_html_e('按数量缩放字号', 'aksrt'); ?></label>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
@@ -155,6 +156,7 @@ class TagCloudWidget extends \WP_Widget {
|
||||
'blank' => !empty($new_instance['blank']) ? 1 : 0,
|
||||
'fixed_width' => !empty($new_instance['fixed_width']) ? 1 : 0,
|
||||
'hide_empty' => !empty($new_instance['hide_empty']) ? 1 : 0,
|
||||
'scale' => !empty($new_instance['scale']) ? 1 : 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user