diff --git a/assets/css/frontend/widget-batch3f.css b/assets/css/frontend/widget-batch3f.css new file mode 100644 index 00000000..5ad9a74d --- /dev/null +++ b/assets/css/frontend/widget-batch3f.css @@ -0,0 +1,157 @@ +/** + * Batch3f: oneline posts + tilt cases. + */ + +.aksrt-oneline { margin-bottom: 12px; } +.aksrt-oneline__track { + display: grid; + grid-auto-flow: column; + grid-auto-columns: minmax(180px, 220px); + gap: 12px; + overflow-x: auto; + scroll-snap-type: x mandatory; + padding-bottom: 6px; + -webkit-overflow-scrolling: touch; +} +.aksrt-oneline.style-mini .aksrt-oneline__track { + grid-auto-columns: minmax(140px, 160px); +} +.aksrt-oneline__item { + display: flex; + flex-direction: column; + border-radius: 12px; + overflow: hidden; + border: 1px solid var(--color-line, #e5e7eb); + background: var(--surface-1, #fff); + text-decoration: none; + color: inherit; + scroll-snap-align: start; + min-width: 0; +} +.aksrt-oneline.style-list .aksrt-oneline__item { + flex-direction: row; + align-items: center; + gap: 10px; + padding: 8px; +} +.aksrt-oneline__thumb { + height: 110px; + background: var(--surface-2, #f3f4f6) center/cover no-repeat; + overflow: hidden; +} +.aksrt-oneline.style-mini .aksrt-oneline__thumb { height: 90px; } +.aksrt-oneline.style-list .aksrt-oneline__thumb { + width: 64px; + height: 64px; + border-radius: 8px; + flex-shrink: 0; +} +.aksrt-oneline__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; } +.aksrt-oneline__thumb.is-empty { background: linear-gradient(135deg, #e2e8f0, #f8fafc); } +.aksrt-oneline__body { padding: 10px 12px 12px; min-width: 0; } +.aksrt-oneline.style-list .aksrt-oneline__body { padding: 0; } +.aksrt-oneline__title { + font-size: 13px; + font-weight: 600; + line-height: 1.4; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} +.aksrt-oneline__meta { margin-top: 4px; font-size: 11px; color: var(--muted-2-color, #999); } + +.aksrt-tilt { + display: grid; + grid-template-columns: 1fr 1.1fr; + gap: 28px; + align-items: center; + margin-bottom: 18px; +} +@media (max-width: 991.98px) { + .aksrt-tilt { grid-template-columns: 1fr; } +} +.aksrt-tilt__badge { + display: inline-flex; + align-items: center; + gap: 6px; + font-size: 12px; + padding: 4px 10px; + border-radius: 999px; + background: #eff6ff; + color: #2563eb; + margin-bottom: 12px; +} +.aksrt-tilt__title { + font-size: 30px; + line-height: 1.25; + margin: 0 0 12px; +} +.aksrt-tilt__hl { + font-style: normal; + background: linear-gradient(90deg, #3b82f6, #a855f7); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} +.aksrt-tilt__subtitle { + font-size: 14px; + color: var(--muted-2-color, #666); + line-height: 1.7; + margin: 0 0 14px; +} +.aksrt-tilt__features { + list-style: none; + margin: 0 0 16px; + padding: 0; + display: flex; + flex-wrap: wrap; + gap: 8px 14px; + font-size: 13px; +} +.aksrt-tilt__features i { color: var(--color-primary, #3b82f6); margin-right: 4px; } +.aksrt-tilt__actions { display: flex; flex-wrap: wrap; gap: 10px; } +.aksrt-tilt__btn { + display: inline-flex; + align-items: center; + padding: 8px 16px; + border-radius: 999px; + background: var(--color-primary, #3b82f6); + color: #fff !important; + text-decoration: none; + font-size: 13px; + font-weight: 600; +} +.aksrt-tilt__showcase { + position: relative; + min-height: 260px; +} +.aksrt-tilt__img { + position: absolute; + border-radius: 14px; + overflow: hidden; + box-shadow: 0 16px 40px rgba(0,0,0,.12); + background: var(--surface-2, #f3f4f6); +} +.aksrt-tilt__img.is-main { + position: relative; + width: 100%; + aspect-ratio: 4/3; +} +.aksrt-tilt__img:not(.is-main) { + width: 42%; + aspect-ratio: 4/3; + right: -4%; + bottom: -8%; + z-index: 2; +} +.aksrt-tilt__img:nth-child(3) { + left: -4%; + top: -6%; + right: auto; + bottom: auto; + width: 38%; + z-index: 1; +} +.aksrt-tilt__img img { width: 100%; height: 100%; object-fit: cover; display: block; } +.aksrt-tilt__img.is-empty { background: linear-gradient(135deg, #dbeafe, #ede9fe); } diff --git a/assets/css/frontend/widgets.css b/assets/css/frontend/widgets.css index 08a76fb6..69e0c933 100644 --- a/assets/css/frontend/widgets.css +++ b/assets/css/frontend/widgets.css @@ -7,3 +7,4 @@ @import url("widget-batch3c.css"); @import url("widget-batch3d.css"); @import url("widget-batch3e.css"); +@import url("widget-batch3f.css"); diff --git a/inc/modules/widgets-register.php b/inc/modules/widgets-register.php index d0c15335..8ba39126 100644 --- a/inc/modules/widgets-register.php +++ b/inc/modules/widgets-register.php @@ -72,6 +72,8 @@ function aksrt_register_widgets() { register_widget('\AKSRT\Widgets\WidgetTermCards'); register_widget('\AKSRT\Widgets\WidgetPaidPosts'); register_widget('\AKSRT\Widgets\WidgetAuthorCard'); + register_widget('\AKSRT\Widgets\WidgetOnelinePosts'); + register_widget('\AKSRT\Widgets\WidgetTiltCases'); // Forum widgets diff --git a/src/AKSRT/Widgets/WidgetOnelinePosts.php b/src/AKSRT/Widgets/WidgetOnelinePosts.php new file mode 100644 index 00000000..98a445df --- /dev/null +++ b/src/AKSRT/Widgets/WidgetOnelinePosts.php @@ -0,0 +1,163 @@ + esc_html__('横向滚动的文章卡片/迷你列表。', 'aksrt'), + 'classname' => 'widget_aksrt_oneline_posts', + ] + ); + } + + public function widget($args, $instance): void { + $count = max(1, min(20, (int) ($instance['count'] ?? 8))); + $style = sanitize_key((string) ($instance['style'] ?? 'card')); + if (!in_array($style, ['card', 'mini', 'list'], true)) { + $style = 'card'; + } + $orderby = sanitize_key((string) ($instance['orderby'] ?? 'date')); + $cat = (int) ($instance['cat'] ?? 0); + $limit_day = max(0, (int) ($instance['limit_day'] ?? 0)); + + $query = [ + 'post_type' => 'post', + 'post_status' => 'publish', + 'posts_per_page' => $count, + 'ignore_sticky_posts' => true, + 'no_found_rows' => true, + ]; + if ($cat > 0) { + $query['cat'] = $cat; + } + if ($limit_day > 0) { + $query['date_query'] = [['after' => $limit_day . ' days ago']]; + } + switch ($orderby) { + case 'views': + $query['meta_key'] = 'aksrt_post_views'; + $query['orderby'] = 'meta_value_num'; + $query['order'] = 'DESC'; + break; + case 'comments': + $query['orderby'] = 'comment_count'; + $query['order'] = 'DESC'; + break; + case 'rand': + $query['orderby'] = 'rand'; + break; + default: + $query['orderby'] = 'date'; + $query['order'] = 'DESC'; + } + + $q = new \WP_Query($query); + if (!$q->have_posts()) { + wp_reset_postdata(); + return; + } + + 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 + } + + echo '
+ +
++ +
++ +
++ +
++ +
++ +
+ sanitize_text_field((string) ($new_instance['title'] ?? '')), + 'count' => max(1, min(20, (int) ($new_instance['count'] ?? 8))), + 'style' => $style, + 'orderby' => $orderby, + 'cat' => max(0, (int) ($new_instance['cat'] ?? 0)), + 'limit_day' => max(0, (int) ($new_instance['limit_day'] ?? 0)), + ]; + } +} diff --git a/src/AKSRT/Widgets/WidgetTiltCases.php b/src/AKSRT/Widgets/WidgetTiltCases.php new file mode 100644 index 00000000..479fe2cb --- /dev/null +++ b/src/AKSRT/Widgets/WidgetTiltCases.php @@ -0,0 +1,258 @@ + esc_html__('左文案 + 右侧叠层图片案例展示。', 'aksrt'), + 'classname' => 'widget_aksrt_tilt_cases', + ] + ); + } + + public function widget($args, $instance): void { + $title = trim((string) ($instance['intro_title'] ?? '')); + $subtitle = trim((string) ($instance['intro_subtitle'] ?? '')); + $badge = trim((string) ($instance['intro_badge_text'] ?? '')); + $images = $this->normalize_images($instance['intro_showcase_images'] ?? []); + $features = $this->normalize_features($instance['intro_features'] ?? []); + $buttons = $this->normalize_buttons($instance['intro_buttons'] ?? []); + + if ($title === '' && $subtitle === '' && !$images) { + return; + } + + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + echo '' . esc_html($subtitle) . '
'; + } + if ($features) { + echo '+ +
++ +
++ +
++ +
++ +
++ +
++ +
++ +
++ +
+ 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'] ?? '')), + 'intro_title_highlight' => sanitize_text_field((string) ($new_instance['intro_title_highlight'] ?? '')), + 'intro_subtitle' => sanitize_textarea_field((string) ($new_instance['intro_subtitle'] ?? '')), + 'intro_features' => $this->normalize_features($new_instance['intro_features'] ?? []), + '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, + ]; + } +}