Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: apply replaceRules in object frontmatter #1343

Merged
merged 1 commit into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions e2e/fixtures/replace-rules/doc/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"text": "foo-meta",
"link": "/foo/"
}
]
1 change: 0 additions & 1 deletion e2e/fixtures/replace-rules/doc/content.mdx

This file was deleted.

1 change: 1 addition & 0 deletions e2e/fixtures/replace-rules/doc/foo/content.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## foo-h2
9 changes: 9 additions & 0 deletions e2e/fixtures/replace-rules/doc/foo/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: foo-title
---

import Content from './content.mdx';

<Content />

foo-content
11 changes: 9 additions & 2 deletions e2e/fixtures/replace-rules/doc/index.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import Content from './content.mdx';
---
pageType: home

<Content />
hero:
name: foo-hero
text: |
Lightning Fast
Static Site Generator
tagline: Simple, efficient and easy to extend
---
4 changes: 2 additions & 2 deletions e2e/fixtures/replace-rules/rspress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export default defineConfig({
root: path.join(__dirname, 'doc'),
replaceRules: [
{
search: /content/g,
replace: 'h1',
search: /foo/g,
replace: 'bar',
},
],
});
37 changes: 34 additions & 3 deletions e2e/tests/replace-rules.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,39 @@ test.describe('replace-rules test', async () => {

test('Index page', async ({ page }) => {
await page.goto(`http://localhost:${appPort}`);
const h1 = await page.$('h1');
const content = await page.evaluate(h1 => h1?.textContent, h1);
expect(content).toContain('h1');

// replace text in _meta.json
const nav = await page.$('.rspress-nav-menu');
const navContent = await page.evaluate(nav => nav?.textContent, nav);

// replace text in object frontmatter
const hero = await page.$('h1');
const heroContent = await page.evaluate(hero => hero?.textContent, hero);

expect(navContent).toEqual('bar-meta');
expect(heroContent).toEqual('bar-hero');
});

test('Foo page', async ({ page }) => {
await page.goto(`http://localhost:${appPort}/foo`);

// text in string frontmatter
const title = await page.$('title');
const titleContent = await page.evaluate(
title => title?.textContent,
title,
);

// replace text in shared mdx content
const h2 = await page.$('h2');
const h2Content = await page.evaluate(h2 => h2?.textContent, h2);

// replace text in mdx content
const text = await page.$('.rspress-doc p');
const textContent = await page.evaluate(text => text?.textContent, text);

expect(titleContent).toEqual('bar-title');
expect(h2Content).toEqual('bar-h2#');
expect(textContent).toEqual('bar-content');
});
});
21 changes: 16 additions & 5 deletions packages/core/src/node/runtimeModule/siteData/extractPageData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ import { importStatementRegex } from '@/node/constants';
import type { RouteService } from '@/node/route/RouteService';
import { applyReplaceRules } from '@/node/utils/applyReplaceRules';

export function applyReplaceRulesToNestedObject(
obj,
replaceRules: ReplaceRule[],
) {
for (const key in obj) {
if (typeof obj[key] === 'string') {
obj[key] = applyReplaceRules(obj[key], replaceRules);
} else if (typeof obj[key] === 'object') {
obj[key] = applyReplaceRulesToNestedObject(obj[key], replaceRules);
}
}

return obj;
}

export async function extractPageData(
replaceRules: ReplaceRule[],
alias: Record<string, string | string[]>,
Expand Down Expand Up @@ -48,11 +63,7 @@ export async function extractPageData(
);

// 1. Replace rules for frontmatter & content
Object.keys(frontmatter).forEach(key => {
if (typeof frontmatter[key] === 'string') {
frontmatter[key] = applyReplaceRules(frontmatter[key], replaceRules);
}
});
applyReplaceRulesToNestedObject(frontmatter, replaceRules);

const { flattenContent } = await flattenMdxContent(
applyReplaceRules(strippedFrontMatter, replaceRules),
Expand Down
18 changes: 18 additions & 0 deletions packages/document/docs/en/api/config/config-basic.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -434,3 +434,21 @@ export default {
},
};
```

## replaceRules

- Type: `{ search: string | RegExp; replace: string; }[]`
- Default: `[]`

You can set text replacement rules for the entire site through `replaceRules`. The rules will apply to everything including `_meta.json` files, frontmatter configurations, and document content and titles.

```ts title="rspress.config.ts"
export default {
replaceRules: [
{
search: /foo/g,
replace: 'bar',
},
],
};
```
18 changes: 18 additions & 0 deletions packages/document/docs/zh/api/config/config-basic.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -433,3 +433,21 @@ export default {
},
};
```

## replaceRules

- Type: `{ search: string | RegExp; replace: string; }[]`
- Default: `[]`

你可以通过 `replaceRules` 来对整个站点设置文本替换规则,规则会作用于包括 `_meta.json` 文件、frontmatter 配置以及文档内容和标题等所有内容。

```ts title="rspress.config.ts"
export default {
replaceRules: [
{
search: /foo/g,
replace: 'bar',
},
],
};
```