and $enlighter_attrs = [ 'data-enlighter-language' => true, 'data-enlighter-theme' => true, 'data-enlighter-group' => true, 'data-enlighter-title' => true, 'data-enlighter-linenumbers' => true, 'data-enlighter-highlight' => true, 'data-enlighter-lineoffset' => true, ]; if (isset($allowed['pre'])) { $allowed['pre'] = array_merge($allowed['pre'], $enlighter_attrs); } if (isset($allowed['code'])) { $allowed['code'] = array_merge($allowed['code'], $enlighter_attrs); } return $allowed; }, 10, 2); // ============================================================ // WP 后台文章列表增强列 — 浏览/点赞/收藏/下载 // ============================================================ add_filter('manage_post_posts_columns', function ($columns) { $new_columns = []; foreach ($columns as $key => $label) { $new_columns[$key] = $label; if ($key === 'title') { $new_columns['aksrt_stats'] = __('互动数据', 'aksrt'); } } return $new_columns; }); add_action('admin_enqueue_scripts', function ($hook) { if ($hook !== 'edit.php') return; wp_enqueue_style('font-awesome-5', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css', [], '5.15.4'); }); add_action('manage_post_posts_custom_column', function ($column, $post_id) { if ($column !== 'aksrt_stats') return; $views = (int) get_post_meta($post_id, 'views', true); $likes = (int) get_post_meta($post_id, 'like', true); $favorites = (int) get_post_meta($post_id, 'favorite', true); $downloads = (int) get_post_meta($post_id, 'download_count', true); $format = function (int $n): string { if ($n >= 10000) return round($n / 10000, 1) . '万'; if ($n >= 1000) return round($n / 1000, 1) . 'k'; return (string) $n; }; $parts = []; $parts[] = ' ' . esc_html($format($views)) . ''; $parts[] = ' ' . esc_html($format($likes)) . ''; $parts[] = ' ' . esc_html($format($favorites)) . ''; if ($downloads > 0) { $parts[] = ' ' . esc_html($format($downloads)) . ''; } echo implode(' · ', $parts); }, 10, 2); // Support sorting by views/likes/favorites in admin add_action('pre_get_posts', function ($query) { if (!is_admin() || !$query->is_main_query()) return; $orderby = $query->get('orderby'); $allowed = ['views', 'like', 'favorite', 'download_count']; if (in_array($orderby, $allowed, true)) { $query->set('meta_key', $orderby); $query->set('orderby', 'meta_value_num'); } }); // ============================================================ // 评论提交:单一合同 // ------------------------------------------------------------ // 评论提交统一走 WordPress 原生 wp-comments-post.php,由前端 // main.js initCommentSystem() 以 AJAX 拦截:它负责人机验证、频率 // 限制、审核管线,并在成功后通过 reloadCommentList() 重新拉取, // 列表仍由 aksrt_comment_callback 这一规范渲染器输出。 // 不再保留并行的 aksrt_submit_comment 动作(避免绕过验证码的第二套提交合同)。 // 详见 comment-contract.md。 // ============================================================ // ============================================================ // Gutenberg 自定义块注册 // ============================================================ add_action('enqueue_block_editor_assets', function () { $base_uri = get_template_directory_uri(); $version = wp_get_theme()->get('Version'); $blocks_js = get_template_directory() . '/assets/js/gutenberg-blocks.js'; if (file_exists($blocks_js)) { wp_enqueue_script( 'aksrt-gutenberg-blocks', $base_uri . '/assets/js/gutenberg-blocks.js', ['wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-hooks'], (string) filemtime($blocks_js), true ); } $blocks_css = get_template_directory() . '/assets/css/gutenberg-blocks.css'; if (file_exists($blocks_css)) { wp_enqueue_style( 'aksrt-gutenberg-blocks', $base_uri . '/assets/css/gutenberg-blocks.css', [], (string) filemtime($blocks_css) ); } }); // Front-end styles for Gutenberg blocks add_action('enqueue_block_assets', function () { if (is_admin()) return; // Already loaded in editor $base_uri = get_template_directory_uri(); $blocks_css = get_template_directory() . '/assets/css/gutenberg-blocks.css'; if (file_exists($blocks_css)) { wp_enqueue_style( 'aksrt-gutenberg-blocks-front', $base_uri . '/assets/css/gutenberg-blocks.css', [], (string) filemtime($blocks_css) ); } }); // ============================================================ // Gutenberg Carousel Block 渲染回调 // ============================================================ add_action('init', function () { if (!function_exists('register_block_type')) return; register_block_type('aksrt/carousel', [ 'render_callback' => function (array $attributes): string { $images = $attributes['images'] ?? []; if (empty($images)) return ''; $autoplay = !empty($attributes['autoplay']) ? 'true' : 'false'; $delay = absint($attributes['delay'] ?? 3000); $effect = sanitize_text_field($attributes['effect'] ?? 'slide'); $slides = ''; foreach ($images as $img) { if (empty($img['url'])) continue; $alt = esc_attr($img['alt'] ?? ''); $url = esc_url($img['url']); $slides .= '
' . $alt . '
'; } if (empty($slides)) return ''; return ''; }, ]); }); // ============================================================ // 付费内容系统:the_content 过滤器 // ============================================================ /** * 未付费内容:替换为付费墙。 */ add_filter('the_content', 'aksrt_paid_content_filter', 20); /** * 已付费内容增强:追加图库轮播/视频播放器。 */ add_filter('the_content', 'aksrt_paid_content_enhance', 25); /** * 付费文章使用统一的 single.php(不再路由到 single-aksrt_resource.php)。 */ add_filter('single_template', function (string $template): string { return $template; });