diff --git a/docs/admin-ia-map.md b/docs/admin-ia-map.md new file mode 100644 index 00000000..ec40ee42 --- /dev/null +++ b/docs/admin-ia-map.md @@ -0,0 +1,150 @@ +# Admin IA Map — zibll-aligned native ops + SPA config + +> Living blueprint for AKSRT admin information architecture after the zibll 1:1 ops-menu migration. +> Source of truth for *where* a surface lives; field-level schema remains in Vue schema / PHP schema provider. + +## Split rule (locked) + +| Layer | Surface | Purpose | +|-------|---------|---------| +| **WP native sidebar** | CPT menus, `aksrt_pay` top menu, `users.php` submenus | Day-to-day **operations** (content CRUD, orders, tickets) | +| **AKSRT SPA** (`admin.php?page=aksrt-settings#/...`) | Schema-driven pages only | **Configuration** (switches, layout, gateways, policies) | + +Do **not** reintroduce operational workbenches into the SPA once native pages ship. + +--- + +## Native sidebar tree (target) + +``` +[pos ~34 separator] +商城 (aksrt_product) pos 35, dashicons-store +├─ 所有商品 / 新增商品 +├─ 商品分类 (aksrt_product_cat) +├─ 特色标签 (aksrt_product_tag) +└─ 优惠活动 (shop_discount) + +支付中心 (aksrt_pay) pos ~36–38, dashicons-cart +├─ 概览 aksrt_pay +├─ 订单 aksrt_orders +├─ 发货及物流 aksrt_shipping +├─ 售后管理 aksrt_after_sale +├─ 优惠码 aksrt_coupons +├─ 卡密管理 aksrt_charge_cards +├─ 创作分成 aksrt_income +├─ 推广返佣 aksrt_rebate +└─ 提现审核 aksrt_withdraw + +[pos ~39 separator] +论坛版块 (aksrt_forum_plate) pos 40, dashicons-buddicons-forums +├─ 所有版块 / 添加版块 +└─ 分区 (aksrt_plate_cat) + +论坛帖子 (aksrt_forum_topic) pos 40, dashicons-buddicons-topics +├─ 所有帖子 / 添加帖子 +├─ 话题 (aksrt_forum_topic_cat) +└─ 标签 (aksrt_forum_tag) + +用户 (WP core users.php) +├─ 消息管理 users.php?page=aksrt_messages +├─ 邀请码管理 users.php?page=aksrt_invite_codes +├─ 身份认证 users.php?page=aksrt_user_auth +└─ 举报&禁封 users.php?page=aksrt_user_ban + +AKSRT (SPA shell) pos 58, dashicons-admin-generic +└─ hash routes: config-only sections +``` + +### Feature gates + +| Surface | Settings key | Notes | +|---------|--------------|-------| +| 商城 CPT/tax | `shop_s` → `AKSRT_Settings::get_shop_settings()['enabled']` | Hide menu when shop off | +| 论坛 CPT/tax | `bbs_s` → `get_forum_settings()['enabled']` | Front skips registration when off; admin still registers but may hide menu | +| 支付中心子项 | payment/shop/rebate switches | Per-submenu | +| 用户子菜单 | message / invite / verify / ban flags | Align SPA users schema | + +Capability baseline: `manage_options` (later may tighten toward super-admin like zibll). + +--- + +## SPA config tree (retained) + +### 支付&付费 `/payment` + +| Route | Type | Notes | +|-------|------|-------| +| `/payment/paid` | custom/schema | Download / paid-content **policy** | +| `/payment/recharge` | schema | Balance recharge | +| `/payment/vip` | schema | VIP plans | +| `/payment/gateway` | custom | Gateway credentials | +| `/payment/order` | schema | Order display settings (not order list) | +| `/payment/affiliate` | schema | Rebate **rules** | +| `/payment/card-pass` | schema | Card rules/copy | +| `/payment/withdrawal` | schema | Withdraw **policy** (tickets → native) | + +**Removed from SPA (ops):** charge-card workbench, revenue table, rebate table. + +### 商城&商品 `/shop` + +| Route | Type | +|-------|------| +| `/shop/basic` | schema | +| `/shop/list` | schema | +| `/shop/single` | schema | +| `/shop/product-defaults` | schema | +| `/shop/contact` | schema | +| `/shop/shipping-config` | schema | +| `/shop/timing` | schema | + +**Removed from SPA (ops):** products, orders, after-sale, shipping, coupons, withdrawals, dashboard. + +Default SPA entry after strip: `/shop/basic`. + +### 社区&论坛 `/forum` + +| Route | Type | +|-------|------| +| `/forum/settings` | schema basic | +| `/forum/settings/names` | schema | +| `/forum/settings/homepage` | schema | +| `/forum/settings/board-page` | schema | +| `/forum/settings/post-page` | schema | +| `/forum/settings/reply` | schema | +| `/forum/settings/permissions` | schema | +| `/forum/settings/other` | schema | +| `/forum/settings/upload` | schema | +| `/forum/settings/credits` | schema | + +**Removed from SPA (ops):** boards, topics, moderators, moderator-applications, dashboard. + +Default SPA entry after strip: `/forum/settings`. + +### 用户&互动 `/users` (config kept) + +auth, oauth, features, signin, credits, verify **settings**, level, badge, notifications, sms, wechat, wechat-template. + +**Removed from SPA (ops):** messages, invite-codes, ban, report queues. + +--- + +## Canonical domain keys + +Internal keys remain: `global`, `page_display`, `post_list`, `permissions`, `users`, `payment`, `shop`, `forum`, `extensions`, `tools`. + +Route paths may stay friendly (`/page-display/...`); ops native pages use `admin.php?page=aksrt_*` slugs above. + +--- + +## Rollout phases + +| Phase | Deliverable | +|-------|-------------| +| 0 | This map + gap matrix | +| 1 | CPT/tax native menus | +| 2 | `aksrt_pay` PHP list pages | +| 3 | `users.php` governance submenus | +| 4 | Strip SPA ops routes/components | +| 5+ | Runtime behavior parity backlog | + +See also: [zibll-gap-matrix.md](./zibll-gap-matrix.md). diff --git a/docs/zibll-gap-matrix.md b/docs/zibll-gap-matrix.md new file mode 100644 index 00000000..a80d52a7 --- /dev/null +++ b/docs/zibll-gap-matrix.md @@ -0,0 +1,105 @@ +# zibll ↔ AKSRT gap matrix (admin ops entry) + +Three-way mapping: **zibll current → AKSRT before migration → AKSRT target**. + +Focus: admin **entry & page shape**. Runtime field parity is Phase 5+. + +--- + +## Shop + +| zibll | AKSRT before | AKSRT target | Data / service | +|-------|--------------|--------------|----------------| +| CPT `shop_product` pos 35, `dashicons-store`, super-admin `show_ui` | `aksrt_product` `show_ui=true`, **`show_in_menu=false`** | Native menu pos 35, store icon; gate on `shop_s` | CPT | +| Tax `shop_cat` | `aksrt_product_cat` show_ui false | show_ui + admin column under product | taxonomy | +| Tax `shop_tag` | `aksrt_product_tag` show_ui false | show_ui under product | taxonomy | +| Tax `shop_discount` | `shop_discount` show_ui false | show_ui under product | `AKSRT_Shop_Term_Meta` | +| Product list columns | Trait exists, wired in `functions.php` | Keep/enhance on native list | admin columns trait | +| Product edit meta | SPA `ShopProducts` + REST | Native meta box (Phase 1b) | product ops / post meta | +| Orders | SPA `ShopOrders` | `admin.php?page=aksrt_orders` | `AKSRT_Order` | +| Shipping | SPA `ShopShipping` | `aksrt_shipping` | `AKSRT_Shipping` | +| After-sale | SPA `ShopAfterSale` | `aksrt_after_sale` | `AKSRT_After_Sale` | +| Coupons | SPA `ShopCoupons` / zibpay coupon page | `aksrt_coupons` | `AKSRT_Coupon` | +| Shop CSF config | SPA shop schema | **Keep SPA schema** | `AKSRT_Settings::get_shop_settings()` | + +--- + +## Forum / community + +| zibll | AKSRT before | AKSRT target | Data / service | +|-------|--------------|--------------|----------------| +| CPT `plate` pos 40, forums icon | `aksrt_forum_plate` **show_in_menu false** | show_in_menu true, pos 40, `dashicons-buddicons-forums` | CPT | +| Tax `plate_cat` | `aksrt_plate_cat` | show_ui under plate | taxonomy | +| CPT `forum_post` pos 40, topics icon | `aksrt_forum_topic` default menu, comments icon | pos 40, `dashicons-buddicons-topics`, explicit menu | CPT | +| Tax `forum_topic` / `forum_tag` | `aksrt_forum_topic_cat` / `aksrt_forum_tag` | show_ui under topic | taxonomy | +| Legacy board tax | — | `aksrt_forum_board` keep rewrite bridge, **hide admin UI** (plate is canonical) | taxonomy | +| Boards/topics SPA | `ForumBoards` / `ForumTopics` | Native CPT lists | `AKSRT_Forum` | +| Moderators / applications | SPA | Plate meta box + optional subpage | moderation service | +| BBS CSF config | SPA forum schema | **Keep SPA schema** | `get_forum_settings()` | + +--- + +## Payment / zibpay ops + +| zibll page | Purpose | AKSRT before | Target slug | Service | +|------------|---------|--------------|-------------|---------| +| `zibpay_page` | Dashboard | SPA dashboards | `aksrt_pay` | aggregates | +| `zibpay_page#/order` | Orders (new) | SPA ShopOrders | `aksrt_orders` | `AKSRT_Order` | +| `zibpay_order_page` | Orders (legacy) | SPA | same native list | | +| `zibpay_page#/shipping` | Shipping | SPA | `aksrt_shipping` | `AKSRT_Shipping` | +| `zibpay_page#/after-sale` | After-sale | SPA | `aksrt_after_sale` | `AKSRT_After_Sale` | +| `zibpay_product_page` | Paid-post sales report | partial | optional later `aksrt_pay_products` | content pay | +| `zibpay_income_page` | Creator income | `PaymentRevenue` | `aksrt_income` | `AKSRT_Revenue` | +| `zibpay_rebate_page` | Rebate | `PaymentRebate` | `aksrt_rebate` | `AKSRT_Rebate` | +| `zibpay_withdraw` | Withdraw | `ShopWithdrawals` | `aksrt_withdraw` | `AKSRT_Withdrawal` | +| `zibpay_charge_card_page` | Charge cards | `PaymentChargeCard` | `aksrt_charge_cards` | `AKSRT_Charge_Card` | +| `zibpay_coupon_page` | Coupons | `ShopCoupons` | `aksrt_coupons` | `AKSRT_Coupon` | +| CSF pay sections | Gateways/VIP/… | SPA payment schema | **Keep SPA** | settings | + +Note: zibll「商品管理」`zibpay_product_page` is **paid article sales**, not the physical `shop_product` CPT list. + +--- + +## User governance + +| zibll | slug | AKSRT before | Target | +|-------|------|--------------|--------| +| 消息管理 | `user_messags` under users.php | SPA `UsersMessages` | `users.php?page=aksrt_messages` | +| 邀请码管理 | `invit_code` | SPA `UsersInviteCodes` | `aksrt_invite_codes` | +| 身份认证 | `user_auth` | SPA `UsersVerify` queue | `aksrt_user_auth` | +| 举报&禁封申诉 | `user_ban` | SPA Ban + Report | single `aksrt_user_ban` with tabs | +| Credits column | users list | `AKSRT_User_Credits_Admin` | keep | +| CSF user config | — | SPA users schema | keep | + +--- + +## SPA ops routes to delete (Phase 4) + +### shop.js +`shop-products`, `shop-orders`, `shop-after-sale`, `shop-shipping`, `shop-coupons`, `shop-withdrawals`, `shop-dashboard` + +### forum.js +`forum-boards`, `forum-topics`, `forum-moderators`, `forum-moderator-applications`, `forum-dashboard` + +### payment.js +`payment-charge-card`, `payment-revenue`, `payment-rebate` (ops tables) + +### users.js +`users-messages`, `users-invite-codes`, `users-ban`, `users-report` (queues) + +--- + +## Phase status + +| Phase | Status | +|-------|--------| +| 0 Docs + matrix | in progress | +| 1 Native CPT/tax menus | in progress | +| 2 Pay list tables | pending | +| 3 users.php submenus | pending | +| 4 SPA strip | pending (after 1–3) | +| 5+ behavior parity | backlog | + +## Dual-UI rule + +Native write path must work **before** removing the matching SPA ops route. No data migration: same tables/meta; UI only. diff --git a/inc/classes/class-aksrt-setup.php b/inc/classes/class-aksrt-setup.php index d56cf07d..86ba18a1 100644 --- a/inc/classes/class-aksrt-setup.php +++ b/inc/classes/class-aksrt-setup.php @@ -121,10 +121,20 @@ class AKSRT_Setup { $product_slug = sanitize_key((string) ($shop_rewrite['product_slug'] ?? 'product')); $suffix_html = !empty($shop_rewrite['suffix_html']); - // 商品 CPT + // Shop admin visibility: align with zibll native sidebar when shop is enabled. + $shop_enabled = true; + if (class_exists('AKSRT_Settings')) { + $shop_settings = AKSRT_Settings::get_shop_settings(); + $shop_enabled = !empty($shop_settings['enabled']); + } + // Always register UI in admin so settings/tools remain reachable; hide menu when disabled. + $shop_show_ui = true; + $shop_show_menu = is_admin() ? $shop_enabled : false; + + // 商品 CPT — native WP sidebar (zibll: shop_product @ pos 35) register_post_type('aksrt_product', [ 'labels' => [ - 'name' => __('商品', 'aksrt'), + 'name' => __('商城', 'aksrt'), 'singular_name' => __('商品', 'aksrt'), 'add_new' => __('新增商品', 'aksrt'), 'add_new_item' => __('新增商品', 'aksrt'), @@ -134,15 +144,18 @@ class AKSRT_Setup { 'search_items' => __('搜索商品', 'aksrt'), 'not_found' => __('未找到商品', 'aksrt'), 'not_found_in_trash' => __('回收站中无商品', 'aksrt'), - 'menu_name' => __('商品', 'aksrt'), + 'all_items' => __('所有商品', 'aksrt'), + 'menu_name' => __('商城', 'aksrt'), ], 'public' => true, 'publicly_queryable' => true, - 'show_ui' => true, - 'show_in_menu' => false, + 'show_ui' => $shop_show_ui, + 'show_in_menu' => $shop_show_menu, 'show_in_rest' => true, 'has_archive' => true, 'hierarchical' => false, + 'menu_position' => 35, + 'menu_icon' => 'dashicons-store', 'supports' => ['title', 'editor', 'excerpt', 'thumbnail', 'author', 'revisions'], 'rewrite' => ['slug' => $product_slug, 'with_front' => false], 'capability_type' => 'post', @@ -163,9 +176,10 @@ class AKSRT_Setup { ], 'public' => true, 'hierarchical' => true, - 'show_ui' => false, + 'show_ui' => $shop_show_ui, + 'show_in_menu' => $shop_show_menu, 'show_in_rest' => true, - 'show_admin_column' => false, + 'show_admin_column' => true, 'rewrite' => ['slug' => 'product-cat', 'with_front' => false], ]); @@ -178,15 +192,15 @@ class AKSRT_Setup { 'all_items' => __('所有商品标签', 'aksrt'), 'edit_item' => __('编辑标签', 'aksrt'), 'add_new_item' => __('新增标签', 'aksrt'), - 'menu_name' => __('商品标签', 'aksrt'), + 'menu_name' => __('特色标签', 'aksrt'), ], 'public' => true, 'hierarchical' => false, - 'show_ui' => false, + 'show_ui' => $shop_show_ui, + 'show_in_menu' => $shop_show_menu, 'show_in_rest' => true, - 'show_admin_column' => false, - 'rewrite' => ['slug' => 'product-tag', 'with_front' => false, - ], + 'show_admin_column' => true, + 'rewrite' => ['slug' => 'product-tag', 'with_front' => false], ]); // 项目展示 diff --git a/inc/classes/class-aksrt-shop-term-meta.php b/inc/classes/class-aksrt-shop-term-meta.php index f14b028e..9db2a11d 100644 --- a/inc/classes/class-aksrt-shop-term-meta.php +++ b/inc/classes/class-aksrt-shop-term-meta.php @@ -45,6 +45,14 @@ class AKSRT_Shop_Term_Meta { return; } + $shop_enabled = true; + if (class_exists('AKSRT_Settings')) { + $shop_settings = AKSRT_Settings::get_shop_settings(); + $shop_enabled = !empty($shop_settings['enabled']); + } + $shop_show_ui = true; + $shop_show_menu = is_admin() ? $shop_enabled : false; + register_taxonomy('shop_discount', 'aksrt_product', [ 'labels' => [ 'name' => __('优惠活动', 'aksrt'), @@ -57,9 +65,10 @@ class AKSRT_Shop_Term_Meta { ], 'public' => true, 'hierarchical' => false, - 'show_ui' => false, + 'show_ui' => $shop_show_ui, + 'show_in_menu' => $shop_show_menu, 'show_in_rest' => true, - 'show_admin_column' => false, + 'show_admin_column' => true, 'rewrite' => ['slug' => 'shop-discount', 'with_front' => false], ]); } diff --git a/inc/classes/setup-traits/trait-aksrt-setup-part-2.php b/inc/classes/setup-traits/trait-aksrt-setup-part-2.php index e069eaf5..326f2af6 100644 --- a/inc/classes/setup-traits/trait-aksrt-setup-part-2.php +++ b/inc/classes/setup-traits/trait-aksrt-setup-part-2.php @@ -5,7 +5,7 @@ trait AKSRT_Setup_Part_2 { /** - * 隐藏默认WordPress菜单项目 + * 隐藏默认WordPress菜单项目 + zibll 风格运营菜单分隔线 */ public function hide_default_menus(): void { // 移除评论默认菜单(已移除该操作以恢复 Comments 菜单) @@ -13,10 +13,22 @@ trait AKSRT_Setup_Part_2 { // 移除链接管理(已废弃但仍可能存在) //remove_menu_page('link-manager.php'); - + // 移除仪表盘中的不必要组件 remove_meta_box('dashboard_primary', 'dashboard', 'normal'); remove_meta_box('dashboard_quick_press', 'dashboard', 'side'); + + // Separators around shop (35) and forum (40) — match zibll admin_menu_separator. + global $menu; + if (!is_array($menu)) { + return; + } + if (!isset($menu[34])) { + $menu[34] = ['', 'read', 'separator-aksrt-shop', '', 'wp-menu-separator']; + } + if (!isset($menu[39])) { + $menu[39] = ['', 'read', 'separator-aksrt-forum', '', 'wp-menu-separator']; + } } /** diff --git a/inc/core-hooks/part-1.php b/inc/core-hooks/part-1.php index 2148b43d..7e0d9eed 100644 --- a/inc/core-hooks/part-1.php +++ b/inc/core-hooks/part-1.php @@ -92,16 +92,25 @@ function aksrt_register_forum_cpt() { } } - // Read custom slugs from settings when available - $plate_slug = 'board'; - $topic_slug = 'topic'; + // Read custom slugs / names from settings when available + $plate_slug = 'board'; + $topic_slug = 'topic'; + $forum_enabled = true; + $forum_settings = []; if (class_exists('AKSRT_Settings')) { - $forum = AKSRT_Settings::get_forum_settings(); - $plate_slug = !empty($forum['other']['plate_slug']) ? $forum['other']['plate_slug'] : 'board'; - $topic_slug = !empty($forum['other']['posts_slug']) ? $forum['other']['posts_slug'] : 'topic'; + $forum_settings = AKSRT_Settings::get_forum_settings(); + $plate_slug = !empty($forum_settings['other']['plate_slug']) ? $forum_settings['other']['plate_slug'] : 'board'; + $topic_slug = !empty($forum_settings['other']['posts_slug']) ? $forum_settings['other']['posts_slug'] : 'topic'; + $forum_enabled = !empty($forum_settings['enabled']); } - - // Forum Board taxonomy + // Admin always registers types; menu follows bbs_s (zibll: show when forum on). + $forum_show_menu = is_admin() ? $forum_enabled : false; + $names = !empty($forum_settings['names']) ? $forum_settings['names'] : []; + $forum_label = sanitize_text_field((string) ($names['forum'] ?? __('论坛', 'aksrt'))); + $posts_label = sanitize_text_field((string) ($names['posts'] ?? __('帖子', 'aksrt'))); + $topic_label = sanitize_text_field((string) ($names['topic'] ?? __('话题', 'aksrt'))); + $tag_label = sanitize_text_field((string) ($names['tag'] ?? __('标签', 'aksrt'))); + // Legacy board taxonomy: keep rewrite/bridge, hide from admin (plate CPT is canonical). register_taxonomy('aksrt_forum_board', 'aksrt_forum_topic', [ 'labels' => [ 'name' => __('论坛版块', 'aksrt'), @@ -113,58 +122,72 @@ function aksrt_register_forum_cpt() { ], 'hierarchical' => true, 'public' => true, + 'show_ui' => false, + 'show_in_menu' => false, 'show_in_rest' => true, - 'show_admin_column' => true, + 'show_admin_column' => false, 'rewrite' => ['slug' => $plate_slug], ]); // Forum Tag taxonomy register_taxonomy('aksrt_forum_tag', 'aksrt_forum_topic', [ 'labels' => [ - 'name' => __('论坛标签', 'aksrt'), - 'singular_name' => __('标签', 'aksrt'), - 'search_items' => __('搜索标签', 'aksrt'), - 'all_items' => __('所有标签', 'aksrt'), - 'edit_item' => __('编辑标签', 'aksrt'), - 'add_new_item' => __('添加标签', 'aksrt'), + 'name' => sprintf(/* translators: %s: forum name */ __('%s标签', 'aksrt'), $forum_label), + 'singular_name' => $tag_label, + 'search_items' => sprintf(/* translators: %s: tag name */ __('搜索%s', 'aksrt'), $tag_label), + 'all_items' => sprintf(/* translators: %s: tag name */ __('所有%s', 'aksrt'), $tag_label), + 'edit_item' => sprintf(/* translators: %s: tag name */ __('编辑%s', 'aksrt'), $tag_label), + 'add_new_item' => sprintf(/* translators: %s: tag name */ __('添加%s', 'aksrt'), $tag_label), + 'menu_name' => $tag_label, ], 'hierarchical' => false, 'public' => true, + 'show_ui' => true, + 'show_in_menu' => $forum_show_menu, 'show_in_rest' => true, - 'show_admin_column' => false, + 'show_admin_column' => true, 'rewrite' => ['slug' => 'forum-tag'], ]); // Forum Topic taxonomy (话题,单选,区别于标签) register_taxonomy('aksrt_forum_topic_cat', 'aksrt_forum_topic', [ 'labels' => [ - 'name' => __('论坛话题', 'aksrt'), - 'singular_name' => __('话题', 'aksrt'), - 'search_items' => __('搜索话题', 'aksrt'), - 'all_items' => __('所有话题', 'aksrt'), - 'edit_item' => __('编辑话题', 'aksrt'), - 'add_new_item' => __('添加话题', 'aksrt'), + 'name' => sprintf(/* translators: %s: forum name */ __('%s话题', 'aksrt'), $forum_label), + 'singular_name' => $topic_label, + 'search_items' => sprintf(/* translators: %s: topic name */ __('搜索%s', 'aksrt'), $topic_label), + 'all_items' => sprintf(/* translators: %s: topic name */ __('所有%s', 'aksrt'), $topic_label), + 'edit_item' => sprintf(/* translators: %s: topic name */ __('编辑%s', 'aksrt'), $topic_label), + 'add_new_item' => sprintf(/* translators: %s: topic name */ __('添加%s', 'aksrt'), $topic_label), + 'menu_name' => $topic_label, ], 'hierarchical' => false, 'public' => true, + 'show_ui' => true, + 'show_in_menu' => $forum_show_menu, 'show_in_rest' => true, 'show_admin_column' => true, 'rewrite' => ['slug' => 'forum-topic'], ]); - // Forum Topic CPT + // Forum Topic CPT — native sidebar (zibll: forum_post @ pos 40) register_post_type('aksrt_forum_topic', [ 'labels' => [ - 'name' => __('论坛主题', 'aksrt'), - 'singular_name' => __('主题', 'aksrt'), - 'add_new_item' => __('发布新主题', 'aksrt'), - 'edit_item' => __('编辑主题', 'aksrt'), - 'view_item' => __('查看主题', 'aksrt'), + 'name' => $forum_label . $posts_label, + 'singular_name' => $posts_label, + 'add_new' => sprintf(/* translators: %s: posts name */ __('添加%s', 'aksrt'), $posts_label), + 'add_new_item' => sprintf(/* translators: %s: posts name */ __('发布新%s', 'aksrt'), $posts_label), + 'edit_item' => sprintf(/* translators: %s: posts name */ __('编辑%s', 'aksrt'), $posts_label), + 'view_item' => sprintf(/* translators: %s: posts name */ __('查看%s', 'aksrt'), $posts_label), + 'all_items' => sprintf(/* translators: %s: posts name */ __('所有%s', 'aksrt'), $posts_label), + 'menu_name' => $forum_label . $posts_label, ], 'public' => true, + 'show_ui' => true, + 'show_in_menu' => $forum_show_menu, 'show_in_rest' => true, 'has_archive' => true, - 'menu_icon' => 'dashicons-comments', + 'menu_position' => 40, + 'menu_icon' => 'dashicons-buddicons-topics', 'supports' => ['title', 'editor', 'author', 'comments', 'thumbnail', 'excerpt'], 'capability_type' => 'post', 'rewrite' => ['slug' => $topic_slug], @@ -186,50 +209,65 @@ function aksrt_register_forum_plate_cpt() { } } - $plate_slug = 'board'; + $plate_slug = 'board'; + $forum_enabled = true; + $forum = []; if (class_exists('AKSRT_Settings')) { - $forum = AKSRT_Settings::get_forum_settings(); - $plate_slug = !empty($forum['other']['plate_slug']) ? $forum['other']['plate_slug'] : 'board'; + $forum = AKSRT_Settings::get_forum_settings(); + $plate_slug = !empty($forum['other']['plate_slug']) ? $forum['other']['plate_slug'] : 'board'; + $forum_enabled = !empty($forum['enabled']); } + $forum_show_menu = is_admin() ? $forum_enabled : false; + $names = !empty($forum['names']) ? $forum['names'] : []; + $forum_label = sanitize_text_field((string) ($names['forum'] ?? __('论坛', 'aksrt'))); + $plate_label = sanitize_text_field((string) ($names['plate'] ?? __('版块', 'aksrt'))); // Plate category taxonomy (分区) register_taxonomy('aksrt_plate_cat', 'aksrt_forum_plate', [ 'labels' => [ - 'name' => __('板块分区', 'aksrt'), + 'name' => sprintf(/* translators: %s: plate name */ __('%s分区', 'aksrt'), $plate_label), 'singular_name' => __('分区', 'aksrt'), 'search_items' => __('搜索分区', 'aksrt'), 'all_items' => __('所有分区', 'aksrt'), 'edit_item' => __('编辑分区', 'aksrt'), 'add_new_item' => __('添加分区', 'aksrt'), + 'menu_name' => __('分区', 'aksrt'), ], 'hierarchical' => true, 'public' => true, + 'show_ui' => true, + 'show_in_menu' => $forum_show_menu, 'show_in_rest' => true, 'show_admin_column' => true, 'rewrite' => ['slug' => 'plate-cat'], ]); - // Plate CPT (板块) + // Plate CPT (板块) — native sidebar (zibll: plate @ pos 40) register_post_type('aksrt_forum_plate', [ 'labels' => [ - 'name' => __('论坛版块', 'aksrt'), - 'singular_name' => __('版块', 'aksrt'), - 'add_new_item' => __('创建版块', 'aksrt'), - 'edit_item' => __('编辑版块', 'aksrt'), - 'view_item' => __('查看版块', 'aksrt'), - 'search_items' => __('搜索版块', 'aksrt'), - 'not_found' => __('未找到版块', 'aksrt'), - 'not_found_in_trash' => __('回收站中未找到版块', 'aksrt'), + 'name' => $forum_label . $plate_label, + 'singular_name' => $plate_label, + 'add_new' => sprintf(/* translators: %s: plate name */ __('添加%s', 'aksrt'), $plate_label), + 'add_new_item' => sprintf(/* translators: %s: plate name */ __('创建%s', 'aksrt'), $plate_label), + 'edit_item' => sprintf(/* translators: %s: plate name */ __('编辑%s', 'aksrt'), $plate_label), + 'view_item' => sprintf(/* translators: %s: plate name */ __('查看%s', 'aksrt'), $plate_label), + 'search_items' => sprintf(/* translators: %s: plate name */ __('搜索%s', 'aksrt'), $plate_label), + 'not_found' => sprintf(/* translators: %s: plate name */ __('未找到%s', 'aksrt'), $plate_label), + 'not_found_in_trash' => sprintf(/* translators: %s: plate name */ __('回收站中未找到%s', 'aksrt'), $plate_label), + 'all_items' => sprintf(/* translators: %s: plate name */ __('所有%s', 'aksrt'), $plate_label), + 'menu_name' => $forum_label . $plate_label, ], 'public' => true, 'hierarchical' => true, + 'show_ui' => true, + 'show_in_menu' => $forum_show_menu, 'show_in_rest' => true, 'has_archive' => false, - 'menu_icon' => 'dashicons-grid-view', + 'menu_position' => 40, + 'menu_icon' => 'dashicons-buddicons-forums', 'supports' => ['title', 'editor', 'author', 'excerpt', 'thumbnail', 'page-attributes'], 'capability_type' => 'post', 'rewrite' => ['slug' => $plate_slug, 'with_front' => false], - 'show_in_menu' => false, ]); // Keep aksrt_forum_topic assignable to plates via taxonomy bridge