max_num_pages); $total = (int) $query->found_posts; return [ 'html' => $html, 'paginate_html' => self::pagination($instance, $page, $max_pages), 'has_more' => $page < $max_pages, 'page' => $page, 'max_pages' => $max_pages, 'total' => $total, ]; } public static function items(\WP_Query $query, array $instance, string $slug, int $page = 1): string { if (!$query->have_posts()) { return function_exists('aksrt_widget_ajax_null') ? aksrt_widget_ajax_null() : RendererHelpers::empty_state(__('暂无内容', 'aksrt')); } $style = (string) ($instance['style'] ?? 'card'); $mode = in_array($style, ['list', 'card', 'mini'], true) ? $style : 'card'; $mini_opt = (array) ($instance['mini_opt'] ?? []); $config = [ 'type' => $mode === 'card' ? 'card' : 'list', 'show_number' => in_array('show_number', $mini_opt, true), 'show_thumb' => in_array('show_thumb', $mini_opt, true), 'show_meta' => in_array('show_meta', $mini_opt, true), 'number_offset' => ($page - 1) * max(1, (int) ($instance['count'] ?? 8)), 'widget_style' => $mode, ]; if ($slug === 'oneline_posts') { return self::oneline($query, $config, $mode); } if ($mode === 'mini') { return aksrt_render_mini_list($query, array_merge($config, ['class' => 'ajax-item']), false); } // The .widget-ajaxpager container rendered by the caller is the ajax // target, so item markup goes in without the page-level list wrapper. return aksrt_render_post_list(array_merge($config, ['skip_wrapper' => true]), $query, false); } private static function oneline(\WP_Query $query, array $config, string $style): string { $items = ''; while ($query->have_posts()) { $query->the_post(); if ($style === 'mini') { $data = aksrt_renderer_collect_post_data($config); $items .= $data ? aksrt_renderer_mini($data, array_merge($config, [ 'class' => 'posts-item', 'show_thumb' => true, 'show_meta' => true, 'show_number' => false, ])) : ''; } else { $items .= aksrt_render_post(array_merge($config, [ 'type' => $style === 'card' ? 'card' : 'list', 'is_mult_thumb' => 'disable', 'is_no_thumb' => 'disable', ])); } } wp_reset_postdata(); return '
' . $items . '
'; } /** * Pagination contract: '' keeps the hidden stub, ajax renders the load * more trigger, number renders numbered page links; all targets carry the * `.widget-ajaxpager` reference attribute. Interactive controls stay clear * of the runtime's legacy `.ajax-next` HTML pipeline — the widget system * owns the REST client in frontend.js. */ private static function pagination(array $instance, int $page, int $max_pages): string { $mode = (string) ($instance['paginate'] ?? ''); if ($mode === '' || $mode === 'none') { return '
'; } if ($max_pages <= 1) { return ''; } if ($mode === 'number' || $mode === 'numbered') { $links = ''; $start = max(1, min($page - 2, $max_pages - 4)); $end = min($max_pages, max($start + 4, $page + 2)); for ($number = $start; $number <= $end; $number++) { if ($number === $page) { $links .= '' . $number . ''; continue; } $links .= '' . $number . ''; } return ''; } return '
' . esc_html__('加载更多', 'aksrt') . '
'; } }