diff --git a/assets/admin/src/pages/content/HomepageSettings.vue b/assets/admin/src/pages/content/HomepageSettings.vue index f6cad8b0..9e06b1c9 100644 --- a/assets/admin/src/pages/content/HomepageSettings.vue +++ b/assets/admin/src/pages/content/HomepageSettings.vue @@ -281,27 +281,19 @@ async function loadSettings() { const res = await api.getHomepageSettings() const d = res?.data || {} - form.home_posts_list_s = d.home_posts_list_s !== false && d.home_posts_list_enabled !== false - form.home_list1_orderby_s = d.home_list1_orderby_s !== false && d.home_list_sort_enabled !== false + form.home_posts_list_s = d.home_posts_list_s !== false + form.home_list1_orderby_s = d.home_list1_orderby_s !== false const orderOpt = d.home_list1_orderby_option && typeof d.home_list1_orderby_option === 'object' ? d.home_list1_orderby_option : {} form.home_list1_orderby_option = { - orderby: orderOpt.orderby || d.homepage_default_sort || 'modified', + orderby: orderOpt.orderby || 'date', options: Array.isArray(orderOpt.options) && orderOpt.options.length ? orderOpt.options - : (Array.isArray(d.home_list_sort_options) && d.home_list_sort_options.length - ? d.home_list_sort_options - : ['modified', 'date', 'views', 'likes', 'comments']), + : ['modified', 'date', 'views', 'likes', 'comments'], } - form.index_list_title = d.index_list_title || d.home_list_title || '最新发布' - form.home_exclude_posts = Array.isArray(d.home_exclude_posts) - ? d.home_exclude_posts - : (Array.isArray(d.home_exclude_post_ids) ? d.home_exclude_post_ids : []) - form.home_exclude_cats = Array.isArray(d.home_exclude_cats) - ? d.home_exclude_cats - : (Array.isArray(d.home_exclude_category_ids) ? d.home_exclude_category_ids : []) - form.home_lists = Array.isArray(d.home_lists) - ? d.home_lists - : (Array.isArray(d.homepage_tabs) ? d.homepage_tabs : []) + form.index_list_title = d.index_list_title || '最新发布' + form.home_exclude_posts = Array.isArray(d.home_exclude_posts) ? d.home_exclude_posts : [] + form.home_exclude_cats = Array.isArray(d.home_exclude_cats) ? d.home_exclude_cats : [] + form.home_lists = Array.isArray(d.home_lists) ? d.home_lists : [] form.homepage_card_style = d.homepage_card_style || 'default' form.homepage_multi_thumb_enabled = d.homepage_multi_thumb_enabled !== false form.homepage_multi_thumb_min_images = d.homepage_multi_thumb_min_images || 3 diff --git a/assets/css/frontend/homepage-fixed/base-3.css b/assets/css/frontend/homepage-fixed/base-3.css index 608b7fcb..c6a47d29 100644 --- a/assets/css/frontend/homepage-fixed/base-3.css +++ b/assets/css/frontend/homepage-fixed/base-3.css @@ -129,6 +129,21 @@ 12. SIDEBAR ================================================================ */ +.aksrt-homepage__aside > .zib-widget, +.aksrt-homepage__aside > .widget { + margin-bottom: 15px; + padding: 15px; + background: var(--surface-1, #fff); + border: 0; + border-radius: var(--main-radius, var(--radius, 8px)); + box-shadow: var(--shadow-sm); +} + +.aksrt-homepage__aside > .zib-widget:last-child, +.aksrt-homepage__aside > .widget:last-child { + margin-bottom: 0; +} + .aksrt-homepage__aside .widget-list li, .aksrt-homepage__aside .widget_recent_entries li, .aksrt-homepage__aside .recent-posts-row { diff --git a/assets/js/core/pagination.js b/assets/js/core/pagination.js index 6c63914a..69c910e7 100644 --- a/assets/js/core/pagination.js +++ b/assets/js/core/pagination.js @@ -34,8 +34,9 @@ var observer = null; var iasEnabled = false; var successfulAutoLoads = 0; - var target = container.previousElementSibling; - if (target && target.classList && target.classList.contains("content-stream__footer")) { + var homepagePanel = container.closest("[data-home-tab-panel]"); + var target = homepagePanel || container.previousElementSibling; + if (!homepagePanel && target && target.classList && target.classList.contains("content-stream__footer")) { target = target.previousElementSibling; } if (isComment) { @@ -161,7 +162,11 @@ temp.innerHTML = res.data.html; var newItems = temp.children; while (newItems.length > 0) { - target.appendChild(newItems[0]); + if (homepagePanel && container.parentNode === target) { + target.insertBefore(newItems[0], container); + } else { + target.appendChild(newItems[0]); + } } if (isComment && window.AksrtFrontend) { AksrtFrontend.rehydrate(target, "ajax"); diff --git a/assets/js/homepage-fixed.js b/assets/js/homepage-fixed.js index ba99a7a8..57eaeb32 100644 --- a/assets/js/homepage-fixed.js +++ b/assets/js/homepage-fixed.js @@ -278,10 +278,12 @@ * Sets data-view, re-binds lazy images, and dispatches events. */ function notifyPostsRendered(panel, viewMode) { - var postsContainer = panel.querySelector('.aksrt-homepage__posts, .posts-row'); - if (postsContainer) { - postsContainer.setAttribute('data-view', viewMode || getDefaultView()); - } + var postsContainer = panel.matches('.aksrt-homepage__posts, .posts-row') + ? panel + : panel.querySelector('.aksrt-homepage__posts, .posts-row'); + if (postsContainer) { + postsContainer.setAttribute('data-view', viewMode || getDefaultView()); + } hydrateLazyImages(panel); dispatchRenderedEvent(panel, { @@ -294,6 +296,37 @@ * Unified AJAX panel loader * ============================================================ */ + function renderPanelPager(panel, options, hasMore) { + var existing = panel.querySelector('.aksrt-homepage__panel-footer'); + if (existing) existing.remove(); + if (!hasMore) return; + + var footer = document.createElement('div'); + footer.className = 'aksrt-homepage__panel-footer'; + var button = document.createElement('button'); + button.type = 'button'; + button.className = 'aksrt-homepage__more'; + button.textContent = (window.aksrtData && aksrtData.ajaxTrigger) || '加载更多'; + button.addEventListener('click', function () { + button.disabled = true; + button.textContent = (window.aksrtData && aksrtData.ajaxLoading) || '正在加载...'; + requestHomepagePanel(panel, { + termId: options.termId, + page: options.page + 1, + perPage: options.perPage, + sort: options.sort, + viewMode: options.viewMode, + pageUrl: options.pageUrl, + panel: options.panel, + source: options.source, + tabOrderby: options.tabOrderby, + append: true + }); + }); + footer.appendChild(button); + panel.appendChild(footer); + } + function buildErrorState(panel, requestOptions) { var wrapper = document.createElement('div'); wrapper.className = 'aksrt-homepage__tab-error'; @@ -334,7 +367,8 @@ pageUrl: requestOptions.pageUrl || window.location.href, panel: requestOptions.panel || panel.getAttribute('data-home-tab-panel') || 'latest', source: requestOptions.source || getPanelSource(panel), - tabOrderby: requestOptions.tabOrderby || getPanelTabOrderby(panel) || '' + tabOrderby: requestOptions.tabOrderby || getPanelTabOrderby(panel) || '', + append: requestOptions.append === true }; var restUrl = buildRestUrl(options); @@ -352,14 +386,16 @@ url: restUrl }); - // Show loading skeleton - panel.innerHTML = ''; - panel.appendChild(buildSkeleton(options.perPage > 6 ? 4 : 3)); + // Full refreshes replace the panel; append requests keep existing cards. + if (!options.append) { + panel.innerHTML = ''; + panel.appendChild(buildSkeleton(options.perPage > 6 ? 4 : 3)); + } function markLoaded() { panel.dataset.loaded = 'true'; panel.dataset.loadedPage = String(options.page); - panel.dataset.loadedSort = options.sort; + panel.dataset.loadedSort = options.tabOrderby || options.sort; panel.dataset.loadedTermId = String(options.termId); } @@ -374,12 +410,21 @@ return response.json(); }) .then(function (data) { - panel.innerHTML = ''; + if (!options.append) panel.innerHTML = ''; markLoaded(); if (data && data.html) { - // 2. Inject HTML - panel.innerHTML = data.html; + // 2. Inject or append article nodes without nesting a posts-row wrapper. + if (options.append) { + var oldFooter = panel.querySelector('.aksrt-homepage__panel-footer'); + if (oldFooter) oldFooter.remove(); + var fragment = document.createElement('div'); + fragment.innerHTML = data.html; + while (fragment.firstChild) panel.appendChild(fragment.firstChild); + } else { + panel.innerHTML = data.html; + } + renderPanelPager(panel, options, !!data.has_more); // 3. Post-inject event dispatchAfterEvent(panel, { @@ -426,7 +471,9 @@ window.setTimeout(doFetch, 3000); return; } - panel.innerHTML = ''; + if (!options.append) panel.innerHTML = ''; + var failedFooter = panel.querySelector('.aksrt-homepage__panel-footer'); + if (failedFooter) failedFooter.remove(); panel.appendChild(buildErrorState(panel, options)); }); } @@ -535,9 +582,10 @@ }); }); - // Mark server-rendered panels as already loaded + // Mark server-rendered panels as already loaded. The panel itself owns + // the posts-row contract, so checking descendants would miss SSR items. panels.forEach(function (panel) { - if (!panel.querySelector('.aksrt-homepage__posts, .posts-row')) return; + if (getRenderedPostCount(panel) < 1) return; panel.dataset.loaded = 'true'; panel.dataset.loadedPage = '1'; panel.dataset.loadedSort = getCurrentSort(stream); @@ -736,16 +784,22 @@ * ============================================================ */ function applyViewMode(buttons, postsContainers, mode) { - buttons.forEach(function (btn) { - var btnMode = btn.getAttribute('data-view-mode'); - btn.classList.toggle('is-active', btnMode === mode); - }); - Array.prototype.forEach.call(postsContainers, function (container) { - container.setAttribute('data-view', mode); - }); - } + buttons.forEach(function (btn) { + var btnMode = btn.getAttribute('data-view-mode'); + var isActive = btnMode === mode; + btn.classList.toggle('is-active', isActive); + btn.setAttribute('aria-pressed', isActive ? 'true' : 'false'); + }); + Array.prototype.forEach.call(postsContainers, function (container) { + container.setAttribute('data-view', mode); + container.querySelectorAll('.posts-item').forEach(function (item) { + item.classList.toggle('card', mode === 'card'); + item.classList.toggle('list', mode === 'list'); + }); + }); + } - function initViewToggle() { + function initViewToggle() { var toggles = document.querySelectorAll('[data-aksrt-view-toggle]'); toggles.forEach(function (toggle) { @@ -754,7 +808,7 @@ if (!stream) return; function getPostsContainers() { - return stream.querySelectorAll('.aksrt-homepage__posts, .posts-row'); + return stream.querySelectorAll('[data-home-tab-panel]'); } function getActiveMode() { @@ -767,8 +821,21 @@ buttons.forEach(function (btn) { btn.addEventListener('click', function () { var mode = btn.getAttribute('data-view-mode') || getDefaultView(); - applyViewMode(buttons, getPostsContainers(), mode); + var activePanel = getActivePanel(stream); + if (!activePanel || mode === getActiveMode()) return; + setViewMode(mode); + applyViewMode(buttons, getPostsContainers(), mode); + requestHomepagePanel(activePanel, { + termId: getPanelTermId(activePanel), + page: 1, + perPage: getHomepagePerPage(activePanel), + sort: getCurrentSort(stream), + viewMode: mode, + panel: activePanel.getAttribute('data-home-tab-panel') || 'latest', + source: 'home', + tabOrderby: getPanelTabOrderby(activePanel) + }); }); }); diff --git a/inc/bootstrap.php b/inc/bootstrap.php index 3fc3155b..9f515c28 100644 --- a/inc/bootstrap.php +++ b/inc/bootstrap.php @@ -25,6 +25,9 @@ require_once AKSRT_DIR . '/inc/helpers/comments/form-parts.php'; require_once AKSRT_DIR . '/inc/helpers/comments/item.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-flow.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-homepage.php'; +require_once AKSRT_DIR . '/inc/helpers/homepage/content.php'; +require_once AKSRT_DIR . '/inc/helpers/homepage/header-components.php'; +require_once AKSRT_DIR . '/inc/helpers/homepage/layout.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-single-components.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-single.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-yiyan.php'; diff --git a/inc/helpers/aksrt-homepage.php b/inc/helpers/aksrt-homepage.php index 8e14035c..610dbd20 100644 --- a/inc/helpers/aksrt-homepage.php +++ b/inc/helpers/aksrt-homepage.php @@ -392,765 +392,3 @@ if (!function_exists('aksrt_homepage_render_sortbar')) { aksrt_homepage_get_post_types(), - 'post_status' => 'publish', - 'posts_per_page' => max(1, (int) get_option('posts_per_page')), - 'paged' => aksrt_homepage_get_current_page(), - 'ignore_sticky_posts' => false, - 'orderby' => 'date', - 'order' => 'DESC', - 'no_found_rows' => false, - ]; - - $exclude_ids = class_exists('\AKSRT\Settings\Settings') - ? \AKSRT\Settings\Settings::home_exclude_post_ids() - : []; - if (!empty($exclude_ids)) { - $query_args['post__not_in'] = $exclude_ids; - } - - $exclude_cat_ids = class_exists('\AKSRT\Settings\Settings') - ? \AKSRT\Settings\Settings::home_exclude_category_ids() - : []; - if (!empty($exclude_cat_ids)) { - $query_args['category__not_in'] = $exclude_cat_ids; - } - - $query = new WP_Query(aksrt_homepage_apply_sort_args($query_args)); - - return $query; - } -} - -if (!function_exists('aksrt_homepage_get_tab_query')) { - /** - * Build a category-tab query. - */ - function aksrt_homepage_get_tab_query(int $term_id, string $orderby = 'date'): WP_Query { - static $queries = []; - - $cache_key = $term_id . '_' . $orderby; - if (isset($queries[$cache_key]) && $queries[$cache_key] instanceof WP_Query) { - return $queries[$cache_key]; - } - - $term = get_term($term_id); - $taxonomy = ($term && !is_wp_error($term)) ? (string) $term->taxonomy : 'category'; - if (!in_array($taxonomy, ['category', 'topics'], true)) { - $taxonomy = 'category'; - } - - $query_args = [ - 'post_type' => aksrt_homepage_get_post_types(), - 'post_status' => 'publish', - 'posts_per_page' => class_exists('\AKSRT\Settings\Settings') - ? \AKSRT\Settings\Settings::homepage_tab_posts_per_page() - : 6, - 'ignore_sticky_posts' => true, - 'orderby' => 'date', - 'order' => 'DESC', - 'no_found_rows' => true, - 'tax_query' => [ - [ - 'taxonomy' => $taxonomy, - 'field' => 'term_id', - 'terms' => [$term_id], - ], - ], - ]; - - $exclude_ids = class_exists('\AKSRT\Settings\Settings') - ? \AKSRT\Settings\Settings::home_exclude_post_ids() - : []; - if (!empty($exclude_ids)) { - $query_args['post__not_in'] = $exclude_ids; - } - - $queries[$cache_key] = new WP_Query( - aksrt_homepage_apply_named_sort_args($query_args, $orderby) - ); - - return $queries[$cache_key]; - } -} - -if (!function_exists('aksrt_homepage_has_active_sidebars')) { - /** - * Check whether any sidebar in the given stack is active. - * - * @param string[] $sidebar_ids - */ - function aksrt_homepage_has_active_sidebars(array $sidebar_ids): bool { - foreach ($sidebar_ids as $sidebar_id) { - if (is_active_sidebar($sidebar_id)) { - return true; - } - } - - return false; - } -} - -if (!function_exists('aksrt_homepage_render_widget_zone')) { - /** - * Render a stacked widget zone. - * - * @param string[] $sidebar_ids - * @param string $wrapper_class - */ - function aksrt_homepage_render_widget_zone(array $sidebar_ids, string $wrapper_class = ''): void { - if (!aksrt_homepage_has_active_sidebars($sidebar_ids)) { - wp_reset_postdata(); - return; - } - - echo '
'; - foreach ($sidebar_ids as $sidebar_id) { - if (is_active_sidebar($sidebar_id)) { - dynamic_sidebar($sidebar_id); - } - } - echo '
'; - } -} - -if (!function_exists('aksrt_homepage_has_sidebar')) { - /** - * Whether the fixed homepage should render an aside column. - */ - function aksrt_homepage_has_sidebar(): bool { - if (function_exists('aksrt_is_show_sidebar')) { - return aksrt_is_show_sidebar(); - } - return aksrt_homepage_has_active_sidebars([ - 'all_sidebar_top', - 'home_sidebar', - 'all_sidebar_bottom', - 'sidebar-blog', - ]); - } -} - -if (!function_exists('aksrt_homepage_render_sidebar')) { - /** - * Render the homepage aside column. - */ - function aksrt_homepage_render_sidebar(): void { - if (!aksrt_homepage_has_sidebar()) { - return; - } - - echo ''; - } -} - -if (!function_exists('aksrt_homepage_get_latest_panel_contract')) { - /** - * Public-safe latest stream contract shared by homepage pagination/AJAX. - * - * @return array{query_context:string,query_vars:string,render_config:string,render_config_array:array} - */ - function aksrt_homepage_get_latest_panel_contract(): array { - $query = aksrt_homepage_get_latest_query(); - $query_vars = $query instanceof WP_Query ? $query->query_vars : []; - if (!is_array($query_vars)) { - $query_vars = []; - } - - unset($query_vars['paged'], $query_vars['page']); - - $render_config = function_exists('aksrt_resolve_post_list_render_config') - ? aksrt_resolve_post_list_render_config(['context' => 'home']) - : [ - 'mode' => 'list', - 'context' => 'home', - ]; - - return [ - 'query_context' => 'homepage_latest', - 'query_vars' => (string) wp_json_encode($query_vars), - 'render_config' => (string) wp_json_encode($render_config), - 'render_config_array' => $render_config, - ]; - } -} - -if (!function_exists('aksrt_homepage_render_pagination')) { - /** - * Render pagination for the fixed homepage latest stream. - */ - function aksrt_homepage_render_pagination(WP_Query $query): void { - $max_pages = (int) $query->max_num_pages; - if ($max_pages < 2) { - return; - } - - $query_page = (int) $query->get('paged'); - $current_page = min(max(1, $query_page > 0 ? $query_page : aksrt_homepage_get_current_page()), $max_pages); - $pagination_mode = class_exists('\AKSRT\Settings\Settings') - ? \AKSRT\Settings\Settings::get_post_pagination_mode() - : 'numbered'; - - if ($pagination_mode === 'numbered') { - $base_url = (string) get_query_var('aksrt_homepage_pagination_base_url'); - $base_args = [ - 'format' => '', - 'current' => $current_page, - 'total' => $max_pages, - 'mid_size' => 2, - 'prev_text' => '', - 'next_text' => '', - 'type' => 'array', - ]; - - if ($base_url !== '') { - $base_args['base'] = add_query_arg( - 'paged', - '%#%', - remove_query_arg(['paged', 'page'], $base_url) - ); - } else { - $base_args['base'] = str_replace(999999999, '%#%', esc_url(get_pagenum_link(999999999))); - } - - $links = paginate_links($base_args); - if (!$links || !is_array($links)) { - return; - } - ?> - - -
- - - - -
- ]+src=["\x27]([^"\x27]+)["\x27]/i', $content, $html_matches) && !empty($html_matches[1])) { - foreach ($html_matches[1] as $raw_url) { - $images[] = esc_url_raw((string) $raw_url); - } - } - - if (preg_match_all('/"url"\s*:\s*"([^"]+)"/i', $content, $block_matches) && !empty($block_matches[1])) { - foreach ($block_matches[1] as $raw_url) { - $images[] = esc_url_raw((string) $raw_url); - } - } - } - - $images = array_values(array_unique(array_filter($images, static function ($url) { - return is_string($url) && $url !== ''; - }))); - - set_transient($transient_key, $images, DAY_IN_SECONDS); - $request_cache[$post_id] = $images; - - return array_slice($images, 0, $limit); - } -} - -if (!function_exists('aksrt_homepage_render_post_card')) { - /** - * Render a homepage post card inline. - */ - function aksrt_homepage_render_post_card(): void { - if (!function_exists('aksrt_render_post')) { - return; - } - - $config = function_exists('aksrt_resolve_post_list_render_config') - ? aksrt_resolve_post_list_render_config(['context' => 'home']) - : [ - 'mode' => 'list', - 'context' => 'home', - ]; - - echo aksrt_render_post($config); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - } -} - -if (!function_exists('aksrt_homepage_render_posts_grid')) { - /** - * Render a list block for the fixed homepage. - */ - function aksrt_homepage_render_posts_grid(?WP_Query $query = null, bool $with_pagination = false): void { - $query = $query instanceof WP_Query ? $query : aksrt_homepage_get_latest_query(); - $config = function_exists('aksrt_resolve_post_list_render_config') - ? aksrt_resolve_post_list_render_config(['context' => 'home']) - : [ - 'mode' => 'list', - 'context' => 'home', - ]; - $config['skip_wrapper'] = true; - $view = (($config['mode'] ?? 'list') === 'card') ? 'card' : 'list'; - - if (function_exists('aksrt_render_post_list')) { - // Panel already provides posts-row.ajaxpager; avoid nested wrapper. - aksrt_render_post_list($query, $config, true); - } else { - if (!$query->have_posts()) { - echo '

' . esc_html__('暂无文章', 'aksrt') . '

'; - } else { - echo '
'; - while ($query->have_posts()) { - $query->the_post(); - aksrt_homepage_render_post_card(); - } - echo '
'; - } - wp_reset_postdata(); - } - - if ($with_pagination) { - aksrt_homepage_render_pagination($query); - } - } -} - -if (!function_exists('aksrt_homepage_render_section')) { - /** - * Render a first-class homepage section (hero / banner). - * - * These are fixed homepage sections, not a freeform module canvas bridge. - */ - function aksrt_homepage_render_section(string $type): void { - $type = sanitize_key($type); - if (!in_array($type, ['hero', 'banner'], true)) { - return; - } - - // Fixed homepage owns these sections directly. - // Keep the existing hero/banner templates as section implementations, - // but do not re-wrap them in a freeform module bridge. - get_template_part('templates/parts/home-modules/module', $type); - } -} - -if (!function_exists('aksrt_header_components_page_type_keys')) { - /** - * Allowed page-type keys for header multi-function (zibll CFS_Module::page_type). - * - * @return list - */ - function aksrt_header_components_page_type_keys(): array { - return [ - 'home', - 'topics', - 'category', - 'tag', - 'author', - 'single', - 'search', - 'forum_home', - 'forum_plate', - 'forum_post', - 'page', - ]; - } -} - -if (!function_exists('aksrt_header_slide_excluded_page_templates')) { - /** - * Page templates excluded from the generic "page" type (zibll parity). - * - * @return list - */ - function aksrt_header_slide_excluded_page_templates(): array { - return [ - 'templates/pages/page-sign.php', - 'templates/pages/page-login.php', - 'templates/pages/page-register.php', - 'templates/pages/page-reset-password.php', - 'templates/pages/page-bind-account.php', - 'templates/pages/page-verify-email.php', - 'templates/pages/page-download.php', - 'templates/pages/page-download-file.php', - 'templates/pages/page-forums.php', - ]; - } -} - -if (!function_exists('aksrt_header_slide_match_page_type')) { - /** - * Whether the current main query matches a header-slider page-type key. - * - * Mirrors zibll zib_header_slide_is_show() matching rules. - */ - function aksrt_header_slide_match_page_type(string $type): bool { - global $wp_query; - - $type = sanitize_key($type); - if ($type === '' || !($wp_query instanceof WP_Query)) { - return false; - } - - $raw_post_type = $wp_query->get('post_type'); - if (is_array($raw_post_type)) { - $post_type = (string) reset($raw_post_type); - } else { - $post_type = (string) $raw_post_type; - } - - // Special keys that are not plain is_{$type} flags. - if ($type === 'topics') { - return is_tax('topics'); - } - - if ($type === 'forum_home') { - return is_page_template('templates/pages/page-forums.php'); - } - - if ($type === 'forum_plate') { - return is_singular('aksrt_forum_plate') || $post_type === 'aksrt_forum_plate'; - } - - if ($type === 'forum_post') { - return is_singular('aksrt_forum_topic') || $post_type === 'aksrt_forum_topic'; - } - - // Generic WP_Query is_* flags (home/category/tag/author/single/search/page). - $query_flag = 'is_' . $type; - if (empty($wp_query->{$query_flag})) { - return false; - } - - if ($type === 'single') { - // Only ordinary posts; CPTs use dedicated keys. - return $post_type === '' || $post_type === 'post'; - } - - if ($type === 'page') { - foreach (aksrt_header_slide_excluded_page_templates() as $template) { - if (is_page_template($template)) { - return false; - } - } - return true; - } - - return true; - } -} - -if (!function_exists('aksrt_header_slide_is_show')) { - /** - * Whether the header multi-function slider should render (zibll header-slider contract). - * - * Master switch: non-empty header_components_show_on + current page-type match. - * Device rule: header_components_device_visibility (only_pc / only_sm). - */ - function aksrt_header_slide_is_show(): bool { - global $wp_query; - - if (is_admin() || !($wp_query instanceof WP_Query)) { - return false; - } - - // Not on paginated views (zibll: query_vars['paged'] non-empty). - $paged = (int) $wp_query->get('paged'); - if ($paged > 1) { - return false; - } - if (function_exists('aksrt_homepage_get_current_page') && aksrt_homepage_get_current_page() > 1) { - return false; - } - - $settings = class_exists('\AKSRT\Settings\Settings') - ? \AKSRT\Settings\Settings::get_header_components_settings() - : []; - $show_on = isset($settings['show_on_pages']) ? (array) $settings['show_on_pages'] : []; - $allowed = array_values(array_intersect( - array_map('sanitize_key', $show_on), - aksrt_header_components_page_type_keys() - )); - - // Empty selection = feature off (zibll header_slider_show). - if ($allowed === []) { - return false; - } - - // Device visibility (zibll header_slider_show_type). - $show_type = (string) ($settings['show_type'] ?? ''); - if ($show_type === 'only_pc' && wp_is_mobile()) { - return false; - } - if ($show_type === 'only_sm' && !wp_is_mobile()) { - return false; - } - - foreach ($allowed as $type) { - if (aksrt_header_slide_match_page_type($type)) { - return true; - } - } - - return false; - } -} - -if (!function_exists('aksrt_header_slide')) { - /** - * Render header slider after the site header (outside main). - */ - function aksrt_header_slide(): void { - if (!aksrt_header_slide_is_show()) { - return; - } - - // Reuse existing hero partial as the slider implementation. - get_template_part('templates/parts/home-modules/module', 'hero'); - } -} - -if (!function_exists('aksrt_homepage_render_layout')) { - /** - * Render the fixed homepage layout (Zibll latest-first content stream). - * - * Order (zibll-aligned): - * fluid top → main.container → top content → banner → tabs/list → bottom content → sidebar - * → fluid bottom. Hero/header-slider is rendered from header.php, not here. - */ - function aksrt_homepage_render_layout(): void { - $current_page = aksrt_homepage_get_current_page(); - $show_tabs = $current_page === 1; - $tab_configs = $show_tabs ? aksrt_homepage_get_tab_configs() : []; - $latest_contract = aksrt_homepage_get_latest_panel_contract(); - $has_sidebar = aksrt_homepage_has_sidebar(); - $banner_on = $show_tabs && aksrt_homepage_module_banner_enabled(); - $main_list_enabled = !class_exists('\AKSRT\Settings\Settings') || \AKSRT\Settings\Settings::home_posts_list_enabled(); - $list_title = class_exists('\AKSRT\Settings\Settings') - ? \AKSRT\Settings\Settings::home_list_title() - : __('最新发布', 'aksrt'); - - // Fluid zones live outside
, once only (removed from header.php). - aksrt_homepage_render_widget_zone( - ['all_top_fluid', 'home_top_fluid'], - 'fluid-widget-wrap aksrt-homepage__fluid-zone aksrt-homepage__fluid-zone--top' - ); - ?> -
-
-
- - - -
- -
-
    - - - - -
- -
- 1) : ?> -
-
- - - - -
-
- -
-
-
- - - - -
-
-
- -
- - - - - - -
-
- -
-
-

- - - -
-
- - - -
-
- - -
- aksrt_homepage_get_post_types(), + 'post_status' => 'publish', + 'posts_per_page' => max(1, (int) get_option('posts_per_page')), + 'paged' => aksrt_homepage_get_current_page(), + 'ignore_sticky_posts' => false, + 'orderby' => 'date', + 'order' => 'DESC', + 'no_found_rows' => false, + ]; + + $exclude_ids = class_exists('\AKSRT\Settings\Settings') + ? \AKSRT\Settings\Settings::home_exclude_post_ids() + : []; + if (!empty($exclude_ids)) { + $query_args['post__not_in'] = $exclude_ids; + } + + $exclude_cat_ids = class_exists('\AKSRT\Settings\Settings') + ? \AKSRT\Settings\Settings::home_exclude_category_ids() + : []; + if (!empty($exclude_cat_ids)) { + $query_args['category__not_in'] = $exclude_cat_ids; + } + + $query = new WP_Query(aksrt_homepage_apply_sort_args($query_args)); + + return $query; + } +} + +if (!function_exists('aksrt_homepage_get_tab_query')) { + /** + * Build a category-tab query. + */ + function aksrt_homepage_get_tab_query(int $term_id, string $orderby = 'date'): WP_Query { + static $queries = []; + + $cache_key = $term_id . '_' . $orderby; + if (isset($queries[$cache_key]) && $queries[$cache_key] instanceof WP_Query) { + return $queries[$cache_key]; + } + + $term = get_term($term_id); + $taxonomy = ($term && !is_wp_error($term)) ? (string) $term->taxonomy : 'category'; + if (!in_array($taxonomy, ['category', 'topics'], true)) { + $taxonomy = 'category'; + } + + $query_args = [ + 'post_type' => aksrt_homepage_get_post_types(), + 'post_status' => 'publish', + 'posts_per_page' => class_exists('\AKSRT\Settings\Settings') + ? \AKSRT\Settings\Settings::homepage_tab_posts_per_page() + : 6, + 'ignore_sticky_posts' => true, + 'orderby' => 'date', + 'order' => 'DESC', + 'no_found_rows' => true, + 'tax_query' => [ + [ + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => [$term_id], + ], + ], + ]; + + $exclude_ids = class_exists('\AKSRT\Settings\Settings') + ? \AKSRT\Settings\Settings::home_exclude_post_ids() + : []; + if (!empty($exclude_ids)) { + $query_args['post__not_in'] = $exclude_ids; + } + + $queries[$cache_key] = new WP_Query( + aksrt_homepage_apply_named_sort_args($query_args, $orderby) + ); + + return $queries[$cache_key]; + } +} + +if (!function_exists('aksrt_homepage_has_active_sidebars')) { + /** + * Check whether any sidebar in the given stack is active. + * + * @param string[] $sidebar_ids + */ + function aksrt_homepage_has_active_sidebars(array $sidebar_ids): bool { + foreach ($sidebar_ids as $sidebar_id) { + if (is_active_sidebar($sidebar_id)) { + return true; + } + } + + return false; + } +} + +if (!function_exists('aksrt_homepage_render_widget_zone')) { + /** + * Render a stacked widget zone. + * + * @param string[] $sidebar_ids + * @param string $wrapper_class + */ + function aksrt_homepage_render_widget_zone(array $sidebar_ids, string $wrapper_class = ''): void { + if (!aksrt_homepage_has_active_sidebars($sidebar_ids)) { + wp_reset_postdata(); + return; + } + + echo '
'; + foreach ($sidebar_ids as $sidebar_id) { + if (is_active_sidebar($sidebar_id)) { + dynamic_sidebar($sidebar_id); + } + } + echo '
'; + } +} + +if (!function_exists('aksrt_homepage_has_sidebar')) { + /** + * Whether the fixed homepage should render an aside column. + */ + function aksrt_homepage_has_sidebar(): bool { + if (function_exists('aksrt_is_show_sidebar')) { + return aksrt_is_show_sidebar(); + } + return aksrt_homepage_has_active_sidebars([ + 'all_sidebar_top', + 'home_sidebar', + 'all_sidebar_bottom', + 'sidebar-blog', + ]); + } +} + +if (!function_exists('aksrt_homepage_render_sidebar')) { + /** + * Render the homepage aside column. + */ + function aksrt_homepage_render_sidebar(): void { + if (!aksrt_homepage_has_sidebar()) { + return; + } + + echo ''; + } +} + +if (!function_exists('aksrt_homepage_get_latest_panel_contract')) { + /** + * Public-safe latest stream contract shared by homepage pagination/AJAX. + * + * @return array{query_context:string,query_vars:string,render_config:string,render_config_array:array} + */ + function aksrt_homepage_get_latest_panel_contract(): array { + $query = aksrt_homepage_get_latest_query(); + $query_vars = $query instanceof WP_Query ? $query->query_vars : []; + if (!is_array($query_vars)) { + $query_vars = []; + } + + unset($query_vars['paged'], $query_vars['page']); + + $render_config = function_exists('aksrt_resolve_post_list_render_config') + ? aksrt_resolve_post_list_render_config(['context' => 'home']) + : [ + 'mode' => 'list', + 'context' => 'home', + ]; + $render_config['skip_wrapper'] = true; + + return [ + 'query_context' => 'homepage_latest', + 'query_vars' => (string) wp_json_encode($query_vars), + 'render_config' => (string) wp_json_encode($render_config), + 'render_config_array' => $render_config, + ]; + } +} + +if (!function_exists('aksrt_homepage_render_pagination')) { + /** + * Render pagination for the fixed homepage latest stream. + */ + function aksrt_homepage_render_pagination(WP_Query $query): void { + $max_pages = (int) $query->max_num_pages; + if ($max_pages < 2) { + return; + } + + $query_page = (int) $query->get('paged'); + $current_page = min(max(1, $query_page > 0 ? $query_page : aksrt_homepage_get_current_page()), $max_pages); + $pagination_mode = class_exists('\AKSRT\Settings\Settings') + ? \AKSRT\Settings\Settings::get_post_pagination_mode() + : 'numbered'; + + if ($pagination_mode === 'numbered') { + $base_url = (string) get_query_var('aksrt_homepage_pagination_base_url'); + $base_args = [ + 'format' => '', + 'current' => $current_page, + 'total' => $max_pages, + 'mid_size' => 2, + 'prev_text' => '', + 'next_text' => '', + 'type' => 'array', + ]; + + if ($base_url !== '') { + $base_args['base'] = add_query_arg( + 'paged', + '%#%', + remove_query_arg(['paged', 'page'], $base_url) + ); + } else { + $base_args['base'] = str_replace(999999999, '%#%', esc_url(get_pagenum_link(999999999))); + } + + $links = paginate_links($base_args); + if (!$links || !is_array($links)) { + return; + } + ?> + + +
+ + + + +
+ ]+src=["\x27]([^"\x27]+)["\x27]/i', $content, $html_matches) && !empty($html_matches[1])) { + foreach ($html_matches[1] as $raw_url) { + $images[] = esc_url_raw((string) $raw_url); + } + } + + if (preg_match_all('/"url"\s*:\s*"([^"]+)"/i', $content, $block_matches) && !empty($block_matches[1])) { + foreach ($block_matches[1] as $raw_url) { + $images[] = esc_url_raw((string) $raw_url); + } + } + } + + $images = array_values(array_unique(array_filter($images, static function ($url) { + return is_string($url) && $url !== ''; + }))); + + set_transient($transient_key, $images, DAY_IN_SECONDS); + $request_cache[$post_id] = $images; + + return array_slice($images, 0, $limit); + } +} + +if (!function_exists('aksrt_homepage_render_post_card')) { + /** + * Render a homepage post card inline. + */ + function aksrt_homepage_render_post_card(): void { + if (!function_exists('aksrt_render_post')) { + return; + } + + $config = function_exists('aksrt_resolve_post_list_render_config') + ? aksrt_resolve_post_list_render_config(['context' => 'home']) + : [ + 'mode' => 'list', + 'context' => 'home', + ]; + + echo aksrt_render_post($config); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} + +if (!function_exists('aksrt_homepage_render_posts_grid')) { + /** + * Render a list block for the fixed homepage. + */ + function aksrt_homepage_render_posts_grid(?WP_Query $query = null, bool $with_pagination = false): void { + $query = $query instanceof WP_Query ? $query : aksrt_homepage_get_latest_query(); + $config = function_exists('aksrt_resolve_post_list_render_config') + ? aksrt_resolve_post_list_render_config(['context' => 'home']) + : [ + 'mode' => 'list', + 'context' => 'home', + ]; + $config['skip_wrapper'] = true; + $view = (($config['mode'] ?? 'list') === 'card') ? 'card' : 'list'; + + if (function_exists('aksrt_render_post_list')) { + // Panel already provides posts-row.ajaxpager; avoid nested wrapper. + aksrt_render_post_list($query, $config, true); + } else { + if (!$query->have_posts()) { + echo '

' . esc_html__('暂无文章', 'aksrt') . '

'; + } else { + echo '
'; + while ($query->have_posts()) { + $query->the_post(); + aksrt_homepage_render_post_card(); + } + echo '
'; + } + wp_reset_postdata(); + } + + if ($with_pagination) { + aksrt_homepage_render_pagination($query); + } + } +} + +if (!function_exists('aksrt_homepage_render_section')) { + /** + * Render a first-class homepage section (hero / banner). + * + * These are fixed homepage sections, not a freeform module canvas bridge. + */ + function aksrt_homepage_render_section(string $type): void { + $type = sanitize_key($type); + if (!in_array($type, ['hero', 'banner'], true)) { + return; + } + + // Fixed homepage owns these sections directly. + // Keep the existing hero/banner templates as section implementations, + // but do not re-wrap them in a freeform module bridge. + get_template_part('templates/parts/home-modules/module', $type); + } +} diff --git a/inc/helpers/homepage/header-components.php b/inc/helpers/homepage/header-components.php new file mode 100644 index 00000000..e9fd63d3 --- /dev/null +++ b/inc/helpers/homepage/header-components.php @@ -0,0 +1,184 @@ + + */ + function aksrt_header_components_page_type_keys(): array { + return [ + 'home', + 'topics', + 'category', + 'tag', + 'author', + 'single', + 'search', + 'forum_home', + 'forum_plate', + 'forum_post', + 'page', + ]; + } +} + +if (!function_exists('aksrt_header_slide_excluded_page_templates')) { + /** + * Page templates excluded from the generic "page" type (zibll parity). + * + * @return list + */ + function aksrt_header_slide_excluded_page_templates(): array { + return [ + 'templates/pages/page-sign.php', + 'templates/pages/page-login.php', + 'templates/pages/page-register.php', + 'templates/pages/page-reset-password.php', + 'templates/pages/page-bind-account.php', + 'templates/pages/page-verify-email.php', + 'templates/pages/page-download.php', + 'templates/pages/page-download-file.php', + 'templates/pages/page-forums.php', + ]; + } +} + +if (!function_exists('aksrt_header_slide_match_page_type')) { + /** + * Whether the current main query matches a header-slider page-type key. + * + * Mirrors zibll zib_header_slide_is_show() matching rules. + */ + function aksrt_header_slide_match_page_type(string $type): bool { + global $wp_query; + + $type = sanitize_key($type); + if ($type === '' || !($wp_query instanceof WP_Query)) { + return false; + } + + $raw_post_type = $wp_query->get('post_type'); + if (is_array($raw_post_type)) { + $post_type = (string) reset($raw_post_type); + } else { + $post_type = (string) $raw_post_type; + } + + // Special keys that are not plain is_{$type} flags. + if ($type === 'topics') { + return is_tax('topics'); + } + + if ($type === 'forum_home') { + return is_page_template('templates/pages/page-forums.php'); + } + + if ($type === 'forum_plate') { + return is_singular('aksrt_forum_plate') || $post_type === 'aksrt_forum_plate'; + } + + if ($type === 'forum_post') { + return is_singular('aksrt_forum_topic') || $post_type === 'aksrt_forum_topic'; + } + + // Generic WP_Query is_* flags (home/category/tag/author/single/search/page). + $query_flag = 'is_' . $type; + if (empty($wp_query->{$query_flag})) { + return false; + } + + if ($type === 'single') { + // Only ordinary posts; CPTs use dedicated keys. + return $post_type === '' || $post_type === 'post'; + } + + if ($type === 'page') { + foreach (aksrt_header_slide_excluded_page_templates() as $template) { + if (is_page_template($template)) { + return false; + } + } + return true; + } + + return true; + } +} + +if (!function_exists('aksrt_header_slide_is_show')) { + /** + * Whether the header multi-function slider should render (zibll header-slider contract). + * + * Master switch: non-empty header_components_show_on + current page-type match. + * Device rule: header_components_device_visibility (only_pc / only_sm). + */ + function aksrt_header_slide_is_show(): bool { + global $wp_query; + + if (is_admin() || !($wp_query instanceof WP_Query)) { + return false; + } + + // Not on paginated views (zibll: query_vars['paged'] non-empty). + $paged = (int) $wp_query->get('paged'); + if ($paged > 1) { + return false; + } + if (function_exists('aksrt_homepage_get_current_page') && aksrt_homepage_get_current_page() > 1) { + return false; + } + + $settings = class_exists('\AKSRT\Settings\Settings') + ? \AKSRT\Settings\Settings::get_header_components_settings() + : []; + $show_on = isset($settings['show_on_pages']) ? (array) $settings['show_on_pages'] : []; + $allowed = array_values(array_intersect( + array_map('sanitize_key', $show_on), + aksrt_header_components_page_type_keys() + )); + + // Empty selection = feature off (zibll header_slider_show). + if ($allowed === []) { + return false; + } + + // Device visibility (zibll header_slider_show_type). + $show_type = (string) ($settings['show_type'] ?? ''); + if ($show_type === 'only_pc' && wp_is_mobile()) { + return false; + } + if ($show_type === 'only_sm' && !wp_is_mobile()) { + return false; + } + + foreach ($allowed as $type) { + if (aksrt_header_slide_match_page_type($type)) { + return true; + } + } + + return false; + } +} + +if (!function_exists('aksrt_header_slide')) { + /** + * Render header slider after the site header (outside main). + */ + function aksrt_header_slide(): void { + if (!aksrt_header_slide_is_show()) { + return; + } + + // Reuse existing hero partial as the slider implementation. + get_template_part('templates/parts/home-modules/module', 'hero'); + } +} diff --git a/inc/helpers/homepage/layout.php b/inc/helpers/homepage/layout.php new file mode 100644 index 00000000..6309abb4 --- /dev/null +++ b/inc/helpers/homepage/layout.php @@ -0,0 +1,166 @@ +, once only (removed from header.php). + aksrt_homepage_render_widget_zone( + ['all_top_fluid', 'home_top_fluid'], + 'fluid-widget-wrap aksrt-homepage__fluid-zone aksrt-homepage__fluid-zone--top' + ); + ?> +
+
+
+ + + +
+ +
+
    + + + + +
+ +
+ 1) : ?> +
+
+ + + + +
+
+ +
+
+
+ + + + +
+
+
+ +
+ + + + + + +
+
+ +
+
+

+ + + +
+
+ + + +
+
+ + +
+ $overrides, ]) : array_merge(['mode' => ($mode !== '' ? $mode : 'list'), 'context' => 'home'], $overrides); + $render_config['skip_wrapper'] = true; $html = aksrt_render_post_list($query, $render_config, false); } elseif ($query->have_posts()) { - $html = '
'; while ($query->have_posts()) { $query->the_post(); if (function_exists('aksrt_homepage_render_post_card')) { @@ -321,7 +321,6 @@ class GlobalController extends ControllerBase { $html .= ob_get_clean(); } } - $html .= '
'; wp_reset_postdata(); } diff --git a/src/AKSRT/Admin/HomepageSettingsRest.php b/src/AKSRT/Admin/HomepageSettingsRest.php index 8108d629..4c8f67b2 100644 --- a/src/AKSRT/Admin/HomepageSettingsRest.php +++ b/src/AKSRT/Admin/HomepageSettingsRest.php @@ -30,17 +30,13 @@ trait HomepageSettingsRest { $allowed_sorts = \AKSRT\Settings\HomeCms::homepage_allowed_sorts(); $settings = []; - // --- Zibll main list contract --- - if (array_key_exists('home_posts_list_s', $params) || array_key_exists('home_posts_list_enabled', $params)) { - $settings['home_posts_list_s'] = array_key_exists('home_posts_list_s', $params) - ? !empty($params['home_posts_list_s']) - : !empty($params['home_posts_list_enabled']); + // --- Canonical Zibll main list contract --- + if (array_key_exists('home_posts_list_s', $params)) { + $settings['home_posts_list_s'] = !empty($params['home_posts_list_s']); } - if (array_key_exists('home_list1_orderby_s', $params) || array_key_exists('home_list_sort_enabled', $params)) { - $settings['home_list1_orderby_s'] = array_key_exists('home_list1_orderby_s', $params) - ? !empty($params['home_list1_orderby_s']) - : !empty($params['home_list_sort_enabled']); + if (array_key_exists('home_list1_orderby_s', $params)) { + $settings['home_list1_orderby_s'] = !empty($params['home_list1_orderby_s']); } if (isset($params['home_list1_orderby_option']) && is_array($params['home_list1_orderby_option'])) { @@ -48,45 +44,22 @@ trait HomepageSettingsRest { $params['home_list1_orderby_option'], $allowed_sorts ); - } elseif (isset($params['home_list_sort_options']) && is_array($params['home_list_sort_options'])) { - $settings['home_list1_orderby_option'] = $this->sanitize_home_list1_orderby_option( - [ - 'orderby' => $params['homepage_default_sort'] ?? 'modified', - 'options' => $params['home_list_sort_options'], - ], - $allowed_sorts - ); - } elseif (isset($params['homepage_default_sort'])) { - $default = sanitize_key((string) $params['homepage_default_sort']); - if (!in_array($default, $allowed_sorts, true)) { - $default = 'modified'; - } - $settings['home_list1_orderby_option'] = [ - 'orderby' => $default, - 'options' => array_values(array_unique(array_merge([$default], ['date', 'views', 'likes', 'comments']))), - ]; } - if (array_key_exists('index_list_title', $params) || array_key_exists('home_list_title', $params)) { - $title = array_key_exists('index_list_title', $params) - ? (string) $params['index_list_title'] - : (string) $params['home_list_title']; - $settings['index_list_title'] = sanitize_text_field($title); + if (array_key_exists('index_list_title', $params)) { + $settings['index_list_title'] = sanitize_text_field((string) $params['index_list_title']); } - if (isset($params['home_exclude_posts']) || isset($params['home_exclude_post_ids'])) { - $raw = $params['home_exclude_posts'] ?? $params['home_exclude_post_ids']; - $settings['home_exclude_posts'] = $this->sanitize_id_list($raw); + if (array_key_exists('home_exclude_posts', $params)) { + $settings['home_exclude_posts'] = $this->sanitize_id_list($params['home_exclude_posts']); } - if (isset($params['home_exclude_cats']) || isset($params['home_exclude_category_ids'])) { - $raw = $params['home_exclude_cats'] ?? $params['home_exclude_category_ids']; - $settings['home_exclude_cats'] = $this->sanitize_id_list($raw); + if (array_key_exists('home_exclude_cats', $params)) { + $settings['home_exclude_cats'] = $this->sanitize_id_list($params['home_exclude_cats']); } - if (isset($params['home_lists']) || isset($params['homepage_tabs'])) { - $raw_tabs = $params['home_lists'] ?? $params['homepage_tabs']; - $settings['home_lists'] = $this->sanitize_home_lists($raw_tabs, $allowed_sorts); + if (array_key_exists('home_lists', $params)) { + $settings['home_lists'] = $this->sanitize_home_lists($params['home_lists'], $allowed_sorts); } // --- AKSRT presentation extras (optional, not Zibll dual-write) --- @@ -140,7 +113,7 @@ trait HomepageSettingsRest { $current[$key] = $value; } - // Drop superseded AKSRT-only keys when canonical Zibll keys are written. + // Canonical writes also remove superseded aliases from persisted settings. $superseded = [ 'home_posts_list_enabled', 'home_list_sort_enabled', @@ -152,38 +125,7 @@ trait HomepageSettingsRest { 'homepage_default_sort', ]; foreach ($superseded as $dead_key) { - if (array_key_exists($dead_key, $current) && ( - array_key_exists('home_posts_list_s', $settings) - || array_key_exists('home_list1_orderby_s', $settings) - || array_key_exists('home_list1_orderby_option', $settings) - || array_key_exists('index_list_title', $settings) - || array_key_exists('home_exclude_posts', $settings) - || array_key_exists('home_exclude_cats', $settings) - || array_key_exists('home_lists', $settings) - )) { - // Only strip keys we actually replaced in this request. - } - } - if (array_key_exists('home_posts_list_s', $settings)) { - unset($current['home_posts_list_enabled']); - } - if (array_key_exists('home_list1_orderby_s', $settings)) { - unset($current['home_list_sort_enabled']); - } - if (array_key_exists('home_list1_orderby_option', $settings)) { - unset($current['home_list_sort_options'], $current['homepage_default_sort']); - } - if (array_key_exists('index_list_title', $settings)) { - unset($current['home_list_title']); - } - if (array_key_exists('home_exclude_posts', $settings)) { - unset($current['home_exclude_post_ids']); - } - if (array_key_exists('home_exclude_cats', $settings)) { - unset($current['home_exclude_category_ids']); - } - if (array_key_exists('home_lists', $settings)) { - unset($current['homepage_tabs']); + unset($current[$dead_key]); } update_option($option_key, $current); diff --git a/src/AKSRT/Core/ScriptsPart1b.php b/src/AKSRT/Core/ScriptsPart1b.php index 2b59ac4d..75d1b053 100644 --- a/src/AKSRT/Core/ScriptsPart1b.php +++ b/src/AKSRT/Core/ScriptsPart1b.php @@ -1036,10 +1036,17 @@ $hmb_js = get_template_directory() . '/assets/js/header-newadd.js'; $enqueue_module('header-components'); // header-slider / hero $enqueue_module('post-card'); $homepage_css_path = get_template_directory() . '/assets/css/frontend/homepage-fixed.css'; + $homepage_style_deps = file_exists($frontend_bundle) + ? ['aksrt-frontend-bundle', 'aksrt-header-components', 'aksrt-post-card'] + : ['aksrt-zibll-compat-vars', 'aksrt-layout', 'aksrt-widgets', 'aksrt-header-components', 'aksrt-post-card']; + $homepage_style_deps = array_values(array_filter( + $homepage_style_deps, + static fn(string $handle): bool => wp_style_is($handle, 'registered') + )); wp_enqueue_style( 'aksrt-homepage-fixed', $base_uri . '/assets/css/frontend/homepage-fixed.css', - ['aksrt-zibll-compat-vars', 'aksrt-layout', 'aksrt-widgets', 'aksrt-post-card'], + $homepage_style_deps, file_exists($homepage_css_path) ? (string) filemtime($homepage_css_path) : $version ); } diff --git a/src/AKSRT/Settings/HomeCms.php b/src/AKSRT/Settings/HomeCms.php index 9628213a..94ef9169 100644 --- a/src/AKSRT/Settings/HomeCms.php +++ b/src/AKSRT/Settings/HomeCms.php @@ -173,24 +173,18 @@ class HomeCms { $s = Settings::get_all(); $allowed_sorts = self::homepage_allowed_sorts(); - // Zibll-aligned primary list contract. - $main_list_enabled = array_key_exists('home_posts_list_s', $s) - ? !empty($s['home_posts_list_s']) - : (!isset($s['home_posts_list_enabled']) || !empty($s['home_posts_list_enabled'])); + // Canonical Zibll-aligned primary list contract. + $main_list_enabled = !array_key_exists('home_posts_list_s', $s) || !empty($s['home_posts_list_s']); + $sort_bar_enabled = !array_key_exists('home_list1_orderby_s', $s) || !empty($s['home_list1_orderby_s']); - $sort_bar_enabled = array_key_exists('home_list1_orderby_s', $s) - ? !empty($s['home_list1_orderby_s']) - : (!isset($s['home_list_sort_enabled']) || !empty($s['home_list_sort_enabled'])); - - $orderby_option = []; - if (isset($s['home_list1_orderby_option']) && is_array($s['home_list1_orderby_option'])) { - $orderby_option = $s['home_list1_orderby_option']; - } - $default_sort = sanitize_key((string) ($orderby_option['orderby'] ?? $s['homepage_default_sort'] ?? 'date')); + $orderby_option = isset($s['home_list1_orderby_option']) && is_array($s['home_list1_orderby_option']) + ? $s['home_list1_orderby_option'] + : []; + $default_sort = sanitize_key((string) ($orderby_option['orderby'] ?? 'date')); if (!in_array($default_sort, $allowed_sorts, true)) { $default_sort = 'date'; } - $sort_options_raw = $orderby_option['options'] ?? $s['home_list_sort_options'] ?? []; + $sort_options_raw = $orderby_option['options'] ?? []; if (!is_array($sort_options_raw)) { $sort_options_raw = []; } @@ -200,29 +194,14 @@ class HomeCms { $sort_options = array_values(array_unique($sort_options)); } - $list_title = ''; - if (array_key_exists('index_list_title', $s)) { - $list_title = sanitize_text_field((string) $s['index_list_title']); - } elseif (array_key_exists('home_list_title', $s)) { - $list_title = sanitize_text_field((string) $s['home_list_title']); - } + $list_title = sanitize_text_field((string) ($s['index_list_title'] ?? '')); if ($list_title === '') { $list_title = __('最新发布', 'aksrt'); } - $exclude_posts = self::normalize_int_array( - $s['home_exclude_posts'] ?? $s['home_exclude_post_ids'] ?? [] - ); - $exclude_cats = self::normalize_int_array( - $s['home_exclude_cats'] ?? $s['home_exclude_category_ids'] ?? [] - ); - - $tabs_raw = []; - if (isset($s['home_lists']) && is_array($s['home_lists'])) { - $tabs_raw = $s['home_lists']; - } elseif (isset($s['homepage_tabs']) && is_array($s['homepage_tabs'])) { - $tabs_raw = $s['homepage_tabs']; - } + $exclude_posts = self::normalize_int_array($s['home_exclude_posts'] ?? []); + $exclude_cats = self::normalize_int_array($s['home_exclude_cats'] ?? []); + $tabs_raw = isset($s['home_lists']) && is_array($s['home_lists']) ? $s['home_lists'] : []; $settings = [ // Canonical Zibll keys. @@ -237,16 +216,6 @@ class HomeCms { 'home_exclude_cats' => $exclude_cats, 'home_lists' => self::normalize_homepage_tabs($tabs_raw), - // Convenience aliases for existing PHP/Vue callers during cutover of this slice. - 'home_posts_list_enabled' => $main_list_enabled, - 'home_list_sort_enabled' => $sort_bar_enabled, - 'homepage_default_sort' => $default_sort, - 'home_list_sort_options' => $sort_options, - 'home_list_title' => $list_title, - 'home_exclude_post_ids' => $exclude_posts, - 'home_exclude_category_ids' => $exclude_cats, - 'homepage_tabs' => self::normalize_homepage_tabs($tabs_raw), - // AKSRT presentation extras. 'homepage_card_style' => isset($s['homepage_card_style']) ? sanitize_key((string) $s['homepage_card_style']) : 'default', 'homepage_multi_thumb_enabled' => !empty($s['homepage_multi_thumb_enabled']),