feat: rewrite schema-driven widget system
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace AKSRT\WidgetSystem;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Shared list/card/mini markup and pagination payloads.
|
||||
*/
|
||||
final class PostRenderer {
|
||||
public static function payload(array $instance, string $slug, int $page = 1, string $segment = ''): array {
|
||||
$segment_config = $slug === 'tab_posts' ? PostQuery::segment($instance, $segment) : [];
|
||||
$query = PostQuery::build($instance, $page, $segment_config);
|
||||
$html = self::items($query, $instance, $slug, $page);
|
||||
$max_pages = max(1, (int) $query->max_num_pages);
|
||||
$total = (int) $query->found_posts;
|
||||
return [
|
||||
'html' => $html,
|
||||
'paginate_html' => self::pagination($instance, $page, $max_pages),
|
||||
'has_more' => $page < $max_pages,
|
||||
'page' => $page,
|
||||
'max_pages' => $max_pages,
|
||||
'total' => $total,
|
||||
];
|
||||
}
|
||||
|
||||
public static function items(\WP_Query $query, array $instance, string $slug, int $page = 1): string {
|
||||
if (!$query->have_posts()) {
|
||||
return RendererHelpers::empty_state(__('暂无文章', 'aksrt'));
|
||||
}
|
||||
$style = (string) ($instance['style'] ?? 'card');
|
||||
$mode = in_array($style, ['list', 'card', 'mini'], true) ? $style : 'card';
|
||||
$config = [
|
||||
'mode' => $mode,
|
||||
'context' => 'widget',
|
||||
'columns' => $mode === 'card' ? 3 : 1,
|
||||
'show_thumb' => $slug !== 'hot_posts' || !empty($instance['show_thumbnail']),
|
||||
'show_meta' => $mode !== 'mini',
|
||||
'show_excerpt' => $mode !== 'mini',
|
||||
'show_author' => false,
|
||||
'show_comments' => true,
|
||||
'show_likes' => true,
|
||||
'show_tags' => false,
|
||||
'show_badges' => true,
|
||||
'show_number' => $slug === 'hot_posts',
|
||||
'number_offset' => ($page - 1) * max(1, (int) ($instance['count'] ?? 8)),
|
||||
'wrapper_class' => 'aksrt-widget-posts aksrt-widget-posts--' . $slug,
|
||||
];
|
||||
if ($slug === 'oneline_posts') {
|
||||
return self::oneline($query, $config, !empty($instance['autoplay']));
|
||||
}
|
||||
if (function_exists('aksrt_render_post_list')) {
|
||||
return aksrt_render_post_list($query, $config, false);
|
||||
}
|
||||
|
||||
$html = '<div class="aksrt-widget-posts aksrt-widget-posts--fallback">';
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
$html .= '<article><a href="' . esc_url(get_permalink()) . '">' . get_the_post_thumbnail(get_the_ID(), 'medium') . '<strong>' . esc_html(get_the_title()) . '</strong></a></article>';
|
||||
}
|
||||
wp_reset_postdata();
|
||||
return $html . '</div>';
|
||||
}
|
||||
|
||||
private static function oneline(\WP_Query $query, array $config, bool $autoplay): string {
|
||||
$slides = '';
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
$item = function_exists('aksrt_render_post')
|
||||
? aksrt_render_post(array_merge($config, ['skip_wrapper' => true]))
|
||||
: '<a href="' . esc_url(get_permalink()) . '">' . esc_html(get_the_title()) . '</a>';
|
||||
$slides .= '<div class="swiper-slide">' . $item . '</div>';
|
||||
}
|
||||
wp_reset_postdata();
|
||||
return '<div class="swiper aksrt-widget-swiper aksrt-widget-oneline" data-aksrt-swiper="scroll" data-autoplay="' . ($autoplay ? '1' : '0') . '"><div class="swiper-wrapper">' . $slides . '</div><button class="swiper-button-prev" type="button" aria-label="' . esc_attr__('上一组', 'aksrt') . '"></button><button class="swiper-button-next" type="button" aria-label="' . esc_attr__('下一组', 'aksrt') . '"></button></div>';
|
||||
}
|
||||
|
||||
private static function pagination(array $instance, int $page, int $max_pages): string {
|
||||
$mode = (string) ($instance['paginate'] ?? 'none');
|
||||
if ($max_pages <= 1 || $mode === 'none') {
|
||||
return '';
|
||||
}
|
||||
if ($mode === 'numbered') {
|
||||
$start = max(1, min($page - 2, $max_pages - 4));
|
||||
$end = min($max_pages, max(5, $page + 2));
|
||||
$html = '<nav class="aksrt-widget-pagination" aria-label="' . esc_attr__('文章分页', 'aksrt') . '">';
|
||||
for ($number = $start; $number <= $end; $number++) {
|
||||
$html .= '<button type="button" data-widget-page="' . $number . '"' . ($number === $page ? ' aria-current="page"' : '') . '>' . $number . '</button>';
|
||||
}
|
||||
return $html . '</nav>';
|
||||
}
|
||||
$label = $mode === 'infinite' ? __('继续加载', 'aksrt') : __('加载更多', 'aksrt');
|
||||
return '<button class="aksrt-widget-load-more" type="button" data-next-page="' . (int) ($page + 1) . '" data-mode="' . esc_attr($mode) . '">' . esc_html($label) . '</button>';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user