From 96bd4c84239148c65680662d7131ca3c446d4232 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Jul 2026 08:04:03 +0800 Subject: [PATCH] feat(widgets): route WidgetSlider through shared aksrt_render_slider Replace one-off fade/carousel inline script with .new-swiper stack, dual height/effect options, and admin empty-state for misconfigured slides. --- src/AKSRT/Widgets/WidgetSlider.php | 173 ++++++++++++++--------------- 1 file changed, 85 insertions(+), 88 deletions(-) diff --git a/src/AKSRT/Widgets/WidgetSlider.php b/src/AKSRT/Widgets/WidgetSlider.php index fa9ad2b6..4dc35535 100644 --- a/src/AKSRT/Widgets/WidgetSlider.php +++ b/src/AKSRT/Widgets/WidgetSlider.php @@ -1,6 +1,6 @@ esc_html__('多图轮播,支持链接与标题。', 'aksrt'), - 'classname' => 'widget_aksrt_slider', + 'description' => esc_html__('多图轮播(共享 new-swiper / Swiper 栈),支持链接与标题。', 'aksrt'), + 'classname' => 'widget_aksrt_slider slide-widget', ] ); } @@ -25,14 +25,38 @@ class WidgetSlider extends \WP_Widget { public function widget($args, $instance): void { $slides = $this->normalize_slides($instance['slides'] ?? []); if (!$slides) { + if (current_user_can('manage_options')) { + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '
' . esc_html__('幻灯片模块:', 'aksrt') . '' . + esc_html__('当前配置下没有可显示的内容,请正确配置或移出该模块', 'aksrt') . '
'; + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } return; } + $interval = max(2, min(20, (int) ($instance['interval'] ?? 4))); - $loop = !empty($instance['loop']); - $dots = !empty($instance['pagination']); - $nav = !empty($instance['button']); + $loop = !isset($instance['loop']) || !empty($instance['loop']); + $dots = !isset($instance['pagination']) || !empty($instance['pagination']); + $nav = !isset($instance['button']) || !empty($instance['button']); $blank = !empty($instance['blank']); $height = max(80, min(800, (int) ($instance['height'] ?? 220))); + $m_height = max(60, min(800, (int) ($instance['m_height'] ?? $height))); + $effect = sanitize_key((string) ($instance['effect'] ?? 'slide')); + if (!in_array($effect, ['slide', 'fade', 'cube', 'coverflow', 'flip'], true)) { + $effect = 'slide'; + } + + $slide_payload = []; + foreach ($slides as $slide) { + $slide_payload[] = [ + 'image' => $slide['image'], + 'link' => $slide['href'], + 'title' => $slide['title'], + 'desc' => $slide['desc'], + 'alt' => $slide['title'], + 'target' => $blank ? '_blank' : '_self', + ]; + } echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped $title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base); @@ -40,97 +64,47 @@ class WidgetSlider extends \WP_Widget { echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } - $uid = 'aksrt-slider-' . esc_attr($this->id); - printf( - '
', - $uid, - $interval * 1000, - $loop ? '1' : '0', - $height - ); - echo '
'; - foreach ($slides as $i => $slide) { - $active = $i === 0 ? ' is-active' : ''; - echo '
'; - $img = '' . esc_attr($slide['title']) . ''; - if ($slide['href'] !== '') { - printf( - '%s', - esc_url($slide['href']), - $blank ? ' target="_blank" rel="noopener noreferrer"' : '', - $img // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - ); - } else { - echo $img; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - } - if ($slide['title'] !== '' || $slide['desc'] !== '') { - echo '
'; - if ($slide['title'] !== '') { - echo '' . esc_html($slide['title']) . ''; - } - if ($slide['desc'] !== '') { - echo '' . esc_html($slide['desc']) . ''; + if (function_exists('aksrt_render_slider')) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo aksrt_render_slider([ + 'slides' => $slide_payload, + 'effect' => $effect, + 'loop' => $loop, + 'autoplay' => true, + 'interval' => $interval * 1000, + 'pc_height' => $height . 'px', + 'm_height' => $m_height . 'px', + 'show_nav' => $nav, + 'show_pagination' => $dots, + 'slider_class' => 'slide-widget', + 'wrapper_class' => 'aksrt-widget-slider-wrap', + ]); + } else { + // Minimal fallback without helper. + echo '
'; + foreach ($slide_payload as $i => $slide) { + $active = $i === 0 ? ' is-active' : ''; + echo '
'; + $img = '' . esc_attr($slide['title']) . ''; + if ($slide['link'] !== '') { + echo '' . $img . ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } else { + echo $img; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } echo '
'; } echo '
'; } - echo '
'; - if ($nav) { - echo ''; - echo ''; - } - if ($dots) { - echo '
'; - foreach ($slides as $i => $slide) { - printf( - '', - $i === 0 ? ' is-active' : '', - (int) $i, - esc_attr(sprintf(__('第 %d 张', 'aksrt'), $i + 1)) - ); - } - echo '
'; - } - echo '
'; - echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - // Inline init once per widget (no extra enqueue dependency). - ?> - - normalize_slides($instance['slides'] ?? []); if (!$slides) { $slides = [ @@ -150,10 +124,26 @@ class WidgetSlider extends \WP_Widget {

-

+

+ +

+

+ +



@@ -177,9 +167,7 @@ class WidgetSlider extends \WP_Widget {

-

+

+ normalize_slides($new_instance['slides'] ?? []); + $effect = sanitize_key((string) ($new_instance['effect'] ?? 'slide')); + if (!in_array($effect, ['slide', 'fade', 'cube', 'coverflow', 'flip'], true)) { + $effect = 'slide'; + } return [ 'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')), 'interval' => max(2, min(20, (int) ($new_instance['interval'] ?? 4))), 'height' => max(80, min(800, (int) ($new_instance['height'] ?? 220))), + 'm_height' => max(60, min(800, (int) ($new_instance['m_height'] ?? ($new_instance['height'] ?? 220)))), + 'effect' => $effect, 'loop' => !empty($new_instance['loop']) ? 1 : 0, 'button' => !empty($new_instance['button']) ? 1 : 0, 'pagination' => !empty($new_instance['pagination']) ? 1 : 0,