feat(widgets): OnelinePosts via swiper-scroll + shared post renderer
Replace private track DOM with slider.js Type A shell and aksrt_render_post cards/mini/list slides, matching product oneline and zibll oneline posts.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Horizontal one-line posts scroller (zibll oneline + remote HTML).
|
||||
* Horizontal one-line posts scroller (zibll zib_widget_ui_oneline_posts).
|
||||
*
|
||||
* Uses shared post renderer + slider.js Type A (.swiper-scroll).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -16,18 +18,22 @@ class WidgetOnelinePosts extends \WP_Widget {
|
||||
'aksrt_oneline_posts',
|
||||
esc_html__('AKSRT 横向文章', 'aksrt'),
|
||||
[
|
||||
'description' => esc_html__('横向滚动的文章卡片/迷你列表。', 'aksrt'),
|
||||
'description' => esc_html__('横向滚动的文章卡片/迷你列表(共享 swiper-scroll)。', 'aksrt'),
|
||||
'classname' => 'widget_aksrt_oneline_posts',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $instance
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public static function build_query_args(array $instance): array {
|
||||
$count = max(1, min(20, (int) ($instance['count'] ?? 8)));
|
||||
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'date'));
|
||||
$cat = (int) ($instance['cat'] ?? 0);
|
||||
$count = max(1, min(20, (int) ($instance['count'] ?? 8)));
|
||||
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'date'));
|
||||
$cat = (int) ($instance['cat'] ?? 0);
|
||||
$limit_day = max(0, (int) ($instance['limit_day'] ?? 0));
|
||||
$query = [
|
||||
$query = [
|
||||
'post_type' => 'post',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => $count,
|
||||
@@ -43,28 +49,32 @@ class WidgetOnelinePosts extends \WP_Widget {
|
||||
switch ($orderby) {
|
||||
case 'views':
|
||||
$query['meta_key'] = 'aksrt_post_views';
|
||||
$query['orderby'] = 'meta_value_num';
|
||||
$query['order'] = 'DESC';
|
||||
$query['orderby'] = 'meta_value_num';
|
||||
$query['order'] = 'DESC';
|
||||
break;
|
||||
case 'comments':
|
||||
$query['orderby'] = 'comment_count';
|
||||
$query['order'] = 'DESC';
|
||||
$query['order'] = 'DESC';
|
||||
break;
|
||||
case 'rand':
|
||||
$query['orderby'] = 'rand';
|
||||
break;
|
||||
default:
|
||||
$query['orderby'] = 'date';
|
||||
$query['order'] = 'DESC';
|
||||
$query['order'] = 'DESC';
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $instance
|
||||
*/
|
||||
public static function render_html(array $instance): string {
|
||||
$style = sanitize_key((string) ($instance['style'] ?? 'card'));
|
||||
if (!in_array($style, ['card', 'mini', 'list'], true)) {
|
||||
$style = 'card';
|
||||
}
|
||||
|
||||
$q = new \WP_Query(self::build_query_args($instance));
|
||||
if (!$q->have_posts()) {
|
||||
wp_reset_postdata();
|
||||
@@ -72,29 +82,75 @@ class WidgetOnelinePosts extends \WP_Widget {
|
||||
? aksrt_get_ajax_null(__('暂无文章', 'aksrt'))
|
||||
: '<p class="widget-empty ajax-item">' . esc_html__('暂无文章', 'aksrt') . '</p>';
|
||||
}
|
||||
ob_start();
|
||||
echo '<div class="aksrt-oneline style-' . esc_attr($style) . ' ajax-item"><div class="aksrt-oneline__track">';
|
||||
while ($q->have_posts()) {
|
||||
$q->the_post();
|
||||
$thumb = get_the_post_thumbnail_url(get_the_ID(), $style === 'card' ? 'medium' : 'thumbnail');
|
||||
echo '<a class="aksrt-oneline__item" href="' . esc_url(get_permalink()) . '">';
|
||||
if ($thumb) {
|
||||
echo '<div class="aksrt-oneline__thumb"><img src="' . esc_url($thumb) . '" alt="" loading="lazy" /></div>';
|
||||
} else {
|
||||
echo '<div class="aksrt-oneline__thumb is-empty"></div>';
|
||||
|
||||
$mode = $style === 'mini' ? 'mini' : ($style === 'list' ? 'list' : 'card');
|
||||
$cfg = [
|
||||
'mode' => $mode,
|
||||
'context' => 'widget',
|
||||
'show_thumb' => true,
|
||||
'show_meta' => $style !== 'mini',
|
||||
'show_excerpt' => false,
|
||||
'show_author' => false,
|
||||
'show_comments' => false,
|
||||
'show_likes' => false,
|
||||
'show_tags' => false,
|
||||
'show_badges' => $style === 'card',
|
||||
'skip_wrapper' => true,
|
||||
'extra_class' => 'posts-item',
|
||||
];
|
||||
|
||||
$slides = '';
|
||||
if (function_exists('aksrt_render_post')) {
|
||||
while ($q->have_posts()) {
|
||||
$q->the_post();
|
||||
$item = aksrt_render_post($cfg);
|
||||
if ($item === '') {
|
||||
continue;
|
||||
}
|
||||
// Ensure freeMode width calc has a posts-item root when renderer wraps differently.
|
||||
if (strpos($item, 'posts-item') === false && strpos($item, 'posts-mini') === false) {
|
||||
$item = '<div class="posts-item">' . $item . '</div>';
|
||||
}
|
||||
$slides .= '<div class="swiper-slide ajax-item">' . $item . '</div>';
|
||||
}
|
||||
echo '<div class="aksrt-oneline__body">';
|
||||
echo '<div class="aksrt-oneline__title">' . esc_html(get_the_title()) . '</div>';
|
||||
if ($style !== 'mini') {
|
||||
echo '<div class="aksrt-oneline__meta">' . esc_html(get_the_date()) . '</div>';
|
||||
wp_reset_postdata();
|
||||
} else {
|
||||
// Fallback: bare thumb+title (should rarely hit).
|
||||
while ($q->have_posts()) {
|
||||
$q->the_post();
|
||||
$thumb = get_the_post_thumbnail_url(get_the_ID(), $style === 'card' ? 'medium' : 'thumbnail');
|
||||
$slides .= '<div class="swiper-slide ajax-item"><a class="posts-item aksrt-oneline-fallback" href="' . esc_url(get_permalink()) . '">';
|
||||
if ($thumb) {
|
||||
$slides .= '<div class="item-thumbnail"><img src="' . esc_url($thumb) . '" alt="" loading="lazy" /></div>';
|
||||
}
|
||||
$slides .= '<div class="item-body"><div class="item-heading">' . esc_html(get_the_title()) . '</div></div></a></div>';
|
||||
}
|
||||
echo '</div></a>';
|
||||
wp_reset_postdata();
|
||||
}
|
||||
|
||||
if ($slides === '') {
|
||||
return function_exists('aksrt_get_ajax_null')
|
||||
? aksrt_get_ajax_null(__('暂无文章', 'aksrt'))
|
||||
: '<p class="widget-empty ajax-item">' . esc_html__('暂无文章', 'aksrt') . '</p>';
|
||||
}
|
||||
|
||||
// zibll: .widget-main-post.style-{card|mini|list} + .swiper-container.swiper-scroll data-slideClass="posts-item".
|
||||
ob_start();
|
||||
echo '<div class="widget-main-post style-' . esc_attr($style) . ' aksrt-oneline-posts ajax-item">';
|
||||
echo '<div class="swiper-container swiper-scroll aksrt-oneline-swiper" data-slideClass="posts-item">';
|
||||
echo '<div class="swiper-wrapper">';
|
||||
echo $slides; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '</div>';
|
||||
echo '<div class="swiper-button-prev" aria-label="' . esc_attr__('上一页', 'aksrt') . '"></div>';
|
||||
echo '<div class="swiper-button-next" aria-label="' . esc_attr__('下一页', 'aksrt') . '"></div>';
|
||||
echo '</div></div>';
|
||||
wp_reset_postdata();
|
||||
return (string) ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $args
|
||||
* @param array<string,mixed> $instance
|
||||
*/
|
||||
public function widget($args, $instance): void {
|
||||
$html = self::render_html($instance);
|
||||
if ($html === '') {
|
||||
@@ -112,6 +168,9 @@ class WidgetOnelinePosts extends \WP_Widget {
|
||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $instance
|
||||
*/
|
||||
public function form($instance): void {
|
||||
?>
|
||||
<p>
|
||||
@@ -156,6 +215,11 @@ class WidgetOnelinePosts extends \WP_Widget {
|
||||
<?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 {
|
||||
$style = sanitize_key((string) ($new_instance['style'] ?? 'card'));
|
||||
if (!in_array($style, ['card', 'mini', 'list'], true)) {
|
||||
|
||||
Reference in New Issue
Block a user