refactor(resource): drop aksrt_resource CPT residue, post+meta only
This commit is contained in:
1 parent
24c135aeec
commit
1af0e9b753
22 files changed
+362
-986
No files matched your search
@@ -41,16 +41,16 @@ if (!function_exists('aksrt_get_term_flow')) {
|
||||
|
||||
if (!function_exists('aksrt_is_resource_post')) {
|
||||
/**
|
||||
* 是否为资源(post + _aksrt_is_resource meta,或历史 aksrt_resource CPT)。
|
||||
* 是否为资源帖:普通 post + _aksrt_is_resource meta。
|
||||
*
|
||||
* @param int|WP_Post|null $post
|
||||
* @return bool
|
||||
*/
|
||||
function aksrt_is_resource_post($post = null): bool {
|
||||
$p = get_post($post);
|
||||
if (!($p instanceof WP_Post)) return false;
|
||||
if ($p->post_type === 'aksrt_resource') return true;
|
||||
if ($p->post_type !== 'post') return false;
|
||||
if (!($p instanceof WP_Post) || $p->post_type !== 'post') {
|
||||
return false;
|
||||
}
|
||||
return (bool) get_post_meta($p->ID, '_aksrt_is_resource', true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,11 +594,11 @@ if (!function_exists('aksrt_set_post_views')) :
|
||||
}
|
||||
if ($post_id <= 0) return;
|
||||
$post_type = get_post_type($post_id);
|
||||
// 只对 post / 历史 aksrt_resource CPT 计数
|
||||
if (!in_array($post_type, ['post', 'aksrt_resource'], true)) return;
|
||||
// 仅普通文章(资源也是 post)计数
|
||||
if ($post_type !== 'post') return;
|
||||
$key = 'aksrt_post_views_' . $post_id;
|
||||
if (!empty($_COOKIE[$key])) return;
|
||||
// 资源(post + _aksrt_is_resource,或旧 CPT)使用独立 meta key,便于排序
|
||||
// 资源帖使用独立 meta key,便于排序
|
||||
$is_resource = function_exists('aksrt_is_resource_post') && aksrt_is_resource_post($post_id);
|
||||
if ($is_resource) {
|
||||
if (function_exists('aksrt_update_post_counter')) {
|
||||
|
||||
@@ -36,27 +36,16 @@ if (!function_exists('aksrt_homepage_get_current_page')) {
|
||||
if (!function_exists('aksrt_homepage_get_post_types')) {
|
||||
/**
|
||||
* Homepage latest feed post types.
|
||||
*
|
||||
* Respects the homepage_content_model setting:
|
||||
* - 'post': standard posts only (default)
|
||||
* - 'mixed': posts + resource CPTs (explicit opt-in)
|
||||
* Resources are ordinary posts with meta — always post.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
function aksrt_homepage_get_post_types(): array {
|
||||
// Default: plain posts only (zibll main-query feel). Mixed/resource is opt-in.
|
||||
$content_model = class_exists('AKSRT_Settings')
|
||||
? AKSRT_Settings::homepage_content_model()
|
||||
: 'post';
|
||||
|
||||
if ($content_model === 'mixed' && function_exists('aksrt_resource_post_types')) {
|
||||
return array_values(array_unique(aksrt_resource_post_types()));
|
||||
}
|
||||
|
||||
return ['post'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!function_exists('aksrt_homepage_get_tab_terms')) {
|
||||
/**
|
||||
* Homepage category tabs with full config.
|
||||
|
||||
@@ -412,10 +412,7 @@ if (!function_exists('aksrt_resource_download_cost')) {
|
||||
|
||||
if (!function_exists('aksrt_resource_meta_query')) {
|
||||
/**
|
||||
* 「是资源」WP_Query meta_query 片段。
|
||||
*
|
||||
* v3.4: 资源 = post + _aksrt_is_resource = 1。
|
||||
* 兼容历史 aksrt_resource CPT 时由调用方决定是否额外加 post_type。
|
||||
* 「是资源」WP_Query meta_query 片段:post + _aksrt_is_resource = 1。
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -428,26 +425,9 @@ if (!function_exists('aksrt_resource_meta_query')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_resource_post_types')) {
|
||||
/**
|
||||
* 资源查询使用的 post_type 数组。
|
||||
*
|
||||
* 当历史 aksrt_resource CPT 仍在站点中存在(未迁移完成)时,会自动包含。
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function aksrt_resource_post_types(): array {
|
||||
$types = ['post'];
|
||||
if (post_type_exists('aksrt_resource')) {
|
||||
$types[] = 'aksrt_resource';
|
||||
}
|
||||
return $types;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_resource_archive_url')) {
|
||||
/**
|
||||
* 取资源归档页 URL(v3.4 起统一为 /resources/)。
|
||||
* 资源列表页 URL(/resources/)。
|
||||
*/
|
||||
function aksrt_resource_archive_url(): string {
|
||||
return home_url('/resources/');
|
||||
@@ -456,19 +436,27 @@ if (!function_exists('aksrt_resource_archive_url')) {
|
||||
|
||||
if (!function_exists('aksrt_is_resource_archive')) {
|
||||
/**
|
||||
* 当前请求是否为资源归档(/resources)。
|
||||
*
|
||||
* 兼容历史 aksrt_resource CPT 归档。
|
||||
* 当前请求是否为资源列表(/resources 虚拟归档)。
|
||||
*/
|
||||
function aksrt_is_resource_archive(): bool {
|
||||
if (function_exists('post_type_exists') && post_type_exists('aksrt_resource')
|
||||
&& function_exists('is_post_type_archive') && is_post_type_archive('aksrt_resource')) {
|
||||
return true;
|
||||
}
|
||||
return (bool) get_query_var('aksrt_is_resource_archive');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize homepage-module content scope.
|
||||
* Values: post | resource (resource = posts marked _aksrt_is_resource).
|
||||
*/
|
||||
if (!function_exists('aksrt_normalize_content_scope')) {
|
||||
function aksrt_normalize_content_scope($scope): string {
|
||||
$scope = sanitize_key((string) $scope);
|
||||
if ($scope === 'resource') {
|
||||
return 'resource';
|
||||
}
|
||||
return 'post';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_detect_cloud_service')) {
|
||||
/**
|
||||
* 从下载链接自动识别云盘服务商。
|
||||
|
||||
@@ -787,545 +787,16 @@ if (!function_exists('aksrt_searchable_post_types')):
|
||||
* @return string[]
|
||||
*/
|
||||
function aksrt_searchable_post_types(): array {
|
||||
$types = ['post'];
|
||||
$types = ['post'];
|
||||
|
||||
if (post_type_exists('aksrt_resource')
|
||||
&& class_exists('AKSRT_Settings')
|
||||
&& AKSRT_Settings::cms_feature('search_include_resource', true)) {
|
||||
$types[] = 'aksrt_resource';
|
||||
}
|
||||
/**
|
||||
* 过滤可检索内容类型。
|
||||
*
|
||||
* @param string[] $types 内容类型 slug 列表。
|
||||
*/
|
||||
$types = apply_filters('aksrt_searchable_post_types', $types);
|
||||
|
||||
/**
|
||||
* 过滤可检索内容类型。
|
||||
*
|
||||
* @param string[] $types 内容类型 slug 列表。
|
||||
*/
|
||||
$types = apply_filters('aksrt_searchable_post_types', $types);
|
||||
|
||||
return array_values(array_unique(array_filter((array) $types)));
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_admin_settings_url')):
|
||||
/**
|
||||
* Build a quick-link URL into the admin SPA settings app.
|
||||
*
|
||||
* @param string $path Route path without leading #/.
|
||||
* @return string
|
||||
*/
|
||||
function aksrt_get_admin_settings_url(string $path): string {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$path = trim($path, "/# \t\n\r\0\x0B");
|
||||
if ($path === '') {
|
||||
return admin_url('admin.php?page=aksrt-settings');
|
||||
}
|
||||
|
||||
return admin_url('admin.php?page=aksrt-settings#/' . $path);
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_render_admin_quick_link')):
|
||||
/**
|
||||
* Render an admin-only front-end shortcut to the corresponding settings page.
|
||||
*
|
||||
* @param string $path Admin SPA route path.
|
||||
* @param string $label Button label.
|
||||
* @param string $class CSS classes.
|
||||
*/
|
||||
function aksrt_render_admin_quick_link(string $path, string $label = '', string $class = 'aksrt-admin-quicklink'): void {
|
||||
$url = aksrt_get_admin_settings_url($path);
|
||||
if ($url === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($label === '') {
|
||||
$label = __('编辑此区域', 'aksrt');
|
||||
}
|
||||
?>
|
||||
<a class="<?php echo esc_attr($class); ?>" href="<?php echo esc_url($url); ?>">
|
||||
<i class="fas fa-sliders-h" aria-hidden="true"></i>
|
||||
<span><?php echo esc_html($label); ?></span>
|
||||
</a>
|
||||
<?php
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_render_search_hot_keywords')):
|
||||
/**
|
||||
* 渲染热门搜索关键词
|
||||
*
|
||||
* @param array $keywords 关键词
|
||||
* @param string $class 容器类名
|
||||
*/
|
||||
function aksrt_render_search_hot_keywords(array $keywords = [], string $class = 'aksrt-search-hot-keywords'): void {
|
||||
if (empty($keywords)) {
|
||||
$keywords = aksrt_get_search_hot_keywords();
|
||||
}
|
||||
|
||||
if (empty($keywords)) {
|
||||
return;
|
||||
}
|
||||
$title = class_exists('AKSRT_Settings') ? AKSRT_Settings::search_popular_title() : __('热门搜索', 'aksrt');
|
||||
?>
|
||||
<div class="<?php echo esc_attr($class); ?>" aria-label="<?php echo esc_attr($title); ?>">
|
||||
<span class="<?php echo esc_attr($class . '__label'); ?>"><?php echo esc_html($title); ?></span>
|
||||
<div class="<?php echo esc_attr($class . '__list tabbar-search-overlay__tags'); ?>">
|
||||
<?php foreach ($keywords as $keyword) : ?>
|
||||
<a class="tabbar-search-overlay__tag" href="<?php echo aksrt_build_search_url($keyword, ['aksrt_search_type' => aksrt_get_default_search_type()]); ?>">
|
||||
<?php echo esc_html($keyword); ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_avatar_url')):
|
||||
/**
|
||||
* 获取统一头像 URL
|
||||
*
|
||||
* @param mixed $id_or_email 用户、评论对象或邮箱
|
||||
* @param array $args get_avatar_data 参数
|
||||
* @return string
|
||||
*/
|
||||
function aksrt_get_avatar_url($id_or_email, array $args = []): string {
|
||||
$data = get_avatar_data($id_or_email, array_merge(['size' => 96], $args));
|
||||
return isset($data['url']) ? (string) $data['url'] : '';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_avatar_html')):
|
||||
/**
|
||||
* 获取统一头像 HTML
|
||||
*
|
||||
* @param mixed $id_or_email 用户、评论对象或邮箱
|
||||
* @param int $size 头像尺寸
|
||||
* @param array $args get_avatar 参数
|
||||
* @return string
|
||||
*/
|
||||
function aksrt_get_avatar_html($id_or_email, int $size = 96, array $args = []): string {
|
||||
$args = array_merge(['size' => $size], $args);
|
||||
|
||||
return get_avatar($id_or_email, $size, '', '', $args);
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_about_info')):
|
||||
/**
|
||||
* 获取 About 页面信息
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function aksrt_get_about_info() {
|
||||
$public = get_option('aksrt_public_settings', array());
|
||||
return array(
|
||||
'display_name' => class_exists('AKSRT_Settings') ? AKSRT_Settings::about_display_name() : aksrt_get_setting('about_display_name', get_bloginfo('name')),
|
||||
'bio' => class_exists('AKSRT_Settings') ? AKSRT_Settings::about_bio() : aksrt_get_setting('about_bio', ''),
|
||||
'avatar_url' => class_exists('AKSRT_Settings') ? AKSRT_Settings::about_avatar() : aksrt_get_setting('about_avatar', ($public['admin_avatar_url'] ?? '')),
|
||||
'contacts' => isset($public['about_contacts']) ? $public['about_contacts'] : array(),
|
||||
);
|
||||
}
|
||||
endif;
|
||||
|
||||
// ============================================================
|
||||
// 模板标签:社交链接图标渲染
|
||||
// ============================================================
|
||||
|
||||
if (!function_exists('aksrt_render_social_links')):
|
||||
/**
|
||||
* 渲染社交链接图标
|
||||
*
|
||||
* @param array $links 联系方式数组 [{name:'GitHub', url:'...'}]
|
||||
*/
|
||||
function aksrt_render_social_links($links = array()) {
|
||||
if (empty($links)) return;
|
||||
|
||||
echo '<div class="profile-social-links">';
|
||||
foreach ($links as $contact):
|
||||
$icon_key = isset($contact['icon']) ? $contact['icon'] : '';
|
||||
|
||||
// 旧数据兼容:从 name 猜测 icon_key
|
||||
if (!$icon_key) {
|
||||
$name_lower = strtolower(isset($contact['name']) ? $contact['name'] : '');
|
||||
$guess = array(
|
||||
'github' => 'github', 'google' => 'google', 'x' => 'x', 'twitter' => 'x',
|
||||
'email' => 'email', 'wechat' => 'wechat', 'qq' => 'qq', 'weibo' => 'weibo',
|
||||
'telegram' => 'telegram', 'discord' => 'discord', 'bilibili' => 'bilibili',
|
||||
'linkedin' => 'linkedin', 'facebook' => 'facebook', 'youtube' => 'youtube',
|
||||
'instagram' => 'instagram', 'rss' => 'web', 'site' => 'web', 'globe' => 'web',
|
||||
);
|
||||
foreach ($guess as $k => $v) {
|
||||
if (strpos($name_lower, $k) !== false) { $icon_key = $v; break; }
|
||||
}
|
||||
if (!$icon_key) $icon_key = 'web';
|
||||
}
|
||||
|
||||
$title = aksrt_icon_key_to_name($icon_key);
|
||||
$svg = aksrt_inline_svg($icon_key);
|
||||
if (!$svg) $svg = aksrt_inline_svg('web');
|
||||
if (!$svg) continue;
|
||||
|
||||
printf(
|
||||
'<a href="%s" target="_blank" rel="noopener" class="social-icon-link" title="%s">%s</a>',
|
||||
esc_url($contact['url']),
|
||||
esc_attr($title),
|
||||
$svg
|
||||
);
|
||||
endforeach;
|
||||
echo '</div>';
|
||||
}
|
||||
endif;
|
||||
|
||||
// ============================================================
|
||||
// Head 输出(Favicon / Canonical / SEO / OpenGraph / Twitter / JSON-LD / robots)
|
||||
// ------------------------------------------------------------
|
||||
// Phase 7:上述 head 输出已统一收口到 AKSRT_SEO_Head(单一装配器,
|
||||
// 见 inc/classes/class-aksrt-seo-head.php 与 seo-output-matrix.md),
|
||||
// 不再在此用多个分散的 wp_head 闭包输出,避免重复与来源不可追踪。
|
||||
// ============================================================
|
||||
|
||||
// ============================================================
|
||||
// Sitemap:兼容历史 aksrt_resource CPT(v3.4 起资源已并入 post,无需特殊处理)
|
||||
// ============================================================
|
||||
add_filter('wp_sitemaps_post_types', function ($post_types) {
|
||||
if (post_type_exists('aksrt_resource') && !isset($post_types['aksrt_resource'])) {
|
||||
$post_types['aksrt_resource'] = get_post_type_object('aksrt_resource');
|
||||
}
|
||||
// 移除内部隐藏的 banner CPT(虽然其 public=false,但兜底)
|
||||
if (isset($post_types['aksrt_banner'])) {
|
||||
unset($post_types['aksrt_banner']);
|
||||
}
|
||||
return $post_types;
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// 模板标签函数(供 index.php / single.php / archive.php 使用)
|
||||
// ============================================================
|
||||
|
||||
if (!function_exists('aksrt_post_categories')):
|
||||
/**
|
||||
* 显示文章分类标签
|
||||
* 定义在 functions.php 中,确保所有模板都能调用
|
||||
*/
|
||||
function aksrt_post_categories() {
|
||||
$categories = get_the_category_list(array(
|
||||
'separator' => '',
|
||||
'before' => '<span class="cat-links">',
|
||||
'after' => '</span>',
|
||||
));
|
||||
echo $categories;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_estimated_reading_time')):
|
||||
/**
|
||||
* 估算阅读时间(分钟)
|
||||
*
|
||||
* @return int 阅读时间(分钟)
|
||||
*/
|
||||
function aksrt_estimated_reading_time() {
|
||||
$content = get_post_field('post_content', get_the_ID(), 'raw');
|
||||
$word_count = str_word_count(strip_tags($content));
|
||||
return max(1, (int) ceil($word_count / 200)); // 假设每分钟200字
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('comments_number_label')):
|
||||
/**
|
||||
* 评论数量显示标签
|
||||
*
|
||||
* @return string 格式化的评论数
|
||||
*/
|
||||
function comments_number_label() {
|
||||
$num = get_comments_number();
|
||||
if ($num === 0) return __('暂无评论', 'aksrt');
|
||||
if ($num === 1) return __('1 条评论', 'aksrt');
|
||||
return sprintf(__('%d 条评论', 'aksrt'), $num);
|
||||
}
|
||||
endif;
|
||||
|
||||
// ============================================================
|
||||
// 模板标签:从文章内容中提取第一张图片
|
||||
// ============================================================
|
||||
|
||||
if (!function_exists('aksrt_get_first_content_image_url')):
|
||||
/**
|
||||
* 从文章内容中提取第一张图片 URL
|
||||
* 支持 <img> 标签和 Gutenberg wp:image 块
|
||||
*
|
||||
* @param int $post_id 文章 ID,默认当前文章
|
||||
* @return string 图片 URL,无图片返回空字符串
|
||||
*/
|
||||
function aksrt_get_first_content_image_url(int $post_id = 0): string {
|
||||
$post_id = $post_id ?: get_the_ID();
|
||||
$content = get_post_field('post_content', $post_id, 'raw');
|
||||
if (!$content) return '';
|
||||
|
||||
// 匹配 <img> 标签的 src
|
||||
if (preg_match('/<img[^>]+src=["\x27"]([^"\x27"]+)["\x27"]/', $content, $m)) {
|
||||
return esc_url_raw($m[1]);
|
||||
}
|
||||
|
||||
// 匹配 Gutenberg image 块的 url 属性
|
||||
if (preg_match('/<!-- wp:image \{[^}]*"url"\s*:\s*"([^"]+)"/', $content, $m)) {
|
||||
return esc_url_raw($m[1]);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
endif;
|
||||
|
||||
// ============================================================
|
||||
// 模板标签:首页分类推荐
|
||||
// ============================================================
|
||||
|
||||
if (!function_exists('aksrt_get_category_recommend_settings')):
|
||||
/**
|
||||
* 获取分类推荐配置
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function aksrt_get_category_recommend_settings(): array {
|
||||
if (class_exists('AKSRT_Settings')) {
|
||||
return AKSRT_Settings::get_category_recommend_settings();
|
||||
}
|
||||
return [];
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_category_recommend_items')):
|
||||
/**
|
||||
* 获取分类推荐渲染数据
|
||||
*
|
||||
* @param array $settings 分类推荐配置
|
||||
* @return array
|
||||
*/
|
||||
function aksrt_get_category_recommend_items(array $settings): array {
|
||||
if (class_exists('AKSRT_Settings')) {
|
||||
return AKSRT_Settings::get_category_recommend_items($settings);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_render_category_recommend_section')):
|
||||
/**
|
||||
* 渲染首页分类推荐模块
|
||||
*
|
||||
* @param array $settings 可选配置,为空则自动读取
|
||||
*/
|
||||
function aksrt_render_category_recommend_section(array $settings = []): void {
|
||||
if (empty($settings)) {
|
||||
$settings = aksrt_get_category_recommend_settings();
|
||||
}
|
||||
|
||||
if (empty($settings['enable_category_recommend'])) return;
|
||||
|
||||
$items = aksrt_get_category_recommend_items($settings);
|
||||
if (empty($items)) return;
|
||||
|
||||
$title = $settings['category_recommend_title'] ?: __('分类推荐', 'aksrt');
|
||||
$columns = max(1, min(4, (int) ($settings['category_recommend_columns'] ?? 2)));
|
||||
$show_desc = !empty($settings['category_recommend_show_description']);
|
||||
$show_dates = !empty($settings['category_recommend_show_dates']);
|
||||
$show_more = !empty($settings['category_recommend_show_more_link']);
|
||||
|
||||
// 懒加载配置
|
||||
$lazy_cfg = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_lazyload_config() : ['enabled' => false, 'placeholder_url' => ''];
|
||||
$lazy_on = !empty($lazy_cfg['enabled']);
|
||||
$placeholder_url = $lazy_cfg['placeholder_url'] ?: (get_template_directory_uri() . '/assets/img/placeholder.svg');
|
||||
|
||||
?>
|
||||
<section class="category-recommend" aria-label="<?php echo esc_attr($title); ?>">
|
||||
<div class="category-recommend__header">
|
||||
<h2 class="category-recommend__title"><?php echo esc_html($title); ?></h2>
|
||||
</div>
|
||||
<div class="category-recommend__grid" style="--cr-columns:<?php echo esc_attr((string) $columns); ?>">
|
||||
<?php foreach ($items as $item) : ?>
|
||||
<div class="category-recommend-card">
|
||||
<div class="category-recommend-card__hero">
|
||||
<a href="<?php echo esc_url($item['link']); ?>">
|
||||
<?php if ($lazy_on) : ?>
|
||||
<span class="aksrt-skeleton"></span>
|
||||
<img class="category-recommend-card__cover aksrt-lazy" data-src="<?php echo esc_url($item['cover']); ?>" src="<?php echo esc_url($placeholder_url); ?>" alt="<?php echo esc_attr($item['name']); ?>">
|
||||
<?php else : ?>
|
||||
<img class="category-recommend-card__cover" src="<?php echo esc_url($item['cover']); ?>" alt="<?php echo esc_attr($item['name']); ?>">
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<span class="category-recommend-card__badge"><?php echo esc_html(sprintf(_n('%d 篇文章', '%d 篇文章', $item['count'], 'aksrt'), $item['count'])); ?></span>
|
||||
</div>
|
||||
<div class="category-recommend-card__meta">
|
||||
<h3 class="category-recommend-card__name">
|
||||
<a href="<?php echo esc_url($item['link']); ?>"><?php echo esc_html($item['name']); ?></a>
|
||||
</h3>
|
||||
<?php if ($show_desc && $item['description']) : ?>
|
||||
<p class="category-recommend-card__desc"><?php echo esc_html($item['description']); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if (!empty($item['posts'])) : ?>
|
||||
<ul class="category-recommend-card__posts">
|
||||
<?php foreach ($item['posts'] as $post) : ?>
|
||||
<li class="category-recommend-card__post-item">
|
||||
<a href="<?php echo esc_url($post['link']); ?>" class="category-recommend-card__post-title"><?php echo esc_html($post['title']); ?></a>
|
||||
<?php if ($show_dates) : ?>
|
||||
<span class="category-recommend-card__post-date"><?php echo esc_html($post['date']); ?></span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
<?php if ($show_more) : ?>
|
||||
<div class="category-recommend-card__more">
|
||||
<a href="<?php echo esc_url($item['link']); ?>"><?php esc_html_e('更多文章', 'aksrt'); ?> →</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php
|
||||
}
|
||||
endif;
|
||||
|
||||
// ============================================================
|
||||
// 模板标签:分页渲染
|
||||
// ============================================================
|
||||
|
||||
if (!function_exists('aksrt_render_pagination')) {
|
||||
/**
|
||||
* 渲染文章列表分页(根据后台配置选择模式)
|
||||
*
|
||||
* @param WP_Query|null $query 可选,传入自定义查询对象
|
||||
*/
|
||||
function aksrt_render_pagination(?WP_Query $query = null, array $args = []): void {
|
||||
$pagination_mode = class_exists('AKSRT_Settings')
|
||||
? AKSRT_Settings::get_post_pagination_mode()
|
||||
: 'numbered';
|
||||
|
||||
if ($pagination_mode === 'numbered') {
|
||||
global $wp_query;
|
||||
$q = $query ?? $wp_query;
|
||||
if (!($q instanceof WP_Query) || $q->max_num_pages <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current_page = max(1, (int) $q->get('paged'), (int) get_query_var('paged'), (int) get_query_var('page'));
|
||||
$max_pages = (int) $q->max_num_pages;
|
||||
$links = paginate_links([
|
||||
'total' => $max_pages,
|
||||
'current' => $current_page,
|
||||
'mid_size' => 2,
|
||||
'prev_text' => '<span aria-hidden="true">‹</span>',
|
||||
'next_text' => '<span aria-hidden="true">›</span>',
|
||||
'type' => 'plain',
|
||||
]);
|
||||
|
||||
if (empty($links)) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<div class="pagenav ajax-pag aksrt-pagination content-stream__footer-nav">';
|
||||
echo wp_kses_post($links);
|
||||
if ($max_pages > 8) {
|
||||
echo '<span class="pag-jump">';
|
||||
echo '<input type="number" class="jump-input" min="1" max="' . esc_attr((string) $max_pages) . '" value="' . esc_attr((string) $current_page) . '" data-max-pages="' . esc_attr((string) $max_pages) . '" />';
|
||||
echo '<button type="button" class="ajax-next order-ajax-next" data-jump-archive="1">' . esc_html__('跳转', 'aksrt') . '</button>';
|
||||
echo '</span>';
|
||||
}
|
||||
echo '</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// load_more / infinite 模式
|
||||
global $wp_query;
|
||||
$q = $query ?? $wp_query;
|
||||
$max_pages = $q->max_num_pages;
|
||||
$current_page = max(1, (int) $q->get('paged'), (int) get_query_var('paged'), (int) get_query_var('page'));
|
||||
|
||||
if ($current_page >= $max_pages) {
|
||||
return;
|
||||
}
|
||||
$query_context = '';
|
||||
if (!empty($args['query_context']) && is_string($args['query_context'])) {
|
||||
$query_context = sanitize_key($args['query_context']);
|
||||
} elseif (is_search()) {
|
||||
$query_context = 'search';
|
||||
} elseif (is_archive()) {
|
||||
$query_context = 'archive';
|
||||
}
|
||||
|
||||
$query_vars = $q instanceof WP_Query ? $q->query_vars : [];
|
||||
if (!is_array($query_vars)) {
|
||||
$query_vars = [];
|
||||
} else {
|
||||
unset($query_vars['paged'], $query_vars['page']);
|
||||
}
|
||||
|
||||
$render_config = !empty($args['render_config']) && is_array($args['render_config'])
|
||||
? $args['render_config']
|
||||
: [];
|
||||
|
||||
$trigger_text = (class_exists('AKSRT_Settings') && ($t = AKSRT_Settings::get_post_list_style_settings()['ajax_trigger_text'] ?? '') !== '') ? $t : __('加载更多', 'aksrt');
|
||||
?>
|
||||
<div class="text-center theme-pagination ajax-pag ajax-pagination aksrt-pagination-ajax content-stream__footer-nav"
|
||||
data-mode="<?php echo esc_attr($pagination_mode); ?>"
|
||||
data-next-page="<?php echo esc_attr((string) ($current_page + 1)); ?>"
|
||||
data-max-pages="<?php echo esc_attr((string) $max_pages); ?>"
|
||||
data-query-context="<?php echo esc_attr($query_context); ?>"
|
||||
data-query-vars="<?php echo esc_attr(wp_json_encode($query_vars)); ?>"
|
||||
data-render-config="<?php echo esc_attr(wp_json_encode($render_config)); ?>"
|
||||
data-lazyload-action="ias">
|
||||
<div class="next-page ajax-next aksrt-load-more-btn" lazyload-action="ias" role="button" tabindex="0">
|
||||
<?php echo esc_html($trigger_text); ?>
|
||||
</div>
|
||||
<div class="aksrt-loading-indicator" style="display:none;" aria-hidden="true">
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
<span><?php esc_html_e('加载中…', 'aksrt'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 分类推荐卡片模块:辅助函数
|
||||
// ============================================================
|
||||
|
||||
if (!function_exists('aksrt_get_category_total_views')) :
|
||||
/**
|
||||
* 获取分类下所有文章的总浏览量
|
||||
*
|
||||
* @param int $cat_id 分类 ID
|
||||
* @return int
|
||||
*/
|
||||
function aksrt_get_category_total_views(int $cat_id): int {
|
||||
global $wpdb;
|
||||
|
||||
$cache_key = 'aksrt_cat_views_' . $cat_id;
|
||||
$cached = wp_cache_get($cache_key, 'aksrt');
|
||||
if ($cached !== false) return (int) $cached;
|
||||
|
||||
$sql = $wpdb->prepare(
|
||||
"SELECT COALESCE(SUM(CAST(pm.meta_value AS UNSIGNED)), 0)
|
||||
FROM {$wpdb->postmeta} pm
|
||||
INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id
|
||||
INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id = p.ID
|
||||
INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
|
||||
WHERE tt.term_id = %d
|
||||
AND tt.taxonomy = 'category'
|
||||
AND p.post_status = 'publish'
|
||||
AND pm.meta_key IN ('aksrt_post_views', '_aksrt_res_view_count')",
|
||||
$cat_id
|
||||
);
|
||||
$result = (int) $wpdb->get_var($sql);
|
||||
|
||||
wp_cache_set($cache_key, $result, 'aksrt', 300);
|
||||
|
||||
return $result;
|
||||
return array_values(array_unique(array_filter((array) $types)));
|
||||
}
|
||||
endif;
|
||||
|
||||
|
||||
Reference in new issue
Block a user