diff --git a/assets/css/frontend/widget-batch5.css b/assets/css/frontend/widget-batch5.css
index fcf64247..027d6884 100644
--- a/assets/css/frontend/widget-batch5.css
+++ b/assets/css/frontend/widget-batch5.css
@@ -2217,3 +2217,82 @@ a.main-color > .icon-cover-card:hover,
width: 100vw;
max-width: 100vw;
}
+
+/* ===== Batch19-21: categories tree, hot meta, paid mini, main renderer, lang ===== */
+
+.aksrt-cat-list.has-thumb .aksrt-cat-list__link,
+.aksrt-cat-list.is-tree .aksrt-cat-list__link {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ text-decoration: none;
+ color: inherit;
+}
+.aksrt-cat-list__thumb {
+ width: 32px;
+ height: 32px;
+ border-radius: 8px;
+ overflow: hidden;
+ flex: 0 0 auto;
+ background: var(--surface-2, #f3f4f6);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ color: #999;
+}
+.aksrt-cat-list__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
+.aksrt-cat-list__text { min-width: 0; flex: 1; display: flex; flex-direction: column; }
+.aksrt-cat-list__name { font-weight: 600; }
+.aksrt-cat-list__desc { margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+.aksrt-cat-list__children {
+ list-style: none;
+ margin: 6px 0 0 18px;
+ padding: 0;
+ border-left: 2px solid var(--color-line, #e5e7eb);
+ padding-left: 10px;
+}
+.aksrt-cat-list .count {
+ margin-left: auto;
+ font-size: 12px;
+ color: var(--muted-2-color, #999);
+ background: var(--surface-2, #f3f4f6);
+ border-radius: 999px;
+ padding: 1px 8px;
+}
+
+.aksrt-paid-posts__item.is-mini {
+ position: relative;
+ margin-bottom: 10px;
+}
+.aksrt-paid-posts__item.is-mini .aksrt-paid-posts__price.badge {
+ position: absolute;
+ top: 6px;
+ right: 6px;
+ z-index: 2;
+ background: rgba(239, 68, 68, .92);
+ color: #fff;
+ font-size: 11px;
+ padding: 2px 8px;
+ border-radius: 999px;
+}
+
+.aksrt-lang-switch-widget.hide-name .aksrt-lang-switch__toggle span,
+.aksrt-lang-switch-widget.hide-name .aksrt-lang-switch__item {
+ font-size: 0;
+}
+.aksrt-lang-switch-widget.hide-current .aksrt-lang-switch__item.is-active,
+.aksrt-lang-switch-widget.hide-current .aksrt-lang-switch__flag.is-active {
+ display: none;
+}
+.aksrt-lang-switch-widget.style-inline .aksrt-lang-switch--flags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.aksrt-forum-widget__item.is-top .aksrt-forum-widget__rank {
+ background: var(--theme-color, #f04494);
+ color: #fff;
+}
+.tag-cloud.aksrt-tag-cloud a { transition: transform .15s ease; }
+.tag-cloud.aksrt-tag-cloud a:hover { transform: translateY(-1px); }
diff --git a/src/AKSRT/Widgets/WidgetForumHotTopics.php b/src/AKSRT/Widgets/WidgetForumHotTopics.php
index aa14b29e..18eb5162 100644
--- a/src/AKSRT/Widgets/WidgetForumHotTopics.php
+++ b/src/AKSRT/Widgets/WidgetForumHotTopics.php
@@ -83,7 +83,7 @@ class WidgetForumHotTopics extends \WP_Widget {
$items = self::render_items_html($q, ($page - 1) * $count);
$html = $items !== '' ? '
' : '';
if ($html === '' && $page === 1) {
- $html = '' . esc_html__('暂无话题', 'aksrt') . '
';
+ $html = function_exists('aksrt_get_ajax_null') ? aksrt_get_ajax_null(__('暂无话题', 'aksrt')) : '' . esc_html__('暂无话题', 'aksrt') . '
';
}
$max_pages = max(1, (int) $q->max_num_pages);
$total = (int) $q->found_posts;
diff --git a/src/AKSRT/Widgets/WidgetForumRecentTopics.php b/src/AKSRT/Widgets/WidgetForumRecentTopics.php
index 2202bda8..c33caf8c 100644
--- a/src/AKSRT/Widgets/WidgetForumRecentTopics.php
+++ b/src/AKSRT/Widgets/WidgetForumRecentTopics.php
@@ -40,6 +40,7 @@ class WidgetForumRecentTopics extends \WP_Widget {
public function form($instance): void {
$title = !empty($instance['title']) ? $instance['title'] : __('最新话题', 'aksrt');
$count = !empty($instance['count']) ? (int) $instance['count'] : 5;
+ $plate = (int) ($instance['plate'] ?? 0);
?>
diff --git a/src/AKSRT/Widgets/WidgetLangSwitch.php b/src/AKSRT/Widgets/WidgetLangSwitch.php
index f9af963f..769d354d 100644
--- a/src/AKSRT/Widgets/WidgetLangSwitch.php
+++ b/src/AKSRT/Widgets/WidgetLangSwitch.php
@@ -1,5 +1,7 @@
__('在侧栏显示多语言切换按钮。', 'aksrt')]
- );
- }
+ public function __construct() {
+ parent::__construct(
+ 'aksrt_lang_switch',
+ __('语言切换器', 'aksrt'),
+ [
+ 'description' => __('在侧栏显示多语言切换按钮。', 'aksrt'),
+ 'classname' => 'widget_aksrt_lang_switch',
+ ]
+ );
+ }
- public function widget($args, $instance): void {
- $title = !empty($instance['title']) ? $instance['title'] : '';
- $style = !empty($instance['style']) ? $instance['style'] : 'dropdown';
+ /**
+ * @param array $args
+ * @param array $instance
+ */
+ public function widget($args, $instance): void {
+ $title = !empty($instance['title']) ? (string) $instance['title'] : '';
+ $style = sanitize_key((string) ($instance['style'] ?? 'dropdown'));
+ if (!in_array($style, ['dropdown', 'flags', 'inline'], true)) {
+ $style = 'dropdown';
+ }
+ $show_name = !isset($instance['show_name']) || !empty($instance['show_name']);
+ $hide_current = !empty($instance['hide_current']);
- if (!function_exists('aksrt_has_multilingual') || !aksrt_has_multilingual()) return;
+ if (!function_exists('aksrt_has_multilingual') || !aksrt_has_multilingual()) {
+ if (current_user_can('manage_options')) {
+ echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ echo '' . esc_html__('语言切换:', 'aksrt') . '' .
+ esc_html__('未检测到多语言插件(Polylang/WPML)或可用语言不足。', 'aksrt') . '
';
+ echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ }
+ return;
+ }
- $html = function_exists('aksrt_render_language_switcher') ? aksrt_render_language_switcher($style) : '';
- if (empty($html)) return;
+ // inline style: treat as flags row without dropdown chrome.
+ $render_style = $style === 'inline' ? 'flags' : $style;
+ $html = function_exists('aksrt_render_language_switcher') ? aksrt_render_language_switcher($render_style) : '';
+ if ($html === '') {
+ if (current_user_can('manage_options')) {
+ echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ echo function_exists('aksrt_get_widget_null')
+ ? aksrt_get_widget_null(__('暂无可用语言', 'aksrt')) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ : '' . esc_html__('暂无可用语言', 'aksrt') . '
';
+ echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ }
+ return;
+ }
- echo $args['before_widget'];
+ // Optional modifiers via wrapper classes.
+ $wrap = 'aksrt-lang-switch-widget style-' . esc_attr($style);
+ if (!$show_name) {
+ $wrap .= ' hide-name';
+ }
+ if ($hide_current) {
+ $wrap .= ' hide-current';
+ }
- if ($title) {
- echo $args['before_title'] . esc_html($title) . $args['after_title'];
- }
+ 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 '' . $html . '
'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ }
- echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ /**
+ * @param array $instance
+ */
+ public function form($instance): void {
+ $title = !empty($instance['title']) ? (string) $instance['title'] : '';
+ $style = !empty($instance['style']) ? (string) $instance['style'] : 'dropdown';
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
- $new_instance
+ * @param array $old_instance
+ * @return array
+ */
+ public function update($new_instance, $old_instance): array {
+ $style = sanitize_key((string) ($new_instance['style'] ?? 'dropdown'));
+ if (!in_array($style, ['dropdown', 'flags', 'inline'], true)) {
+ $style = 'dropdown';
+ }
+ return [
+ 'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
+ 'style' => $style,
+ 'show_name' => !empty($new_instance['show_name']) ? 1 : 0,
+ 'hide_current' => !empty($new_instance['hide_current']) ? 1 : 0,
+ ];
+ }
}
diff --git a/src/AKSRT/Widgets/WidgetProductOneline.php b/src/AKSRT/Widgets/WidgetProductOneline.php
index 81848bcd..d1ce7a17 100644
--- a/src/AKSRT/Widgets/WidgetProductOneline.php
+++ b/src/AKSRT/Widgets/WidgetProductOneline.php
@@ -15,7 +15,10 @@ class WidgetProductOneline extends WidgetProductList {
\WP_Widget::__construct(
'aksrt_product_oneline',
__('横滑商品', 'aksrt'),
- ['description' => __('AKSRT 单行横滑商品列表(AJAX 同源)。', 'aksrt')]
+ [
+ 'description' => __('AKSRT 单行横滑商品(swiper-scroll,同源 product list)。', 'aksrt'),
+ 'classname' => 'widget_aksrt_product_oneline',
+ ]
);
}
@@ -29,13 +32,21 @@ class WidgetProductOneline extends WidgetProductList {
}
public function form($instance): void {
- $instance = wp_parse_args($instance, ['style' => 'oneline', 'paginate' => 'none']);
+ $instance = wp_parse_args($instance, [
+ 'title' => __('横滑商品', 'aksrt'),
+ 'style' => 'oneline',
+ 'paginate' => 'none',
+ 'per_page' => 8,
+ ]);
parent::form($instance);
}
public function update($new_instance, $old_instance): array {
$out = parent::update($new_instance, $old_instance);
$out['style'] = 'oneline';
+ if (($out['paginate'] ?? '') === '') {
+ $out['paginate'] = 'none';
+ }
return $out;
}
}