feat(forum): plate lists widget payload + REST
Shared query_payload for plate lists and /forum/frontend/widgets/plates for remote refresh.
This commit is contained in:
@@ -252,6 +252,11 @@ class Forum {
|
|||||||
'callback' => [$this, 'rest_widget_topics'],
|
'callback' => [$this, 'rest_widget_topics'],
|
||||||
'permission_callback' => '__return_true',
|
'permission_callback' => '__return_true',
|
||||||
]);
|
]);
|
||||||
|
register_rest_route('aksrt/v1', '/forum/frontend/widgets/plates', [
|
||||||
|
'methods' => 'GET',
|
||||||
|
'callback' => [$this, 'rest_widget_plates'],
|
||||||
|
'permission_callback' => '__return_true',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rest_widget_topics(\WP_REST_Request $request) {
|
public function rest_widget_topics(\WP_REST_Request $request) {
|
||||||
@@ -278,6 +283,24 @@ class Forum {
|
|||||||
], 200);
|
], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function rest_widget_plates(\WP_REST_Request $request) {
|
||||||
|
if (!class_exists('\AKSRT\Widgets\WidgetForumPlateLists')) {
|
||||||
|
return new \WP_REST_Response(['success' => false, 'message' => 'widget unavailable'], 500);
|
||||||
|
}
|
||||||
|
$instance = [
|
||||||
|
'showposts' => max(1, min(30, (int) ($request->get_param('showposts') ?? $request->get_param('count') ?? 8))),
|
||||||
|
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'menu_order')),
|
||||||
|
'style' => sanitize_key((string) ($request->get_param('style') ?? 'default')),
|
||||||
|
'filter' => sanitize_key((string) ($request->get_param('filter') ?? '')),
|
||||||
|
'cat' => sanitize_text_field((string) ($request->get_param('cat') ?? '')),
|
||||||
|
];
|
||||||
|
$payload = \AKSRT\Widgets\WidgetForumPlateLists::query_payload($instance);
|
||||||
|
return new \WP_REST_Response([
|
||||||
|
'success' => true,
|
||||||
|
'html' => (string) ($payload['html'] ?? ''),
|
||||||
|
], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function render_board_cards(array $boards): void {
|
public function render_board_cards(array $boards): void {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Forum plate list (zibll zib_bbs_widget_ui_plate_lists lite).
|
* Forum plate list (zibll zib_bbs_widget_ui_plate_lists + ajax).
|
||||||
*
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
@@ -16,20 +16,18 @@ class WidgetForumPlateLists extends \WP_Widget {
|
|||||||
'aksrt_forum_plate_lists',
|
'aksrt_forum_plate_lists',
|
||||||
esc_html__('论坛 - 版块列表(Plate)', 'aksrt'),
|
esc_html__('论坛 - 版块列表(Plate)', 'aksrt'),
|
||||||
[
|
[
|
||||||
'description' => esc_html__('展示论坛 plate 版块列表,支持排序与卡片样式。', 'aksrt'),
|
'description' => esc_html__('展示论坛 plate 版块列表,支持排序/卡片/AJAX。', 'aksrt'),
|
||||||
'classname' => 'widget_aksrt_forum_plate_lists',
|
'classname' => 'widget_aksrt_forum_plate_lists',
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function widget($args, $instance): void {
|
/**
|
||||||
if (!post_type_exists('aksrt_forum_plate')) {
|
* @return array
|
||||||
return;
|
*/
|
||||||
}
|
public static function build_query_args(array $instance): array {
|
||||||
|
|
||||||
$limit = max(1, min(30, (int) ($instance['showposts'] ?? 8)));
|
$limit = max(1, min(30, (int) ($instance['showposts'] ?? 8)));
|
||||||
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'menu_order'));
|
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'menu_order'));
|
||||||
$style = sanitize_key((string) ($instance['style'] ?? 'default'));
|
|
||||||
$filter = sanitize_key((string) ($instance['filter'] ?? ''));
|
$filter = sanitize_key((string) ($instance['filter'] ?? ''));
|
||||||
$cat_raw = (string) ($instance['cat'] ?? '');
|
$cat_raw = (string) ($instance['cat'] ?? '');
|
||||||
$cat_ids = array_values(array_filter(array_map('intval', preg_split('/[\s,]+/', $cat_raw) ?: [])));
|
$cat_ids = array_values(array_filter(array_map('intval', preg_split('/[\s,]+/', $cat_raw) ?: [])));
|
||||||
@@ -39,6 +37,7 @@ class WidgetForumPlateLists extends \WP_Widget {
|
|||||||
'post_status' => 'publish',
|
'post_status' => 'publish',
|
||||||
'posts_per_page' => $limit,
|
'posts_per_page' => $limit,
|
||||||
'order' => 'ASC',
|
'order' => 'ASC',
|
||||||
|
'no_found_rows' => true,
|
||||||
];
|
];
|
||||||
|
|
||||||
switch ($orderby) {
|
switch ($orderby) {
|
||||||
@@ -81,8 +80,61 @@ class WidgetForumPlateLists extends \WP_Widget {
|
|||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
$plates = get_posts($query_args);
|
return $query_args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function render_items_html(array $plates, string $style = 'default'): string {
|
||||||
if (!$plates) {
|
if (!$plates) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
ob_start();
|
||||||
|
$self = new self();
|
||||||
|
if ($style === 'card') {
|
||||||
|
echo '<div class="aksrt-plate-cards ajax-item">';
|
||||||
|
foreach ($plates as $post) {
|
||||||
|
if ($post instanceof \WP_Post) {
|
||||||
|
$self->render_card($post);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '</div>';
|
||||||
|
} else {
|
||||||
|
echo '<div class="aksrt-plate-lists ajax-item">';
|
||||||
|
foreach ($plates as $post) {
|
||||||
|
if ($post instanceof \WP_Post) {
|
||||||
|
$self->render_row($post);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '</div>';
|
||||||
|
}
|
||||||
|
return (string) ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array{html:string}
|
||||||
|
*/
|
||||||
|
public static function query_payload(array $instance): array {
|
||||||
|
if (!post_type_exists('aksrt_forum_plate')) {
|
||||||
|
return ['html' => ''];
|
||||||
|
}
|
||||||
|
$style = sanitize_key((string) ($instance['style'] ?? 'default'));
|
||||||
|
$plates = get_posts(self::build_query_args($instance));
|
||||||
|
$html = self::render_items_html($plates ?: [], $style === 'card' ? 'card' : 'default');
|
||||||
|
if ($html === '') {
|
||||||
|
$html = function_exists('aksrt_get_ajax_null')
|
||||||
|
? aksrt_get_ajax_null(__('暂无版块', 'aksrt'))
|
||||||
|
: '<p class="aksrt-plate-empty ajax-item">' . esc_html__('暂无版块', 'aksrt') . '</p>';
|
||||||
|
}
|
||||||
|
return ['html' => $html];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function widget($args, $instance): void {
|
||||||
|
if (!post_type_exists('aksrt_forum_plate')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$style = sanitize_key((string) ($instance['style'] ?? 'default'));
|
||||||
|
$payload = self::query_payload($instance);
|
||||||
|
if ($payload['html'] === '') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,24 +144,16 @@ class WidgetForumPlateLists extends \WP_Widget {
|
|||||||
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($style === 'card') {
|
// IAS-like: first paint is SSR; optional remote refresh via rest for customize.
|
||||||
echo '<div class="aksrt-plate-cards">';
|
$rest = rest_url('aksrt/v1/forum/frontend/widgets/plates');
|
||||||
foreach ($plates as $post) {
|
echo '<div class="widget-plate-lists ajaxpager mb20" data-aksrt-ajaxpager data-aksrt-ajax-url="' . esc_url($rest) . '">';
|
||||||
$this->render_card($post);
|
echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
}
|
echo '</div>';
|
||||||
echo '</div>';
|
|
||||||
} else {
|
|
||||||
echo '<div class="aksrt-plate-lists">';
|
|
||||||
foreach ($plates as $post) {
|
|
||||||
$this->render_row($post);
|
|
||||||
}
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
}
|
}
|
||||||
|
|
||||||
private function render_row(\WP_Post $post): void {
|
public function render_row(\WP_Post $post): void {
|
||||||
$id = (int) $post->ID;
|
$id = (int) $post->ID;
|
||||||
$url = get_permalink($id);
|
$url = get_permalink($id);
|
||||||
$thumb = get_the_post_thumbnail_url($id, 'thumbnail');
|
$thumb = get_the_post_thumbnail_url($id, 'thumbnail');
|
||||||
@@ -136,7 +180,7 @@ class WidgetForumPlateLists extends \WP_Widget {
|
|||||||
echo '</div></a>';
|
echo '</div></a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
private function render_card(\WP_Post $post): void {
|
public function render_card(\WP_Post $post): void {
|
||||||
$id = (int) $post->ID;
|
$id = (int) $post->ID;
|
||||||
$url = get_permalink($id);
|
$url = get_permalink($id);
|
||||||
$thumb = get_the_post_thumbnail_url($id, 'medium');
|
$thumb = get_the_post_thumbnail_url($id, 'medium');
|
||||||
|
|||||||
Reference in New Issue
Block a user