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( 'aksrt-font-awesome', get_template_directory_uri() . '/assets/fontawesome5/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'); } }); // ============================================================ // 评论提交:单一合同 // ------------------------------------------------------------ // 主路径:前端 comments.js → REST /comment/submit(aksrt_require_captcha)。 // 兜底 / 原生 wp-comments-post.php 经 preprocess_comment 做人机验证,避免绕过。 // 列表仍由 aksrt_comment_callback 统一渲染。 // ============================================================ // ============================================================ // Gutenberg 自定义块注册 // ============================================================ // Register category server-side so it exists before JS registerBlockType runs. // Keep untyped + defensive: some plugins pass unexpected shapes; typed params can 500 the editor. add_filter('block_categories_all', static function ($categories, $context = null) { if (!is_array($categories)) { return $categories; } foreach ($categories as $category) { $slug = ''; if (is_array($category)) { $slug = (string) ($category['slug'] ?? ''); } elseif (is_object($category) && isset($category->slug)) { $slug = (string) $category->slug; } if ($slug === 'aksrt-blocks') { return $categories; } } $categories[] = [ 'slug' => 'aksrt-blocks', 'title' => 'AKSRT', 'icon' => null, ]; return $categories; }, 10, 2); 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-media-utils: MediaUpload for carousel block ['wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-hooks', 'wp-media-utils', 'wp-data'], (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 $posts = []; $queried = get_queried_object(); if ($queried instanceof \WP_Post) { $posts[$queried->ID] = $queried; } global $wp_query; if ($wp_query instanceof \WP_Query) { foreach ((array) $wp_query->posts as $post) { if ($post instanceof \WP_Post) { $posts[$post->ID] = $post; } } } $has_carousel = false; foreach ($posts as $post) { if (has_block('aksrt/carousel', $post)) { $has_carousel = true; break; } } if (!$has_carousel) return; $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 .= '
'; } 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。 */ add_filter('single_template', function (string $template): string { return $template; });