diff --git a/assets/css/frontend/widget-batch5.css b/assets/css/frontend/widget-batch5.css index bfcfd826..95fc7429 100644 --- a/assets/css/frontend/widget-batch5.css +++ b/assets/css/frontend/widget-batch5.css @@ -377,3 +377,79 @@ .aksrt-cover-card__bg.is-video video { width: 100%; height: 100%; object-fit: cover; display: block; } + +.widget-buttons { + display: flex; + flex-wrap: wrap; + gap: var(--btn-gap, 10px); + margin-bottom: 8px; +} +.widget-buttons--vertical { flex-direction: column; } +.widget-buttons.align-center { justify-content: center; } +.widget-buttons.align-left { justify-content: flex-start; } +.widget-buttons.align-right { justify-content: flex-end; } +.widget-buttons__btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 8px 16px; + border-radius: 8px; + text-decoration: none; + font-size: 13px; + font-weight: 600; + background: var(--color-primary, #3b82f6); + color: #fff !important; +} +.widget-buttons.is-radius .widget-buttons__btn { border-radius: 999px; } +.widget-buttons.is-hollow .widget-buttons__btn { + background: transparent; + color: var(--color-primary, #3b82f6) !important; + border: 1px solid currentColor; +} +.widget-buttons__btn--secondary { background: #64748b; } +.widget-buttons__btn--outline { + background: transparent; + color: inherit !important; + border: 1px solid var(--color-line, #ddd); +} +.widget-buttons__btn--text { + background: transparent; + color: var(--color-primary, #3b82f6) !important; + padding-left: 0; + padding-right: 0; +} +.widget-buttons__btn--pink { background: #ec4899; } +.widget-buttons__btn--blue { background: #3b82f6; } +.widget-buttons__btn--green { background: #22c55e; } + +.aksrt-video-widget { + position: relative; + width: 100%; + height: 0; + border-radius: 8px; + overflow: hidden; + background: #111; + margin-bottom: 10px; +} +.aksrt-video-widget iframe, +.aksrt-video-widget video { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + border: 0; + object-fit: cover; +} +.aksrt-video-widget.controller-hide video::-webkit-media-controls { + display: none !important; +} + +.widget-recent-comments__post { + margin-top: 2px; + font-size: 11px; +} +.widget-recent-comments__post a { + color: var(--muted-2-color, #999); + text-decoration: none; +} diff --git a/src/AKSRT/Widgets/ButtonsWidget.php b/src/AKSRT/Widgets/ButtonsWidget.php index cadfde31..20eb79b2 100644 --- a/src/AKSRT/Widgets/ButtonsWidget.php +++ b/src/AKSRT/Widgets/ButtonsWidget.php @@ -1,5 +1,7 @@ esc_html__('显示一组自定义按钮', 'aksrt'), - ]); - } + public function __construct() { + parent::__construct('aksrt_buttons', esc_html__('AKSRT 按钮组', 'aksrt'), [ + 'description' => esc_html__('显示一组自定义按钮,支持外链跳转与样式。', 'aksrt'), + ]); + } - public function widget($args, $instance): void { - echo $args['before_widget']; - $title = apply_filters('widget_title', $instance['title'] ?? '', $instance, $this->id_base); - $buttons = isset($instance['buttons']) && is_array($instance['buttons']) ? $instance['buttons'] : []; - $layout = sanitize_key($instance['layout'] ?? 'vertical'); + public function widget($args, $instance): void { + $buttons = isset($instance['buttons']) && is_array($instance['buttons']) ? $instance['buttons'] : []; + $layout = sanitize_key((string) ($instance['layout'] ?? 'horizontal')); + if (!in_array($layout, ['vertical', 'horizontal'], true)) { + $layout = 'horizontal'; + } + $align = sanitize_key((string) ($instance['align'] ?? 'center')); + if (!in_array($align, ['left', 'center', 'right'], true)) { + $align = 'center'; + } + $radius = !empty($instance['radius']); + $hollow = !empty($instance['hollow']); + $go_link = !empty($instance['go_link']); + $gap = max(4, min(30, (int) ($instance['gap'] ?? 10))); - if ($title) echo $args['before_title'] . esc_html($title) . $args['after_title']; + $items = []; + foreach ($buttons as $btn) { + if (!is_array($btn)) { + continue; + } + $text = sanitize_text_field((string) ($btn['text'] ?? '')); + $url = esc_url_raw(trim((string) ($btn['url'] ?? ''))); + if ($text === '') { + continue; + } + if ($url !== '' && $go_link && function_exists('aksrt_go_link')) { + $url = aksrt_go_link($url, true); + } + $items[] = [ + 'text' => $text, + 'url' => $url, + 'style' => sanitize_key((string) ($btn['style'] ?? 'primary')), + 'icon' => sanitize_text_field((string) ($btn['icon'] ?? $btn['icon_left'] ?? '')), + 'icon_right' => sanitize_text_field((string) ($btn['icon_right'] ?? '')), + 'new_window' => !empty($btn['new_window']) || !empty($btn['target']), + ]; + } + if (!$items) { + return; + } - if (!empty($buttons)) : ?> -
- id_base); + if ($title !== '') { + echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } - echo $args['after_widget']; - } + $wrap = 'widget-buttons widget-buttons--' . $layout . ' align-' . $align; + if ($radius) { + $wrap .= ' is-radius'; + } + if ($hollow) { + $wrap .= ' is-hollow'; + } + echo '- - -
-- - -
-- " value="" placeholder=""> -
-- " value="" placeholder=""> -
-- -
-- " value="" placeholder=""> -
-- -
-+ +
++ + +
++ + + +
+ $btn) : ?> +- - -
-- - -
-- -
- ++ +
++ +
++ +
++ +
++ +
+ sanitize_text_field($new_instance['title'] ?? ''), - 'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))), - 'show_avatar' => !empty($new_instance['show_avatar']), - ]; - } + public function update($new_instance, $old_instance): array { + return [ + 'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')), + 'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))), + 'outpost' => max(0, (int) ($new_instance['outpost'] ?? 0)), + 'outer' => sanitize_text_field((string) ($new_instance['outer'] ?? '')), + 'show_avatar' => !empty($new_instance['show_avatar']) ? 1 : 0, + ]; + } } diff --git a/src/AKSRT/Widgets/WidgetVideoPlayer.php b/src/AKSRT/Widgets/WidgetVideoPlayer.php index 40888ed5..d20a2d0f 100644 --- a/src/AKSRT/Widgets/WidgetVideoPlayer.php +++ b/src/AKSRT/Widgets/WidgetVideoPlayer.php @@ -1,5 +1,7 @@ __('在侧栏嵌入视频播放器。', 'aksrt')] - ); - } + public function __construct() { + parent::__construct( + 'aksrt_video_player', + __('视频播放器', 'aksrt'), + ['description' => __('侧栏/流体区嵌入视频播放器。', 'aksrt')] + ); + } - public function widget($args, $instance): void { - $title = !empty($instance['title']) ? $instance['title'] : ''; - $video_url = !empty($instance['video_url']) ? $instance['video_url'] : ''; - $poster = !empty($instance['poster']) ? $instance['poster'] : ''; - $autoplay = !empty($instance['autoplay']); - $aspect_ratio = !empty($instance['aspect_ratio']) ? $instance['aspect_ratio'] : '16:9'; + public function widget($args, $instance): void { + $title = (string) ($instance['title'] ?? ''); + $video_url = trim((string) ($instance['video_url'] ?? $instance['url'] ?? '')); + $poster = trim((string) ($instance['poster'] ?? $instance['pic'] ?? '')); + $autoplay = !empty($instance['autoplay']); + $loop = !empty($instance['loop']); + $muted = $autoplay || !empty($instance['muted']); + $hide_controller = !empty($instance['hide_controller']); + $scale = max(20, min(100, (int) ($instance['scale_height'] ?? 56))); + $aspect = (string) ($instance['aspect_ratio'] ?? ''); - if (empty($video_url)) return; + if ($video_url === '') { + return; + } - // 解析视频类型 - $embed_url = $this->get_embed_url($video_url); - $is_embed = !empty($embed_url); + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + if ($title !== '') { + echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } - echo $args['before_widget']; + if ($aspect !== '' && str_contains($aspect, ':')) { + $parts = explode(':', $aspect); + if (count($parts) === 2 && (int) $parts[0] > 0) { + $scale = (int) round(((int) $parts[1] / (int) $parts[0]) * 100); + } + } - if ($title) { - echo $args['before_title'] . esc_html($title) . $args['after_title']; - } + $embed = $this->get_embed_url($video_url); + $cls = 'aksrt-video-widget' . ($hide_controller ? ' controller-hide' : ''); + echo '
- comment_content, 15, '...')); ?> -
- - ID)); ?> - -