feat(admin): rebuild page display settings
This commit is contained in:
@@ -1,113 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Banner — v4.0 Zibll-Inspired
|
||||
*
|
||||
* 内联轮播条,使用与 header-slider 相同的 Swiper 架构,
|
||||
* 但以圆角卡片形式嵌入内容流中(非全宽)。
|
||||
*
|
||||
* 支持配置:
|
||||
* - 自动播放
|
||||
* - 圆角卡片样式
|
||||
* - 标题/副标题叠加
|
||||
* - 点击跳转
|
||||
*
|
||||
* @package AKSRT
|
||||
* @version 4.0.0
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (class_exists('\AKSRT\Settings\Settings') && !\AKSRT\Settings\Settings::homepage_module_banner_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$banners = function_exists('aksrt_get_banners') ? aksrt_get_banners(8) : [];
|
||||
if (empty($banners)) {
|
||||
if (current_user_can('manage_options')) {
|
||||
echo '<div class="home-module home-module--banner home-module--banner-empty box-body">';
|
||||
echo '<p class="muted-2-color">' . esc_html__('No Banner slides found. Add banner slides in admin.', 'aksrt') . '</p>';
|
||||
if (function_exists('aksrt_render_admin_quick_link')) {
|
||||
echo '<div class="home-module__admin-tools">';
|
||||
aksrt_render_admin_quick_link('page-display/banner', __('Banner 轮播管理', 'aksrt'));
|
||||
echo '</div>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$slide_count = count($banners);
|
||||
|
||||
// Swiper config — Banner uses a subset of the global slider config
|
||||
$slider_cfg = function_exists('aksrt_get_slider_config') ? aksrt_get_slider_config() : [];
|
||||
$swiper_config = [
|
||||
'effect' => 'slide', // Banner always uses slide effect
|
||||
'loop' => $slide_count > 1 && ($slider_cfg['loop'] ?? true),
|
||||
'speed' => 500,
|
||||
'autoplay' => $slide_count > 1 ? ['delay' => ($slider_cfg['autoplay_interval'] ?? 5000), 'disableOnInteraction' => false] : false,
|
||||
'pagination' => false,
|
||||
'navigation' => !empty($slider_cfg['navigation']),
|
||||
'keyboard' => ['enabled' => true],
|
||||
'spaceBetween' => ($slider_cfg['space_between'] ?? 0),
|
||||
];
|
||||
?>
|
||||
<div class="home-module home-module--banner slide-widget mb20">
|
||||
<div class="banner-module zib-slider">
|
||||
<div class="swiper new-swiper banner-module__swiper slide-widget-swiper" data-swiper-config="<?php echo esc_attr(wp_json_encode($swiper_config)); ?>">
|
||||
<div class="swiper-wrapper">
|
||||
<?php foreach ($banners as $index => $slide) :
|
||||
$device_vis = $slide['device_visibility'] ?? 'all';
|
||||
$slide_classes = 'swiper-slide';
|
||||
if ($device_vis === 'pc') {
|
||||
$slide_classes .= ' banner-slide--pc-only';
|
||||
} elseif ($device_vis === 'mobile') {
|
||||
$slide_classes .= ' banner-slide--mobile-only';
|
||||
}
|
||||
$link_target = !empty($slide['link_target']) ? $slide['link_target'] : '_self';
|
||||
?>
|
||||
<div class="<?php echo esc_attr($slide_classes); ?>"<?php if (!empty($slide['link'])) : ?> data-link="<?php echo esc_url($slide['link']); ?>" data-target="<?php echo esc_attr($link_target); ?>"<?php endif; ?>>
|
||||
<div class="banner-module__slide-bg">
|
||||
<?php if (!empty($slide['image'])) : ?>
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_sider', (string) $slide['image'], 'fit-cover', aksrt_get_lazy_thumb('lg')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
alt="<?php echo esc_attr($slide['title'] ?: get_bloginfo('name')); ?>"
|
||||
decoding="async"
|
||||
>
|
||||
<?php else : ?>
|
||||
<div class="banner-module__slide-fallback"></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="banner-module__slide-overlay"></div>
|
||||
<?php
|
||||
$show_text = !isset($slide['show_text']) || $slide['show_text'];
|
||||
$has_title = !empty($slide['title']);
|
||||
$has_subtitle = !empty($slide['subtitle']);
|
||||
?>
|
||||
<?php if ($show_text && ($has_title || $has_subtitle)) : ?>
|
||||
<div class="banner-module__content">
|
||||
<?php if ($has_title) : ?>
|
||||
<h3 class="banner-module__title"><?php echo esc_html($slide['title']); ?></h3>
|
||||
<?php endif; ?>
|
||||
<?php if ($has_subtitle) : ?>
|
||||
<p class="banner-module__subtitle"><?php echo esc_html($slide['subtitle']); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($slide_count > 1) : ?>
|
||||
<!-- 前后箭头 -->
|
||||
<div class="banner-module__prev swiper-button-prev"></div>
|
||||
<div class="banner-module__next swiper-button-next"></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (function_exists('aksrt_render_admin_quick_link')) : ?>
|
||||
<div class="home-module__admin-tools">
|
||||
<?php aksrt_render_admin_quick_link('page-display/banner', __('Banner 轮播管理', 'aksrt')); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Button Group
|
||||
*
|
||||
* config: { title?, buttons: [{ label, url, style?, icon? }], align? }
|
||||
*
|
||||
* 按钮组模块,用于 CTA 引导。
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
$buttons = isset($cfg['buttons']) && is_array($cfg['buttons']) ? $cfg['buttons'] : [];
|
||||
$align = sanitize_key((string) ($cfg['align'] ?? 'center'));
|
||||
|
||||
if (empty($buttons)) return;
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--button-group container" style="text-align:<?php echo esc_attr($align); ?>">
|
||||
<?php if ($title !== '') : ?>
|
||||
<h2 class="home-module__title"><?php echo esc_html($title); ?></h2>
|
||||
<?php endif; ?>
|
||||
<div class="home-module__buttons">
|
||||
<?php foreach ($buttons as $btn) :
|
||||
$label = (string) ($btn['label'] ?? '');
|
||||
$url = (string) ($btn['url'] ?? '#');
|
||||
$style = sanitize_key((string) ($btn['style'] ?? 'primary'));
|
||||
$icon = (string) ($btn['icon'] ?? '');
|
||||
if ($label === '') continue;
|
||||
?>
|
||||
<a href="<?php echo esc_url($url); ?>" class="aksrt-btn aksrt-btn--<?php echo esc_attr($style); ?>">
|
||||
<?php if ($icon !== '') : ?>
|
||||
<i class="<?php echo esc_attr($icon); ?>" aria-hidden="true"></i>
|
||||
<?php endif; ?>
|
||||
<span><?php echo esc_html($label); ?></span>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,65 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Category
|
||||
*
|
||||
* config: { cat_id, count, layout, columns, title? }
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$cat_id = isset($cfg['cat_id']) ? (int) $cfg['cat_id'] : 0;
|
||||
$count = max(1, min(20, (int) ($cfg['count'] ?? 8)));
|
||||
$layout = (string) ($cfg['layout'] ?? 'card');
|
||||
$columns = max(1, min(6, (int) ($cfg['columns'] ?? 4)));
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
|
||||
if (!in_array($layout, ['card', 'list'], true)) {
|
||||
$layout = 'card';
|
||||
}
|
||||
|
||||
$args = [
|
||||
'post_type' => 'post',
|
||||
'posts_per_page' => $count,
|
||||
'post_status' => 'publish',
|
||||
'no_found_rows' => true,
|
||||
];
|
||||
if ($cat_id > 0) {
|
||||
$args['cat'] = $cat_id;
|
||||
}
|
||||
|
||||
$query = new WP_Query($args);
|
||||
if (!$query->have_posts()) {
|
||||
wp_reset_postdata();
|
||||
return;
|
||||
}
|
||||
|
||||
$display_title = $title;
|
||||
if ($display_title === '' && $cat_id > 0) {
|
||||
$term = get_term($cat_id, 'category');
|
||||
if ($term && !is_wp_error($term)) $display_title = $term->name;
|
||||
}
|
||||
$more_link = $cat_id > 0 ? get_category_link($cat_id) : '';
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--category container" aria-label="<?php echo esc_attr($display_title ?: __('分类', 'aksrt')); ?>">
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($display_title ?: __('精选内容', 'aksrt')); ?></h2>
|
||||
<?php if ($more_link) : ?>
|
||||
<a class="home-module__more" href="<?php echo esc_url($more_link); ?>">
|
||||
<?php esc_html_e('查看更多', 'aksrt'); ?> <i class="fa fas fa-arrow-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<div class="posts-row ajaxpager">
|
||||
<?php
|
||||
aksrt_render_post_list([
|
||||
'type' => $layout === 'card' ? 'card' : 'list',
|
||||
'is_home' => true,
|
||||
'skip_wrapper' => true,
|
||||
], $query);
|
||||
?>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,115 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Category Recommend Cards
|
||||
*
|
||||
* 4 张分类卡片 2×2 布局,每张卡片包含:
|
||||
* 上部:封面图 + 浏览量胶囊 + 分类名/描述 + 文章数 + 更多链接
|
||||
* 下部:5 篇最新文章列表(标题 + 相对发布时间)
|
||||
*
|
||||
* config: { title?, cat_ids[], show_views?, show_dates? }
|
||||
*
|
||||
* 封面图来源:分类 term meta → 最新文章缩略图 → 占位图
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$module_title = (string) ($cfg['title'] ?? __('分类推荐', 'aksrt'));
|
||||
$cat_ids = array_map('absint', (array) ($cfg['cat_ids'] ?? []));
|
||||
$cat_ids = array_slice(array_filter($cat_ids, fn($id) => $id > 0), 0, 4);
|
||||
$show_views = !isset($cfg['show_views']) || !empty($cfg['show_views']);
|
||||
$show_dates = !isset($cfg['show_dates']) || !empty($cfg['show_dates']);
|
||||
|
||||
if (empty($cat_ids)) return;
|
||||
|
||||
$placeholder = aksrt_get_lazy_thumb('lg');
|
||||
|
||||
// 组装卡片数据
|
||||
$cards = [];
|
||||
foreach ($cat_ids as $idx => $cat_id) {
|
||||
$term = get_term($cat_id, 'category');
|
||||
if (!$term || is_wp_error($term)) continue;
|
||||
|
||||
// 封面图
|
||||
$cover_url = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_category_cover_url($cat_id)
|
||||
: $placeholder;
|
||||
|
||||
// 分类描述(优先 term meta 推荐描述,其次原生 description)
|
||||
$desc = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_category_recommend_desc($cat_id)
|
||||
: (string) $term->description;
|
||||
|
||||
// 5 篇最新文章
|
||||
$posts = get_posts([
|
||||
'category__in' => [$cat_id],
|
||||
'posts_per_page' => 5,
|
||||
'post_status' => 'publish',
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'no_found_rows' => true,
|
||||
]);
|
||||
|
||||
// 浏览量
|
||||
$views = $show_views ? aksrt_get_category_total_views($cat_id) : 0;
|
||||
|
||||
$cards[] = [
|
||||
'term' => $term,
|
||||
'cover' => $cover_url,
|
||||
'desc' => $desc,
|
||||
'posts' => $posts,
|
||||
'views' => $views,
|
||||
'count' => (int) $term->count,
|
||||
'link' => get_category_link($cat_id),
|
||||
];
|
||||
}
|
||||
|
||||
if (empty($cards)) return;
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--cat-cards" aria-label="<?php echo esc_attr($module_title); ?>">
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($module_title); ?></h2>
|
||||
</header>
|
||||
|
||||
<div class="cat-cards-grid">
|
||||
<?php foreach ($cards as $card) : ?>
|
||||
<div class="cat-card">
|
||||
<div class="cat-card__top">
|
||||
<div class="cat-card__banner">
|
||||
<?php if ($show_views && $card['views'] > 0) : ?>
|
||||
<span class="cat-card__views"><?php echo esc_html(function_exists('aksrt_format_number') ? aksrt_format_number($card['views']) : number_format_i18n($card['views'])); ?></span>
|
||||
<?php endif; ?>
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_cover', (string) $card['cover'], 'cat-card__cover', $placeholder); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="<?php echo esc_attr($card['term']->name); ?>">
|
||||
</div>
|
||||
<div class="cat-card__info">
|
||||
<div>
|
||||
<div class="cat-card__name"><?php echo esc_html($card['term']->name); ?></div>
|
||||
<?php if ($card['desc'] !== '') : ?>
|
||||
<div class="cat-card__desc"><?php echo esc_html($card['desc']); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="cat-card__foot">
|
||||
<span><?php printf(esc_html__('%d篇文章', 'aksrt'), $card['count']); ?></span>
|
||||
<a href="<?php echo esc_url($card['link']); ?>" class="cat-card__more"><?php esc_html_e('>更多文章', 'aksrt'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($card['posts'])) : ?>
|
||||
<ul class="cat-card__list">
|
||||
<?php foreach ($card['posts'] as $p) : ?>
|
||||
<li>
|
||||
<a href="<?php echo esc_url(get_permalink($p->ID)); ?>"><?php echo esc_html(get_the_title($p->ID)); ?></a>
|
||||
<?php if ($show_dates) : ?>
|
||||
<span class="cat-card__time"><?php echo esc_html(aksrt_time_ago($p->post_date)); ?></span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Data Grid
|
||||
*
|
||||
* config: { title?, items: [{ value, label, icon? }], columns? }
|
||||
*
|
||||
* 数据展示网格,用于统计数据、里程碑等。
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
$items = isset($cfg['items']) && is_array($cfg['items']) ? $cfg['items'] : [];
|
||||
$columns = max(2, min(6, (int) ($cfg['columns'] ?? 4)));
|
||||
|
||||
if (empty($items)) return;
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--data-grid container">
|
||||
<?php if ($title !== '') : ?>
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title); ?></h2>
|
||||
</header>
|
||||
<?php endif; ?>
|
||||
<div class="home-module__data-grid" style="grid-template-columns:repeat(<?php echo esc_attr((string) $columns); ?>, 1fr)">
|
||||
<?php foreach ($items as $item) :
|
||||
$value = (string) ($item['value'] ?? '');
|
||||
$label = (string) ($item['label'] ?? '');
|
||||
$icon = (string) ($item['icon'] ?? '');
|
||||
if ($value === '' && $label === '') continue;
|
||||
?>
|
||||
<div class="aksrt-data-cell">
|
||||
<?php if ($icon !== '') : ?>
|
||||
<i class="<?php echo esc_attr($icon); ?>" aria-hidden="true"></i>
|
||||
<?php endif; ?>
|
||||
<span class="aksrt-data-cell__value"><?php echo esc_html($value); ?></span>
|
||||
<span class="aksrt-data-cell__label"><?php echo esc_html($label); ?></span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · FAQ
|
||||
*
|
||||
* config: { title?, items: [{ q, a }], columns? }
|
||||
*
|
||||
* FAQ 手风琴模块。
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
$items = isset($cfg['items']) && is_array($cfg['items']) ? $cfg['items'] : [];
|
||||
$columns = max(1, min(3, (int) ($cfg['columns'] ?? 1)));
|
||||
|
||||
if (empty($items)) return;
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--faq container">
|
||||
<?php if ($title !== '') : ?>
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title); ?></h2>
|
||||
</header>
|
||||
<?php endif; ?>
|
||||
<div class="home-module__faq-grid" style="column-count:<?php echo esc_attr((string) $columns); ?>">
|
||||
<?php foreach ($items as $i => $item) :
|
||||
$q = (string) ($item['q'] ?? '');
|
||||
$a = (string) ($item['a'] ?? '');
|
||||
if ($q === '') continue;
|
||||
?>
|
||||
<details class="aksrt-faq-item">
|
||||
<summary class="aksrt-faq-item__question"><?php echo esc_html($q); ?></summary>
|
||||
<div class="aksrt-faq-item__answer"><?php echo wp_kses_post($a); ?></div>
|
||||
</details>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Friend Links
|
||||
*
|
||||
* config: { title? }
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
|
||||
$friend_links = aksrt_get_friend_links();
|
||||
if (!is_array($friend_links) || empty($friend_links)) return;
|
||||
if (empty($friend_links)) return;
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--friends container" aria-label="<?php echo esc_attr($title ?: __('友情链接', 'aksrt')); ?>">
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title ?: __('友情链接', 'aksrt')); ?></h2>
|
||||
</header>
|
||||
|
||||
<ul class="home-module__friends-list">
|
||||
<?php foreach ($friend_links as $link) :
|
||||
$url = $link['url'] ?? '';
|
||||
$name = $link['name'] ?? '';
|
||||
$description = $link['description'] ?? '';
|
||||
$logo = $link['logo'] ?? '';
|
||||
if (!$url || !$name) continue;
|
||||
?>
|
||||
<li>
|
||||
<a href="<?php echo esc_url($url); ?>" target="_blank" rel="noopener noreferrer external" class="home-module__friend-card">
|
||||
<?php if ($logo) : ?>
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_other', (string) $logo, 'home-module__friend-avatar'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="">
|
||||
<?php endif; ?>
|
||||
<div class="home-module__friend-meta">
|
||||
<strong><?php echo esc_html($name); ?></strong>
|
||||
<?php if ($description) : ?>
|
||||
<span><?php echo esc_html($description); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</section>
|
||||
@@ -1,52 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Highlight Cards
|
||||
*
|
||||
* config: { title?, items: [{ title, desc, icon?, image?, url? }], columns? }
|
||||
*
|
||||
* 亮点卡片模块,用于产品特性、服务介绍等。
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
$items = isset($cfg['items']) && is_array($cfg['items']) ? $cfg['items'] : [];
|
||||
$columns = max(1, min(4, (int) ($cfg['columns'] ?? 3)));
|
||||
|
||||
if (empty($items)) return;
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--highlight-cards container">
|
||||
<?php if ($title !== '') : ?>
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title); ?></h2>
|
||||
</header>
|
||||
<?php endif; ?>
|
||||
<div class="home-module__highlight-grid" style="grid-template-columns:repeat(<?php echo esc_attr((string) $columns); ?>, 1fr)">
|
||||
<?php foreach ($items as $item) :
|
||||
$item_title = (string) ($item['title'] ?? '');
|
||||
$item_desc = (string) ($item['desc'] ?? '');
|
||||
$item_icon = (string) ($item['icon'] ?? '');
|
||||
$item_image = (string) ($item['image'] ?? '');
|
||||
$item_url = (string) ($item['url'] ?? '');
|
||||
if ($item_title === '') continue;
|
||||
|
||||
$card_tag = $item_url !== '' ? 'a' : 'div';
|
||||
$card_attrs = $item_url !== '' ? ' href="' . esc_url($item_url) . '"' : '';
|
||||
?>
|
||||
<<?php echo esc_attr($card_tag); ?> class="aksrt-highlight-card"<?php echo $card_attrs; ?>>
|
||||
<?php if ($item_image !== '') : ?>
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_other', (string) $item_image, 'aksrt-highlight-card__image'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="">
|
||||
<?php elseif ($item_icon !== '') : ?>
|
||||
<div class="aksrt-highlight-card__icon"><i class="<?php echo esc_attr($item_icon); ?>"></i></div>
|
||||
<?php endif; ?>
|
||||
<h3 class="aksrt-highlight-card__title"><?php echo esc_html($item_title); ?></h3>
|
||||
<?php if ($item_desc !== '') : ?>
|
||||
<p class="aksrt-highlight-card__desc"><?php echo esc_html($item_desc); ?></p>
|
||||
<?php endif; ?>
|
||||
</<?php echo esc_attr($card_tag); ?>>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Hotspot 热点推荐
|
||||
*
|
||||
* 纯文章列表(无图片),仅桌面端显示。
|
||||
* config: { count, source, title? }
|
||||
*
|
||||
* source:
|
||||
* 'auto' → 优先读取 aksrt_recommend meta,不足时用最新补充
|
||||
* 'recent' → 按时间倒序
|
||||
* 'views' → 按阅读量排序
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) {
|
||||
$cfg = [];
|
||||
}
|
||||
|
||||
$count = max(3, min(20, (int) ($cfg['count'] ?? 6)));
|
||||
$source = (string) ($cfg['source'] ?? 'auto');
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
|
||||
if (!in_array($source, ['auto', 'recent', 'views'], true)) {
|
||||
$source = 'auto';
|
||||
}
|
||||
|
||||
$args = [
|
||||
'post_type' => 'post',
|
||||
'posts_per_page' => $count,
|
||||
'post_status' => 'publish',
|
||||
'no_found_rows' => true,
|
||||
];
|
||||
|
||||
if ($source === 'auto') {
|
||||
$args['meta_query'] = [
|
||||
'relation' => 'OR',
|
||||
['key' => 'aksrt_recommend', 'value' => '1', 'compare' => '='],
|
||||
['key' => 'aksrt_recommend', 'compare' => 'NOT EXISTS'],
|
||||
];
|
||||
$args['orderby'] = 'modified';
|
||||
$args['order'] = 'DESC';
|
||||
} elseif ($source === 'views') {
|
||||
$args['meta_key'] = '_aksrt_res_view_count';
|
||||
$args['orderby'] = 'meta_value_num';
|
||||
$args['order'] = 'DESC';
|
||||
} else {
|
||||
$args['orderby'] = 'date';
|
||||
$args['order'] = 'DESC';
|
||||
}
|
||||
|
||||
$query = new WP_Query($args);
|
||||
if (!$query->have_posts()) {
|
||||
wp_reset_postdata();
|
||||
return;
|
||||
}
|
||||
|
||||
$display_title = $title ?: __('热点推荐', 'aksrt');
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--hotspot hotspot--desktop-only" aria-label="<?php echo esc_attr($display_title); ?>">
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title">
|
||||
<i class="fa fas fa-fire" aria-hidden="true"></i>
|
||||
<?php echo esc_html($display_title); ?>
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<ol class="hotspot__list">
|
||||
<?php
|
||||
$rank = 1;
|
||||
while ($query->have_posts()) :
|
||||
$query->the_post();
|
||||
$cats = get_the_category();
|
||||
$cat_name = $cats ? $cats[0]->name : '';
|
||||
$views = (int) get_post_meta(get_the_ID(), '_aksrt_res_view_count', true);
|
||||
?>
|
||||
<li class="hotspot__item">
|
||||
<span class="hotspot__num hotspot__num--<?php echo $rank <= 3 ? 'top' : 'normal'; ?>"><?php echo (int) $rank; ?></span>
|
||||
<div class="hotspot__body">
|
||||
<a class="hotspot__title" href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
|
||||
<?php the_title(); ?>
|
||||
</a>
|
||||
<div class="hotspot__meta">
|
||||
<?php if ($cat_name) : ?>
|
||||
<span class="hotspot__cat"><?php echo esc_html($cat_name); ?></span>
|
||||
<?php endif; ?>
|
||||
<span class="hotspot__date"><?php echo esc_html(get_the_date('Y-m-d')); ?></span>
|
||||
<?php if ($views > 0) : ?>
|
||||
<span class="hotspot__views"><?php echo esc_html(number_format_i18n($views)); ?> <?php esc_html_e('阅读', 'aksrt'); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<?php
|
||||
$rank++;
|
||||
endwhile;
|
||||
wp_reset_postdata();
|
||||
?>
|
||||
</ol>
|
||||
</section>
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · HTML
|
||||
*
|
||||
* config: { html, title? }
|
||||
*
|
||||
* 已通过 wp_kses_post 在写入时清洗,渲染时直接输出。
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$html = (string) ($cfg['html'] ?? '');
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
|
||||
if ($html === '') return;
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--html container">
|
||||
<?php if ($title !== '') : ?>
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title); ?></h2>
|
||||
</header>
|
||||
<?php endif; ?>
|
||||
<div class="home-module__html-body">
|
||||
<?php echo wp_kses_post($html); ?>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · More (Discover Categories)
|
||||
*
|
||||
* Maps to zibll widget-more capability.
|
||||
* config: { title?, cat_ids[], count, columns, show_post_count, show_latest_posts, latest_count }
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) {
|
||||
$cfg = [];
|
||||
}
|
||||
|
||||
$title = trim((string) ($cfg['title'] ?? ''));
|
||||
$cat_ids = isset($cfg['cat_ids']) && is_array($cfg['cat_ids']) ? array_map('absint', $cfg['cat_ids']) : [];
|
||||
$count = max(1, min(12, (int) ($cfg['count'] ?? 6)));
|
||||
$columns = max(2, min(4, (int) ($cfg['columns'] ?? 3)));
|
||||
$show_post_count = !isset($cfg['show_post_count']) || !empty($cfg['show_post_count']);
|
||||
$show_latest_posts = !isset($cfg['show_latest_posts']) || !empty($cfg['show_latest_posts']);
|
||||
$latest_count = max(1, min(10, (int) ($cfg['latest_count'] ?? 5)));
|
||||
|
||||
// Fetch categories.
|
||||
if (!empty($cat_ids)) {
|
||||
$categories = get_categories([
|
||||
'include' => array_slice($cat_ids, 0, $count),
|
||||
'orderby' => 'include',
|
||||
]);
|
||||
} else {
|
||||
$categories = get_categories([
|
||||
'number' => $count,
|
||||
'orderby' => 'count',
|
||||
'order' => 'DESC',
|
||||
'hide_empty' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
if (empty($categories)) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--more container" aria-label="<?php echo esc_attr($title ?: __('发现更多', 'aksrt')); ?>">
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title ?: __('发现更多', 'aksrt')); ?></h2>
|
||||
</header>
|
||||
|
||||
<div class="home-module__more-grid" style="--cols: <?php echo (int) $columns; ?>;">
|
||||
<?php foreach ($categories as $cat) :
|
||||
$cat_link = get_category_link($cat);
|
||||
$cover = '';
|
||||
if (function_exists('aksrt_get_category_cover')) {
|
||||
$cover = aksrt_get_category_cover($cat->term_id);
|
||||
}
|
||||
?>
|
||||
<div class="home-module__more-card">
|
||||
<a href="<?php echo esc_url($cat_link); ?>" class="home-module__more-link">
|
||||
<?php if ($cover) : ?>
|
||||
<div class="home-module__more-cover">
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_other', (string) $cover); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="">
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="home-module__more-cover home-module__more-cover--placeholder">
|
||||
<i class="fa fas fa-folder" aria-hidden="true"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="home-module__more-body">
|
||||
<strong class="home-module__more-name"><?php echo esc_html($cat->name); ?></strong>
|
||||
<?php if ($show_post_count) : ?>
|
||||
<span class="home-module__more-count">
|
||||
<?php
|
||||
/* translators: %d: number of posts */
|
||||
printf(esc_html__('%d 篇文章', 'aksrt'), (int) $cat->count);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</a>
|
||||
<?php if ($show_latest_posts) :
|
||||
$recent = get_posts([
|
||||
'category' => $cat->term_id,
|
||||
'posts_per_page' => $latest_count,
|
||||
'post_status' => 'publish',
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
]);
|
||||
if (!empty($recent)) :
|
||||
?>
|
||||
<ul class="home-module__more-posts">
|
||||
<?php foreach ($recent as $rp) : ?>
|
||||
<li>
|
||||
<a href="<?php echo esc_url(get_permalink($rp)); ?>"><?php echo esc_html($rp->post_title); ?></a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php
|
||||
endif;
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Partner Marquee
|
||||
*
|
||||
* config: { title?, items: [{ name, image, url? }], speed? }
|
||||
*
|
||||
* 合作伙伴横向滚动模块。
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
$items = isset($cfg['items']) && is_array($cfg['items']) ? $cfg['items'] : [];
|
||||
$speed = max(10, min(120, (int) ($cfg['speed'] ?? 30)));
|
||||
|
||||
if (empty($items)) return;
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--partner-marquee container">
|
||||
<?php if ($title !== '') : ?>
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title); ?></h2>
|
||||
</header>
|
||||
<?php endif; ?>
|
||||
<div class="aksrt-marquee" style="--marquee-duration:<?php echo esc_attr((string) $speed); ?>s">
|
||||
<div class="aksrt-marquee__track">
|
||||
<?php
|
||||
// 渲染两份以实现无缝循环
|
||||
for ($pass = 0; $pass < 2; $pass++) :
|
||||
foreach ($items as $partner) :
|
||||
$name = (string) ($partner['name'] ?? '');
|
||||
$image = (string) ($partner['image'] ?? '');
|
||||
$url = (string) ($partner['url'] ?? '');
|
||||
if ($image === '' && $name === '') continue;
|
||||
|
||||
$tag = $url !== '' ? 'a' : 'span';
|
||||
$attrs = $url !== '' ? ' href="' . esc_url($url) . '" target="_blank" rel="noopener"' : '';
|
||||
?>
|
||||
<<?php echo esc_attr($tag); ?> class="aksrt-marquee__item"<?php echo $attrs; ?>>
|
||||
<?php if ($image !== '') : ?>
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_other', (string) $image); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="<?php echo esc_attr($name); ?>">
|
||||
<?php else : ?>
|
||||
<span><?php echo esc_html($name); ?></span>
|
||||
<?php endif; ?>
|
||||
</<?php echo esc_attr($tag); ?>>
|
||||
<?php
|
||||
endforeach;
|
||||
endfor;
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Product Showcase
|
||||
*
|
||||
* config: { title?, products: [{ title, desc, image, price?, url? }], columns? }
|
||||
*
|
||||
* 产品展示模块,用于商城/资源推荐。
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
$products = isset($cfg['products']) && is_array($cfg['products']) ? $cfg['products'] : [];
|
||||
$columns = max(1, min(4, (int) ($cfg['columns'] ?? 3)));
|
||||
|
||||
if (empty($products)) return;
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--product-showcase container">
|
||||
<?php if ($title !== '') : ?>
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title); ?></h2>
|
||||
</header>
|
||||
<?php endif; ?>
|
||||
<div class="home-module__product-grid" style="grid-template-columns:repeat(<?php echo esc_attr((string) $columns); ?>, 1fr)">
|
||||
<?php foreach ($products as $product) :
|
||||
$p_title = (string) ($product['title'] ?? '');
|
||||
$p_desc = (string) ($product['desc'] ?? '');
|
||||
$p_image = (string) ($product['image'] ?? '');
|
||||
$p_price = (string) ($product['price'] ?? '');
|
||||
$p_url = (string) ($product['url'] ?? '');
|
||||
if ($p_title === '') continue;
|
||||
?>
|
||||
<a href="<?php echo esc_url($p_url ?: '#'); ?>" class="aksrt-product-card">
|
||||
<?php if ($p_image !== '') : ?>
|
||||
<div class="aksrt-product-card__image">
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_other', (string) $p_image); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="<?php echo esc_attr($p_title); ?>">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="aksrt-product-card__body">
|
||||
<h3 class="aksrt-product-card__title"><?php echo esc_html($p_title); ?></h3>
|
||||
<?php if ($p_desc !== '') : ?>
|
||||
<p class="aksrt-product-card__desc"><?php echo esc_html($p_desc); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if ($p_price !== '') : ?>
|
||||
<span class="aksrt-product-card__price"><?php echo esc_html($p_price); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,98 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Ranking
|
||||
*
|
||||
* config: { metric: 'views|downloads|comments', count, title? }
|
||||
* Lists ordinary posts only (no content-type split).
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) {
|
||||
$cfg = [];
|
||||
}
|
||||
|
||||
$metric = (string) ($cfg['metric'] ?? 'downloads');
|
||||
$count = max(1, min(20, (int) ($cfg['count'] ?? 6)));
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
|
||||
if (!in_array($metric, ['views', 'downloads', 'comments'], true)) {
|
||||
$metric = 'downloads';
|
||||
}
|
||||
|
||||
$args = [
|
||||
'post_type' => 'post',
|
||||
'posts_per_page' => $count,
|
||||
'post_status' => 'publish',
|
||||
'no_found_rows' => true,
|
||||
];
|
||||
|
||||
switch ($metric) {
|
||||
case 'views':
|
||||
$args['meta_key'] = '_aksrt_res_view_count';
|
||||
$args['orderby'] = 'meta_value_num';
|
||||
$args['order'] = 'DESC';
|
||||
break;
|
||||
case 'comments':
|
||||
$args['orderby'] = 'comment_count';
|
||||
$args['order'] = 'DESC';
|
||||
break;
|
||||
case 'downloads':
|
||||
default:
|
||||
$args['meta_key'] = '_aksrt_res_download_count';
|
||||
$args['orderby'] = 'meta_value_num';
|
||||
$args['order'] = 'DESC';
|
||||
break;
|
||||
}
|
||||
|
||||
$query = new WP_Query($args);
|
||||
if (!$query->have_posts()) {
|
||||
wp_reset_postdata();
|
||||
return;
|
||||
}
|
||||
|
||||
$metric_label = [
|
||||
'views' => __('阅读量', 'aksrt'),
|
||||
'downloads' => __('下载量', 'aksrt'),
|
||||
'comments' => __('评论数', 'aksrt'),
|
||||
][$metric];
|
||||
|
||||
$display_title = $title ?: sprintf(__('%s 排行榜', 'aksrt'), $metric_label);
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--ranking container" aria-label="<?php echo esc_attr($display_title); ?>">
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title">
|
||||
<i class="fa fas fa-trophy" aria-hidden="true"></i>
|
||||
<?php echo esc_html($display_title); ?>
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<ol class="home-module__ranking-list">
|
||||
<?php
|
||||
$rank = 1;
|
||||
while ($query->have_posts()) :
|
||||
$query->the_post();
|
||||
$value = 0;
|
||||
if ($metric === 'views') {
|
||||
$value = (int) get_post_meta(get_the_ID(), '_aksrt_res_view_count', true);
|
||||
} elseif ($metric === 'comments') {
|
||||
$value = (int) get_comments_number();
|
||||
} else {
|
||||
$value = (int) get_post_meta(get_the_ID(), '_aksrt_res_download_count', true);
|
||||
}
|
||||
?>
|
||||
<li class="home-module__ranking-item home-module__ranking-item--<?php echo $rank <= 3 ? 'top' : 'normal'; ?>">
|
||||
<span class="home-module__ranking-num"><?php echo (int) $rank; ?></span>
|
||||
<a class="home-module__ranking-link" href="<?php the_permalink(); ?>">
|
||||
<?php the_title(); ?>
|
||||
</a>
|
||||
<span class="home-module__ranking-value"><?php echo esc_html(number_format_i18n($value)); ?></span>
|
||||
</li>
|
||||
<?php
|
||||
$rank++;
|
||||
endwhile;
|
||||
wp_reset_postdata();
|
||||
?>
|
||||
</ol>
|
||||
</section>
|
||||
@@ -1,63 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Recent
|
||||
*
|
||||
* config: { count, layout, title? }
|
||||
* Lists ordinary posts only (no content-type split).
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) {
|
||||
$cfg = [];
|
||||
}
|
||||
|
||||
$count = max(1, min(20, (int) ($cfg['count'] ?? 6)));
|
||||
$layout = (string) ($cfg['layout'] ?? 'card');
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
|
||||
if (!in_array($layout, ['card', 'list'], true)) {
|
||||
$layout = 'card';
|
||||
}
|
||||
|
||||
$args = [
|
||||
'post_type' => 'post',
|
||||
'posts_per_page' => $count,
|
||||
'post_status' => 'publish',
|
||||
'no_found_rows' => true,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
];
|
||||
|
||||
$query = new WP_Query($args);
|
||||
if (!$query->have_posts()) {
|
||||
wp_reset_postdata();
|
||||
return;
|
||||
}
|
||||
|
||||
$display_title = $title ?: __('最新文章', 'aksrt');
|
||||
$archive_link = get_permalink(get_option('page_for_posts'));
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--recent container" aria-label="<?php echo esc_attr($display_title); ?>">
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($display_title); ?></h2>
|
||||
<?php if ($archive_link) : ?>
|
||||
<a class="home-module__more" href="<?php echo esc_url($archive_link); ?>">
|
||||
<?php esc_html_e('查看更多', 'aksrt'); ?> <i class="fa fas fa-arrow-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<div class="posts-row ajaxpager">
|
||||
<?php
|
||||
aksrt_render_post_list([
|
||||
'type' => $layout === 'card' ? 'card' : 'list',
|
||||
'is_home' => true,
|
||||
'skip_wrapper' => true,
|
||||
], $query);
|
||||
?>
|
||||
</div>
|
||||
</section>
|
||||
<?php
|
||||
wp_reset_postdata();
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Spacing
|
||||
*
|
||||
* config: { height? }
|
||||
*
|
||||
* 间距模块,用于模块间留白。
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$height = max(8, min(200, (int) ($cfg['height'] ?? 40)));
|
||||
?>
|
||||
|
||||
<div class="home-module--spacing" style="height:<?php echo esc_attr((string) $height); ?>px" aria-hidden="true"></div>
|
||||
@@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Tabs
|
||||
*
|
||||
* config: { cat_ids: int[], count, layout, title? }
|
||||
*
|
||||
* P6 阶段先实现"按 Tab 标题分组渲染",Tab 切换交互在 P9 阶段引入 JS。
|
||||
* 默认行为:渲染选中分类(cat_ids[0])的卡片,其它 Tab 用 data-* 标记,
|
||||
* 配合 cms-home-modules.js 切换 active。
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$cat_ids = isset($cfg['cat_ids']) && is_array($cfg['cat_ids']) ? array_map('intval', $cfg['cat_ids']) : [];
|
||||
$cat_ids = array_filter($cat_ids, fn($x) => $x > 0);
|
||||
$count = max(1, min(20, (int) ($cfg['count'] ?? 8)));
|
||||
$layout = (string) ($cfg['layout'] ?? 'card');
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
|
||||
if (!in_array($layout, ['card', 'list'], true)) {
|
||||
$layout = 'card';
|
||||
}
|
||||
|
||||
if (empty($cat_ids)) {
|
||||
// 没有指定 → 取站点最热的两个分类
|
||||
$top_cats = get_terms([
|
||||
'taxonomy' => 'category',
|
||||
'orderby' => 'count',
|
||||
'order' => 'DESC',
|
||||
'number' => 4,
|
||||
'hide_empty' => true,
|
||||
'fields' => 'ids',
|
||||
]);
|
||||
if (is_wp_error($top_cats)) $top_cats = [];
|
||||
$cat_ids = array_map('intval', $top_cats);
|
||||
}
|
||||
|
||||
if (empty($cat_ids)) return;
|
||||
|
||||
$tabs = [];
|
||||
foreach ($cat_ids as $cid) {
|
||||
$term = get_term($cid, 'category');
|
||||
if (!$term || is_wp_error($term)) continue;
|
||||
$tabs[] = [
|
||||
'id' => $cid,
|
||||
'name' => $term->name,
|
||||
'link' => get_category_link($cid),
|
||||
];
|
||||
}
|
||||
if (empty($tabs)) return;
|
||||
|
||||
$active_id = $tabs[0]['id'];
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--tabs container home-tab-content index-tab-main" aria-label="<?php echo esc_attr($title ?: __('分类切换', 'aksrt')); ?>">
|
||||
<header class="home-module__header home-module__header--tabs">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title ?: __('热门分类', 'aksrt')); ?></h2>
|
||||
<nav class="home-module__tabs" role="tablist" data-aksrt-tabs>
|
||||
<?php foreach ($tabs as $i => $t) : ?>
|
||||
<button type="button"
|
||||
role="tab"
|
||||
class="home-module__tab<?php echo $i === 0 ? ' is-active' : ''; ?>"
|
||||
aria-selected="<?php echo $i === 0 ? 'true' : 'false'; ?>"
|
||||
data-tab-target="cat-<?php echo (int) $t['id']; ?>">
|
||||
<?php echo esc_html($t['name']); ?>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<?php foreach ($tabs as $i => $t) :
|
||||
$query = new WP_Query([
|
||||
'cat' => $t['id'],
|
||||
'post_type' => 'post',
|
||||
'posts_per_page' => $count,
|
||||
'post_status' => 'publish',
|
||||
'no_found_rows' => true,
|
||||
]);
|
||||
?>
|
||||
<div class="home-module__tab-panel tab-pane<?php echo $i === 0 ? ' is-active' : ''; ?>"
|
||||
role="tabpanel"
|
||||
data-tab-id="cat-<?php echo (int) $t['id']; ?>"
|
||||
<?php echo $i !== 0 ? 'hidden' : ''; ?>>
|
||||
<?php if ($query->have_posts()) : ?>
|
||||
<div class="posts-row ajaxpager tab-content">
|
||||
<?php
|
||||
aksrt_render_post_list([
|
||||
'type' => $layout === 'card' ? 'card' : 'list',
|
||||
'is_home' => true,
|
||||
'skip_wrapper' => true,
|
||||
], $query);
|
||||
?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<p class="home-module__empty"><?php esc_html_e('该分类暂无内容', 'aksrt'); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</section>
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Tag Cloud
|
||||
*
|
||||
* config: { limit, title? }
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$limit = max(5, min(100, (int) ($cfg['limit'] ?? 30)));
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
|
||||
$tags = get_terms([
|
||||
'taxonomy' => 'post_tag',
|
||||
'orderby' => 'count',
|
||||
'order' => 'DESC',
|
||||
'number' => $limit,
|
||||
'hide_empty' => true,
|
||||
]);
|
||||
if (is_wp_error($tags) || empty($tags)) return;
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--tags container" aria-label="<?php echo esc_attr($title ?: __('热门标签', 'aksrt')); ?>">
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title ?: __('热门标签', 'aksrt')); ?></h2>
|
||||
</header>
|
||||
|
||||
<ul class="home-module__tag-cloud">
|
||||
<?php foreach ($tags as $tag) : ?>
|
||||
<li>
|
||||
<a href="<?php echo esc_url(get_tag_link($tag->term_id)); ?>" class="home-module__tag">
|
||||
<span class="home-module__tag-name">#<?php echo esc_html($tag->name); ?></span>
|
||||
<span class="home-module__tag-count"><?php echo (int) $tag->count; ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</section>
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · Text Title
|
||||
*
|
||||
* config: { title, subtitle?, align?, tag? }
|
||||
*
|
||||
* 纯文本标题模块,用于页面分隔和标题引导。
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) $cfg = [];
|
||||
|
||||
$title = (string) ($cfg['title'] ?? '');
|
||||
$subtitle = (string) ($cfg['subtitle'] ?? '');
|
||||
$align = sanitize_key((string) ($cfg['align'] ?? 'left'));
|
||||
$tag = sanitize_key((string) ($cfg['tag'] ?? 'h2'));
|
||||
|
||||
if ($title === '' && $subtitle === '') return;
|
||||
|
||||
$valid_tags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
||||
if (!in_array($tag, $valid_tags, true)) $tag = 'h2';
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--text-title container" style="text-align:<?php echo esc_attr($align); ?>">
|
||||
<?php if ($title !== '') : ?>
|
||||
<<?php echo esc_attr($tag); ?> class="home-module__title"><?php echo esc_html($title); ?></<?php echo esc_attr($tag); ?>>
|
||||
<?php endif; ?>
|
||||
<?php if ($subtitle !== '') : ?>
|
||||
<p class="home-module__subtitle"><?php echo esc_html($subtitle); ?></p>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Home Module · User Cards
|
||||
*
|
||||
* Maps to zibll widget-user capability.
|
||||
* config: { title?, count, columns, order(recent/posts/manual), user_ids[], show_stats }
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$cfg = get_query_var('aksrt_module_config', []);
|
||||
if (!is_array($cfg)) {
|
||||
$cfg = [];
|
||||
}
|
||||
|
||||
$title = trim((string) ($cfg['title'] ?? ''));
|
||||
$count = max(1, min(12, (int) ($cfg['count'] ?? 4)));
|
||||
$columns = max(2, min(6, (int) ($cfg['columns'] ?? 4)));
|
||||
$order = sanitize_key((string) ($cfg['order'] ?? 'recent'));
|
||||
$user_ids = isset($cfg['user_ids']) && is_array($cfg['user_ids']) ? array_map('absint', $cfg['user_ids']) : [];
|
||||
$show_stats = !isset($cfg['show_stats']) || !empty($cfg['show_stats']);
|
||||
|
||||
// Build user query.
|
||||
if ($order === 'manual' && !empty($user_ids)) {
|
||||
$query_args = [
|
||||
'include' => array_slice($user_ids, 0, $count),
|
||||
'orderby' => 'include',
|
||||
'number' => $count,
|
||||
];
|
||||
} elseif ($order === 'posts') {
|
||||
$query_args = [
|
||||
'number' => $count,
|
||||
'orderby' => 'post_count',
|
||||
'order' => 'DESC',
|
||||
];
|
||||
} else {
|
||||
// 'recent' = newest registrations.
|
||||
$query_args = [
|
||||
'number' => $count,
|
||||
'orderby' => 'registered',
|
||||
'order' => 'DESC',
|
||||
];
|
||||
}
|
||||
|
||||
$users = get_users($query_args);
|
||||
if (empty($users)) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
|
||||
<section class="home-module home-module--users container" aria-label="<?php echo esc_attr($title ?: __('推荐用户', 'aksrt')); ?>">
|
||||
<header class="home-module__header">
|
||||
<h2 class="home-module__title"><?php echo esc_html($title ?: __('推荐用户', 'aksrt')); ?></h2>
|
||||
</header>
|
||||
|
||||
<div class="home-module__users-grid" style="--cols: <?php echo (int) $columns; ?>;">
|
||||
<?php foreach ($users as $user) :
|
||||
$uid = $user->ID;
|
||||
$avatar = get_avatar_url($uid, ['size' => 96]);
|
||||
$display = $user->display_name ?: $user->user_login;
|
||||
$bio = get_user_meta($uid, 'description', true);
|
||||
$post_cnt = count_user_posts($uid);
|
||||
$profile = function_exists('aksrt_get_user_home_url')
|
||||
? aksrt_get_user_home_url($uid)
|
||||
: get_author_posts_url($uid);
|
||||
?>
|
||||
<div class="home-module__user-card">
|
||||
<a href="<?php echo esc_url($profile); ?>" class="home-module__user-link">
|
||||
<img<?php echo aksrt_get_lazy_attr('lazy_avatar', (string) $avatar, 'home-module__user-avatar', aksrt_get_lazy_thumb('sm')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="">
|
||||
<strong class="home-module__user-name"><?php echo esc_html($display); ?></strong>
|
||||
</a>
|
||||
<?php if ($bio) : ?>
|
||||
<p class="home-module__user-bio"><?php echo esc_html(wp_trim_words($bio, 12, '...')); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if ($show_stats) : ?>
|
||||
<span class="home-module__user-stats">
|
||||
<span class="home-module__user-stat">
|
||||
<i class="fa fas fa-file-alt" aria-hidden="true"></i>
|
||||
<?php echo (int) $post_cnt; ?>
|
||||
</span>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
Reference in New Issue
Block a user