From 6a78b553d665e5b3f001236e35ad1344bc6654c8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Jul 2026 12:42:57 +0800 Subject: [PATCH 1/3] feat(widgets): singular post pay purchase sidebar box Add WidgetPostPayBox (zibll posts_pay parity) with theme skins, paid/unpaid CTAs, sales badge, and registration. --- assets/css/frontend/widget-batch5.css | 38 ++++++ inc/modules/widgets-register.php | 1 + src/AKSRT/Widgets/WidgetPostPayBox.php | 181 +++++++++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 src/AKSRT/Widgets/WidgetPostPayBox.php diff --git a/assets/css/frontend/widget-batch5.css b/assets/css/frontend/widget-batch5.css index ddc37d63..c5d94b39 100644 --- a/assets/css/frontend/widget-batch5.css +++ b/assets/css/frontend/widget-batch5.css @@ -2479,3 +2479,41 @@ a.main-color > .icon-cover-card:hover, .widget-tab-posts__skeleton .placeholder.k1 { width: 80%; } .widget-tab-posts__skeleton .placeholder.s1 { width: 48%; } .posts-mini-lists.aksrt-main-posts { /* zibll mini outer */ } + + +/* batch37-39 residual */ +.aksrt-post-pay-box { position: relative; overflow: hidden; } +.aksrt-post-pay-box .pay-tag.abs-center { + position: absolute; top: 12px; left: 50%; transform: translateX(-50%); + z-index: 2; padding: 2px 10px; border-radius: 999px; background: rgba(0,0,0,.35); color: #fff; font-size: 12px; +} +.aksrt-post-pay-box__hero { position: relative; overflow: hidden; min-height: 120px; color: #fff; } +.aksrt-post-pay-box__blob { opacity: .55; pointer-events: none; } +.aksrt-post-pay-box__blob--a { height: 200px; left: 75%; width: 200px; top: -34%; border-radius: 100%; } +.aksrt-post-pay-box__blob--b { height: 305px; width: 337px; left: -229px; border-radius: 100%; opacity: .7; } +.aksrt-post-pay-box .box-body { position: relative; z-index: 1; } +.aksrt-post-pay-box .img-badge.hot { position: absolute; top: 8px; right: 8px; z-index: 2; } +.aksrt-post-pay-box .but.btn-block { width: 100%; justify-content: center; } +.aksrt-main-posts__skeleton .placeholder-row, +.aksrt-product-tab__skeleton .placeholder-row { + display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; +} +.aksrt-main-posts__skeleton .posts-mini.placeholder-row { flex-direction: row; align-items: center; gap: 10px; } +.aksrt-main-posts__skeleton .thumb-placeholder, +.aksrt-product-tab__skeleton .placeholder.thumb { + width: 72px; height: 54px; border-radius: 8px; background: var(--surface-2, #eee); +} +.aksrt-product-tab__skeleton .placeholder.thumb { width: 100%; height: 100px; } +.aksrt-main-posts__skeleton .placeholder.k1, +.aksrt-main-posts__skeleton .placeholder.t1, +.aksrt-main-posts__skeleton .placeholder.s1, +.aksrt-product-tab__skeleton .placeholder.k1, +.aksrt-product-tab__skeleton .placeholder.s1 { + height: 12px; border-radius: 4px; background: var(--surface-2, #eee); +} +.aksrt-main-posts__skeleton .placeholder.k1, +.aksrt-product-tab__skeleton .placeholder.k1 { width: 80%; } +.aksrt-main-posts__skeleton .placeholder.s1, +.aksrt-product-tab__skeleton .placeholder.s1 { width: 48%; } +.aksrt-main-posts[data-load-mode="ajax"].is-ajax-loading { opacity: .85; } +.widget-search-box.is-affix { position: sticky; top: 72px; } diff --git a/inc/modules/widgets-register.php b/inc/modules/widgets-register.php index fcde9935..3b9ab49b 100644 --- a/inc/modules/widgets-register.php +++ b/inc/modules/widgets-register.php @@ -81,6 +81,7 @@ function aksrt_register_widgets() { register_widget('\AKSRT\Widgets\WidgetFeatureIntro'); register_widget('\AKSRT\Widgets\WidgetTermCards'); register_widget('\AKSRT\Widgets\WidgetPaidPosts'); + register_widget('\AKSRT\Widgets\WidgetPostPayBox'); register_widget('\AKSRT\Widgets\WidgetAuthorCard'); register_widget('\AKSRT\Widgets\WidgetOnelinePosts'); register_widget('\AKSRT\Widgets\WidgetTiltCases'); diff --git a/src/AKSRT/Widgets/WidgetPostPayBox.php b/src/AKSRT/Widgets/WidgetPostPayBox.php new file mode 100644 index 00000000..7128f12b --- /dev/null +++ b/src/AKSRT/Widgets/WidgetPostPayBox.php @@ -0,0 +1,181 @@ + esc_html__('显示当前文章/帖子的付费购买模块,推荐放在详情侧栏。', 'aksrt'), + 'classname' => 'widget_aksrt_post_pay_box', + ] + ); + } + + /** + * @param array $instance + */ + public static function render_html(array $instance = []): string { + if (!is_singular(['post', 'page', 'aksrt_forum_topic', 'aksrt_product'])) { + return ''; + } + $post = get_queried_object(); + if (!$post instanceof \WP_Post) { + return ''; + } + if (!function_exists('aksrt_get_pay_meta') || !function_exists('aksrt_is_paid_post')) { + return ''; + } + if (!aksrt_is_paid_post($post)) { + return ''; + } + + $meta = aksrt_get_pay_meta($post); + $pay_type = (string) ($meta['pay_type'] ?? 'no'); + if ($pay_type === '' || $pay_type === 'no') { + return ''; + } + + $theme = sanitize_html_class((string) ($instance['theme'] ?? 'jb-red')); + if ($theme === '') { + $theme = 'jb-red'; + } + + $has_access = function_exists('aksrt_has_paid_access') ? aksrt_has_paid_access($post) : false; + $priced = function_exists('aksrt_get_user_pay_price') ? aksrt_get_user_pay_price($post) : null; + $pay_modo = is_array($priced) && (($priced['modo'] ?? '') === 'points') ? 'points' : '0'; + $amount = is_array($priced) ? (float) ($priced['amount'] ?? 0) : (float) ($meta['price'] ?? 0); + $currency = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_currency_name() : __('积分', 'aksrt'); + $cash_symbol = '¥'; + if (class_exists('\AKSRT\Settings\Settings')) { + $paid_s = \AKSRT\Settings\Settings::get_paid_content_settings(); + $cash_symbol = (string) ($paid_s['display']['currency_symbol'] ?? '¥'); + } + $price_text = $pay_modo === 'points' + ? (function_exists('aksrt_format_price') ? aksrt_format_price($amount) : (string) $amount) . ' ' . $currency + : $cash_symbol . (function_exists('aksrt_format_price') ? aksrt_format_price($amount) : number_format($amount, 2, '.', '')); + + $type_labels = [ + 'reading' => __('付费阅读', 'aksrt'), + 'download' => __('付费下载', 'aksrt'), + 'gallery' => __('付费图库', 'aksrt'), + 'video' => __('付费视频', 'aksrt'), + 'vip' => __('会员专属', 'aksrt'), + ]; + $type_label = $type_labels[$pay_type] ?? __('付费内容', 'aksrt'); + $cta_map = [ + 'reading' => __('查看内容', 'aksrt'), + 'download' => __('获取下载', 'aksrt'), + 'gallery' => __('查看图片', 'aksrt'), + 'video' => __('查看视频', 'aksrt'), + 'vip' => __('查看内容', 'aksrt'), + ]; + $cta_label = $cta_map[$pay_type] ?? __('查看内容', 'aksrt'); + + $sales = 0; + if (function_exists('aksrt_get_download_box_meta')) { + $box = aksrt_get_download_box_meta($post); + $sales = (int) ($box['sales_count'] ?? 0); + } + + $login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink($post)); + $is_logged_in = is_user_logged_in(); + $demo = trim((string) ($meta['demo_url'] ?? '')); + + ob_start(); + echo '
'; + echo '' . esc_html($type_label) . ''; + echo '
'; + echo '
'; + echo '
'; + echo '
'; + if ($has_access) { + echo '

'; + echo '' . esc_html__('已解锁', 'aksrt') . ''; + } else { + echo '
'; + if ($amount > 0) { + echo '
' . esc_html($price_text) . '
'; + } else { + echo '
' . esc_html__('免费', 'aksrt') . '
'; + } + echo '
'; + } + echo '
'; + + echo '
'; + if ($has_access) { + echo ''; + } elseif (!$is_logged_in) { + echo ''; + if ($amount > 0 && $pay_modo !== 'points' && function_exists('aksrt_allow_guest_content_pay') && aksrt_allow_guest_content_pay($post)) { + echo '
'; + } + } else { + echo '
'; + } + if ($demo !== '') { + echo ''; + } + echo '
'; + if ($sales > 0) { + echo '' . esc_html(sprintf(/* translators: sales count */ __('已售 %s', 'aksrt'), (string) $sales)) . ''; + } + echo '
'; + return (string) ob_get_clean(); + } + + public function widget($args, $instance): void { + $html = self::render_html($instance); + if ($html === '') { + return; + } + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + public function form($instance): void { + $theme = sanitize_html_class((string) ($instance['theme'] ?? 'jb-red')); + $opts = [ + 'jb-red' => __('红', 'aksrt'), + 'jb-yellow' => __('橙', 'aksrt'), + 'jb-blue' => __('蓝', 'aksrt'), + 'jb-green' => __('绿', 'aksrt'), + 'jb-purple' => __('紫', 'aksrt'), + 'jb-vip1' => __('会员金', 'aksrt'), + 'jb-vip2' => __('会员灰', 'aksrt'), + ]; + ?> +

+

+ +

+ $theme]; + } +} From aed056152ce78943785a54ead00d635e45e14b62 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Jul 2026 12:42:58 +0800 Subject: [PATCH 2/3] feat(widgets): shared tab JS + main posts ajax load_mode Move category/forum/product tab lazy load into widget-set.js with skeletons; MainPosts gains load_mode=ajax first-paint placeholders. --- assets/js/widget-set.js | 283 ++++++++++++++++++++- src/AKSRT/Widgets/CategoryTabsWidget.php | 61 +---- src/AKSRT/Widgets/WidgetForumTabTopics.php | 46 +--- src/AKSRT/Widgets/WidgetMainPosts.php | 67 ++++- src/AKSRT/Widgets/WidgetProductTab.php | 41 +-- 5 files changed, 344 insertions(+), 154 deletions(-) diff --git a/assets/js/widget-set.js b/assets/js/widget-set.js index 5ee91678..6bd366d6 100644 --- a/assets/js/widget-set.js +++ b/assets/js/widget-set.js @@ -9,8 +9,16 @@ (function () { 'use strict'; + function restHeaders() { + var headers = { Accept: 'application/json' }; + if (window.aksrtData && aksrtData.restNonce) { + headers['X-WP-Nonce'] = aksrtData.restNonce; + } + return headers; + } + function initWidgetTabs() { - document.querySelectorAll('.widget-tab-posts').forEach(function (widget) { + document.querySelectorAll('.widget-tab-posts[data-aksrt-tab-posts]').forEach(function (widget) { if (widget.dataset.aksrtWidgetTabsBound === '1') return; widget.dataset.aksrtWidgetTabsBound = '1'; @@ -37,11 +45,7 @@ }); var url = rest + (rest.indexOf('?') > -1 ? '&' : '?') + qs.toString(); panel.classList.add('is-ajax-loading'); - var headers = { Accept: 'application/json' }; - if (window.aksrtData && aksrtData.restNonce) { - headers['X-WP-Nonce'] = aksrtData.restNonce; - } - fetch(url, { credentials: 'same-origin', headers: headers }) + fetch(url, { credentials: 'same-origin', headers: restHeaders() }) .then(function (r) { return r.json(); }) .then(function (j) { var d = (j && j.data) || j || {}; @@ -59,16 +63,16 @@ tabs.forEach(function (tab) { tab.addEventListener('click', function () { var target = tab.getAttribute('data-tab'); - tabs.forEach(function (item) { var active = item === tab; item.classList.toggle('active', active); + item.classList.toggle('is-active', active); item.setAttribute('aria-selected', active ? 'true' : 'false'); }); - panels.forEach(function (panel) { var active = panel.getAttribute('data-tab-panel') === target; panel.classList.toggle('active', active); + panel.classList.toggle('is-active', active); if (active) { panel.removeAttribute('hidden'); loadPanel(panel, tab); @@ -81,6 +85,265 @@ }); } + // Homepage category tabs (was inline in CategoryTabsWidget). + function initCategoryTabs() { + document.querySelectorAll('[data-aksrt-home-cat-tabs]').forEach(function (section) { + if (section.dataset.aksrtCatTabsBound === '1') return; + section.dataset.aksrtCatTabsBound = '1'; + var rest = section.getAttribute('data-rest') || ''; + var count = section.getAttribute('data-count') || '6'; + var layout = section.getAttribute('data-layout') || 'card'; + var columns = section.getAttribute('data-columns') || '3'; + var context = section.getAttribute('data-context') || 'homepage'; + var showMore = section.getAttribute('data-show-more') === '1'; + var tabs = [].slice.call(section.querySelectorAll('.widget-tab-posts__tab')); + var panels = [].slice.call(section.querySelectorAll('.widget-tab-posts__panel')); + if (!tabs.length || !panels.length || !rest) return; + + function load(panel) { + if (!panel || panel.getAttribute('data-loaded') === '1') return; + var cat = panel.getAttribute('data-cat') || '0'; + var more = panel.getAttribute('data-more') || ''; + var qs = new URLSearchParams({ + cat: cat, + count: String(count), + layout: layout, + columns: String(columns), + context: context, + }); + var url = rest + (rest.indexOf('?') > -1 ? '&' : '?') + qs.toString(); + panel.classList.add('is-ajax-loading'); + fetch(url, { credentials: 'same-origin', headers: restHeaders() }) + .then(function (r) { return r.json(); }) + .then(function (j) { + var d = (j && j.data) || j || {}; + var html = d.html || ''; + if (showMore && more) { + html += ''; + } + panel.innerHTML = html || '
暂无文章
'; + panel.setAttribute('data-loaded', '1'); + panel.classList.remove('is-ajax-loading'); + }) + .catch(function () { + panel.classList.remove('is-ajax-loading'); + }); + } + + tabs.forEach(function (tab) { + tab.addEventListener('click', function () { + var target = tab.getAttribute('data-tab'); + tabs.forEach(function (item) { + var active = item === tab; + item.classList.toggle('active', active); + item.setAttribute('aria-selected', active ? 'true' : 'false'); + }); + panels.forEach(function (panel) { + var active = panel.getAttribute('data-tab-panel') === target; + panel.classList.toggle('active', active); + if (active) { + panel.removeAttribute('hidden'); + load(panel); + } else { + panel.setAttribute('hidden', ''); + } + }); + }); + }); + }); + } + + // Forum multi-tab topics. + function initForumTabTopics() { + document.querySelectorAll('.aksrt-ftab[data-aksrt-ftab]').forEach(function (root) { + if (root.dataset.aksrtFtabBound === '1') return; + root.dataset.aksrtFtabBound = '1'; + var rest = root.getAttribute('data-rest') || ''; + var count = root.getAttribute('data-count') || '6'; + var style = root.getAttribute('data-style') || 'mini'; + var plate = root.getAttribute('data-plate') || '0'; + var btns = [].slice.call(root.querySelectorAll('.aksrt-ftab__btn')); + var panels = [].slice.call(root.querySelectorAll('.aksrt-ftab__panel')); + + function load(panel, orderby) { + if (!panel || panel.getAttribute('data-loaded') === '1' || !rest) return; + var qs = new URLSearchParams({ + page: '1', + count: count, + orderby: orderby || 'date', + style: style, + plate: plate, + period: 'all', + paginate: 'none', + }); + var url = rest + (rest.indexOf('?') > -1 ? '&' : '?') + qs.toString(); + panel.classList.add('is-ajax-loading'); + fetch(url, { credentials: 'same-origin', headers: restHeaders() }) + .then(function (r) { return r.json(); }) + .then(function (j) { + var d = (j && j.data) || j || {}; + var html = d.html || ''; + panel.innerHTML = html || '
暂无内容
'; + panel.setAttribute('data-loaded', '1'); + panel.classList.remove('is-ajax-loading'); + }) + .catch(function () { + panel.classList.remove('is-ajax-loading'); + }); + } + + function go(i) { + btns.forEach(function (b, idx) { + var on = idx === i; + b.classList.toggle('is-active', on); + b.setAttribute('aria-selected', on ? 'true' : 'false'); + }); + panels.forEach(function (p, idx) { + var on = idx === i; + p.classList.toggle('is-active', on); + if (on) { + p.removeAttribute('hidden'); + } else { + p.setAttribute('hidden', ''); + } + }); + var btn = btns[i]; + var panel = panels[i]; + if (btn && panel) load(panel, btn.getAttribute('data-orderby') || 'date'); + } + + btns.forEach(function (b) { + b.addEventListener('click', function () { + go(parseInt(b.getAttribute('data-index') || '0', 10)); + }); + }); + }); + } + + // Product multi-tab. + function initProductTabs() { + document.querySelectorAll('[data-aksrt-product-tab]').forEach(function (root) { + if (root.dataset.aksrtProductTabBound === '1') return; + root.dataset.aksrtProductTabBound = '1'; + var rest = root.getAttribute('data-rest') || ''; + var per = root.getAttribute('data-per-page') || '8'; + var style = root.getAttribute('data-style') || 'default'; + var paginate = root.getAttribute('data-paginate') || 'ajax'; + + function skeleton(n) { + n = Math.max(1, Math.min(12, parseInt(n, 10) || 4)); + var html = '
'; + for (var i = 0; i < n; i++) { + html += '
'; + } + return html + '
'; + } + + function loadPanel(panel, btn) { + if (!panel || panel.getAttribute('data-loaded') === '1' || !rest) return; + var grid = panel.querySelector('[data-aksrt-ajaxpager]'); + if (!grid) return; + var qs = new URLSearchParams({ + page: '1', + per_page: per, + style: style, + paginate: paginate, + orderby: btn.getAttribute('data-orderby') || 'date', + order: 'DESC', + cat_ids: btn.getAttribute('data-cat-ids') || '', + tag_ids: btn.getAttribute('data-tag-ids') || '', + discount_ids: btn.getAttribute('data-discount-ids') || '', + }); + var url = rest + (rest.indexOf('?') > -1 ? '&' : '?') + qs.toString(); + grid.classList.add('is-ajax-loading'); + if (!grid.querySelector('.aksrt-product-tab__skeleton') && !grid.querySelector('.ajax-item')) { + grid.insertAdjacentHTML('afterbegin', skeleton(per)); + } + fetch(url, { credentials: 'same-origin', headers: restHeaders() }) + .then(function (r) { return r.json(); }) + .then(function (j) { + var d = (j && j.data && (j.data.data || j.data)) || j || {}; + var html = d.html || ''; + var pag = d.paginate_html || d.paginateHtml || ''; + var loader = grid.querySelector('[data-aksrt-ajax-loader]'); + grid.innerHTML = ''; + if (html) grid.insertAdjacentHTML('beforeend', html); + else grid.insertAdjacentHTML('beforeend', '

暂无商品

'); + if (pag) grid.insertAdjacentHTML('beforeend', pag); + if (loader) grid.appendChild(loader); + panel.setAttribute('data-loaded', '1'); + grid.classList.remove('is-ajax-loading'); + }) + .catch(function () { + grid.classList.remove('is-ajax-loading'); + }); + } + + root.querySelectorAll('.aksrt-product-tab__header').forEach(function (btn) { + btn.addEventListener('click', function () { + root.querySelectorAll('.aksrt-product-tab__header').forEach(function (b) { + b.classList.remove('is-active'); + }); + root.querySelectorAll('.aksrt-product-tab__panel').forEach(function (p) { + p.style.display = 'none'; + p.classList.remove('is-active'); + }); + btn.classList.add('is-active'); + var idx = btn.getAttribute('data-tab-index'); + var panel = root.querySelector('.aksrt-product-tab__panel[data-tab-index="' + idx + '"]'); + if (panel) { + panel.style.display = ''; + panel.classList.add('is-active'); + loadPanel(panel, btn); + } + }); + }); + }); + } + + // Main posts load_mode=ajax first paint. + function initMainPostsLazy() { + document.querySelectorAll('.aksrt-main-posts[data-load-mode="ajax"]').forEach(function (root) { + if (root.dataset.aksrtMainLazyBound === '1') return; + root.dataset.aksrtMainLazyBound = '1'; + if (root.getAttribute('data-loaded') === '1') return; + var rest = root.getAttribute('data-aksrt-ajax-url') || root.getAttribute('data-rest') || ''; + if (!rest) return; + var qs = root.getAttribute('data-query') || ''; + var url = rest + (rest.indexOf('?') > -1 ? '&' : '?') + (qs || 'page=1'); + root.classList.add('is-ajax-loading'); + fetch(url, { credentials: 'same-origin', headers: restHeaders() }) + .then(function (r) { return r.json(); }) + .then(function (j) { + var d = (j && j.data) || j || {}; + var html = d.html || ''; + var pag = d.paginate_html || d.paginateHtml || ''; + var loader = root.querySelector('[data-aksrt-ajax-loader]'); + // Remove skeleton rows. + root.querySelectorAll('.aksrt-main-posts__skeleton, .posts-mini.placeholder-row, .placeholder-row').forEach(function (n) { + n.remove(); + }); + if (html) { + root.insertAdjacentHTML('afterbegin', html); + } else { + root.insertAdjacentHTML('afterbegin', '

暂无文章

'); + } + // Replace/append paginate. + var oldPag = root.querySelector('.ajax-pag, .pagenav.ajax-pag'); + if (oldPag) oldPag.remove(); + if (pag) { + if (loader) loader.insertAdjacentHTML('beforebegin', pag); + else root.insertAdjacentHTML('beforeend', pag); + } + root.setAttribute('data-loaded', '1'); + root.classList.remove('is-ajax-loading'); + }) + .catch(function () { + root.classList.remove('is-ajax-loading'); + }); + }); + } + function initFloatingQRCodes() { var wrap = document.querySelector('.float-right'); if (!wrap) return; @@ -121,6 +384,10 @@ function init() { initWidgetTabs(); + initCategoryTabs(); + initForumTabTopics(); + initProductTabs(); + initMainPostsLazy(); initFloatingQRCodes(); } diff --git a/src/AKSRT/Widgets/CategoryTabsWidget.php b/src/AKSRT/Widgets/CategoryTabsWidget.php index 41f0242a..f279e824 100644 --- a/src/AKSRT/Widgets/CategoryTabsWidget.php +++ b/src/AKSRT/Widgets/CategoryTabsWidget.php @@ -38,7 +38,7 @@ class CategoryTabsWidget extends \WP_Widget { $tabs = $this->resolve_tabs($instance); echo $args['before_widget']; - echo '
'; + echo '
'; if (empty($tabs)) { echo function_exists('aksrt_get_widget_null') ? aksrt_get_widget_null(__('暂无可用分类', 'aksrt')) : '

' . esc_html__('暂无可用分类', 'aksrt') . '

'; @@ -95,65 +95,16 @@ class CategoryTabsWidget extends \WP_Widget { -
+
+ +
+ +
- - '; echo $args['after_widget']; } diff --git a/src/AKSRT/Widgets/WidgetForumTabTopics.php b/src/AKSRT/Widgets/WidgetForumTabTopics.php index 96adebd1..da1ef675 100644 --- a/src/AKSRT/Widgets/WidgetForumTabTopics.php +++ b/src/AKSRT/Widgets/WidgetForumTabTopics.php @@ -50,7 +50,7 @@ class WidgetForumTabTopics extends \WP_Widget { echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } - echo '
'; + echo '
'; echo '
    '; foreach ($tabs as $i => $tab) { $cls = $i === 0 ? ' is-active' : ''; @@ -78,50 +78,6 @@ class WidgetForumTabTopics extends \WP_Widget { echo '
'; } echo '
'; - ?> - - !isset($instance['show_meta']) || !empty($instance['show_meta']) ? 1 : 0, 'show_number' => !empty($instance['show_number']) ? 1 : 0, 'paginate' => $paginate, + 'load_mode' => sanitize_key((string) ($new_instance['load_mode'] ?? 'detail')) === 'ajax' ? 'ajax' : 'detail', ], static function ($v) { return $v !== '' && $v !== null; }); @@ -288,28 +289,63 @@ class WidgetMainPosts extends \WP_Widget { $style = 'list'; } $paginate = sanitize_key((string) ($instance['paginate'] ?? 'none')); + if (!in_array($paginate, ['none', 'ajax', 'number'], true)) { + $paginate = 'none'; + } + $load_mode = sanitize_key((string) ($instance['load_mode'] ?? 'detail')); + if (!in_array($load_mode, ['detail', 'ajax'], true)) { + $load_mode = 'detail'; + } $instance['style'] = $style; $instance['paginate'] = $paginate; - $payload = self::query_payload($instance, 1); - if ($payload['html'] === '' && empty($payload['total'])) { - 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 } + $count = max(1, min(30, (int) ($instance['count'] ?? 6))); $rest = rest_url('aksrt/v1/widgets/posts'); + $qs = http_build_query(array_filter([ + 'page' => 1, + 'count' => $count, + 'orderby' => sanitize_key((string) ($instance['orderby'] ?? 'date')), + 'cat' => (int) ($instance['cat'] ?? 0), + 'limit_day' => (int) ($instance['limit_day'] ?? 0), + 'topics' => (string) ($instance['topics'] ?? ''), + 'pay_type' => sanitize_key((string) ($instance['pay_type'] ?? '')), + 'style' => $style, + 'show_thumb' => !isset($instance['show_thumb']) || !empty($instance['show_thumb']) ? 1 : 0, + 'show_meta' => !isset($instance['show_meta']) || !empty($instance['show_meta']) ? 1 : 0, + 'show_number' => !empty($instance['show_number']) ? 1 : 0, + 'paginate' => $paginate, + 'load_mode' => sanitize_key((string) ($new_instance['load_mode'] ?? 'detail')) === 'ajax' ? 'ajax' : 'detail', + ], static function ($v) { + return $v !== '' && $v !== null; + })); $wrap_cls = 'aksrt-main-posts style-' . $style . ' ajaxpager'; if ($style === 'mini') { $wrap_cls .= ' zib-widget posts-mini-lists'; } - echo '
'; - echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '
'; + + if ($load_mode === 'ajax') { + // Skeleton first paint (zibll load_mode=ajax). + echo '
'; + for ($si = 0; $si < $count; $si++) { + if ($style === 'card') { + echo '
'; + } else { + echo '
'; + } + } + echo '
'; + } else { + $payload = self::query_payload($instance, 1); + echo $payload['html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $payload['paginate_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } echo ''; echo '
'; @@ -345,8 +381,8 @@ class WidgetMainPosts extends \WP_Widget { - - + + @@ -361,7 +397,15 @@ class WidgetMainPosts extends \WP_Widget {

-

+

+ +

+




- +
+

'; - if ($title_text !== '') { - echo '
' . esc_html($title_text) . '
'; + if ($title_text !== '' || $apply_html !== '') { + echo '
'; + echo $title_text !== '' ? '
' . esc_html($title_text) . '
' : '
'; + echo $apply_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '
'; } echo '
'; foreach ($people as $row) { @@ -144,7 +163,8 @@ class WidgetForumPlateModerator extends \WP_Widget {

- +
+

sanitize_text_field((string) ($new_instance['title_text'] ?? '')), 'style' => ($new_instance['style'] ?? '') === 'grid' ? 'grid' : 'list', 'show_avatar' => !empty($new_instance['show_avatar']) ? 1 : 0, + 'apply_btn' => !empty($new_instance['apply_btn']) ? 1 : 0, ]; } } diff --git a/src/AKSRT/Widgets/WidgetIframe.php b/src/AKSRT/Widgets/WidgetIframe.php index cd2d04d9..07452987 100644 --- a/src/AKSRT/Widgets/WidgetIframe.php +++ b/src/AKSRT/Widgets/WidgetIframe.php @@ -31,8 +31,9 @@ class WidgetIframe extends \WP_Widget { if ($raw === '') { if (current_user_can('manage_options')) { echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - echo '
' . esc_html__('超级嵌入:', 'aksrt') . '' . - esc_html__('请配置 URL 或 iframe 代码', 'aksrt') . '
'; + echo function_exists('aksrt_get_widget_null') + ? aksrt_get_widget_null(__('请配置 URL 或 iframe 代码', 'aksrt')) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + : '
' . esc_html__('超级嵌入:', 'aksrt') . '' . esc_html__('请配置 URL 或 iframe 代码', 'aksrt') . '
'; echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } return;