Commit 517b0af0 by dreamer6680 Committed by GitHub

feat: move robots.txt to toc.mdx (#5372)

* feat: move robots.txt to toc.mdx

* fix: add en toc
parent 7bcee82f
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import fg from 'fast-glob';
import matter from 'gray-matter';
import { i18n } from '@/lib/i18n';
export const revalidate = false;
// 黑名单路径(不带语言前缀)
const blacklist = ['use-cases/index', 'protocol/index', 'api/index'];
// 将文件路径转换为 URL 路径(包括文件名)
function filePathToUrl(filePath: string, defaultLanguage: string): string {
let relativePath = filePath.replace('./content/docs/', '');
const basePath = defaultLanguage === 'zh-CN' ? '/docs' : '/en/docs';
if (defaultLanguage !== 'zh-CN' && relativePath.endsWith('.en.mdx')) {
relativePath = relativePath.replace(/\.en\.mdx$/, '');
} else if (relativePath.endsWith('.mdx')) {
relativePath = relativePath.replace(/\.mdx$/, '');
}
return `${basePath}/${relativePath}`.replace(/\/\/+/g, '/');
}
// 判断是否为黑名单路径
function isBlacklisted(url: string): boolean {
return blacklist.some(
(item) => url.endsWith(`/docs/${item}`) || url.endsWith(`/en/docs/${item}`)
);
}
export async function GET(request: Request) {
const defaultLanguage = i18n.defaultLanguage;
const requestUrl = new URL(request.url);
const isEnRobotsRoute = requestUrl.pathname === '/en/robots';
let globPattern;
if (isEnRobotsRoute) {
globPattern = ['./content/docs/**/*.en.mdx'];
} else if (defaultLanguage === 'zh-CN') {
globPattern = ['./content/docs/**/*.mdx'];
} else {
globPattern = ['./content/docs/**/*.en.mdx'];
}
const files = await fg(globPattern, { caseSensitiveMatch: true });
// 转换文件路径为 URL,并过滤黑名单
const urls = files
.map((file) => filePathToUrl(file, defaultLanguage))
.filter((url) => !isBlacklisted(url));
urls.sort((a, b) => a.localeCompare(b));
const html = `
<html>
<head>
<title>FastGPT 文档目录</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
h1 { color: #333; }
ul { list-style-type: none; padding: 0; }
li { margin: 10px 0; }
a { color: #0066cc; text-decoration: none; }
a:hover { text-decoration: underline; }
</style>
</head>
<body>
<h1>Documentation Links</h1>
<ul>
${urls.map((url) => `<li><a href="${url}">${url}</a></li>`).join('')}
</ul>
</body>
</html>
`;
return new Response(html, {
headers: {
'Content-Type': 'text/html'
}
});
}
// app/api/robots/route.ts
import { i18n } from '@/lib/i18n';
import { NextResponse } from 'next/server';
export async function GET() {
const host =
i18n.defaultLanguage === 'zh-cn' ? 'https://localhost:3000' : 'https://localhost:3000/en';
const robotsTxt = `User-agent: *
Allow: /
Allow: /en/
Disallow: /zh-cn/
Host: ${host}
Sitemap: ${host}/sitemap.xml`;
return new NextResponse(robotsTxt, {
headers: {
'Content-Type': 'text/plain'
}
});
}
---
title: FastGPT Toc
description: FastGPT Toc
---
- [/en/docs/introduction/index](/en/docs/introduction/index)
- [/en/docs/protocol/open-source](/en/docs/protocol/open-source)
- [/en/docs/protocol/privacy](/en/docs/protocol/privacy)
- [/en/docs/protocol/terms](/en/docs/protocol/terms)
import * as fs from 'node:fs/promises';
import path from 'node:path';
import fg from 'fast-glob';
// 假设 i18n.defaultLanguage = 'zh-CN',这里不用 i18n 直接写两份逻辑即可
// 黑名单路径(不带语言前缀)
const blacklist = [
'use-cases/index',
'protocol/index',
'api/index',
'faq/index',
'upgrading/index',
'toc'
];
function filePathToUrl(filePath, lang) {
const baseDir = path.resolve('../content/docs');
let relativePath = path.relative(baseDir, path.resolve(filePath)).replace(/\\/g, '/');
const basePath = lang === 'zh-CN' ? '/docs' : '/en/docs';
if (lang !== 'zh-CN' && relativePath.endsWith('.en.mdx')) {
relativePath = relativePath.replace(/\.en\.mdx$/, '');
} else if (lang === 'zh-CN' && relativePath.endsWith('.mdx')) {
relativePath = relativePath.replace(/\.mdx$/, '');
}
return `${basePath}/${relativePath}`.replace(/\/\/+/g, '/');
}
function isBlacklisted(url) {
return blacklist.some(
(item) => url.endsWith(`/docs/${item}`) || url.endsWith(`/en/docs/${item}`)
);
}
function isEnFile(file) {
return file.endsWith('.en.mdx');
}
function isZhFile(file) {
return file.endsWith('.mdx') && !file.endsWith('.en.mdx');
}
async function generateToc() {
// 匹配所有 mdx 文件
const allFiles = await fg('../content/docs/**/*.mdx');
// 筛选中英文文件
const zhFiles = allFiles.filter(isZhFile);
const enFiles = allFiles.filter(isEnFile);
// 生成中文 URL
const zhUrls = zhFiles
.map((file) => filePathToUrl(file, 'zh-CN'))
.filter((url) => !isBlacklisted(url))
.sort();
// 生成英文 URL
const enUrls = enFiles
.map((file) => filePathToUrl(file, 'en'))
.filter((url) => !isBlacklisted(url))
.sort();
const makeMdxContent = (urls, title, isChinese = true) =>
`---
title: ${title}
description: ${isChinese ? 'FastGPT 文档目录' : 'FastGPT Toc'}
---
${urls.map((url) => `- [${url}](${url})`).join('\n')}
`;
// 写文件路径
const baseDir = path.resolve('../content/docs');
const zhOutputPath = path.join(baseDir, 'toc.mdx');
const enOutputPath = path.join(baseDir, 'toc.en.mdx');
// 写入文件
await fs.mkdir(baseDir, { recursive: true });
await fs.writeFile(zhOutputPath, makeMdxContent(zhUrls, 'FastGPT 文档目录', true), 'utf8');
await fs.writeFile(enOutputPath, makeMdxContent(enUrls, 'FastGPT Toc', false), 'utf8');
console.log(`✅ 写入中文目录 ${zhOutputPath}`);
console.log(`✅ 写入英文目录 ${enOutputPath}`);
}
generateToc().catch(console.error);
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
"format-code": "prettier --config \"./.prettierrc.js\" --write \"./**/src/**/*.{ts,tsx,scss}\"", "format-code": "prettier --config \"./.prettierrc.js\" --write \"./**/src/**/*.{ts,tsx,scss}\"",
"format-doc": "zhlint --dir ./document/ *.mdx --fix", "format-doc": "zhlint --dir ./document/ *.mdx --fix",
"initDocTime": "node ./document/github.js", "initDocTime": "node ./document/github.js",
"initDocToc": "node ./document/lib/generateToc.js",
"gen:theme-typings": "chakra-cli tokens packages/web/styles/theme.ts --out node_modules/.pnpm/node_modules/@chakra-ui/styled-system/dist/theming.types.d.ts", "gen:theme-typings": "chakra-cli tokens packages/web/styles/theme.ts --out node_modules/.pnpm/node_modules/@chakra-ui/styled-system/dist/theming.types.d.ts",
"postinstall": "pnpm gen:theme-typings", "postinstall": "pnpm gen:theme-typings",
"initIcon": "node ./scripts/icon/init.js", "initIcon": "node ./scripts/icon/init.js",
...@@ -45,6 +46,7 @@ ...@@ -45,6 +46,7 @@
"./document/**/**/*.mdx": [ "./document/**/**/*.mdx": [
"pnpm format-doc", "pnpm format-doc",
"pnpm initDocTime", "pnpm initDocTime",
"pnpm initDocToc",
"git add ." "git add ."
] ]
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment