From 93833ad381bc5b49af53c020dca817f4a4e8101c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Jul 2026 13:55:16 +0800 Subject: [PATCH 1/2] feat(widgets): zibll-like in_affix sticky option across side modules Add sidebar affix (data-affix) to ranking, user/author cards, main/hot/ paid/forum lists, comments, tag cloud, categories and text title with shared sticky CSS. --- assets/css/frontend/widget-batch5.css | 13 +++++++++++++ src/AKSRT/Widgets/CategoriesWidget.php | 11 +++++++++++ src/AKSRT/Widgets/HotPostsWidget.php | 8 ++++++-- src/AKSRT/Widgets/RecentCommentsWidget.php | 10 ++++++++++ src/AKSRT/Widgets/TagCloudWidget.php | 10 +++++++++- src/AKSRT/Widgets/WidgetAuthorCard.php | 7 ++++++- src/AKSRT/Widgets/WidgetForumHotTopics.php | 7 ++++++- src/AKSRT/Widgets/WidgetForumRecentTopics.php | 8 +++++++- src/AKSRT/Widgets/WidgetMainPosts.php | 10 ++++++++-- src/AKSRT/Widgets/WidgetPaidPosts.php | 7 ++++++- src/AKSRT/Widgets/WidgetTextTitle.php | 14 +++++++++++++- src/AKSRT/Widgets/WidgetUserCard.php | 11 ++++++++++- src/AKSRT/Widgets/WidgetUserRanking.php | 11 ++++++++++- 13 files changed, 115 insertions(+), 12 deletions(-) diff --git a/assets/css/frontend/widget-batch5.css b/assets/css/frontend/widget-batch5.css index 977feeca..b5a663a4 100644 --- a/assets/css/frontend/widget-batch5.css +++ b/assets/css/frontend/widget-batch5.css @@ -2552,3 +2552,16 @@ a.main-color > .icon-cover-card:hover, display: inline-block; margin-top: 4px; padding: 1px 6px; border-radius: 4px; background: rgba(240,68,148,.1); color: var(--theme-color, #f04494); font-size: 12px; } + + +/* batch46-48 residual */ +.widget .is-affix[data-affix="true"], +.ajaxpager.is-affix[data-affix="true"], +.zib-widget.is-affix[data-affix="true"], +.aksrt-author-card.is-affix[data-affix="true"], +.aksrt-text-title.is-affix[data-affix="true"] { + position: sticky; + top: 72px; + z-index: 2; +} +.avatar-img.link-img img.aksrt-lazy { object-fit: cover; } diff --git a/src/AKSRT/Widgets/CategoriesWidget.php b/src/AKSRT/Widgets/CategoriesWidget.php index d034cc8d..bf0904d5 100644 --- a/src/AKSRT/Widgets/CategoriesWidget.php +++ b/src/AKSRT/Widgets/CategoriesWidget.php @@ -176,7 +176,14 @@ class CategoriesWidget extends \WP_Widget { if ($title !== '') { echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } + $in_affix = !empty($instance['in_affix']); + if ($in_affix) { + echo '
'; + } echo self::render_html($instance); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + if ($in_affix) { + echo '
'; + } echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } @@ -231,6 +238,9 @@ class CategoriesWidget extends \WP_Widget {

+

+ +

!empty($new_instance['show_thumb']) ? 1 : 0, 'hide_empty' => !empty($new_instance['hide_empty']) ? 1 : 0, 'hierarchical' => !empty($new_instance['hierarchical']) ? 1 : 0, + 'in_affix' => !empty($new_instance['in_affix']) ? 1 : 0, ]; } } diff --git a/src/AKSRT/Widgets/HotPostsWidget.php b/src/AKSRT/Widgets/HotPostsWidget.php index 1ab3eaff..0a5b5336 100644 --- a/src/AKSRT/Widgets/HotPostsWidget.php +++ b/src/AKSRT/Widgets/HotPostsWidget.php @@ -204,10 +204,12 @@ class HotPostsWidget extends \WP_Widget { if ($title) { echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } + $in_affix = !empty($instance['in_affix']); $instance['paginate'] = sanitize_key((string) ($instance['paginate'] ?? 'ajax')); $payload = self::query_payload($instance, 1); $rest = rest_url('aksrt/v1/widgets/hot-posts'); - echo '
'; + $wrap = 'ajaxpager' . ($in_affix ? ' is-affix' : ''); + echo '
'; echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo ''; @@ -244,7 +246,8 @@ class HotPostsWidget extends \WP_Widget {

- +
+

'; + } echo self::render_html($instance); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + if ($in_affix) { + echo '
'; + } echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } @@ -202,6 +209,9 @@ class RecentCommentsWidget extends \WP_Widget {

+

+ +

'; + } echo self::render_html($instance); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + if ($in_affix) { + echo '
'; + } echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } @@ -154,7 +161,8 @@ class TagCloudWidget extends \WP_Widget {


- +
+

$author_id, 'follow' => false, 'class' => 'flex ac jc']) : '' . esc_html($user->display_name) . ''; + $in_affix = !empty($instance['in_affix']); echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped $title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base); if ($title !== '') { echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } - echo '
'; + $card_cls = 'aksrt-author-card user-card author zib-widget' . ($show_bg ? ' has-cover' : '') . ($in_affix ? ' is-affix' : ''); + echo '
'; if ($show_bg) { $bg = $cover !== '' ? ' style="background-image:url(' . esc_url($cover) . ')"' : ''; echo '
'; @@ -208,6 +210,9 @@ class WidgetAuthorCard extends \WP_Widget {

+

+ +

'; + $in_affix = !empty($instance['in_affix']); + $wrap = 'ajaxpager' . ($in_affix ? ' is-affix' : ''); + echo '
'; echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo ''; @@ -243,6 +245,9 @@ class WidgetForumHotTopics extends \WP_Widget {

+

+ +

'; + $in_affix = !empty($instance['in_affix']); + $wrap = 'ajaxpager' . ($in_affix ? ' is-affix' : ''); + echo '
'; echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo ''; @@ -84,6 +86,9 @@ class WidgetForumRecentTopics extends \WP_Widget {

+

+ +

max(0, (int) ($new_instance['plate'] ?? 0)), 'style' => $style, 'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) : 'ajax', + 'in_affix' => !empty($new_instance['in_affix']) ? 1 : 0, ]; } } diff --git a/src/AKSRT/Widgets/WidgetMainPosts.php b/src/AKSRT/Widgets/WidgetMainPosts.php index 8d217ffa..28228652 100644 --- a/src/AKSRT/Widgets/WidgetMainPosts.php +++ b/src/AKSRT/Widgets/WidgetMainPosts.php @@ -324,11 +324,15 @@ class WidgetMainPosts extends \WP_Widget { ], static function ($v) { return $v !== '' && $v !== null; })); + $in_affix = !empty($instance['in_affix']); $wrap_cls = 'aksrt-main-posts style-' . $style . ' ajaxpager'; if ($style === 'mini') { $wrap_cls .= ' zib-widget posts-mini-lists'; } - echo '
'; + if ($in_affix) { + $wrap_cls .= ' is-affix'; + } + echo '
'; if ($load_mode === 'ajax') { // Skeleton first paint (zibll load_mode=ajax). @@ -435,7 +439,8 @@ class WidgetMainPosts extends \WP_Widget {



- +
+

!empty($new_instance['show_thumb']) ? 1 : 0, 'show_meta' => !empty($new_instance['show_meta']) ? 1 : 0, 'show_number' => !empty($new_instance['show_number']) ? 1 : 0, + 'in_affix' => !empty($new_instance['in_affix']) ? 1 : 0, ]; } } diff --git a/src/AKSRT/Widgets/WidgetPaidPosts.php b/src/AKSRT/Widgets/WidgetPaidPosts.php index 86e3c508..6d82464b 100644 --- a/src/AKSRT/Widgets/WidgetPaidPosts.php +++ b/src/AKSRT/Widgets/WidgetPaidPosts.php @@ -187,8 +187,10 @@ class WidgetPaidPosts extends \WP_Widget { echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } + $in_affix = !empty($instance['in_affix']); $rest = rest_url('aksrt/v1/widgets/paid-posts'); - echo '
'; + $wrap = 'aksrt-paid-posts-wrap ajaxpager' . ($in_affix ? ' is-affix' : ''); + echo '
'; echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo ''; @@ -246,6 +248,9 @@ class WidgetPaidPosts extends \WP_Widget {

+

+ +

' . esc_html__('请填写标题或描述', 'aksrt') . '

'; + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } return; } @@ -101,7 +108,9 @@ class WidgetTextTitle extends \WP_Widget { } } - echo '
'; + $in_affix = !empty($instance['in_affix']); + $box = 'aksrt-text-title text-title align-' . esc_attr($align) . ($in_affix ? ' is-affix' : ''); + echo '
'; if ($title_html !== '') { echo '
' . $title_html . '
'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } @@ -173,6 +182,9 @@ class WidgetTextTitle extends \WP_Widget {

+

+ +

'; + } if ($user_id <= 0) { $this->render_guest($show_cover, $loged_title); + if ($in_affix) { + echo '
'; + } echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped return; } @@ -249,7 +256,8 @@ class WidgetUserCard extends \WP_Widget {


- +
+

'; + $box_cls = 'zib-widget user-ranking-box aksrt-user-ranking-box' . ($in_affix ? ' is-affix' : ''); + echo '
'; if (!empty($instance['checkin_btn']) && is_user_logged_in() && function_exists('aksrt_header_user_checkin_btn')) { $cbtn = aksrt_header_user_checkin_btn(get_current_user_id()); if ($cbtn !== '') { @@ -336,6 +338,12 @@ class WidgetUserRanking extends \WP_Widget {

+

+ +

Date: Tue, 21 Jul 2026 13:55:16 +0800 Subject: [PATCH 2/2] fix(widgets): link card lazy class + product paginate sanitize Mark bookmark/friend link avatars with aksrt-lazy; clamp product list paginate enum to none|ajax|number on save. --- inc/helpers/aksrt-links.php | 2 +- src/AKSRT/Widgets/WidgetProductList.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/helpers/aksrt-links.php b/inc/helpers/aksrt-links.php index 947e531d..737c398a 100644 --- a/inc/helpers/aksrt-links.php +++ b/inc/helpers/aksrt-links.php @@ -152,7 +152,7 @@ if (!function_exists('aksrt_links_box')) : $dec = !empty($link['desc']) ? (string) $link['desc'] : ''; $rel = $nofollow ? ' rel="nofollow noopener noreferrer"' : ' rel="noopener noreferrer"'; $img_src = $src !== '' ? $src : $placeholder; - $img = ''; + $img = ''; $data_dec = $dec !== '' ? ' title="' . esc_attr($title) . '" data-content="' . esc_attr($dec) . '"' : ' data-content="' . esc_attr($title) . '"'; diff --git a/src/AKSRT/Widgets/WidgetProductList.php b/src/AKSRT/Widgets/WidgetProductList.php index e4ac748d..b455b40e 100644 --- a/src/AKSRT/Widgets/WidgetProductList.php +++ b/src/AKSRT/Widgets/WidgetProductList.php @@ -387,7 +387,7 @@ class WidgetProductList extends \WP_Widget { 'discount_ids' => sanitize_text_field((string) ($new_instance['discount_ids'] ?? '')), 'exclude_cat' => !empty($new_instance['exclude_cat']) ? 1 : 0, 'style' => sanitize_key((string) ($new_instance['style'] ?? 'default')), - 'paginate' => sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), + 'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) : 'ajax', ]; } }