feat(search): exclude content from search results

pull/2602/head
Jérémy Riverain 3 years ago
parent 66189c3f43
commit fa3215644d

@ -87,6 +87,17 @@ export default defineConfig({
title: 'Example', title: 'Example',
description: 'An example app using VitePress.', description: 'An example app using VitePress.',
themeConfig: { themeConfig: {
sidebar sidebar,
search: {
provider: 'local',
options: {
exclude: (pageData) => {
return (
pageData.relativePath.startsWith('local-search/excluded') ||
pageData.frontmatter.search === false
)
}
}
}
} }
}) })

@ -0,0 +1 @@
# Local search config excluded

@ -0,0 +1,5 @@
---
search: false
---
# Local search frontmatter excluded

@ -0,0 +1 @@
# Local search included

@ -0,0 +1,30 @@
beforeEach(async () => {
await goto('/')
})
describe('Local search', () => {
test('exclude content from search results', async () => {
await page.locator('#local-search button').click()
const input = await page.locator('input#localsearch-input')
await input.waitFor({ state: 'visible' })
await input.type('local')
await page.waitForSelector('ul#localsearch-list', { state: 'visible' })
const searchResults = await page.locator('#localsearch-list')
expect(await searchResults.locator('li[role=option]').count()).toBe(1)
await searchResults.filter({ hasText: 'Local search included' }).isVisible()
expect(
await searchResults.filter({ hasText: 'Local search excluded' }).count()
).toBe(0)
expect(
await searchResults
.filter({ hasText: 'Local search frontmatter excluded' })
.count()
).toBe(0)
})
})

@ -7,6 +7,7 @@ import type { SiteConfig } from '../config'
import type { MarkdownEnv } from '../markdown' import type { MarkdownEnv } from '../markdown'
import { createMarkdownRenderer } from '../markdown' import { createMarkdownRenderer } from '../markdown'
import { resolveSiteDataByRoute, slash, type DefaultTheme } from '../shared' import { resolveSiteDataByRoute, slash, type DefaultTheme } from '../shared'
import matter from 'gray-matter'
const debug = _debug('vitepress:local-search') const debug = _debug('vitepress:local-search')
@ -120,7 +121,20 @@ export async function localSearchPlugin(
const documentsByLocale = new Map<string, IndexObject[]>() const documentsByLocale = new Map<string, IndexObject[]>()
await Promise.all( await Promise.all(
files files
.filter((file) => fs.existsSync(file)) .filter((file) => {
if (!fs.existsSync(file)) {
return false
}
const src = fs.readFileSync(file, 'utf-8')
const { data: frontmatter } = matter(src, {
excerpt: true
})
const { relativePath } = createMarkdownEnv(file)
return !siteConfig.userConfig.themeConfig?.search?.options?.exclude({
relativePath,
frontmatter
})
})
.map(async (file) => { .map(async (file) => {
const fileId = getDocId(file) const fileId = getDocId(file)
const sections = splitPageIntoSections( const sections = splitPageIntoSections(

@ -350,6 +350,12 @@ export namespace DefaultTheme {
*/ */
searchOptions?: MiniSearchOptions['searchOptions'] searchOptions?: MiniSearchOptions['searchOptions']
} }
/**
* exclude content from search results
*/
exclude?: (
pageData: Pick<PageData, 'frontmatter' | 'relativePath'>
) => boolean
} }
// algolia ------------------------------------------------------------------- // algolia -------------------------------------------------------------------

Loading…
Cancel
Save