'']), 1, []); return \AKSRT\WidgetSystem\PostRenderer::items($query, $instance, 'oneline_posts'); } $inner = self::ajaxpager($instance, $slug, $widget_id, 1, ''); $html = '
'; $html .= $style === 'mini' ? '
' : ''; $html .= $inner; $html .= $style === 'mini' ? '
' : ''; return $html . '
'; } /** The .widget-ajaxpager container contract shared by posts and tab panes. */ private static function ajaxpager(array $instance, string $slug, string $widget_id, int $page, string $segment): string { $attrs = ' data-widget-items data-widget="' . esc_attr($slug) . '" data-instance="' . esc_attr($widget_id) . '" data-page="' . (int) $page . '"'; if ($segment !== '') { $attrs .= ' data-segment="' . esc_attr($segment) . '"'; } if (($instance['load_mode'] ?? '') === 'ajax') { // The runtime (lazysizes + lazyload-action) reveals this container // and clicks the single .ias-btn trigger; frontend.js then loads // the first page through the REST client. $trigger = ''; return '
' . $trigger . '
' . self::placeholder($instance) . '
'; } $payload = PostRenderer::payload($instance, $slug, $page, $segment); return '
' . $payload['html'] . $payload['paginate_html'] . '
'; } private static function placeholder(array $instance): string { $style = (string) ($instance['style'] ?? 'list'); $count = max(1, (int) ($instance['count'] ?? 6)); if ($style === 'mini') { $mini_opt = (array) ($instance['mini_opt'] ?? []); return aksrt_render_placeholder( in_array('show_thumb', $mini_opt, true) ? 'mini_thumb' : 'mini', $count ); } return aksrt_render_placeholder($style === 'card' ? 'card' : 'list', $count); } private static function tab_posts(array $instance, array $context): string { $style = in_array(($instance['style'] ?? 'mini'), ['list', 'card', 'mini'], true) ? (string) $instance['style'] : 'mini'; $tabs = array_values((array) ($instance['tabs'] ?? [])); if (!$tabs) { return ''; } $widget_id = (string) ($context['widget_id'] ?? 'preview'); $buttons = ''; $panels = ''; $key = sanitize_html_class($widget_id) ?: 'preview'; $panel_id = 'aksrt-tab-panel-' . $key; $visible_index = 0; foreach ($tabs as $index => $tab) { if (!is_array($tab) || trim((string) ($tab['title'] ?? '')) === '') continue; $tab_id = 'aksrt-tab-' . $key . '-' . $visible_index; $selected = $visible_index === 0; $buttons .= '
  • ' . wp_kses_post((string) $tab['title']) . '
  • '; if ($selected) { $body = self::ajaxpager($instance, 'tab_posts', $widget_id, 1, (string) $index); } else { // Inactive panes load lazily through the REST client on switch. $body = '
    '; } // 显隐交给 .is-loading,内联 display:none 会让 REST 客户端无法展开骨架。 $body .= '
    ' . self::placeholder($instance) . '
    '; $panels .= '
    ' . $body . '
    '; $visible_index++; } if ($buttons === '') return ''; return '
    ' . $panels . '
    '; } private static function term_cards(array $instance): string { $term_ids = array_values(array_filter(array_map('absint', (array) ($instance['term_id'] ?? [])))); if (!$term_ids) { return ''; } $terms = get_terms(['taxonomy' => 'category', 'include' => $term_ids, 'orderby' => 'include']); if (is_wp_error($terms) || !$terms) { return ''; } $pc_row = max(1, (int) ($instance['pc_row'] ?? 2)); $m_row = max(1, (int) ($instance['m_row'] ?? 2)); $row_class = 'col-sm-' . (int) (12 / $pc_row); $row_class .= $m_row > 1 ? ' col-xs-' . (int) (12 / $m_row) : ''; $is_row = count($terms) > 1; $target_blank = !empty($instance['target_blank']) ? '_blank' : ''; $animation = (string) ($instance['obs_animation'] ?? ''); $html = ''; foreach ($terms as $term) { $count = (int) $term->count; $name = aksrt_widget_str_cut((string) $term->name, 16); $description = aksrt_widget_str_cut((string) $term->description, 24); $href = get_term_link($term); if (is_wp_error($href)) { continue; } $icon = ''; $card = [ 'type' => (string) ($instance['type'] ?? 'style-1'), 'class' => 'mb10', 'img' => aksrt_widget_term_cover_url((int) $term->term_id), 'alt' => $name . '-' . $description, 'link' => ['url' => esc_url((string) $href), 'target' => $target_blank], 'text1' => $name, 'text2' => $description, 'text3' => $icon . $count . __('篇文章', 'aksrt'), 'height_scale' => (int) ($instance['height_scale'] ?? 60), 'mask_opacity' => (int) ($instance['mask_opacity'] ?? 10), ]; $type = (string) $card['type']; if ($type === 'style-2' || $type === 'style-4') { $card['text3'] = '' . $icon . $count . ''; } elseif ($type === 'style-3') { $card['text1'] = $icon . $name; $card['text3'] = '' . $count . __('篇文章', 'aksrt'); } $attr = ''; $col_class = ''; if ($animation !== '') { $col_class .= ' obs-animate ani-' . sanitize_html_class($animation); $attr .= ' data-animation="' . esc_attr($animation) . '"'; if (!empty($instance['animation_repeat'])) { $attr .= ' data-animation-repeat="true"'; } } if ($is_row) { $col_class .= ' ' . $row_class; } $html .= '
    ' . aksrt_graphic_card($card) . '
    '; } return '
    ' . ($is_row ? '
    ' : '') . $html . ($is_row ? '
    ' : '') . '
    '; } private static function term_aggregation(array $instance): string { $term_ids = array_values(array_filter(array_map('absint', (array) ($instance['term_id'] ?? [])))); if (!$term_ids) { return ''; } $pc_row = max(1, min(2, (int) ($instance['pc_row'] ?? 2))); $row_class = 'col-sm-' . (int) (12 / $pc_row) . ' col-xs-12'; $is_row = count($term_ids) > 1; $animation = (string) ($instance['obs_animation'] ?? ''); $html = ''; foreach ($term_ids as $key => $term_id) { $attr = ''; $col_class = ''; if ($animation !== '') { $col_class .= ' obs-animate ani-' . sanitize_html_class($animation); $attr .= ' data-animation="' . esc_attr($animation) . '"'; $attr .= ' style=" --delay: ' . esc_attr((string) ($key * 0.15)) . 's; "'; if (!empty($instance['animation_repeat'])) { $attr .= ' data-animation-repeat="true"'; } } if ($is_row) { $col_class .= ' ' . $row_class; } $html .= '
    '; $html .= aksrt_widget_term_aggregation([ 'term_id' => (int) $term_id, 'target_blank' => !empty($instance['target_blank']), 'orderby' => (string) ($instance['orderby'] ?? 'modified'), 'order' => (($instance['order'] ?? 'desc') === 'asc') ? 'ASC' : 'DESC', 'count' => (int) ($instance['count'] ?? 4), ]); $html .= '
    '; } return '
    ' . ($is_row ? '
    ' : '') . $html . ($is_row ? '
    ' : '') . '
    '; } private static function post_pay(array $instance): string { $post = get_post(); if (!$post instanceof \WP_Post || !function_exists('aksrt_get_pay_meta')) { return ''; } $meta = aksrt_get_pay_meta($post); if (($meta['pay_type'] ?? 'no') === 'no') { return ''; } return aksrt_get_paywall_html($post, [ 'layout' => 'widget', 'theme' => (string) $instance['theme'], ]); } }