feat(widgets): product mini rows + paid list/card styles

Product list mini/list compact DOM; paid posts style mini|list|card via
shared post renderer; residual CSS for mini product/paid grids.
This commit is contained in:
kate522 committed 2026-07-21 13:13:08 +08:00
1 parent 1de0cac8df
commit c507ffaa23
4 files changed
+65 -12

No files matched your search

+19
View File
@@ -2533,3 +2533,22 @@ a.main-color > .icon-cover-card:hover,
.aksrt-plate-info .count-mates .em14 { font-weight: 700; line-height: 1.2; } .aksrt-plate-info .count-mates .em14 { font-weight: 700; line-height: 1.2; }
.aksrt-fi[data-aksrt-feature-intro] .aksrt-fi__panel { display: none; } .aksrt-fi[data-aksrt-feature-intro] .aksrt-fi__panel { display: none; }
.aksrt-fi[data-aksrt-feature-intro] .aksrt-fi__panel.is-active { display: block; } .aksrt-fi[data-aksrt-feature-intro] .aksrt-fi__panel.is-active { display: block; }
/* batch43-45 residual */
.aksrt-product-widget__item--mini {
gap: 10px; padding: 8px 0;
border-bottom: 1px solid var(--color-line, rgba(0,0,0,.06));
}
.aksrt-product-widget__item--mini:last-child { border-bottom: 0; }
.aksrt-product-widget__thumb.mini {
flex: 0 0 56px; width: 56px; height: 56px; border-radius: 8px; overflow: hidden;
background: var(--surface-2, #f3f4f6); display: block;
}
.aksrt-product-widget__thumb.mini img { width: 100%; height: 100%; object-fit: cover; display: block; }
.aksrt-paid-posts.style-card { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
.aksrt-paid-posts.style-list .aksrt-paid-posts__item { margin-bottom: 10px; }
.aksrt-paid-posts__price.badge {
display: inline-block; margin-top: 4px; padding: 1px 6px; border-radius: 4px;
background: rgba(240,68,148,.1); color: var(--theme-color, #f04494); font-size: 12px;
}
+1
View File
@@ -134,6 +134,7 @@ class WidgetAjax {
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')), 'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')),
'cat' => max(0, (int) ($request->get_param('cat') ?? 0)), 'cat' => max(0, (int) ($request->get_param('cat') ?? 0)),
'limit_day' => max(0, (int) ($request->get_param('limit_day') ?? 0)), 'limit_day' => max(0, (int) ($request->get_param('limit_day') ?? 0)),
'style' => sanitize_key((string) ($request->get_param('style') ?? 'mini')),
'paginate' => $paginate, 'paginate' => $paginate,
]; ];
$page = max(1, (int) ($request->get_param('page') ?? $request->get_param('paged') ?? 1)); $page = max(1, (int) ($request->get_param('page') ?? $request->get_param('paged') ?? 1));
+23 -7
View File
@@ -72,7 +72,7 @@ class WidgetPaidPosts extends \WP_Widget {
return $query; return $query;
} }
public static function render_items_html(\WP_Query $q): string { public static function render_items_html(\WP_Query $q, string $style = 'mini'): string {
if (!$q->have_posts()) { if (!$q->have_posts()) {
return ''; return '';
} }
@@ -91,17 +91,18 @@ class WidgetPaidPosts extends \WP_Widget {
} else { } else {
$badge = __('付费', 'aksrt'); $badge = __('付费', 'aksrt');
} }
$mode = in_array($style, ['list', 'card', 'mini'], true) ? $style : 'mini';
if (function_exists('aksrt_render_post')) { if (function_exists('aksrt_render_post')) {
$item = aksrt_render_post([ $item = aksrt_render_post([
'mode' => 'mini', 'mode' => $mode,
'context' => 'widget', 'context' => 'widget',
'show_thumb' => true, 'show_thumb' => true,
'show_meta' => true, 'show_meta' => true,
'show_excerpt' => false, 'show_excerpt' => $mode === 'list',
'extra_class' => 'ajax-item aksrt-paid-posts__mini', 'extra_class' => 'ajax-item aksrt-paid-posts__' . $mode,
]); ]);
if ($item !== '') { if ($item !== '') {
echo '<div class="aksrt-paid-posts__item is-mini ajax-item">'; echo '<div class="aksrt-paid-posts__item is-' . esc_attr($mode) . ' ajax-item">';
echo $item; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $item; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<span class="aksrt-paid-posts__price badge">' . esc_html($badge) . '</span>'; echo '<span class="aksrt-paid-posts__price badge">' . esc_html($badge) . '</span>';
echo '</div>'; echo '</div>';
@@ -126,9 +127,13 @@ class WidgetPaidPosts extends \WP_Widget {
$paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax')); $paginate = sanitize_key((string) ($instance['paginate'] ?? 'ajax'));
$count = max(1, min(20, (int) ($instance['count'] ?? 6))); $count = max(1, min(20, (int) ($instance['count'] ?? 6)));
$q = new \WP_Query(self::build_query_args($instance, $page)); $q = new \WP_Query(self::build_query_args($instance, $page));
$items = self::render_items_html($q); $style = sanitize_key((string) ($instance['style'] ?? 'mini'));
if (!in_array($style, ['mini', 'list', 'card'], true)) {
$style = 'mini';
}
$items = self::render_items_html($q, $style);
$wrap_tag = (strpos($items, 'posts-mini') !== false || strpos($items, 'aksrt-paid-posts__mini') !== false) ? 'div' : 'ul'; $wrap_tag = (strpos($items, 'posts-mini') !== false || strpos($items, 'aksrt-paid-posts__mini') !== false) ? 'div' : 'ul';
$html = $items !== '' ? '<' . $wrap_tag . ' class="aksrt-paid-posts">' . $items . '</' . $wrap_tag . '>' : ''; $html = $items !== '' ? '<' . $wrap_tag . ' class="aksrt-paid-posts style-' . esc_attr($style) . '">' . $items . '</' . $wrap_tag . '>' : '';
if ($html === '' && $page === 1) { if ($html === '' && $page === 1) {
$html = function_exists('aksrt_get_ajax_null') $html = function_exists('aksrt_get_ajax_null')
? aksrt_get_ajax_null(__('暂无付费内容', 'aksrt')) ? aksrt_get_ajax_null(__('暂无付费内容', 'aksrt'))
@@ -142,6 +147,7 @@ class WidgetPaidPosts extends \WP_Widget {
'orderby' => sanitize_key((string) ($instance['orderby'] ?? 'date')), 'orderby' => sanitize_key((string) ($instance['orderby'] ?? 'date')),
'cat' => max(0, (int) ($instance['cat'] ?? 0)), 'cat' => max(0, (int) ($instance['cat'] ?? 0)),
'limit_day' => max(0, (int) ($instance['limit_day'] ?? 0)), 'limit_day' => max(0, (int) ($instance['limit_day'] ?? 0)),
'style' => $style,
'paginate' => $paginate, 'paginate' => $paginate,
], static function ($v) { ], static function ($v) {
return $v !== '' && $v !== null; return $v !== '' && $v !== null;
@@ -203,6 +209,15 @@ class WidgetPaidPosts extends \WP_Widget {
<input class="tiny-text" type="number" min="1" max="20" name="<?php echo esc_attr($this->get_field_name('count')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['count'] ?? 6))); ?>"> <input class="tiny-text" type="number" min="1" max="20" name="<?php echo esc_attr($this->get_field_name('count')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['count'] ?? 6))); ?>">
</label> </label>
</p> </p>
<p>
<label><?php esc_html_e('样式', 'aksrt'); ?>
<select name="<?php echo esc_attr($this->get_field_name('style')); ?>">
<option value="mini" <?php selected(($instance['style'] ?? 'mini'), 'mini'); ?>><?php esc_html_e('迷你', 'aksrt'); ?></option>
<option value="list" <?php selected(($instance['style'] ?? ''), 'list'); ?>><?php esc_html_e('列表', 'aksrt'); ?></option>
<option value="card" <?php selected(($instance['style'] ?? ''), 'card'); ?>><?php esc_html_e('卡片', 'aksrt'); ?></option>
</select>
</label>
</p>
<p> <p>
<label><?php esc_html_e('排序', 'aksrt'); ?> <label><?php esc_html_e('排序', 'aksrt'); ?>
<select name="<?php echo esc_attr($this->get_field_name('orderby')); ?>"> <select name="<?php echo esc_attr($this->get_field_name('orderby')); ?>">
@@ -243,6 +258,7 @@ class WidgetPaidPosts extends \WP_Widget {
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')), 'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'count' => max(1, min(20, (int) ($new_instance['count'] ?? 6))), 'count' => max(1, min(20, (int) ($new_instance['count'] ?? 6))),
'orderby' => $orderby, 'orderby' => $orderby,
'style' => in_array(sanitize_key((string) ($new_instance['style'] ?? 'mini')), ['mini', 'list', 'card'], true) ? sanitize_key((string) ($new_instance['style'] ?? 'mini')) : 'mini',
'cat' => max(0, (int) ($new_instance['cat'] ?? 0)), 'cat' => max(0, (int) ($new_instance['cat'] ?? 0)),
'limit_day' => max(0, (int) ($new_instance['limit_day'] ?? 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', 'paginate' => in_array(sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')), ['none', 'ajax', 'number'], true) ? sanitize_key((string) ($new_instance['paginate'] ?? 'ajax')) : 'ajax',
+22 -5
View File
@@ -94,6 +94,7 @@ class WidgetProductList extends \WP_Widget {
return ''; return '';
} }
$oneline = $style === 'oneline'; $oneline = $style === 'oneline';
$mini = $style === 'mini' || $style === 'list';
ob_start(); ob_start();
while ($products->have_posts()) { while ($products->have_posts()) {
$products->the_post(); $products->the_post();
@@ -101,19 +102,35 @@ class WidgetProductList extends \WP_Widget {
$card = class_exists('\AKSRT\Shop\Shop') $card = class_exists('\AKSRT\Shop\Shop')
? \AKSRT\Shop\Shop::get_instance()->build_product_card_view($pid) ? \AKSRT\Shop\Shop::get_instance()->build_product_card_view($pid)
: []; : [];
$price = (float) ($card['price'] ?? 0);
$image = (string) ($card['image'] ?? '');
$ph = get_template_directory_uri() . '/assets/img/placeholder.svg';
if ($oneline) { if ($oneline) {
echo '<div class="swiper-slide ajax-item">'; echo '<div class="swiper-slide ajax-item">';
} }
if (function_exists('get_template_part') && !empty($card['id'])) { if ($mini) {
// Compact row: thumb + title + price (zibll mini shop row lite).
echo '<div class="aksrt-product-widget__item aksrt-product-widget__item--mini ajax-item flex ac">';
echo '<a href="' . esc_url(get_permalink($pid)) . '" class="aksrt-product-widget__thumb mini">';
if ($image !== '') {
echo '<img class="aksrt-lazy lazyload fit-cover" data-src="' . esc_url($image) . '" src="' . esc_url($ph) . '" alt="' . esc_attr(get_the_title($pid)) . '" loading="lazy" width="56" height="56">';
}
echo '</a>';
echo '<div class="aksrt-product-widget__info flex1 min-w0">';
echo '<a href="' . esc_url(get_permalink($pid)) . '" class="aksrt-product-widget__title text-ellipsis">' . esc_html(get_the_title($pid)) . '</a>';
echo '<div class="aksrt-product-widget__meta flex jsb ac">';
echo '<span class="aksrt-product-widget__price c-red">&yen;' . esc_html(number_format_i18n($price, 2)) . '</span>';
if (!empty($card['sales'])) {
echo '<span class="aksrt-product-widget__sales muted-2-color em09">' . esc_html((string) $card['sales']) . esc_html__(' 已售', 'aksrt') . '</span>';
}
echo '</div></div></div>';
} elseif (function_exists('get_template_part') && !empty($card['id'])) {
get_template_part('templates/parts/shop/product', 'card', [ get_template_part('templates/parts/shop/product', 'card', [
'product' => $card, 'product' => $card,
'show_sales' => true, 'show_sales' => true,
]); ]);
} else { } else {
// Fallback mini card (lazy thumbs). // Fallback card (lazy thumbs).
$price = (float) ($card['price'] ?? 0);
$image = (string) ($card['image'] ?? '');
$ph = get_template_directory_uri() . '/assets/img/placeholder.svg';
echo '<div class="aksrt-product-widget__item ajax-item">'; echo '<div class="aksrt-product-widget__item ajax-item">';
if ($image !== '') { if ($image !== '') {
echo '<a href="' . esc_url(get_permalink($pid)) . '" class="aksrt-product-widget__thumb">'; echo '<a href="' . esc_url(get_permalink($pid)) . '" class="aksrt-product-widget__thumb">';