diff --git a/theme/src/node/plugins.ts b/theme/src/node/plugins.ts index 8c3e7c94..6d53c5d0 100644 --- a/theme/src/node/plugins.ts +++ b/theme/src/node/plugins.ts @@ -30,6 +30,7 @@ import autoFrontmatter from './autoFrontmatter.js' import { resolveLocaleOptions } from './resolveLocaleOptions.js' import { pathJoin } from './utils.js' import { resolveNotesList } from './resolveNotesList.js' +import { resolvedDocsearchOption, resolvedSearchOptions } from './searchPluginOptions.js' export function setupPlugins( app: App, @@ -129,16 +130,16 @@ export function setupPlugins( })) } - if (options.search !== false) - plugins.push(searchPlugin(options.search)) - - if (options.docsearch !== false && !options.search) { - if (options.docsearch?.appId && options.docsearch?.apiKey) - plugins.push(docsearchPlugin(options.docsearch)) + if (options.docsearch) { + if (options.docsearch.appId && options.docsearch.apiKey) + plugins.push(docsearchPlugin(resolvedDocsearchOption(app, options.docsearch))) else console.error('docsearch plugin: appId and apiKey are both required') } + else if (options.search !== false) { + plugins.push(searchPlugin(resolvedSearchOptions(app, options.search))) + } if (options.shikiji !== false) { plugins.push(shikijiPlugin({ diff --git a/theme/src/node/searchPluginOptions.ts b/theme/src/node/searchPluginOptions.ts new file mode 100644 index 00000000..93435cc0 --- /dev/null +++ b/theme/src/node/searchPluginOptions.ts @@ -0,0 +1,88 @@ +import type { DocsearchPluginOptions } from '@vuepress/plugin-docsearch' +import type { SearchPluginOptions } from '@vuepress/plugin-search' +import type { App } from '@vuepress/core' +import { deepMerge } from '@pengzhanbo/utils' + +// `en-US` is used by default +const defaultDocsearchLocales: NonNullable = { + 'zh-CN': { + placeholder: '搜索文档', + translations: { + button: { + buttonText: '搜索文档', + buttonAriaLabel: '搜索文档', + }, + modal: { + searchBox: { + resetButtonTitle: '清除查询条件', + resetButtonAriaLabel: '清除查询条件', + cancelButtonText: '取消', + cancelButtonAriaLabel: '取消', + }, + startScreen: { + recentSearchesTitle: '搜索历史', + noRecentSearchesText: '没有搜索历史', + saveRecentSearchButtonTitle: '保存至搜索历史', + removeRecentSearchButtonTitle: '从搜索历史中移除', + favoriteSearchesTitle: '收藏', + removeFavoriteSearchButtonTitle: '从收藏中移除', + }, + errorScreen: { + titleText: '无法获取结果', + helpText: '你可能需要检查你的网络连接', + }, + footer: { + selectText: '选择', + navigateText: '切换', + closeText: '关闭', + searchByText: '搜索提供者', + }, + noResultsScreen: { + noResultsText: '无法找到相关结果', + suggestedQueryText: '你可以尝试查询', + reportMissingResultsText: '你认为该查询应该有结果?', + reportMissingResultsLinkText: '点击反馈', + }, + }, + }, + }, +} + +const defaultSearchLocales: NonNullable = { + 'zh-CN': { placeholder: '搜索' }, + 'en-US': { placeholder: 'Search' }, +} + +export function resolvedDocsearchOption(app: App, options: DocsearchPluginOptions): DocsearchPluginOptions { + options.locales ??= {} + + Object.keys(app.siteData.locales || {}).forEach((locale) => { + const lang = app.siteData.locales![locale]?.lang || 'en-US' + if (defaultDocsearchLocales[lang]) { + options.locales![locale] = deepMerge( + {}, + defaultDocsearchLocales[lang], + options.locales![locale] || {}, + ) + } + }) + + return options +} + +export function resolvedSearchOptions(app: App, options: SearchPluginOptions = {}): SearchPluginOptions { + options.locales ??= {} + + Object.keys(app.siteData.locales || {}).forEach((locale) => { + const lang = app.siteData.locales![locale]?.lang || 'en-US' + if (defaultSearchLocales[lang]) { + options.locales![locale] = deepMerge( + {}, + defaultSearchLocales[lang], + options.locales![locale] || {}, + ) + } + }) + + return options +}