diff --git a/assets/admin/src/constants/sections/page-display.js b/assets/admin/src/constants/sections/page-display.js
index 3a752a7e..273f9a48 100644
--- a/assets/admin/src/constants/sections/page-display.js
+++ b/assets/admin/src/constants/sections/page-display.js
@@ -60,6 +60,15 @@ export const pageDisplaySection = {
canonicalDomain: 'page_display',
section: 'tag',
}),
+ schemaPage({
+ key: 'page-display-topics',
+ name: 'PageDisplayTopics',
+ label: '专题页面',
+ route: '/page-display/topics',
+ title: '专题页面',
+ canonicalDomain: 'page_display',
+ section: 'topics',
+ }),
schemaPage({
key: 'page-display-user-home',
name: 'PageDisplayUserHome',
diff --git a/assets/admin/src/schema/sections/global/search.js b/assets/admin/src/schema/sections/global/search.js
index 81fb9e04..2825a918 100644
--- a/assets/admin/src/schema/sections/global/search.js
+++ b/assets/admin/src/schema/sections/global/search.js
@@ -63,12 +63,13 @@ export const searchSchema = {
{ key: 'search_custom_key_s', label: '自定义匹配范围', type: 'switch', default: true, help: '启用后可配置搜索匹配字段范围' },
{ key: 'search_custom_key', label: '匹配字段', type: 'checkbox', default: ['title', 'content', 'excerpt', 'category', 'post_tag'], dependsOn: { key: 'search_custom_key_s', value: true }, options: [
{ label: '标题', value: 'title' }, { label: '内容', value: 'content' }, { label: '简介', value: 'excerpt' },
- { label: '分类', value: 'category' }, { label: '标签', value: 'post_tag' },
+ { label: '分类', value: 'category' }, { label: '标签', value: 'post_tag' }, { label: '专题', value: 'topics' },
{ label: '评论', value: 'coment' }, { label: '作者昵称', value: 'user' },
] },
{ key: 'search_facets', label: '搜索筛选', type: 'fieldset', sanitizeType: 'array', default: {}, dependsOn: { key: 'search_ms_s', value: false }, help: '搜索结果中显示的筛选列表;启用 Meilisearch 后由搜索引擎生成关联筛选。', fields: [
{ key: 'category', label: '[文章] 分类', type: 'taxonomy_select', taxonomy: 'category', multiple: true, default: [] },
{ key: 'post_tag', label: '[文章] 标签', type: 'taxonomy_select', taxonomy: 'post_tag', multiple: true, default: [] },
+ { key: 'topics', label: '[文章] 专题', type: 'taxonomy_select', taxonomy: 'topics', multiple: true, default: [] },
] },
],
},
diff --git a/assets/admin/src/schema/sections/post-list/filter.js b/assets/admin/src/schema/sections/post-list/filter.js
index 578684d4..dc229cff 100644
--- a/assets/admin/src/schema/sections/post-list/filter.js
+++ b/assets/admin/src/schema/sections/post-list/filter.js
@@ -18,7 +18,7 @@ export const filterSchema = {
key: 'filter_intro',
type: 'content',
ui_only: true,
- content: '
文章高级筛选功能:通过此功能可实现更加复杂、精细化的内容筛选
添加筛选类型和内容值之后,编写文章时候,可以进行选择,且在前台也可以实现精准筛选
例如影视网站:[类型]有[剧情/喜剧/悬疑/惊悚/犯罪],[地区]有[大陆/美国/日韩/港台/印度],[年份]有[2022/2021/2020/10年代/00年代]等
注意事项:添加类型key时候,只能使用英文加下划线,不能有空格,且尽量复杂一点(不能为tag,category等系统已存在的类型),避免与其他mate_key重复!类型名称不能为分类、标签等系统已存在的类型
',
+ content: '文章高级筛选功能:通过此功能可实现更加复杂、精细化的内容筛选
添加筛选类型和内容值之后,编写文章时候,可以进行选择,且在前台也可以实现精准筛选
例如影视网站:[类型]有[剧情/喜剧/悬疑/惊悚/犯罪],[地区]有[大陆/美国/日韩/港台/印度],[年份]有[2022/2021/2020/10年代/00年代]等
注意事项:添加类型key时候,只能使用英文加下划线,不能有空格,且尽量复杂一点(不能为tag,category,topics等系统已存在的类型),避免与其他mate_key重复!类型名称不能为分类、专题、标签等系统已存在的类型
',
},
{
key: 'custom_filter_show',
@@ -28,6 +28,7 @@ export const filterSchema = {
options: [
{ label: '分类页面显示', value: 'cat' },
{ label: '标签页面显示', value: 'tag' },
+ { label: '专题页面显示', value: 'topics' },
],
description: '勾选后将会在对应页面默认显示全部筛选,您可以在下方为单独的分类添加自定义筛选',
},
@@ -87,6 +88,18 @@ export const filterSchema = {
{ key: 'dropdown', label: '下拉列表', type: 'switch', default: false, description: '用下拉框显示更多内容' },
],
},
+ { key: 'topics_s', label: '专题筛选', type: 'switch', default: false, description: '在所选分类页显示的专题筛选列表' },
+ {
+ key: 'topics_lists',
+ label: ' ',
+ type: 'fieldset',
+ default: { lists: [], dropdown: false },
+ dependsOn: { key: 'topics_s', value: true },
+ fields: [
+ { key: 'lists', label: '按钮列表', type: 'async_select', source: 'topics', multiple: true, sortable: true, default: [] },
+ { key: 'dropdown', label: '下拉列表', type: 'switch', default: false },
+ ],
+ },
{ key: 'orderby_s', label: '排序方式', type: 'switch', default: true, description: '在所选分类页显示排序方式按钮' },
{
key: 'orderby_lists',
diff --git a/assets/admin/src/schema/sections/post-list/list.js b/assets/admin/src/schema/sections/post-list/list.js
index 8104ebe3..1231d3ee 100644
--- a/assets/admin/src/schema/sections/post-list/list.js
+++ b/assets/admin/src/schema/sections/post-list/list.js
@@ -13,11 +13,12 @@ export const listSchema = {
post_list_author: true,
post_list_time: true,
list_meta_show: 'like',
- list_badge_show: ['pay', 'cat', 'tag'],
+ list_badge_show: ['pay', 'tag', 'topics', 'cat'],
list_show_type: 'separate',
list_type: 'thumb',
list_card_home: false,
list_card_tag: false,
+ list_card_topics: false,
list_card_author: false,
list_card_cat: [],
list_list_option: { style: 'null', img_position: 'left', scale: 70 },
@@ -39,7 +40,7 @@ export const listSchema = {
{ label: '发布时间', value: 'date' }, { label: '更新时间', value: 'modified' },
] },
{ key: 'sticky_s', label: '显示置顶文章', type: 'checkbox', default: ['home', 'cat'], options: [
- { label: '首页', value: 'home' }, { label: '分类页', value: 'cat' }, { label: '标签页', value: 'tag' },
+ { label: '首页', value: 'home' }, { label: '分类页', value: 'cat' }, { label: '标签页', value: 'tag' }, { label: '专题页', value: 'topics' },
] },
],
},
@@ -52,8 +53,8 @@ export const listSchema = {
{ key: 'list_meta_show', label: '列表小部件(移动端优先)', type: 'radio', default: 'like', options: [
{ label: '阅读量', value: 'view' }, { label: '点赞数', value: 'like' }, { label: '评论', value: 'comm' },
] },
- { key: 'list_badge_show', label: '显示列表标签', type: 'checkbox', default: ['pay', 'cat', 'tag'], options: [
- { label: '付费信息', value: 'pay' }, { label: '分类', value: 'cat' }, { label: '标签', value: 'tag' },
+ { key: 'list_badge_show', label: '显示列表标签', type: 'checkbox', default: ['pay', 'tag', 'topics', 'cat'], options: [
+ { label: '付费信息', value: 'pay' }, { label: '分类', value: 'cat' }, { label: '专题', value: 'topics' }, { label: '标签', value: 'tag' },
] },
],
},
@@ -70,8 +71,9 @@ export const listSchema = {
], help: '文字、自动图文和多图模式仅在开启侧栏的页面有效。' },
{ key: 'list_card_home', label: '首页列表卡片模式', type: 'switch', default: false, dependsOn: { key: 'list_type', not: true, value: 'card' } },
{ key: 'list_card_tag', label: '标签页列表卡片模式', type: 'switch', default: false, dependsOn: { key: 'list_type', not: true, value: 'card' } },
+ { key: 'list_card_topics', label: '专题页列表卡片模式', type: 'switch', default: false, dependsOn: { key: 'list_type', not: true, value: 'card' } },
{ key: 'list_card_author', label: '用户页列表卡片模式', type: 'switch', default: false, dependsOn: { key: 'list_type', not: true, value: 'card' } },
- { key: 'list_card_cat', label: '分类页自定义卡片模式', type: 'taxonomy_select', taxonomy: 'category', multiple: true, default: [], dependsOn: { key: 'list_type', not: true, value: 'card' } },
+ { key: 'list_card_cat', label: '分类、专题页自定义卡片模式', type: 'taxonomy_select', taxonomy: 'category,topics', multiple: true, default: [], dependsOn: { key: 'list_type', not: true, value: 'card' } },
{ key: 'list_list_option', label: '列表模式 UI 配置', type: 'fieldset', default: { style: 'null', img_position: 'left', scale: 70 }, fields: [
{ key: 'style', label: '列表样式', type: 'radio', default: 'null', options: [
{ label: '默认', value: 'null' }, { label: '样式 2', value: 'style2' },
diff --git a/assets/admin/src/schema/sections/post-list/submit.js b/assets/admin/src/schema/sections/post-list/submit.js
index a80caa50..998d1d55 100644
--- a/assets/admin/src/schema/sections/post-list/submit.js
+++ b/assets/admin/src/schema/sections/post-list/submit.js
@@ -7,6 +7,8 @@ export const submitSchema = {
post_article_s: true,
post_article_btn_txte: '发布文章',
post_article_cat: [],
+ post_article_topics_s: false,
+ post_article_topics: [],
post_article_custom_filter_s: true,
post_article_tag: true,
post_article_user: 1,
@@ -34,6 +36,8 @@ export const submitSchema = {
},
{ key: 'post_article_btn_txte', label: '按钮文字', type: 'input', default: '发布文章', dependsOn: { key: 'post_article_s', value: true }, description: '投稿按钮的显示的文字,推荐4个字更加协调' },
{ key: 'post_article_cat', label: '投稿允许选择的分类', type: 'taxonomy_select', taxonomy: 'category', multiple: true, default: [], placeholder: '输入关键词以搜索分类', dependsOn: { key: 'post_article_s', value: true }, description: '投稿允许选择的分类,为空则允许选择全部分类,所选分类下如果有子分类则会自动显示,如果选择了上级分类,则不要再选该分类下的子分类。注意:请确保所选分类包含子分类总数不要超过50个,否则可能会引起页面崩溃' },
+ { key: 'post_article_topics_s', label: '允许选择专题', type: 'switch', default: false, dependsOn: { key: 'post_article_s', value: true } },
+ { key: 'post_article_topics', label: '投稿允许选择的专题', type: 'taxonomy_select', taxonomy: 'topics', multiple: true, default: [], dependsOn: { all: [{ key: 'post_article_s', value: true }, { key: 'post_article_topics_s', value: true }] } },
{ key: 'post_article_custom_filter_s', label: '允许选择高级筛选', type: 'switch', default: true, dependsOn: { key: 'post_article_s', value: true } },
{
key: 'submit_filter_notice',
diff --git a/assets/creator-studio/src/components/category-select.tsx b/assets/creator-studio/src/components/category-select.tsx
index 8cebc69b..c5ada5e7 100644
--- a/assets/creator-studio/src/components/category-select.tsx
+++ b/assets/creator-studio/src/components/category-select.tsx
@@ -19,9 +19,10 @@ type Props = {
options: CategoryOption[];
value: number[];
onChange: (ids: number[]) => void;
+ label?: string;
};
-export function CategorySelect({ options, value, onChange }: Props) {
+export function CategorySelect({ options, value, onChange, label = __('分类', 'jio') }: Props) {
const [open, setOpen] = useState(false);
const [query, setQuery] = useState('');
const { triggerRef, panelRef, position } = useAnchoredPanel({
@@ -71,16 +72,16 @@ export function CategorySelect({ options, value, onChange }: Props) {
setQuery(event.target.value)}
/>
-
+
{filtered.length === 0 && (
-
{__('没有匹配的分类', 'jio')}
+
{sprintf(__('没有匹配的%s', 'jio'), label)}
)}
{filtered.map((option) => {
const active = selected.has(option.id);
@@ -133,7 +134,7 @@ export function CategorySelect({ options, value, onChange }: Props) {
>
{chosen.length === 0 ? (
- {__('选择分类(可多选)', 'jio')}
+ {sprintf(__('选择%s(可多选)', 'jio'), label)}
) : (
chosen.map((option) => (
@@ -143,7 +144,7 @@ export function CategorySelect({ options, value, onChange }: Props) {
+ {taxonomy.topics.enabled && taxonomy.topics.items.length > 0 && (
+
+ )}
+
{taxonomy.tags.enabled && (
diff --git a/assets/creator-studio/src/draft.ts b/assets/creator-studio/src/draft.ts
index 68106068..18621829 100644
--- a/assets/creator-studio/src/draft.ts
+++ b/assets/creator-studio/src/draft.ts
@@ -57,6 +57,7 @@ export type Draft = {
content: string;
schedule: Schedule;
categories: number[];
+ topics: number[];
tags: string[];
custom: Record;
featured: Featured;
@@ -66,6 +67,7 @@ export type Draft = {
export function initialDraft(bootstrap: Record): Draft {
const pay = bootstrap.pay || {};
const selected = (bootstrap.categories && bootstrap.categories.selected) || [];
+ const selectedTopics = (bootstrap.topics && bootstrap.topics.selected) || [];
const tags = (bootstrap.tags && bootstrap.tags.items) || [];
return {
postId: Number(bootstrap.sourceId || 0),
@@ -75,6 +77,7 @@ export function initialDraft(bootstrap: Record): Draft {
content: String(bootstrap.content || ''),
schedule: { enabled: false, at: '' },
categories: selected.map(Number),
+ topics: selectedTopics.map(Number),
tags: tags.slice(),
custom: bootstrap.custom || {},
featured: bootstrap.featured || { type: '', data: {} },
diff --git a/assets/creator-studio/src/index.tsx b/assets/creator-studio/src/index.tsx
index 84804222..95d3793c 100644
--- a/assets/creator-studio/src/index.tsx
+++ b/assets/creator-studio/src/index.tsx
@@ -207,6 +207,7 @@ function Studio(): JSX.Element {
title: current.title,
content: current.content,
categories: current.categories,
+ topics: current.topics,
tags: current.tags,
custom: current.custom,
featured: current.featured,
@@ -859,6 +860,10 @@ function Studio(): JSX.Element {
canPay={!!capabilities.canPay}
taxonomy={{
categories: (bootstrap.categories && bootstrap.categories.items) || [],
+ topics: {
+ enabled: !!bootstrap.topics?.enabled,
+ items: (bootstrap.topics && bootstrap.topics.items) || [],
+ },
tags: {
enabled: !!bootstrap.tags?.enabled,
suggestions: (bootstrap.tags && bootstrap.tags.suggestions) || [],
@@ -866,12 +871,14 @@ function Studio(): JSX.Element {
customDefs: bootstrap.customDefs || [],
}}
categories={draft.categories}
+ topics={draft.topics}
tags={draft.tags}
custom={draft.custom}
onFeaturedChange={(featured) => patchDraft({ featured })}
onScheduleChange={(enabled, at) => patchDraft({ schedule: { enabled, at } })}
onPayEnabledChange={(enabled) => patchDraft({ pay: { ...draftRef.current.pay, enabled } })}
onCategoriesChange={(categories) => patchDraft({ categories })}
+ onTopicsChange={(topics) => patchDraft({ topics })}
onTagsChange={(tags) => patchDraft({ tags })}
onCustomChange={(custom) => patchDraft({ custom })}
onOpenPaySettings={() => setDrawerOpen(true)}
diff --git a/functions.php b/functions.php
index 758fd4e3..5246ba66 100644
--- a/functions.php
+++ b/functions.php
@@ -16,7 +16,7 @@
defined('ABSPATH') || exit;
-define('JIO_VERSION', '3.4.1-dev');
+define('JIO_VERSION', '3.4.2-dev');
define('JIO_DIR', get_template_directory());
define('JIO_URI', get_template_directory_uri());
diff --git a/inc/core-hooks.php b/inc/core-hooks.php
index 55a9dd58..748318c2 100644
--- a/inc/core-hooks.php
+++ b/inc/core-hooks.php
@@ -385,11 +385,6 @@ add_action('pre_get_posts', function ($query) {
// 站内搜索:分类/标签名搜索(内容类型始终为 post)
if ($query->is_search() && empty($query->get('post_type'))) {
$search_type = sanitize_key((string) $query->get('type'));
- $trem = absint($query->get('trem'));
- if ($trem > 0) {
- $query->set('cat', $trem);
- }
-
if (in_array($search_type, ['category', 'tag'], true)) {
$taxonomy = $search_type === 'category' ? 'category' : 'post_tag';
$term_ids = get_terms([
diff --git a/inc/helpers/homepage/header-components.php b/inc/helpers/homepage/header-components.php
index 43f13588..79463fa1 100644
--- a/inc/helpers/homepage/header-components.php
+++ b/inc/helpers/homepage/header-components.php
@@ -80,6 +80,9 @@ if (!function_exists('jio_header_slide_current_page_type')) {
if (is_tag()) {
return 'tag';
}
+ if (function_exists('is_tax') && is_tax('topics')) {
+ return 'topics';
+ }
if (is_singular('post')) {
return 'single';
}
diff --git a/inc/helpers/homepage/layout.php b/inc/helpers/homepage/layout.php
index c71653d2..04a4a895 100644
--- a/inc/helpers/homepage/layout.php
+++ b/inc/helpers/homepage/layout.php
@@ -122,7 +122,9 @@ if (!function_exists('jio_homepage_get_tab_panes_html')) {
$html = '';
foreach ($tab_configs as $index => $tab_cfg) {
- $config = jio_archive_get_render_config(['context' => 'category', 'term_id' => (int) $tab_cfg['term_id']]);
+ $term = $tab_cfg['term'] ?? null;
+ $context = $term instanceof WP_Term && $term->taxonomy === 'topics' ? 'topics' : 'category';
+ $config = jio_archive_get_render_config(['context' => $context, 'term_id' => (int) $tab_cfg['term_id']]);
$is_card = ($config['mode'] ?? 'list') === 'card';
$placeholder = jio_render_placeholder($is_card ? 'card' : 'list', $is_card ? (wp_is_mobile() ? 4 : 12) : (wp_is_mobile() ? 4 : 6));
$html .= '