diff --git a/assets/css/frontend/widget-batch5.css b/assets/css/frontend/widget-batch5.css index 9ea93067..1932594b 100644 --- a/assets/css/frontend/widget-batch5.css +++ b/assets/css/frontend/widget-batch5.css @@ -305,3 +305,65 @@ .aksrt-bookmark-links__text { min-width: 0; display: flex; flex-direction: column; } .aksrt-bookmark-links__name { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .aksrt-bookmark-links__desc { font-size: 11px; color: var(--muted-2-color, #999); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } + + +/* Search keywords */ +.aksrt-search-widget__keywords { margin-top: 10px; } +.aksrt-search-widget__kw-title { + font-size: 12px; + color: var(--muted-2-color, #888); + margin-bottom: 6px; +} +.aksrt-search-widget__kw-list { display: flex; flex-wrap: wrap; gap: 6px; } +.aksrt-search-widget__kw { + display: inline-block; + padding: 3px 10px; + border-radius: 999px; + background: var(--surface-2, #f3f4f6); + color: inherit; + text-decoration: none; + font-size: 12px; +} +.aksrt-search-widget__more { margin-top: 8px; text-align: right; font-size: 12px; } +.aksrt-search-widget__more a { color: var(--color-primary, #3b82f6); text-decoration: none; } + +/* Scroll notice */ +.aksrt-scroll-notice { + display: flex; + align-items: center; + gap: 10px; + padding: 10px 14px; + border-radius: 10px; + background: #eff6ff; + color: #1d4ed8; + margin-bottom: 8px; + overflow: hidden; +} +.aksrt-scroll-notice.is-radius { border-radius: 999px; } +.aksrt-scroll-notice.color-c-green { background: #ecfdf5; color: #047857; } +.aksrt-scroll-notice.color-c-yellow { background: #fffbeb; color: #b45309; } +.aksrt-scroll-notice.color-c-red { background: #fef2f2; color: #b91c1c; } +.aksrt-scroll-notice.color-c-purple { background: #f5f3ff; color: #6d28d9; } +.aksrt-scroll-notice__icon { flex-shrink: 0; } +.aksrt-scroll-notice__viewport { position: relative; flex: 1; min-width: 0; height: 1.4em; } +.aksrt-scroll-notice__item { + position: absolute; + inset: 0; + opacity: 0; + transform: translateY(8px); + transition: opacity .35s ease, transform .35s ease; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-size: 13px; + line-height: 1.4; +} +.aksrt-scroll-notice__item.is-active { + opacity: 1; + transform: translateY(0); +} +.aksrt-scroll-notice__item a { + color: inherit; + text-decoration: none; +} +.aksrt-scroll-notice__item i { margin-right: 6px; opacity: .85; } diff --git a/src/AKSRT/Widgets/NoticeWidget.php b/src/AKSRT/Widgets/NoticeWidget.php index 08a03955..18ff6ebc 100644 --- a/src/AKSRT/Widgets/NoticeWidget.php +++ b/src/AKSRT/Widgets/NoticeWidget.php @@ -1,5 +1,7 @@ esc_html__('显示公告/通知信息', 'aksrt'), - ]); - } + public function __construct() { + parent::__construct('aksrt_notice', 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); - $content = wp_kses_post($instance['content'] ?? ''); - $style = sanitize_key($instance['style'] ?? 'info'); - $icon = sanitize_text_field($instance['icon'] ?? 'fas fa-bullhorn'); + public function widget($args, $instance): void { + $items = $this->normalize_items($instance); + if (!$items) { + return; + } - if ($title) echo $args['before_title'] . esc_html($title) . $args['after_title']; - ?> -
- -
- -
-
- -

- - -

-

- - -

-

- - -

-

- - - -

- id_base); + if ($title !== '') { + echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } - public function update($new_instance, $old_instance): array { - return [ - 'title' => sanitize_text_field($new_instance['title'] ?? ''), - 'content' => wp_kses_post($new_instance['content'] ?? ''), - 'style' => in_array($new_instance['style'] ?? '', ['info', 'success', 'warning', 'danger'], true) ? $new_instance['style'] : 'info', - 'icon' => sanitize_text_field($new_instance['icon'] ?? 'fas fa-bullhorn'), - ]; - } + $uid = 'aksrt-notice-' . esc_attr($this->id); + $class = 'aksrt-scroll-notice color-' . $color . ($radius ? ' is-radius' : ''); + echo '
'; + echo '
'; + echo '
'; + foreach ($items as $i => $item) { + $active = $i === 0 ? ' is-active' : ''; + $inner = ''; + if ($item['icon'] !== '') { + $inner .= ' '; + } + $inner .= esc_html($item['title']); + echo '
'; + if ($item['href'] !== '') { + $tgt = $blank ? ' target="_blank" rel="noopener noreferrer"' : ''; + echo '' . $inner . ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } else { + echo '' . $inner . ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + echo '
'; + } + echo '
'; + + if (count($items) > 1) { + ?> + + $instance + * @return array + */ + private function normalize_items(array $instance): array { + $raw = $instance['items'] ?? $instance['img_ids'] ?? null; + if ($raw === null && !empty($instance['content'])) { + // Legacy single content. + return [[ + 'title' => wp_strip_all_tags((string) $instance['content']), + 'icon' => sanitize_text_field((string) ($instance['icon'] ?? 'fas fa-bullhorn')), + 'href' => '', + ]]; + } + if (is_string($raw)) { + $decoded = json_decode($raw, true); + $raw = is_array($decoded) ? $decoded : []; + } + if (!is_array($raw)) { + return []; + } + $out = []; + foreach ($raw as $row) { + if (!is_array($row)) { + continue; + } + $title = sanitize_text_field((string) ($row['title'] ?? $row['content'] ?? '')); + if ($title === '') { + continue; + } + $out[] = [ + 'title' => $title, + 'icon' => sanitize_text_field((string) ($row['icon'] ?? '')), + 'href' => esc_url_raw(trim((string) ($row['href'] ?? $row['url'] ?? $row['link'] ?? ''))), + ]; + if (count($out) >= 12) { + break; + } + } + return $out; + } + + public function form($instance): void { + $items = $this->normalize_items($instance); + if (!$items) { + $items = [ + ['title' => '', 'icon' => 'fas fa-bullhorn', 'href' => ''], + ['title' => '', 'icon' => 'fas fa-info-circle', 'href' => ''], + ]; + } + $json = wp_json_encode($items, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + ?> +

+ +

+

+ +

+

+ +

+

+ +

+

+
+ +

+ sanitize_text_field((string) ($new_instance['title'] ?? '')), + 'items' => $this->normalize_items(['items' => $new_instance['items'] ?? []]), + 'interval' => max(2, min(15, (int) ($new_instance['interval'] ?? 4))), + 'color' => sanitize_html_class((string) ($new_instance['color'] ?? 'c-blue')), + 'blank' => !empty($new_instance['blank']) ? 1 : 0, + 'radius' => !empty($new_instance['radius']) ? 1 : 0, + ]; + } } diff --git a/src/AKSRT/Widgets/SearchWidget.php b/src/AKSRT/Widgets/SearchWidget.php index eca6bc69..c986b90b 100644 --- a/src/AKSRT/Widgets/SearchWidget.php +++ b/src/AKSRT/Widgets/SearchWidget.php @@ -1,5 +1,7 @@ esc_html__('带样式的搜索框', 'aksrt'), - ]); - } + public function __construct() { + parent::__construct('aksrt_search', 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); - if ($title) echo $args['before_title'] . esc_html($title) . $args['after_title']; - $placeholder = sanitize_text_field($instance['placeholder'] ?? __('搜索文章...', 'aksrt')); - ?> - - id_base); + if ($title !== '') { + echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } - public function form($instance): void { - ?> -

- - -

-

- - -

- sanitize_text_field($new_instance['title'] ?? ''), - 'placeholder' => sanitize_text_field($new_instance['placeholder'] ?? ''), - ]; - } + $keywords = []; + if ($show_kw) { + if (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'hot_search_keywords')) { + $keywords = \AKSRT\Settings\Settings::hot_search_keywords(); + } elseif (function_exists('aksrt_get_setting')) { + $raw = (string) aksrt_get_setting('hot_search_keywords', ''); + $keywords = array_values(array_filter(array_map('trim', preg_split('/[\r\n,,]+/', $raw) ?: []))); + } + $custom = trim((string) ($instance['keywords'] ?? '')); + if ($custom !== '') { + $keywords = array_values(array_filter(array_map('trim', preg_split('/[\r\n,,]+/', $custom) ?: []))); + } + $keywords = array_slice($keywords, 0, 12); + } + ?> + + +

+ +

+

+ +

+

+ +

+

+ +

+

+ +

+

+ +

+

+ +

+ sanitize_text_field((string) ($new_instance['title'] ?? '')), + 'placeholder' => sanitize_text_field((string) ($new_instance['placeholder'] ?? '')), + 'show_keywords' => !empty($new_instance['show_keywords']) ? 1 : 0, + 'keywords_title' => sanitize_text_field((string) ($new_instance['keywords_title'] ?? '')), + 'keywords' => sanitize_textarea_field((string) ($new_instance['keywords'] ?? '')), + 'more_but' => sanitize_text_field((string) ($new_instance['more_but'] ?? '')), + 'more_but_url' => esc_url_raw(trim((string) ($new_instance['more_but_url'] ?? ''))), + ]; + } }