Skip to content

Commit

Permalink
feat(experimental): support passing function for rewrites (#4274)
Browse files Browse the repository at this point in the history
  • Loading branch information
brc-dd authored Oct 12, 2024
1 parent 92b92ae commit 8436472
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 29 deletions.
44 changes: 29 additions & 15 deletions docs/en/guide/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,22 +156,24 @@ You can customize the mapping between the source directory structure and the gen

```
.
─ packages
├─ pkg-a
│ └─ src
├─ pkg-a-code.ts
└─ pkg-a-docs.md
└─ pkg-b
└─ src
├─ pkg-b-code.ts
└─ pkg-b-docs.md
─ packages
├─ pkg-a
│ └─ src
│ ├─ foo.md
│ └─ index.md
└─ pkg-b
└─ src
├─ bar.md
└─ index.md
```

And you want the VitePress pages to be generated like this:

```
packages/pkg-a/src/pkg-a-docs.md --> /pkg-a/index.html
packages/pkg-b/src/pkg-b-docs.md --> /pkg-b/index.html
packages/pkg-a/src/index.md --> /pkg-a/index.html
packages/pkg-a/src/foo.md --> /pkg-a/foo.html
packages/pkg-b/src/index.md --> /pkg-b/index.html
packages/pkg-b/src/bar.md --> /pkg-b/bar.html
```

You can achieve this by configuring the [`rewrites`](../reference/site-config#rewrites) option like this:
Expand All @@ -180,8 +182,10 @@ You can achieve this by configuring the [`rewrites`](../reference/site-config#re
// .vitepress/config.js
export default {
rewrites: {
'packages/pkg-a/src/pkg-a-docs.md': 'pkg-a/index.md',
'packages/pkg-b/src/pkg-b-docs.md': 'pkg-b/index.md'
'packages/pkg-a/src/index.md': 'pkg-a/index.md',
'packages/pkg-a/src/foo.md': 'pkg-a/foo.md',
'packages/pkg-b/src/index.md': 'pkg-b/index.md',
'packages/pkg-b/src/bar.md': 'pkg-b/bar.md'
}
}
```
Expand All @@ -191,12 +195,22 @@ The `rewrites` option also supports dynamic route parameters. In the above examp
```ts
export default {
rewrites: {
'packages/:pkg/src/(.*)': ':pkg/index.md'
'packages/:pkg/src/:slug*': ':pkg/:slug*'
}
}
```

The rewrite paths are compiled using the `path-to-regexp` package - consult [its documentation](https://github.com/pillarjs/path-to-regexp#parameters) for more advanced syntax.
The rewrite paths are compiled using the `path-to-regexp` package - consult [its documentation](https://github.com/pillarjs/path-to-regexp/tree/6.x#parameters) for more advanced syntax.

`rewrites` can also be a function that receives the original path and returns the new path:

```ts
export default {
rewrites(id) {
return id.replace(/^packages\/([^/]+)\/src\//, '$1/')
}
}
```

::: warning Relative Links with Rewrites

Expand Down
39 changes: 26 additions & 13 deletions src/node/plugins/rewritesPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,35 @@ export function resolveRewrites(
pages: string[],
userRewrites: UserConfig['rewrites']
) {
const rewriteRules = Object.entries(userRewrites || {}).map(([from, to]) => ({
toPath: compile(`/${to}`, { validate: false }),
matchUrl: match(from.startsWith('^') ? new RegExp(from) : from)
}))

const pageToRewrite: Record<string, string> = {}
const rewriteToPage: Record<string, string> = {}
if (rewriteRules.length) {

if (typeof userRewrites === 'function') {
for (const page of pages) {
for (const { matchUrl, toPath } of rewriteRules) {
const res = matchUrl(page)
if (res) {
const dest = toPath(res.params).slice(1)
pageToRewrite[page] = dest
rewriteToPage[dest] = page
break
const dest = userRewrites(page)
if (dest && dest !== page) {
pageToRewrite[page] = dest
rewriteToPage[dest] = page
}
}
} else if (typeof userRewrites === 'object') {
const rewriteRules = Object.entries(userRewrites || {}).map(
([from, to]) => ({
toPath: compile(`/${to}`, { validate: false }),
matchUrl: match(from.startsWith('^') ? new RegExp(from) : from)
})
)

if (rewriteRules.length) {
for (const page of pages) {
for (const { matchUrl, toPath } of rewriteRules) {
const res = matchUrl(page)
if (res) {
const dest = toPath(res.params).slice(1)
pageToRewrite[page] = dest
rewriteToPage[dest] = page
break
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/node/siteConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export interface UserConfig<ThemeConfig = any>
*
* source -> destination
*/
rewrites?: Record<string, string>
rewrites?: Record<string, string> | ((id: string) => string)

/**
* @experimental
Expand Down

0 comments on commit 8436472

Please sign in to comment.