feat(phase2): shared common-form layer + CommonWidgetFields trait for all widgets

- Extract Zibll CSF_Widget::params() common-field parity into
  inc/modules/widget-common.php (required by widgets-register.php to keep
  both files <1000 lines): subtitle, title_style(simple/big), title_highlight
  +color, title_link x3, title_link_style colors, sidebar_affix, show_type
  (all/only_pc/only_sm), show_id_type(show/hide), show_ids, animation_in,
  animation_repeat, layout_pin_pc/m, layout_bg(white/dark). Adds
  normalize_link/normalize_bg helpers, affix_attrs, common_wrapper_attr,
  render_title, animation_class. Back-compat normalizes legacy tokens
  (in_affix->sidebar_affix, pc/only_pc, include/exclude->show/hide).
- Add src/AKSRT/Widgets/Traits/CommonWidgetFields.php trait
  (render_common_form_section + update_common_fields).
- Wire all 57 widgets to use the trait; migrate the 16 hand-rolled in_affix
  implementations to shared sidebar_affix (fixes 6 latent bugs where
  in_affix was never persisted). SearchWidget intentionally skips the shared
  form section (its business show_type collides) but adopts the affix helper.
- widget_display_callback parity verified via tmp assertion script.

Refs .specs/plans/zibll-widgets-1to1.md Phase 2 (US1/US5)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-07-30 20:42:46 +08:00
parent 98aeee3cc1
commit d975ff4ce6
60 changed files with 1227 additions and 489 deletions
+8 -3
View File
@@ -5,9 +5,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class AboutWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -367,12 +371,13 @@ class AboutWidget extends \WP_Widget {
<?php esc_html_e('留空则使用默认背景图。已登录用户可使用个人封面图。', 'aksrt'); ?>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'cover' => esc_url_raw($new_instance['cover'] ?? ''),
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class ButtonsWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct('aksrt_buttons', esc_html__('AKSRT 按钮组', 'aksrt'), [
@@ -213,7 +217,8 @@ class ButtonsWidget extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name("buttons[{$i}][new_window]")); ?>" value="1" <?php checked(!empty($btn['new_window'])); ?>> <?php esc_html_e('新窗口', 'aksrt'); ?></label>
</div>
<?php endforeach;
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -244,7 +249,7 @@ class ButtonsWidget extends \WP_Widget {
}
}
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'align' => in_array(($new_instance['align'] ?? ''), ['left', 'center', 'right'], true) ? $new_instance['align'] : 'center',
'radius' => !empty($new_instance['radius']) ? 1 : 0,
@@ -256,6 +261,6 @@ class ButtonsWidget extends \WP_Widget {
'obs_animation' => sanitize_key((string) ($new_instance['obs_animation'] ?? '')),
'animation_repeat'=> !empty($new_instance['animation_repeat']) ? 1 : 0,
'buttons' => $buttons,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+10 -10
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class CategoriesWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -176,12 +179,12 @@ 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 '<div class="is-affix" data-affix="true">';
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
if ($affix['class'] !== '') {
echo '<div class="is-affix"' . $affix['attr'] . '>';
}
echo self::render_html($instance); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
if ($in_affix) {
if ($affix['class'] !== '') {
echo '</div>';
}
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
@@ -238,9 +241,7 @@ class CategoriesWidget extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hide_empty')); ?>" value="1" <?php checked(!isset($instance['hide_empty']) || !empty($instance['hide_empty'])); ?>> <?php esc_html_e('隐藏空分类', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hierarchical')); ?>" value="1" <?php checked(!empty($instance['hierarchical'])); ?>> <?php esc_html_e('层级树', 'aksrt'); ?></label>
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
@@ -254,7 +255,7 @@ class CategoriesWidget extends \WP_Widget {
if (!in_array($orderby, ['count', 'name', 'id', 'slug'], true)) {
$orderby = 'count';
}
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'count' => max(1, min(50, (int) ($new_instance['count'] ?? 8))),
'orderby' => $orderby,
@@ -267,7 +268,6 @@ class CategoriesWidget extends \WP_Widget {
'show_thumb' => !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,
];
]);
}
}
+8 -3
View File
@@ -5,6 +5,8 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
/**
@@ -311,6 +313,8 @@ if (!function_exists('aksrt_home_widget_get_lazyload_args')) {
* Homepage category block widget.
*/
class CategoryBlockWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -486,10 +490,11 @@ class CategoryBlockWidget extends \WP_Widget {
</p>
<?php if (function_exists('aksrt_widget_render_location_help')) { aksrt_widget_render_location_help('hybrid'); } ?>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'category_id' => absint($new_instance['category_id'] ?? 0),
'count' => max(1, min(12, absint($new_instance['count'] ?? 6))),
@@ -497,7 +502,7 @@ class CategoryBlockWidget extends \WP_Widget {
'layout' => aksrt_home_widget_resolve_layout($new_instance['layout'] ?? 'card', 'card'),
'show_more' => ! empty($new_instance['show_more']) ? 1 : 0,
'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'none')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'none')) : 'none',
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
public static function resolve_category_id_static(array $instance): int {
@@ -5,12 +5,16 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
/**
* Homepage category recommend cards widget.
*/
class CategoryRecommendWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -194,10 +198,11 @@ class CategoryRecommendWidget extends \WP_Widget {
</p>
<?php if (function_exists('aksrt_widget_render_location_help')) { aksrt_widget_render_location_help('homepage'); } ?>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'category_ids' => aksrt_home_widget_normalize_category_ids($new_instance['category_ids'] ?? [], 4),
'posts_per_category' => max(1, min(8, absint($new_instance['posts_per_category'] ?? 5))),
@@ -206,7 +211,7 @@ class CategoryRecommendWidget extends \WP_Widget {
'show_description' => ! empty($new_instance['show_description']) ? 1 : 0,
'show_dates' => ! empty($new_instance['show_dates']) ? 1 : 0,
'show_more' => ! empty($new_instance['show_more']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
/**
+8 -3
View File
@@ -5,12 +5,16 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
/**
* Homepage category tabs widget.
*/
class CategoryTabsWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -157,17 +161,18 @@ public function form($instance): void {
</p>
<?php if (function_exists('aksrt_widget_render_location_help')) { aksrt_widget_render_location_help('hybrid'); } ?>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'category_ids' => aksrt_home_widget_normalize_category_ids($new_instance['category_ids'] ?? [], 6),
'count' => max(1, min(12, absint($new_instance['count'] ?? 6))),
'columns' => max(1, min(4, absint($new_instance['columns'] ?? 3))),
'layout' => aksrt_home_widget_resolve_layout($new_instance['layout'] ?? 'card', 'card'),
'show_more' => ! empty($new_instance['show_more']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
/**
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class CustomHtmlGapWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct('aksrt_custom_html_gap', esc_html__('AKSRT 自定义HTML/间距', 'aksrt'), [
@@ -90,7 +94,8 @@ class CustomHtmlGapWidget extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('full_width')); ?>" value="1" <?php checked(!empty($instance['full_width'])); ?>> <?php esc_html_e('HTML 通栏', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -98,13 +103,13 @@ class CustomHtmlGapWidget extends \WP_Widget {
* @return array<string,mixed>
*/
public function update($new_instance, $old_instance): array {
return [
$business = [
'mode' => in_array(($new_instance['mode'] ?? ''), ['html', 'gap'], true) ? $new_instance['mode'] : 'html',
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'content' => wp_kses_post((string) ($new_instance['content'] ?? '')),
'gap_height' => max(0, min(500, (int) ($new_instance['gap_height'] ?? 20))),
'gap_height_m' => max(0, min(500, (int) ($new_instance['gap_height_m'] ?? $new_instance['gap_height'] ?? 20))),
'full_width' => !empty($new_instance['full_width']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -2
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class FriendLinksWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct('aksrt_friend_links', esc_html__('AKSRT 友情链接', 'aksrt'), [
@@ -155,7 +159,8 @@ class FriendLinksWidget extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_box')); ?>" value="1" <?php checked(!isset($instance['show_box']) || !empty($instance['show_box'])); ?>> <?php esc_html_e('外框盒子', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -167,7 +172,7 @@ class FriendLinksWidget extends \WP_Widget {
if (!in_array($type, ['card', 'bigcard', 'image', 'simple'], true)) {
$type = 'card';
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'source' => ($new_instance['source'] ?? '') === 'bookmarks' ? 'bookmarks' : 'settings',
'type' => $type,
@@ -183,5 +188,6 @@ class FriendLinksWidget extends \WP_Widget {
'columns' => max(1, min(4, (int) ($new_instance['columns'] ?? 2))),
'show_icon' => !empty($new_instance['show_icon']) ? 1 : 0,
];
return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+10 -8
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class HotPostsWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -204,12 +207,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']);
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$instance['paginate'] = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
$payload = self::query_payload($instance, 1);
$rest = rest_url('aksrt/v1/widgets/hot-posts');
$wrap = 'ajaxpager' . ($in_affix ? ' is-affix' : '');
echo '<div class="' . esc_attr($wrap) . '" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '"' . ($in_affix ? ' data-affix="true"' : '') . '>';
$wrap = 'ajaxpager' . $affix['class'];
echo '<div class="' . esc_attr($wrap) . '" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '"' . $affix['attr'] . '>';
echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<div class="post_ajax_loader" data-aksrt-ajax-loader data-aksrt-ajax-loader-hide hidden></div>';
@@ -246,8 +249,7 @@ class HotPostsWidget extends \WP_Widget {
<input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('days')); ?>" name="<?php echo esc_attr($this->get_field_name('days')); ?>" type="number" min="0" max="365" value="<?php echo (int) $days; ?>">
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_thumb')); ?>" value="1" <?php checked(!empty($instance['show_thumb'])); ?>> <?php esc_html_e('显示缩略图', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_thumb')); ?>" value="1" <?php checked(!empty($instance['show_thumb'])); ?>> <?php esc_html_e('显示缩略图', 'aksrt'); ?></label>
</p>
<p>
<label><?php esc_html_e('分页', 'aksrt'); ?>
@@ -258,18 +260,18 @@ class HotPostsWidget extends \WP_Widget {
</select>
</label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
public function update($new_instance, $old_instance): array {
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'count' => absint($new_instance['count'] ?? 5),
'order_by' => in_array($new_instance['order_by'] ?? '', ['views', 'comments', 'likes', 'favorites', 'downloads'], true) ? $new_instance['order_by'] : 'views',
'days' => absint($new_instance['days'] ?? 30),
'show_thumb' => !empty($new_instance['show_thumb']) ? 1 : 0,
'in_affix' => !empty($new_instance['in_affix']) ? 1 : 0,
'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) : 'ajax',
];
]);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class IconCardsWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct('aksrt_icon_cards', esc_html__('AKSRT 图标卡片', 'aksrt'), [
@@ -193,7 +197,8 @@ class IconCardsWidget extends \WP_Widget {
<input class="widefat" type="url" name="<?php echo esc_attr($this->get_field_name("cards[{$i}][url]")); ?>" value="<?php echo esc_attr((string) ($card['url'] ?? '')); ?>" placeholder="<?php esc_attr_e('链接', 'aksrt'); ?>">
</div>
<?php endforeach;
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -201,7 +206,7 @@ class IconCardsWidget extends \WP_Widget {
* @return array<string,mixed>
*/
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'columns' => max(1, min(6, (int) ($new_instance['columns'] ?? 2))),
'm_row' => max(1, min(4, (int) ($new_instance['m_row'] ?? 2))),
@@ -210,6 +215,6 @@ class IconCardsWidget extends \WP_Widget {
'icon_radius' => !empty($new_instance['icon_radius']) ? 1 : 0,
'obs_animation' => sanitize_key((string) ($new_instance['obs_animation'] ?? '')),
'cards' => $this->normalize($new_instance['cards'] ?? []),
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+10 -11
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class NoticeWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct('aksrt_notice', esc_html__('AKSRT 滚动公告', 'aksrt'), [
@@ -36,7 +39,7 @@ if (!$items) {
$radius = !empty($instance['radius']);
$interval = max(2, min(15, (int) ($instance['interval'] ?? 4)));
$align = sanitize_html_class((string) ($instance['alignment'] ?? ''));
$in_affix = !empty($instance['in_affix']);
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base);
@@ -51,12 +54,9 @@ if (!$items) {
if ($align !== '') {
$wrap_cls .= ' ' . $align;
}
if ($in_affix) {
$wrap_cls .= ' is-affix';
}
$wrap_cls .= $affix['class'];
$attr = $in_affix ? ' data-affix="true"' : '';
echo '<div class="' . esc_attr($wrap_cls) . '"' . $attr . '>';
echo '<div class="' . esc_attr($wrap_cls) . '"' . $affix['attr'] . '>';
echo '<div class="aksrt-scroll-notice__icon bulletin-icon"><i class="fas fa-bullhorn" aria-hidden="true"></i></div>';
// Prefer shared vertical new-swiper (zib_notice parity) via slider.js Type C.
@@ -192,14 +192,14 @@ if (!$items) {
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('blank')); ?>" value="1" <?php checked(!empty($instance['blank'])); ?>> <?php esc_html_e('链接新窗口', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('radius')); ?>" value="1" <?php checked(!empty($instance['radius'])); ?>> <?php esc_html_e('两端圆形', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('radius')); ?>" value="1" <?php checked(!empty($instance['radius'])); ?>> <?php esc_html_e('两端圆形', 'aksrt'); ?></label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
public function update($new_instance, $old_instance): array {
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => 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))),
@@ -207,7 +207,6 @@ if (!$items) {
'alignment' => sanitize_html_class((string) ($new_instance['alignment'] ?? '')),
'blank' => !empty($new_instance['blank']) ? 1 : 0,
'radius' => !empty($new_instance['radius']) ? 1 : 0,
'in_affix' => !empty($new_instance['in_affix']) ? 1 : 0,
];
]);
}
}
+10 -9
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class RecentCommentsWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct('aksrt_recent_comments', esc_html__('AKSRT 最新评论', 'aksrt'), [
@@ -169,12 +172,12 @@ class RecentCommentsWidget 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 '<div class="is-affix" data-affix="true">';
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
if ($affix['class'] !== '') {
echo '<div class="is-affix"' . $affix['attr'] . '>';
}
echo self::render_html($instance); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
if ($in_affix) {
if ($affix['class'] !== '') {
echo '</div>';
}
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
@@ -209,9 +212,7 @@ class RecentCommentsWidget extends \WP_Widget {
</label>
<small><?php esc_html_e('填数字 ID 时按作者排除;填文字时按内容关键词排除(兼容旧配置)。', 'aksrt'); ?></small>
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
@@ -221,12 +222,12 @@ class RecentCommentsWidget extends \WP_Widget {
* @return array<string,mixed>
*/
public function update($new_instance, $old_instance): array {
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))),
'show_avatar' => !empty($new_instance['show_avatar']) ? 1 : 0,
'outpost' => sanitize_text_field((string) ($new_instance['outpost'] ?? '')),
'outer' => sanitize_text_field((string) ($new_instance['outer'] ?? '')),
];
]);
}
}
+24 -6
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class SearchWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct('aksrt_search', esc_html__('AKSRT 搜索', 'aksrt'), [
@@ -32,10 +35,20 @@ class SearchWidget extends \WP_Widget {
$show_kw = !empty($instance['show_keywords']);
$show_history = !empty($instance['show_history']);
$show_types = !empty($instance['show_type']) || !isset($instance['show_type']);
// NOTE: SearchWidget owns a business `show_type` checkbox (search-type
// toggle) that shares the key name with the common `show_type` (device
// visibility). To avoid an admin-form collision, this widget does NOT
// render the shared common-form section (render_common_form_section is
// intentionally not called). The shared affix helper is still wired in
// widget() via aksrt_widget_affix_attrs(), and update_common_fields()
// persists common keys — but note the shared show_type cannot be set
// here, so display_callback treats it as 'all' (always visible).
$show_cat = !empty($instance['show_input_cat']);
$kw_title = sanitize_text_field((string) ($instance['keywords_title'] ?? __('热门搜索', 'aksrt')));
$more_but = sanitize_text_field((string) ($instance['more_but'] ?? ''));
$more_url = esc_url_raw(trim((string) ($instance['more_but_url'] ?? '')));
// Affix helper (shared layer sidebar_affix).
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$state = function_exists('aksrt_get_search_form_state')
? aksrt_get_search_form_state()
@@ -109,7 +122,7 @@ class SearchWidget extends \WP_Widget {
$uid = 'aksrt-sw-' . esc_attr($this->id);
?>
<div class="widget-search-box aksrt-search-widget search-input<?php echo !empty($instance['in_affix']) ? ' is-affix' : ''; ?>" id="<?php echo $uid; ?>"<?php echo !empty($instance['in_affix']) ? ' data-affix="true"' : ''; ?>>
<div class="widget-search-box aksrt-search-widget search-input<?php echo $affix['class']; ?>" id="<?php echo $uid; ?>"<?php echo $affix['attr']; ?>>
<form
role="search"
method="get"
@@ -239,8 +252,7 @@ class SearchWidget extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_type')); ?>" value="1" <?php checked(!empty($instance['show_type']) || !isset($instance['show_type'])); ?>> <?php esc_html_e('显示类型切换(≥2 种时)', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_input_cat')); ?>" value="1" <?php checked(!empty($instance['show_input_cat'])); ?>> <?php esc_html_e('显示分类筛选', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_keywords')); ?>" value="1" <?php checked(!empty($instance['show_keywords'])); ?>> <?php esc_html_e('显示热门关键词', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_history')); ?>" value="1" <?php checked(!empty($instance['show_history'])); ?>> <?php esc_html_e('显示搜索历史', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_history')); ?>" value="1" <?php checked(!empty($instance['show_history'])); ?>> <?php esc_html_e('显示搜索历史', 'aksrt'); ?></label>
</p>
<p>
<label><?php esc_html_e('默认类型', 'aksrt'); ?>
@@ -281,11 +293,18 @@ class SearchWidget extends \WP_Widget {
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('more_but_url')); ?>" value="<?php echo esc_attr((string) ($instance['more_but_url'] ?? '')); ?>">
</label>
</p>
<?php // Common-form section intentionally skipped: SearchWidget owns a
// business `show_type` checkbox (search-type toggle) that collides
// with the shared common `show_type` (device visibility). The
// shared affix/display/animation/layout fields are therefore not
// rendered here; update_common_fields() below still persists any
// common keys submitted through other surfaces, and the affix
// helper is wired in widget() via aksrt_widget_affix_attrs(). ?>
<?php
}
public function update($new_instance, $old_instance): array {
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'placeholder' => sanitize_text_field((string) ($new_instance['placeholder'] ?? '')),
'show_keywords' => !empty($new_instance['show_keywords']) ? 1 : 0,
@@ -299,7 +318,6 @@ class SearchWidget extends \WP_Widget {
'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'] ?? ''))),
'in_affix' => !empty($new_instance['in_affix']) ? 1 : 0,
];
]);
}
}
+7 -2
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class TabPostsWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -348,7 +352,8 @@ class TabPostsWidget extends \WP_Widget {
</p>
</div>
<?php endforeach;
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
$style = sanitize_key((string) ($new_instance['style'] ?? 'mini'));
@@ -389,6 +394,6 @@ class TabPostsWidget extends \WP_Widget {
}
}
$result['tabs'] = !empty($tabs) ? $tabs : 'latest,comments,random';
return $result;
return $this->update_common_fields($new_instance, $old_instance, $result);
}
}
+11 -8
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class TagCloudWidget extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -101,12 +104,12 @@ class TagCloudWidget 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 '<div class="is-affix" data-affix="true">';
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
if ($affix['class'] !== '') {
echo '<div class="is-affix"' . $affix['attr'] . '>';
}
echo self::render_html($instance); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
if ($in_affix) {
if ($affix['class'] !== '') {
echo '</div>';
}
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
@@ -161,14 +164,14 @@ class TagCloudWidget extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('blank')); ?>" value="1" <?php checked(!empty($instance['blank'])); ?>> <?php esc_html_e('新窗口', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('fixed_width')); ?>" value="1" <?php checked(!empty($instance['fixed_width'])); ?>> <?php esc_html_e('固定宽度', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hide_empty')); ?>" value="1" <?php checked(!empty($instance['hide_empty'])); ?>> <?php esc_html_e('隐藏空标签', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('scale')); ?>" value="1" <?php checked(!empty($instance['scale'])); ?>> <?php esc_html_e('按数量缩放字号', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('scale')); ?>" value="1" <?php checked(!empty($instance['scale'])); ?>> <?php esc_html_e('按数量缩放字号', 'aksrt'); ?></label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
public function update($new_instance, $old_instance): array {
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'taxonomy' => sanitize_key((string) ($new_instance['taxonomy'] ?? 'post_tag')),
'count' => max(1, min(80, (int) ($new_instance['count'] ?? 15))),
@@ -179,6 +182,6 @@ class TagCloudWidget extends \WP_Widget {
'fixed_width' => !empty($new_instance['fixed_width']) ? 1 : 0,
'hide_empty' => !empty($new_instance['hide_empty']) ? 1 : 0,
'scale' => !empty($new_instance['scale']) ? 1 : 0,
];
]);
}
}
@@ -0,0 +1,73 @@
<?php
/**
* CommonWidgetFields trait — single seat-belt for shared widget form/update.
*
* Every AKSRT widget `use`s this trait so the Zibll common-field family
* (title block, display rules, affix, animation, layout bg) is declared and
* persisted in exactly one place: inc/modules/widget-common.php.
*
* Widgets keep only their business fields; the trait wires the shared section
* into form() and folds the shared keys into update().
*
* @package AKSRT\Widgets\Traits
*/
namespace AKSRT\Widgets\Traits;
defined('ABSPATH') || exit;
trait CommonWidgetFields {
/**
* Whether this widget should render the shared common-form section.
*
* Override and return false for pure-display widgets with no admin form.
* Default: true (every widget gets the shared block).
*
* @return bool
*/
protected function use_common_form(): bool {
return true;
}
/**
* Render the shared common-form section at the end of a widget's form().
*
* Call from form(): render business fields, then `$this->render_common_form_section($instance);`.
*
* @param array<string,mixed> $instance Widget instance.
*/
protected function render_common_form_section(array $instance): void {
if (!$this->use_common_form()) {
return;
}
if (function_exists('aksrt_widget_render_common_form')) {
aksrt_widget_render_common_form($instance);
}
}
/**
* Merge shared common fields into a widget's update() result.
*
* Usage in update():
* return $this->update_common_fields($new_instance, $old_instance, [
* 'title' => sanitize_text_field(...),
* ...business fields...
* ]);
*
* @param array<string,mixed> $new_instance New submitted instance.
* @param array<string,mixed> $old_instance Previous instance.
* @param array<string,mixed> $business Sanitized business fields to keep.
* @return array<string,mixed>
*/
protected function update_common_fields(array $new_instance, array $old_instance, array $business = []): array {
if (!$this->use_common_form()) {
return $business;
}
if (function_exists('aksrt_widget_update_common')) {
$common = aksrt_widget_update_common($new_instance, $old_instance);
return array_merge($business, $common);
}
return $business;
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetAnnouncement extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -148,7 +152,8 @@ class WidgetAnnouncement extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('blank')); ?>" value="1" <?php checked(!empty($instance['blank'])); ?>> <?php esc_html_e('链接新窗口', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -160,7 +165,7 @@ class WidgetAnnouncement extends \WP_Widget {
if (!in_array($mode, ['swiper', 'marquee'], true)) {
$mode = 'swiper';
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'items' => sanitize_textarea_field((string) ($new_instance['items'] ?? '')),
'icon' => sanitize_text_field((string) ($new_instance['icon'] ?? 'fas fa-bullhorn')),
@@ -168,6 +173,6 @@ class WidgetAnnouncement extends \WP_Widget {
'mode' => $mode,
'interval' => max(2, min(15, (int) ($new_instance['interval'] ?? 4))),
'blank' => !empty($new_instance['blank']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+9 -8
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetAuthorCard extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -84,15 +87,15 @@ class WidgetAuthorCard extends \WP_Widget {
? aksrt_get_user_name(['id' => $author_id, 'follow' => false, 'class' => 'flex ac jc'])
: '<a href="' . esc_url($home) . '">' . esc_html($user->display_name) . '</a>';
$in_affix = !empty($instance['in_affix']);
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
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
}
$card_cls = 'aksrt-author-card user-card author zib-widget' . ($show_bg ? ' has-cover' : '') . ($in_affix ? ' is-affix' : '');
echo '<div class="' . esc_attr($card_cls) . '"' . ($in_affix ? ' data-affix="true"' : '') . '>';
$card_cls = 'aksrt-author-card user-card author zib-widget' . ($show_bg ? ' has-cover' : '') . $affix['class'];
echo '<div class="' . esc_attr($card_cls) . '"' . $affix['attr'] . '>';
if ($show_bg) {
$bg = $cover !== '' ? ' style="background-image:url(' . esc_url($cover) . ')"' : '';
echo '<div class="aksrt-author-card__cover user-cover graphic"' . $bg . '></div>';
@@ -210,9 +213,7 @@ class WidgetAuthorCard extends \WP_Widget {
</select>
</label>
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
@@ -225,7 +226,7 @@ class WidgetAuthorCard extends \WP_Widget {
if (!in_array($orderby, ['date', 'views', 'comment_count', 'modified', 'rand'], true)) {
$orderby = 'date';
}
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'user_id' => max(0, (int) ($new_instance['user_id'] ?? 0)),
'show_img_bg' => !empty($new_instance['show_img_bg']) ? 1 : 0,
@@ -236,6 +237,6 @@ class WidgetAuthorCard extends \WP_Widget {
'limit' => max(0, min(12, (int) ($new_instance['limit'] ?? 6))),
'post_style' => $post_style,
'orderby' => $orderby,
];
]);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetBookmarkLinks extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -135,14 +139,15 @@ class WidgetBookmarkLinks extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_box')); ?>" value="1" <?php checked(!empty($instance['show_box'])); ?>> <?php esc_html_e('外框盒子', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
$type = sanitize_key((string) ($new_instance['type'] ?? 'card'));
if (!in_array($type, ['card', 'bigcard', 'image', 'simple'], true)) {
$type = 'card';
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'links_cats' => sanitize_text_field((string) ($new_instance['links_cats'] ?? '')),
'links_limit' => max(0, min(100, (int) ($new_instance['links_limit'] ?? 12))),
@@ -153,6 +158,6 @@ class WidgetBookmarkLinks extends \WP_Widget {
'nofollow' => !empty($new_instance['nofollow']) ? 1 : 0,
'go_link' => !empty($new_instance['go_link']) ? 1 : 0,
'show_box' => !empty($new_instance['show_box']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetComboInfo extends \WP_Widget {
use CommonWidgetFields;
private const BANDS = ['blue', 'cyan', 'green', 'yellow', 'pink', 'purple'];
@@ -250,10 +254,11 @@ class WidgetComboInfo extends \WP_Widget {
</label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'cards' => $this->normalize_cards($new_instance['cards'] ?? []),
'pc_row' => max(1, min(6, (int) ($new_instance['pc_row'] ?? 4))),
@@ -265,6 +270,6 @@ class WidgetComboInfo extends \WP_Widget {
'go_link' => !empty($new_instance['go_link']) ? 1 : 0,
'obs_animation' => sanitize_key((string) ($new_instance['obs_animation'] ?? '')),
'animation_repeat'=> !empty($new_instance['animation_repeat']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetCoverCards extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -200,7 +204,8 @@ class WidgetCoverCards extends \WP_Widget {
<small><?php esc_html_e('字段: image, video, title, link, target, hide(pc|m), height, mask', 'aksrt'); ?></small>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -208,7 +213,7 @@ class WidgetCoverCards extends \WP_Widget {
* @return array<string,mixed>
*/
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'pc_row' => max(1, min(6, (int) ($new_instance['pc_row'] ?? 2))),
'm_row' => max(1, min(3, (int) ($new_instance['m_row'] ?? 1))),
@@ -220,6 +225,6 @@ class WidgetCoverCards extends \WP_Widget {
'font_bold' => !empty($new_instance['font_bold']) ? 1 : 0,
'font_color' => sanitize_hex_color((string) ($new_instance['font_color'] ?? '')) ?: '',
'items' => $this->normalize($new_instance['items'] ?? []),
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetFaq extends \WP_Widget {
use CommonWidgetFields;
private const BADGE_TONES = ['purple', 'pink', 'green', 'orange', 'blue'];
@@ -332,10 +336,11 @@ class WidgetFaq extends \WP_Widget {
</label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'search_s' => !empty($new_instance['search_s']) ? 1 : 0,
'search_placeholder' => sanitize_text_field((string) ($new_instance['search_placeholder'] ?? '')),
@@ -350,6 +355,6 @@ class WidgetFaq extends \WP_Widget {
'help_icon' => sanitize_text_field((string) ($new_instance['help_icon'] ?? '')),
'help_btn_text' => sanitize_text_field((string) ($new_instance['help_btn_text'] ?? '')),
'help_btn_url' => esc_url_raw(trim((string) ($new_instance['help_btn_url'] ?? ''))),
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetFeatureIntro extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -206,10 +210,11 @@ class WidgetFeatureIntro extends \WP_Widget {
</label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'heading' => sanitize_text_field((string) ($new_instance['heading'] ?? '')),
'description' => wp_kses_post((string) ($new_instance['description'] ?? '')),
'slides' => $this->normalize_slides($new_instance['slides'] ?? []),
@@ -220,6 +225,6 @@ class WidgetFeatureIntro extends \WP_Widget {
'stat_number' => sanitize_text_field((string) ($new_instance['stat_number'] ?? '')),
'stat_suffix' => sanitize_text_field((string) ($new_instance['stat_suffix'] ?? '')),
'stat_label' => sanitize_text_field((string) ($new_instance['stat_label'] ?? '')),
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetForumBoardList extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -180,7 +184,8 @@ class WidgetForumBoardList extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hide_empty')); ?>" value="1" <?php checked(!isset($instance['hide_empty']) || !empty($instance['hide_empty'])); ?>> <?php esc_html_e('隐藏空版块(分类模式)', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
$orderby = sanitize_key((string) ($new_instance['orderby'] ?? 'menu_order'));
@@ -188,12 +193,12 @@ class WidgetForumBoardList extends \WP_Widget {
if (!in_array($orderby, $allowed, true)) {
$orderby = 'menu_order';
}
return [
$business = [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'count' => max(1, min(50, (int) ($new_instance['count'] ?? 30))),
'orderby' => $orderby,
'style' => ($new_instance['style'] ?? '') === 'mini' ? 'mini' : 'list',
'hide_empty' => !empty($new_instance['hide_empty']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+9 -8
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetForumHotTopics extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -179,9 +182,9 @@ class WidgetForumHotTopics extends \WP_Widget {
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$rest = rest_url('aksrt/v1/widgets/forum-topics');
$in_affix = !empty($instance['in_affix']);
$wrap = 'ajaxpager' . ($in_affix ? ' is-affix' : '');
echo '<div class="' . esc_attr($wrap) . '" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '"' . ($in_affix ? ' data-affix="true"' : '') . '>';
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$wrap = 'ajaxpager' . $affix['class'];
echo '<div class="' . esc_attr($wrap) . '" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '"' . $affix['attr'] . '>';
echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<div class="post_ajax_loader" data-aksrt-ajax-loader data-aksrt-ajax-loader-hide hidden></div>';
@@ -245,9 +248,7 @@ class WidgetForumHotTopics extends \WP_Widget {
</select>
</label>
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
@@ -260,7 +261,7 @@ class WidgetForumHotTopics extends \WP_Widget {
if (!in_array($style, ['mini', 'rank'], true)) {
$style = 'mini';
}
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))),
'period' => in_array($new_instance['period'] ?? '', ['all', 'week', 'month'], true) ? $new_instance['period'] : 'week',
@@ -268,6 +269,6 @@ class WidgetForumHotTopics extends \WP_Widget {
'style' => $style,
'plate' => max(0, (int) ($new_instance['plate'] ?? 0)),
'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) : 'ajax',
];
]);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetForumPlateInfo extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -156,14 +160,15 @@ class WidgetForumPlateInfo extends \WP_Widget {
</p>
<p class="description"><?php esc_html_e('仅在版块页或帖子页显示对应版块信息。', 'aksrt'); ?></p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'show_stats' => !empty($new_instance['show_stats']) ? 1 : 0,
'show_follow' => !empty($new_instance['show_follow']) ? 1 : 0,
'show_compose' => !empty($new_instance['show_compose']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetForumPlateLists extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -260,20 +264,21 @@ class WidgetForumPlateLists extends \WP_Widget {
</label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
$orderby = sanitize_key((string) ($new_instance['orderby'] ?? 'menu_order'));
if (!in_array($orderby, ['menu_order', 'date', 'posts', 'views', 'follow'], true)) {
$orderby = 'menu_order';
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'showposts' => max(1, min(30, (int) ($new_instance['showposts'] ?? 8))),
'orderby' => $orderby,
'style' => ($new_instance['style'] ?? '') === 'card' ? 'card' : 'default',
'filter' => ($new_instance['filter'] ?? '') === 'is_hot' ? 'is_hot' : '',
'cat' => sanitize_text_field((string) ($new_instance['cat'] ?? '')),
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetForumPlateModerator extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -230,15 +233,16 @@ class WidgetForumPlateModerator extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('apply_btn')); ?>" value="1" <?php checked(!isset($instance['apply_btn']) || !empty($instance['apply_btn'])); ?>> <?php esc_html_e('显示申请版主入口', 'aksrt'); ?></label>
</p>
<p class="description"><?php esc_html_e('仅在版块/帖子页显示。', 'aksrt'); ?></p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
public function update($new_instance, $old_instance): array {
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title_text' => sanitize_text_field((string) ($new_instance['title_text'] ?? '')),
'style' => ($new_instance['style'] ?? '') === 'grid' ? 'grid' : 'list',
'show_avatar' => !empty($new_instance['show_avatar']) ? 1 : 0,
'apply_btn' => !empty($new_instance['apply_btn']) ? 1 : 0,
];
]);
}
}
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetForumRecentTopics extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -40,9 +43,9 @@ class WidgetForumRecentTopics extends \WP_Widget {
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$rest = rest_url('aksrt/v1/widgets/forum-topics');
$in_affix = !empty($instance['in_affix']);
$wrap = 'ajaxpager' . ($in_affix ? ' is-affix' : '');
echo '<div class="' . esc_attr($wrap) . '" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '"' . ($in_affix ? ' data-affix="true"' : '') . '>';
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$wrap = 'ajaxpager' . $affix['class'];
echo '<div class="' . esc_attr($wrap) . '" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '"' . $affix['attr'] . '>';
echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<div class="post_ajax_loader" data-aksrt-ajax-loader data-aksrt-ajax-loader-hide hidden></div>';
@@ -86,9 +89,7 @@ class WidgetForumRecentTopics extends \WP_Widget {
</select>
</label>
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
@@ -97,13 +98,12 @@ class WidgetForumRecentTopics extends \WP_Widget {
if (!in_array($style, ['mini', 'rank'], true)) {
$style = 'mini';
}
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))),
'plate' => 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,
];
]);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetForumTabTopics extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -165,19 +169,20 @@ class WidgetForumTabTopics extends \WP_Widget {
</label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
$style = sanitize_key((string) ($new_instance['style'] ?? 'mini'));
if (!in_array($style, ['mini', 'rank'], true)) {
$style = 'mini';
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 6))),
'style' => $style,
'plate' => max(0, (int) ($new_instance['plate'] ?? 0)),
'tabs' => sanitize_textarea_field((string) ($new_instance['tabs'] ?? '')),
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetForumTopicLists extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -271,10 +275,11 @@ class WidgetForumTopicLists extends \WP_Widget {
</label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'count' => max(1, min(30, (int) ($new_instance['count'] ?? 8))),
'orderby' => sanitize_key((string) ($new_instance['orderby'] ?? 'date')),
@@ -282,6 +287,6 @@ class WidgetForumTopicLists extends \WP_Widget {
'plate_id' => max(0, (int) ($new_instance['plate_id'] ?? 0)),
'current_plate' => !empty($new_instance['current_plate']) ? 1 : 0,
'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) : 'ajax',
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetForumTopicTerms extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -153,20 +157,21 @@ class WidgetForumTopicTerms extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hide_empty')); ?>" value="1" <?php checked(!isset($instance['hide_empty']) || !empty($instance['hide_empty'])); ?>> <?php esc_html_e('隐藏空标签', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
$orderby = sanitize_key((string) ($new_instance['orderby'] ?? 'count'));
if (!in_array($orderby, ['count', 'name', 'views'], true)) {
$orderby = 'count';
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'number' => max(1, min(40, (int) ($new_instance['number'] ?? 12))),
'orderby' => $orderby,
'style' => ($new_instance['style'] ?? '') === 'card' ? 'card' : 'mini',
'include' => sanitize_text_field((string) ($new_instance['include'] ?? '')),
'hide_empty' => !empty($new_instance['hide_empty']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetHighlights extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -187,7 +191,8 @@ class WidgetHighlights extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('go_link')); ?>" value="1" <?php checked(!empty($instance['go_link'])); ?>> <?php esc_html_e('外链跳转页', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -195,12 +200,12 @@ class WidgetHighlights extends \WP_Widget {
* @return array<string,mixed>
*/
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'cards' => $this->normalize($new_instance['cards'] ?? []),
'go_link' => !empty($new_instance['go_link']) ? 1 : 0,
'obs_animation' => sanitize_key((string) ($new_instance['obs_animation'] ?? 'slideup')),
'animation_repeat' => !empty($new_instance['animation_repeat']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetIconCoverCards extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -183,7 +187,8 @@ class WidgetIconCoverCards extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('go_link')); ?>" value="1" <?php checked(!empty($instance['go_link'])); ?>> <?php esc_html_e('外链跳转页', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -191,7 +196,7 @@ class WidgetIconCoverCards extends \WP_Widget {
* @return array<string,mixed>
*/
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'cards' => $this->normalize($new_instance['cards'] ?? []),
'pc_row' => max(1, min(4, (int) ($new_instance['pc_row'] ?? 2))),
@@ -200,6 +205,6 @@ class WidgetIconCoverCards extends \WP_Widget {
'icon_radius4' => !empty($new_instance['icon_radius4']) ? 1 : 0,
'show_widget_bg' => !empty($new_instance['show_widget_bg']) ? 1 : 0,
'go_link' => !empty($new_instance['go_link']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetIframe extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -137,7 +141,8 @@ class WidgetIframe extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('allowfullscreen')); ?>" value="1" <?php checked(!empty($instance['allowfullscreen'])); ?>> <?php esc_html_e('允许全屏', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -145,11 +150,11 @@ class WidgetIframe extends \WP_Widget {
* @return array<string,mixed>
*/
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'url' => trim((string) ($new_instance['url'] ?? '')),
'aspect' => max(20, min(300, (int) ($new_instance['aspect'] ?? 55))),
'allowfullscreen' => !empty($new_instance['allowfullscreen']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetLangSwitch extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -101,7 +105,8 @@ class WidgetLangSwitch extends \WP_Widget {
</p>
<p><small><?php esc_html_e('需要安装 Polylang 或 WPML 等多语言插件才能生效。', 'aksrt'); ?></small></p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -113,11 +118,11 @@ class WidgetLangSwitch extends \WP_Widget {
if (!in_array($style, ['dropdown', 'flags', 'inline'], true)) {
$style = 'dropdown';
}
return [
$business = [
'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,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+10 -10
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetMainPosts extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -324,15 +327,13 @@ class WidgetMainPosts extends \WP_Widget {
], static function ($v) {
return $v !== '' && $v !== null;
}));
$in_affix = !empty($instance['in_affix']);
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$wrap_cls = 'aksrt-main-posts style-' . $style . ' ajaxpager';
if ($style === 'mini') {
$wrap_cls .= ' zib-widget posts-mini-lists';
}
if ($in_affix) {
$wrap_cls .= ' is-affix';
}
echo '<div class="' . esc_attr($wrap_cls) . '" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '" data-load-mode="' . esc_attr($load_mode) . '" data-query="' . esc_attr($qs) . '"' . ($load_mode === 'ajax' ? ' data-loaded="0"' : ' data-loaded="1"') . ($in_affix ? ' data-affix="true"' : '') . '>';
$wrap_cls .= $affix['class'];
echo '<div class="' . esc_attr($wrap_cls) . '" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '" data-load-mode="' . esc_attr($load_mode) . '" data-query="' . esc_attr($qs) . '"' . ($load_mode === 'ajax' ? ' data-loaded="0"' : ' data-loaded="1"') . $affix['attr'] . '>';
if ($load_mode === 'ajax') {
// Skeleton first paint (zibll load_mode=ajax).
@@ -439,9 +440,9 @@ class WidgetMainPosts extends \WP_Widget {
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_thumb')); ?>" value="1" <?php checked(!isset($instance['show_thumb']) || !empty($instance['show_thumb'])); ?>> <?php esc_html_e('显示缩略图', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_meta')); ?>" value="1" <?php checked(!isset($instance['show_meta']) || !empty($instance['show_meta'])); ?>> <?php esc_html_e('显示 meta', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_number')); ?>" value="1" <?php checked(!empty($instance['show_number'])); ?>> <?php esc_html_e('显示序号', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_number')); ?>" value="1" <?php checked(!empty($instance['show_number'])); ?>> <?php esc_html_e('显示序号', 'aksrt'); ?></label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
@@ -458,7 +459,7 @@ class WidgetMainPosts extends \WP_Widget {
if (!in_array($paginate, ['none', 'ajax', 'number'], true)) {
$paginate = 'none';
}
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'count' => max(1, min(30, (int) ($new_instance['count'] ?? 6))),
'style' => $style,
@@ -472,7 +473,6 @@ class WidgetMainPosts extends \WP_Widget {
'show_thumb' => !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,
];
]);
}
}
+8 -3
View File
@@ -9,9 +9,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetOnelinePosts extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -249,7 +253,8 @@ class WidgetOnelinePosts extends \WP_Widget {
</label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -265,7 +270,7 @@ class WidgetOnelinePosts extends \WP_Widget {
if (!in_array($orderby, ['date', 'views', 'comments', 'rand'], true)) {
$orderby = 'date';
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 8))),
'style' => $style,
@@ -274,6 +279,6 @@ class WidgetOnelinePosts extends \WP_Widget {
'limit_day' => max(0, (int) ($new_instance['limit_day'] ?? 0)),
'topics' => sanitize_text_field((string) ($new_instance['topics'] ?? '')),
'pay_type' => sanitize_key((string) ($new_instance['pay_type'] ?? '')),
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+9 -8
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetPaidPosts extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -187,10 +190,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']);
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$rest = rest_url('aksrt/v1/widgets/paid-posts');
$wrap = 'aksrt-paid-posts-wrap ajaxpager' . ($in_affix ? ' is-affix' : '');
echo '<div class="' . esc_attr($wrap) . '" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '"' . ($in_affix ? ' data-affix="true"' : '') . '>';
$wrap = 'aksrt-paid-posts-wrap ajaxpager' . $affix['class'];
echo '<div class="' . esc_attr($wrap) . '" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '"' . $affix['attr'] . '>';
echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<div class="post_ajax_loader" data-aksrt-ajax-loader data-aksrt-ajax-loader-hide hidden></div>';
@@ -248,9 +251,7 @@ class WidgetPaidPosts extends \WP_Widget {
<input class="tiny-text" type="number" min="0" name="<?php echo esc_attr($this->get_field_name('limit_day')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['limit_day'] ?? 0))); ?>">
</label>
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
@@ -259,7 +260,7 @@ class WidgetPaidPosts extends \WP_Widget {
if (!in_array($orderby, ['date', 'views', 'price'], true)) {
$orderby = 'date';
}
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 6))),
'orderby' => $orderby,
@@ -267,6 +268,6 @@ class WidgetPaidPosts extends \WP_Widget {
'cat' => max(0, (int) ($new_instance['cat'] ?? 0)),
'limit_day' => max(0, (int) ($new_instance['limit_day'] ?? 0)),
'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) : 'ajax',
];
]);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetPartnersScroll extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -326,10 +330,11 @@ class WidgetPartnersScroll extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_widget_bg')); ?>" value="1" <?php checked(!empty($instance['show_widget_bg']) || !isset($instance['show_widget_bg'])); ?>> <?php esc_html_e('显示背景盒子', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'link_type' => in_array(($new_instance['link_type'] ?? ''), ['manual', 'link'], true) ? $new_instance['link_type'] : 'manual',
'partners' => $this->normalize_manual($new_instance['partners'] ?? []),
@@ -350,6 +355,6 @@ class WidgetPartnersScroll extends \WP_Widget {
'end_fade' => !empty($new_instance['end_fade']) ? 1 : 0,
'go_link' => !empty($new_instance['go_link']) ? 1 : 0,
'show_widget_bg' => !empty($new_instance['show_widget_bg']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+7 -2
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetPostPayBox extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -168,7 +172,8 @@ class WidgetPostPayBox extends \WP_Widget {
</label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
$theme = sanitize_html_class((string) ($new_instance['theme'] ?? 'jb-red'));
@@ -176,6 +181,6 @@ class WidgetPostPayBox extends \WP_Widget {
if (!in_array($theme, $allowed, true)) {
$theme = 'jb-red';
}
return ['theme' => $theme];
$business = ['theme' => $theme]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+9 -16
View File
@@ -10,9 +10,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetPostsNavs extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -39,7 +42,7 @@ class WidgetPostsNavs extends \WP_Widget {
$title = sanitize_text_field((string) ($instance['title'] ?? __('文章目录', 'aksrt')));
$mini_title = sanitize_text_field((string) ($instance['mini_title'] ?? ''));
$in_affix = !empty($instance['in_affix']);
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$data_title = $title;
if ($mini_title !== '') {
@@ -50,16 +53,13 @@ class WidgetPostsNavs extends \WP_Widget {
}
// Mirror aksrt-single-render built-in TOC shell so page-template.js binds.
$classes = 'zib-widget toc-widget posts-nav-box';
if ($in_affix) {
$classes .= ' is-affix';
}
$classes = 'zib-widget toc-widget posts-nav-box' . $affix['class'];
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
printf(
'<div class="%s"%s data-title="%s" aria-label="%s">',
esc_attr($classes),
$in_affix ? ' data-affix="true"' : '',
$affix['attr'],
esc_attr($data_title),
esc_attr($data_title)
);
@@ -72,7 +72,6 @@ class WidgetPostsNavs extends \WP_Widget {
public function form($instance): void {
$title = (string) ($instance['title'] ?? __('文章目录', 'aksrt'));
$mini_title = (string) ($instance['mini_title'] ?? '');
$in_affix = !empty($instance['in_affix']);
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php esc_html_e('标题:', 'aksrt'); ?></label>
@@ -82,21 +81,15 @@ class WidgetPostsNavs extends \WP_Widget {
<label for="<?php echo esc_attr($this->get_field_id('mini_title')); ?>"><?php esc_html_e('副标题:', 'aksrt'); ?></label>
<input class="widefat" type="text" id="<?php echo esc_attr($this->get_field_id('mini_title')); ?>" name="<?php echo esc_attr($this->get_field_name('mini_title')); ?>" value="<?php echo esc_attr($mini_title); ?>">
</p>
<p>
<label>
<input type="checkbox" id="<?php echo esc_attr($this->get_field_id('in_affix')); ?>" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked($in_affix); ?>>
<?php esc_html_e('侧栏随动(仅侧边栏)', 'aksrt'); ?>
</label>
</p>
<p class="description"><?php esc_html_e('请添加到文章/帖子侧栏。正文标题 ≥3 个时由前端填充目录;无标题则自动移除。', 'aksrt'); ?></p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
public function update($new_instance, $old_instance): array {
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'mini_title' => sanitize_text_field((string) ($new_instance['mini_title'] ?? '')),
'in_affix' => !empty($new_instance['in_affix']) ? 1 : 0,
];
]);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetPricingPlans extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -232,15 +236,16 @@ class WidgetPricingPlans extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('go_link')); ?>" value="1" <?php checked(!empty($instance['go_link'])); ?>> <?php esc_html_e('外链跳转页', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'currency' => sanitize_text_field((string) ($new_instance['currency'] ?? '¥')),
'lists' => $this->normalize_plans($new_instance['lists'] ?? []),
'trust_items' => $this->normalize_trust($new_instance['trust_items'] ?? []),
'go_link' => !empty($new_instance['go_link']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -5,6 +5,8 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
/**
@@ -14,6 +16,8 @@ defined('ABSPATH') || exit;
* AJAX load-more (via rest widget list endpoint); per-page count.
*/
class WidgetProductList extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -377,10 +381,11 @@ class WidgetProductList extends \WP_Widget {
</select>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'per_page' => max(1, min(50, (int) ($new_instance['per_page'] ?? 8))),
'orderby' => sanitize_key((string) ($new_instance['orderby'] ?? 'date')),
@@ -391,6 +396,6 @@ class WidgetProductList extends \WP_Widget {
'exclude_cat' => !empty($new_instance['exclude_cat']) ? 1 : 0,
'style' => sanitize_key((string) ($new_instance['style'] ?? 'default')),
'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) : 'ajax',
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -5,6 +5,8 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
/**
@@ -12,6 +14,8 @@ defined('ABSPATH') || exit;
* First tab renders immediately via shared payload; other tabs lazy-load via REST.
*/
class WidgetProductTab extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -160,15 +164,16 @@ class WidgetProductTab extends \WP_Widget {
</select>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'tabs' => sanitize_textarea_field((string) ($new_instance['tabs'] ?? '')),
'per_page' => max(1, min(20, (int) ($new_instance['per_page'] ?? 8))),
'style' => sanitize_key((string) ($new_instance['style'] ?? 'default')),
'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) : 'ajax',
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetReviews extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -148,14 +152,15 @@ class WidgetReviews extends \WP_Widget {
</label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'reviews' => $this->normalize($new_instance['reviews'] ?? []),
'desktop_per_view' => max(1, min(6, (float) ($new_instance['desktop_per_view'] ?? 3))),
'mobile_per_view' => max(1, min(3, (float) ($new_instance['mobile_per_view'] ?? 1.2))),
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetSlider extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -185,7 +189,8 @@ class WidgetSlider extends \WP_Widget {
?>
<p class="description"><?php esc_html_e('使用主题共享 Swiper(.new-swiper)。图片 URL 必填;仅 1 张时不滑动。', 'aksrt'); ?></p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
$slides = $this->normalize_slides($new_instance['slides'] ?? []);
@@ -193,7 +198,7 @@ class WidgetSlider extends \WP_Widget {
if (!in_array($effect, ['slide', 'fade', 'cube', 'coverflow', 'flip'], true)) {
$effect = 'slide';
}
return [
$business = [
'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))),
@@ -204,7 +209,7 @@ class WidgetSlider extends \WP_Widget {
'pagination' => !empty($new_instance['pagination']) ? 1 : 0,
'blank' => !empty($new_instance['blank']) ? 1 : 0,
'slides' => $slides,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
/**
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetStats extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -174,16 +178,17 @@ if (!$stats) {
</label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'stats' => $this->normalize_stats($new_instance['stats'] ?? []),
'columns' => max(1, min(4, (int) ($new_instance['columns'] ?? 4))),
'mobile_columns' => max(1, min(3, (int) ($new_instance['mobile_columns'] ?? 2))),
'intro_title' => sanitize_text_field((string) ($new_instance['intro_title'] ?? '')),
'intro_subtitle' => sanitize_text_field((string) ($new_instance['intro_subtitle'] ?? '')),
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetTermAggregation extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -309,7 +313,8 @@ class WidgetTermAggregation extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('target_blank')); ?>" value="1" <?php checked(!empty($instance['target_blank'])); ?>> <?php esc_html_e('新窗口打开', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -321,7 +326,7 @@ class WidgetTermAggregation extends \WP_Widget {
if (!in_array($orderby, ['date', 'modified', 'views', 'like', 'comment_count'], true)) {
$orderby = 'date';
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'taxonomy' => sanitize_key((string) ($new_instance['taxonomy'] ?? 'category')),
'term_ids' => sanitize_text_field((string) ($new_instance['term_ids'] ?? '')),
@@ -330,6 +335,6 @@ class WidgetTermAggregation extends \WP_Widget {
'orderby' => $orderby,
'auto_terms' => max(1, min(4, (int) ($new_instance['auto_terms'] ?? 2))),
'target_blank' => !empty($new_instance['target_blank']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetTermCards extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -271,7 +275,8 @@ class WidgetTermCards extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('target_blank')); ?>" value="1" <?php checked(!empty($instance['target_blank'])); ?>> <?php esc_html_e('新窗口打开', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -283,7 +288,7 @@ class WidgetTermCards extends \WP_Widget {
if (!in_array($type, ['style-1', 'style-2', 'style-3', 'style-4'], true)) {
$type = 'style-1';
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'taxonomy' => sanitize_key((string) ($new_instance['taxonomy'] ?? 'category')),
'number' => max(1, min(30, (int) ($new_instance['number'] ?? 8))),
@@ -297,6 +302,6 @@ class WidgetTermCards extends \WP_Widget {
'include' => sanitize_text_field((string) ($new_instance['include'] ?? '')),
'hide_empty' => !empty($new_instance['hide_empty']) ? 1 : 0,
'target_blank' => !empty($new_instance['target_blank']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+9 -8
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetTextTitle extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -108,9 +111,9 @@ class WidgetTextTitle extends \WP_Widget {
}
}
$in_affix = !empty($instance['in_affix']);
$box = 'aksrt-text-title text-title align-' . esc_attr($align) . ($in_affix ? ' is-affix' : '');
echo '<div class="' . esc_attr($box) . '" style="' . esc_attr($style) . '"' . ($in_affix ? ' data-affix="true"' : '') . '>';
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$box = 'aksrt-text-title text-title align-' . esc_attr($align) . $affix['class'];
echo '<div class="' . esc_attr($box) . '" style="' . esc_attr($style) . '"' . $affix['attr'] . '>';
if ($title_html !== '') {
echo '<div class="aksrt-text-title__main">' . $title_html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
@@ -182,9 +185,7 @@ class WidgetTextTitle extends \WP_Widget {
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('desc_color')); ?>" value="<?php echo esc_attr((string) ($instance['desc_color'] ?? '')); ?>">
</label>
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
@@ -194,7 +195,7 @@ class WidgetTextTitle extends \WP_Widget {
* @return array<string,mixed>
*/
public function update($new_instance, $old_instance): array {
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'desc' => sanitize_text_field((string) ($new_instance['desc'] ?? '')),
'align' => in_array(($new_instance['align'] ?? ''), ['left', 'center', 'right'], true) ? $new_instance['align'] : 'center',
@@ -207,6 +208,6 @@ class WidgetTextTitle extends \WP_Widget {
'obs_animation' => sanitize_key((string) ($new_instance['obs_animation'] ?? '')),
'animation_repeat' => !empty($new_instance['animation_repeat']) ? 1 : 0,
'title_icon_width' => max(0, min(64, (int) ($new_instance['title_icon_width'] ?? 0))),
];
]);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetTiltCases extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -249,10 +253,11 @@ class WidgetTiltCases extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('go_link')); ?>" value="1" <?php checked(!empty($instance['go_link'])); ?>> <?php esc_html_e('外链跳转页', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'intro_badge_text' => sanitize_text_field((string) ($new_instance['intro_badge_text'] ?? '')),
'intro_badge_icon' => sanitize_text_field((string) ($new_instance['intro_badge_icon'] ?? '')),
'intro_title' => sanitize_textarea_field((string) ($new_instance['intro_title'] ?? '')),
@@ -262,6 +267,6 @@ class WidgetTiltCases extends \WP_Widget {
'intro_buttons' => $this->normalize_buttons($new_instance['intro_buttons'] ?? []),
'intro_showcase_images' => $this->normalize_images($new_instance['intro_showcase_images'] ?? []),
'go_link' => !empty($new_instance['go_link']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+17 -9
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetUserCard extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -27,7 +30,7 @@ class WidgetUserCard extends \WP_Widget {
// zibll user widget forces show_posts=false; author widget enables it.
// AKSRT keeps optional show_posts for current-user card (default off).
$show_posts = !empty($instance['show_posts']);
$in_affix = !empty($instance['in_affix']);
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$loged_title = (string) ($instance['loged_title'] ?? __('Hi!请登录', 'aksrt'));
$btn1_text = (string) ($instance['button_1_text'] ?? __('发布文章', 'aksrt'));
$btn2_text = (string) ($instance['button_2_text'] ?? __('用户中心', 'aksrt'));
@@ -49,13 +52,13 @@ class WidgetUserCard extends \WP_Widget {
if ($title !== '') {
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
if ($in_affix) {
echo '<div class="is-affix" data-affix="true">';
if ($affix['class'] !== '') {
echo '<div class="is-affix"' . $affix['attr'] . '>';
}
if ($user_id <= 0) {
$this->render_guest($show_cover, $loged_title);
if ($in_affix) {
if ($affix['class'] !== '') {
echo '</div>';
}
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
@@ -64,6 +67,9 @@ class WidgetUserCard extends \WP_Widget {
$user = get_userdata($user_id);
if (!$user) {
if ($affix['class'] !== '') {
echo '</div>';
}
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
return;
}
@@ -173,6 +179,9 @@ class WidgetUserCard extends \WP_Widget {
echo '</div></div>';
if ($affix['class'] !== '') {
echo '</div>';
}
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
@@ -256,8 +265,7 @@ class WidgetUserCard extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_stats')); ?>" value="1" <?php checked(!isset($instance['show_stats']) || !empty($instance['show_stats'])); ?>> <?php esc_html_e('显示统计', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_button')); ?>" value="1" <?php checked(!isset($instance['show_button']) || !empty($instance['show_button'])); ?>> <?php esc_html_e('显示操作按钮', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_checkin')); ?>" value="1" <?php checked(!isset($instance['show_checkin']) || !empty($instance['show_checkin'])); ?>> <?php esc_html_e('显示签到(本人)', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_posts')); ?>" value="1" <?php checked(!empty($instance['show_posts'])); ?>> <?php esc_html_e('显示更多文章', 'aksrt'); ?></label><br>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('show_posts')); ?>" value="1" <?php checked(!empty($instance['show_posts'])); ?>> <?php esc_html_e('显示更多文章', 'aksrt'); ?></label>
</p>
<p>
<label><?php esc_html_e('文章数量', 'aksrt'); ?>
@@ -282,6 +290,7 @@ class WidgetUserCard extends \WP_Widget {
</select>
</label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
@@ -294,7 +303,7 @@ class WidgetUserCard extends \WP_Widget {
if (!in_array($orderby, ['date', 'views', 'comment_count', 'modified', 'rand'], true)) {
$orderby = 'date';
}
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'user_id' => max(0, (int) ($new_instance['user_id'] ?? 0)),
'loged_title' => sanitize_text_field((string) ($new_instance['loged_title'] ?? '')),
@@ -305,10 +314,9 @@ class WidgetUserCard extends \WP_Widget {
'show_button' => !empty($new_instance['show_button']) ? 1 : 0,
'show_checkin' => !empty($new_instance['show_checkin']) ? 1 : 0,
'show_posts' => !empty($new_instance['show_posts']) ? 1 : 0,
'in_affix' => !empty($new_instance['in_affix']) ? 1 : 0,
'limit' => max(0, min(12, (int) ($new_instance['limit'] ?? 6))),
'post_style' => $post_style,
'orderby' => $orderby,
];
]);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetUserLists extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -196,7 +200,8 @@ class WidgetUserLists extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('blur_bg')); ?>" value="1" <?php checked(!empty($instance['blur_bg'])); ?>> <?php esc_html_e('头像模糊背景', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
/**
* @param array<string,mixed> $new_instance
@@ -209,7 +214,7 @@ class WidgetUserLists extends \WP_Widget {
if (!in_array($orderby, $allowed, true)) {
$orderby = 'user_registered';
}
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'number' => max(1, min(50, (int) ($new_instance['number'] ?? 8))),
'include' => sanitize_text_field((string) ($new_instance['include'] ?? '')),
@@ -218,6 +223,6 @@ class WidgetUserLists extends \WP_Widget {
'order' => strtoupper((string) ($new_instance['order'] ?? 'DESC')) === 'ASC' ? 'ASC' : 'DESC',
'hide_box' => !empty($new_instance['hide_box']) ? 1 : 0,
'blur_bg' => !empty($new_instance['blur_bg']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+16 -19
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetUserRanking extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -29,14 +32,14 @@ class WidgetUserRanking extends \WP_Widget {
$show_avatar = !isset($instance['show_avatar']) || !empty($instance['show_avatar']);
$desc_mode = sanitize_key((string) ($instance['desc'] ?? 'desc'));
$top_badge = !empty($instance['top_badge']);
$in_affix = !empty($instance['in_affix']);
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$users = $this->get_ranking($rank_by, $count, $desc_mode);
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$box_cls = 'zib-widget user-ranking-box aksrt-user-ranking-box' . ($in_affix ? ' is-affix' : '');
echo '<div class="' . esc_attr($box_cls) . '"' . ($in_affix ? ' data-affix="true"' : '') . '>';
$box_cls = 'zib-widget user-ranking-box aksrt-user-ranking-box' . $affix['class'];
echo '<div class="' . esc_attr($box_cls) . '"' . $affix['attr'] . '>';
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 !== '') {
@@ -338,25 +341,19 @@ class WidgetUserRanking extends \WP_Widget {
<?php esc_html_e('前三名 TOP 角标', 'aksrt'); ?>
</label>
</p>
<p>
<label>
<input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>>
<?php esc_html_e('侧栏随动', 'aksrt'); ?>
</label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
public function update($new_instance, $old_instance): array {
$instance = [];
$instance['title'] = sanitize_text_field($new_instance['title'] ?? '');
$instance['rank_by'] = in_array($new_instance['rank_by'] ?? '', ['credits', 'posts', 'followers', 'checkin_all_day', 'checkin_continuous_day'], true) ? $new_instance['rank_by'] : 'credits';
$instance['count'] = max(1, min(20, (int) ($new_instance['count'] ?? 5)));
$instance['show_avatar'] = !empty($new_instance['show_avatar']) ? 1 : 0;
$instance['checkin_btn'] = !empty($new_instance['checkin_btn']) ? 1 : 0;
$instance['top_badge'] = !empty($new_instance['top_badge']) ? 1 : 0;
$instance['desc'] = in_array($new_instance['desc'] ?? '', ['desc', 'user_registered', 'last_login', 'last_checkin'], true) ? $new_instance['desc'] : 'desc';
$instance['in_affix'] = !empty($new_instance['in_affix']) ? 1 : 0;
return $instance;
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'rank_by' => in_array($new_instance['rank_by'] ?? '', ['credits', 'posts', 'followers', 'checkin_all_day', 'checkin_continuous_day'], true) ? $new_instance['rank_by'] : 'credits',
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 5))),
'show_avatar' => !empty($new_instance['show_avatar']) ? 1 : 0,
'checkin_btn' => !empty($new_instance['checkin_btn']) ? 1 : 0,
'top_badge' => !empty($new_instance['top_badge']) ? 1 : 0,
'desc' => in_array($new_instance['desc'] ?? '', ['desc', 'user_registered', 'last_login', 'last_checkin'], true) ? $new_instance['desc'] : 'desc',
]);
}
}
+8 -3
View File
@@ -7,9 +7,13 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetVideoPlayer extends \WP_Widget {
use CommonWidgetFields;
public function __construct() {
parent::__construct(
@@ -130,10 +134,11 @@ class WidgetVideoPlayer extends \WP_Widget {
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('hide_controller')); ?>" value="1" <?php checked(!empty($instance['hide_controller'])); ?>> <?php esc_html_e('隐藏控制条样式', 'aksrt'); ?></label>
</p>
<?php
}
$this->render_common_form_section($instance);
}
public function update($new_instance, $old_instance): array {
return [
$business = [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'video_url' => esc_url_raw(trim((string) ($new_instance['video_url'] ?? ''))),
'poster' => esc_url_raw(trim((string) ($new_instance['poster'] ?? ''))),
@@ -141,6 +146,6 @@ class WidgetVideoPlayer extends \WP_Widget {
'autoplay' => !empty($new_instance['autoplay']) ? 1 : 0,
'loop' => !empty($new_instance['loop']) ? 1 : 0,
'hide_controller' => !empty($new_instance['hide_controller']) ? 1 : 0,
];
]; return $this->update_common_fields($new_instance, $old_instance, $business);
}
}
+11 -9
View File
@@ -7,9 +7,12 @@
namespace AKSRT\Widgets;
use AKSRT\Widgets\Traits\CommonWidgetFields;
defined('ABSPATH') || exit;
class WidgetYiyan extends \WP_Widget {
use CommonWidgetFields;
/**
* @return array<string,string>
@@ -58,7 +61,7 @@ class WidgetYiyan extends \WP_Widget {
$interval = !empty($instance['interval']) ? max(3, min(30, (int) $instance['interval'])) : 5;
$type = self::sanitize_type((string) ($instance['type'] ?? ''));
$icon = !empty($instance['icon']) ? (string) $instance['icon'] : 'fas fa-quote-left';
$in_affix = !empty($instance['in_affix']);
$affix = function_exists('aksrt_widget_affix_attrs') ? aksrt_widget_affix_attrs($instance) : ['class' => '', 'attr' => ''];
$anim = sanitize_key((string) ($instance['obs_animation'] ?? ''));
$anim_repeat = !empty($instance['animation_repeat']);
@@ -69,13 +72,15 @@ class WidgetYiyan extends \WP_Widget {
}
// zibll shell: theme-box + yiyan-box main-bg text-center box-body radius8 main-shadow.
// NOTE: obs_animation is this widget's own per-widget animation business
// field (kept as-is); the shared common `animation_in` field added via
// render_common_form_section() is a separate additional control.
$pack = function_exists('aksrt_obs_animate_attrs')
? aksrt_obs_animate_attrs($anim, $anim_repeat, 0)
: ['class' => '', 'attr' => ''];
$affix = $in_affix ? ' data-affix="true"' : '';
$box_class = 'theme-box yiyan-box-wrap' . $pack['class'];
echo '<div' . $affix . ' class="' . esc_attr(trim($box_class)) . '"' . $pack['attr'] . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<div' . $affix['attr'] . ' class="' . esc_attr(trim($box_class)) . '"' . $pack['attr'] . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<div class="yiyan-box main-bg text-center box-body radius8 main-shadow">';
if (function_exists('aksrt_render_yiyan_block')) {
@@ -155,9 +160,6 @@ class WidgetYiyan extends \WP_Widget {
name="<?php echo esc_attr($this->get_field_name('icon')); ?>" type="text"
value="<?php echo esc_attr($icon); ?>">
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('in_affix')); ?>" value="1" <?php checked(!empty($instance['in_affix'])); ?>> <?php esc_html_e('侧栏随动', 'aksrt'); ?></label>
</p>
<p>
<label><?php esc_html_e('入场动画', 'aksrt'); ?>
<select name="<?php echo esc_attr($this->get_field_name('obs_animation')); ?>">
@@ -168,6 +170,7 @@ class WidgetYiyan extends \WP_Widget {
</select>
</label>
</p>
<?php $this->render_common_form_section($instance); ?>
<?php
}
@@ -177,15 +180,14 @@ class WidgetYiyan extends \WP_Widget {
* @return array<string,mixed>
*/
public function update($new_instance, $old_instance): array {
return [
return $this->update_common_fields($new_instance, $old_instance, [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'count' => max(1, min(10, absint($new_instance['count'] ?? 5))),
'interval' => max(3, min(30, absint($new_instance['interval'] ?? 5))),
'type' => self::sanitize_type((string) ($new_instance['type'] ?? '')),
'icon' => sanitize_text_field((string) ($new_instance['icon'] ?? 'fas fa-quote-left')),
'in_affix' => !empty($new_instance['in_affix']) ? 1 : 0,
'obs_animation' => sanitize_key((string) ($new_instance['obs_animation'] ?? '')),
'animation_repeat' => !empty($new_instance['animation_repeat']) ? 1 : 0,
];
]);
}
}