120, 'width' => 300, 'flex-height' => true, 'flex-width' => true, 'header-text' => true, ]); add_theme_support('customize-selective-refresh-widgets'); add_theme_support('align-wide'); add_theme_support('wp-block-styles'); add_theme_support('responsive-embeds'); // 文章格式 add_theme_support('post-formats', ['aside', 'image', 'video', 'quote', 'link', 'gallery']); // 图片尺寸 add_image_size('aksrt-cover', 1200, 675, true); add_image_size('aksrt-card', 400, 260, true); add_image_size('aksrt-thumb', 150, 150, true); // 内容宽度(用于区块编辑器) if (!isset($GLOBALS['content_width'])) { $GLOBALS['content_width'] = 900; } } public function register_nav_menus(): void { register_nav_menus([ 'primary' => __('主导航', 'aksrt'), 'mobile' => __('移动端菜单', 'aksrt'), 'footer' => __('页脚菜单', 'aksrt'), 'social' => __('社交链接', 'aksrt'), 'header_actions' => __('顶部右侧入口', 'aksrt'), ]); } /** * 注册自定义文章类型 * * 资源不是 CPT:元数据挂在普通 post 上, * 通过 _aksrt_is_resource meta 标记是否为资源。 */ public function register_post_types(): void { // 项目展示 register_post_type('project', [ 'labels' => [ 'name' => __('项目展示', 'aksrt'), 'singular_name' => __('项目', 'aksrt'), 'add_new' => __('新建项目', 'aksrt'), 'add_new_item' => __('新建项目', 'aksrt'), 'edit_item' => __('编辑项目', 'aksrt'), 'new_item' => __('新项目', 'aksrt'), 'view_item' => __('查看项目', 'aksrt'), 'search_items' => __('搜索项目', 'aksrt'), 'not_found' => __('未找到项目', 'aksrt'), 'not_found_in_trash' => __('回收站中无项目', 'aksrt'), 'menu_name' => __('项目展示', 'aksrt'), ], 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => false, 'show_in_nav_menus' => false, 'has_archive' => false, 'hierarchical' => false, 'menu_position' => 25, 'menu_icon' => 'dashicons-portfolio', 'supports' => ['title', 'editor', 'excerpt', 'thumbnail', 'author', 'revisions'], 'rewrite' => ['slug' => 'project'], 'capability_type' => 'post', 'map_meta_cap' => true, ]); } /** * 注册资源 post meta + 分类 term meta(aksrt_flow) * * 全部 show_in_rest,便于 Block Editor + Vue SPA 读写。 * * v3.4: 资源元数据全部挂在 post 上,配合 _aksrt_is_resource 开关使用。 */ public function register_meta_fields(): void { $post_edit_auth = static function () { return current_user_can('edit_posts'); }; // Core switch: mark a post as resource. register_post_meta('post', DomainModel::RESOURCE_MARKER_KEY, [ 'type' => 'boolean', 'description' => 'Whether this post is a resource post.', 'single' => true, 'default' => false, 'show_in_rest' => true, 'sanitize_callback' => static function ($v) { return (bool) $v; }, 'auth_callback' => $post_edit_auth, ]); register_post_meta('post', DomainModel::PAY_META_KEY, [ 'type' => 'object', 'description' => 'Canonical paid content payload.', 'single' => true, 'default' => DomainModel::default_pay_meta(), 'show_in_rest' => [ 'schema' => [ 'type' => 'object', 'properties' => [ 'pay_type' => [ 'type' => 'string', 'enum' => array_keys(DomainModel::pay_type_labels()), ], 'pay_modo' => ['type' => 'string', 'enum' => ['0', 'points']], 'price' => ['type' => 'number'], 'points_price' => ['type' => 'integer'], 'original_price' => ['type' => 'number'], 'vip1_price' => ['type' => 'number'], 'vip2_price' => ['type' => 'number'], 'vip1_points' => ['type' => 'integer'], 'vip2_points' => ['type' => 'integer'], 'pay_limit' => ['type' => 'integer', 'enum' => [0, 1, 2]], 'version' => ['type' => 'string'], 'size' => ['type' => 'string'], 'license' => ['type' => 'string'], 'compat' => ['type' => 'string'], 'demo_url' => ['type' => 'string', 'format' => 'uri'], 'video_url' => ['type' => 'string', 'format' => 'uri'], 'downloads' => [ 'type' => 'array', 'items' => [ 'type' => 'object', 'properties' => [ 'label' => ['type' => 'string'], 'url' => ['type' => 'string', 'format' => 'uri'], 'type' => ['type' => 'string'], 'extract_code' => ['type' => 'string'], ], ], ], 'attributes' => [ 'type' => 'array', 'items' => [ 'type' => 'object', 'properties' => [ 'key' => ['type' => 'string'], 'value' => ['type' => 'string'], ], ], ], 'gallery' => [ 'type' => 'array', 'items' => ['type' => 'string', 'format' => 'uri'], ], 'require_login' => ['type' => 'boolean'], 'require_captcha' => ['type' => 'boolean'], ], ], ], 'sanitize_callback' => [DomainModel::class, 'sanitize_pay_meta'], 'auth_callback' => $post_edit_auth, ]); register_post_meta('post', DomainModel::PAY_TYPE_KEY, [ 'type' => 'string', 'description' => 'Query-friendly paid content type.', 'single' => true, 'default' => DomainModel::PAY_TYPE_NO, 'show_in_rest' => true, 'sanitize_callback' => [DomainModel::class, 'normalize_pay_type'], 'auth_callback' => $post_edit_auth, ]); register_post_meta('post', DomainModel::PAY_PRICE_KEY, [ 'type' => 'number', 'description' => 'Query-friendly paid content price.', 'single' => true, 'default' => 0, 'show_in_rest' => true, 'sanitize_callback' => static function ($value) { return max(0, (float) $value); }, 'auth_callback' => $post_edit_auth, ]); foreach ([ DomainModel::RESOURCE_DOWNLOAD_COUNT_KEY => 'Resource download count', DomainModel::RESOURCE_VIEW_COUNT_KEY => 'Resource view count', DomainModel::POST_VIEW_COUNT_KEY => 'Generic post view count', ] as $meta_key => $description) { register_post_meta('post', $meta_key, [ 'type' => 'integer', 'description' => $description, 'single' => true, 'default' => 0, 'show_in_rest' => true, 'sanitize_callback' => 'absint', 'auth_callback' => $post_edit_auth, ]); } register_term_meta('category', 'aksrt_flow', [ 'type' => 'string', 'description' => 'Category flow mode: inherit/blog/cms', 'single' => true, 'default' => 'inherit', 'show_in_rest' => true, 'sanitize_callback' => function ($v) { $v = is_string($v) ? $v : 'inherit'; return in_array($v, ['inherit', 'blog', 'cms'], true) ? $v : 'inherit'; }, 'auth_callback' => function () { return current_user_can('manage_categories'); }, ]); } public static function sanitize_downloads_meta($value): array { return DomainModel::sanitize_downloads($value); } /** * 为 Customizer 小工具实时预览补齐编辑态包裹。 * * @param array $params Dynamic sidebar params. * @return array */ public function filter_sidebar_widget_params(array $params): array { if (!is_customize_preview() || empty($params[0]['before_widget']) || empty($params[0]['after_widget'])) { return $params; } $params[0]['before_widget'] = '
' . $params[0]['before_widget']; $params[0]['after_widget'] = $params[0]['after_widget'] . '
'; return $params; } /** * 注册侧边栏 */ }