[{"data":1,"prerenderedAt":410},["ShallowReactive",2],{"page-/post/frame/contentlayer-md-metadata":3,"surrounding-page":401},{"id":4,"title":5,"author":6,"body":7,"date":389,"description":13,"extension":390,"group":6,"lastmod":391,"meta":392,"navigation":393,"path":394,"rawbody":395,"seo":396,"showTitle":5,"stem":397,"tags":398,"versions":6,"__hash__":400},"content/post/frame/contentlayer-md-metadata.md","【contentlayer】兼容不同的md文件metadata的字段",null,{"type":8,"value":9,"toc":387},"minimark",[10,14,17,29,32,43,46,53,64,75,86,188,191,334,337,370,377,380,383],[11,12,13],"p",{},"markdown顶部可以设置一组元数据，用于解析成作者，发布日期，简介等信息",[11,15,16],{},"使用过多种Markdown编辑器以及多种博客框架的人都知道，每个框架使用的字段有可能不太一样。",[11,18,19,20,24,25,28],{},"比如简介。有的用的是",[21,22,23],"code",{},"description","，有的用的是",[21,26,27],{},"summary","。",[11,30,31],{},"如果你在一款md编辑器中写好了一篇文章，这篇文章被你使用Astro的某模板进行开发和部署，后面你又换了其他的框架，比如NextJS，结果新框架使用的matedata是不一样的，而你又有那么多的文章需要搬运。这无疑是一件很头疼的事。",[11,33,34,35,38,39,38,41,28],{},"虽然作为一个程序员，可以自己写一个脚本，批量的把matadata修改一下，再放在某一个文件夹内，但这就明显会造成一种心智负担：很快你就会混淆，一篇文章的简介到底该写",[21,36,37],{},"desc","，还是",[21,40,23],{},[21,42,27],{},[11,44,45],{},"所以，我希望可以是不关心文章的简介用什么字段表示，只管写文章就好了。",[11,47,48,49,52],{},"于是乎，我就调研了一下",[21,50,51],{},"contentlayer","的文档，把自己手头的模板稍稍改动一下，用来支持多种字段表示同一个信息",[11,54,55,56,59,60,63],{},"我目前在用的",[21,57,58],{},"NextJS","博客模板是",[21,61,62],{},"Tailwind Nextjs Starter Blog","，所以我以这个为例",[11,65,66,67,70,71,74],{},"在",[21,68,69],{},"contentlayer.config.ts","中，有一个",[21,72,73],{},"computedFields","的配置",[11,76,77,78,81,82,85],{},"假如我有些文章发布时期用的 ",[21,79,80],{},"date","， 有些用的 ",[21,83,84],{},"published","，那就可以这样配置",[87,88,93],"pre",{"className":89,"code":90,"language":91,"meta":92,"style":92},"language-typescript shiki shiki-themes github-light","const computedFields: ComputedFields = {\n    // ...\n    showDate: {\n        type: 'date',\n        resolve: (doc) => doc.date || doc.published,\n    }\n}\n","typescript","",[21,94,95,122,129,135,148,176,182],{"__ignoreMap":92},[96,97,100,104,108,111,115,118],"span",{"class":98,"line":99},"line",1,[96,101,103],{"class":102},"sD7c4","const",[96,105,107],{"class":106},"sYu0t"," computedFields",[96,109,110],{"class":102},":",[96,112,114],{"class":113},"s7eDp"," ComputedFields",[96,116,117],{"class":102}," =",[96,119,121],{"class":120},"sgsFI"," {\n",[96,123,125],{"class":98,"line":124},2,[96,126,128],{"class":127},"sAwPA","    // ...\n",[96,130,132],{"class":98,"line":131},3,[96,133,134],{"class":120},"    showDate: {\n",[96,136,138,141,145],{"class":98,"line":137},4,[96,139,140],{"class":120},"        type: ",[96,142,144],{"class":143},"sYBdl","'date'",[96,146,147],{"class":120},",\n",[96,149,151,154,157,161,164,167,170,173],{"class":98,"line":150},5,[96,152,153],{"class":113},"        resolve",[96,155,156],{"class":120},": (",[96,158,160],{"class":159},"sqxcx","doc",[96,162,163],{"class":120},") ",[96,165,166],{"class":102},"=>",[96,168,169],{"class":120}," doc.date ",[96,171,172],{"class":102},"||",[96,174,175],{"class":120}," doc.published,\n",[96,177,179],{"class":98,"line":178},6,[96,180,181],{"class":120},"    }\n",[96,183,185],{"class":98,"line":184},7,[96,186,187],{"class":120},"}\n",[11,189,190],{},"同时，在Fileds里加入这两种字段",[87,192,194],{"className":89,"code":193,"language":91,"meta":92,"style":92},"export const Blog = defineDocumentType(() => ({\n    name: 'Blog',\n    filePathPattern: 'blog/**/*.mdx',\n    contentType: 'mdx',\n    fields: {\n        title: { type: 'string', required: true },\n        date: { type: 'date', required: true },\n        published: { type: 'date', required: false },\n        // ...\n    },\n    computedFields: {\n        // ...\n    },\n}))\n",[21,195,196,220,230,240,250,255,272,285,300,306,312,318,323,328],{"__ignoreMap":92},[96,197,198,201,204,207,209,212,215,217],{"class":98,"line":99},[96,199,200],{"class":102},"export",[96,202,203],{"class":102}," const",[96,205,206],{"class":106}," Blog",[96,208,117],{"class":102},[96,210,211],{"class":113}," defineDocumentType",[96,213,214],{"class":120},"(() ",[96,216,166],{"class":102},[96,218,219],{"class":120}," ({\n",[96,221,222,225,228],{"class":98,"line":124},[96,223,224],{"class":120},"    name: ",[96,226,227],{"class":143},"'Blog'",[96,229,147],{"class":120},[96,231,232,235,238],{"class":98,"line":131},[96,233,234],{"class":120},"    filePathPattern: ",[96,236,237],{"class":143},"'blog/**/*.mdx'",[96,239,147],{"class":120},[96,241,242,245,248],{"class":98,"line":137},[96,243,244],{"class":120},"    contentType: ",[96,246,247],{"class":143},"'mdx'",[96,249,147],{"class":120},[96,251,252],{"class":98,"line":150},[96,253,254],{"class":120},"    fields: {\n",[96,256,257,260,263,266,269],{"class":98,"line":178},[96,258,259],{"class":120},"        title: { type: ",[96,261,262],{"class":143},"'string'",[96,264,265],{"class":120},", required: ",[96,267,268],{"class":106},"true",[96,270,271],{"class":120}," },\n",[96,273,274,277,279,281,283],{"class":98,"line":184},[96,275,276],{"class":120},"        date: { type: ",[96,278,144],{"class":143},[96,280,265],{"class":120},[96,282,268],{"class":106},[96,284,271],{"class":120},[96,286,288,291,293,295,298],{"class":98,"line":287},8,[96,289,290],{"class":120},"        published: { type: ",[96,292,144],{"class":143},[96,294,265],{"class":120},[96,296,297],{"class":106},"false",[96,299,271],{"class":120},[96,301,303],{"class":98,"line":302},9,[96,304,305],{"class":127},"        // ...\n",[96,307,309],{"class":98,"line":308},10,[96,310,311],{"class":120},"    },\n",[96,313,315],{"class":98,"line":314},11,[96,316,317],{"class":120},"    computedFields: {\n",[96,319,321],{"class":98,"line":320},12,[96,322,305],{"class":127},[96,324,326],{"class":98,"line":325},13,[96,327,311],{"class":120},[96,329,331],{"class":98,"line":330},14,[96,332,333],{"class":120},"}))\n",[11,335,336],{},"然后再去修改date的文件里，可以边看页面边调试",[338,339,340,351,360],"ul",{},[341,342,343,344,347,348],"li",{},"把相应的 ",[21,345,346],{},"post.date"," 改为 ",[21,349,350],{},"post.showDate",[341,352,353,354,347,357],{},"把 ",[21,355,356],{},"const { date } = post",[21,358,359],{},"const { showDate } = post",[341,361,362,363,365,366,369],{},"然后再把",[21,364,80],{},"插入的内容处，替换为",[21,367,368],{},"showDate","即可",[11,371,372,376],{},[373,374,375],"strong",{},"确保替换完","上述内容之后，你就可以随意在其他md编辑器中使用你设置好的多种字段了",[11,378,379],{},"有任何问题，欢迎咨询。",[11,381,382],{},"👋🏻👋🏻",[384,385,386],"style",{},"html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":92,"searchDepth":124,"depth":124,"links":388},[],"2024-08-18T00:00:00.000Z","md","2025-08-19T00:00:00.000Z",{},true,"/post/frame/contentlayer-md-metadata","---\ndate: 2024-08-18\nlastmod: 2025-08-19\ntitle: 【contentlayer】兼容不同的md文件metadata的字段\nshowTitle: 【contentlayer】兼容不同的md文件metadata的字段\ntags: [\"Next\"]\n\n---\nmarkdown顶部可以设置一组元数据，用于解析成作者，发布日期，简介等信息\n\n使用过多种Markdown编辑器以及多种博客框架的人都知道，每个框架使用的字段有可能不太一样。\n\n比如简介。有的用的是`description`，有的用的是`summary`。\n\n如果你在一款md编辑器中写好了一篇文章，这篇文章被你使用Astro的某模板进行开发和部署，后面你又换了其他的框架，比如NextJS，结果新框架使用的matedata是不一样的，而你又有那么多的文章需要搬运。这无疑是一件很头疼的事。\n\n虽然作为一个程序员，可以自己写一个脚本，批量的把matadata修改一下，再放在某一个文件夹内，但这就明显会造成一种心智负担：很快你就会混淆，一篇文章的简介到底该写`desc`，还是`description`，还是`summary`。\n\n所以，我希望可以是不关心文章的简介用什么字段表示，只管写文章就好了。\n\n于是乎，我就调研了一下`contentlayer`的文档，把自己手头的模板稍稍改动一下，用来支持多种字段表示同一个信息\n\n我目前在用的`NextJS`博客模板是`Tailwind Nextjs Starter Blog`，所以我以这个为例\n\n在`contentlayer.config.ts`中，有一个`computedFields`的配置\n\n假如我有些文章发布时期用的 `date`， 有些用的 `published`，那就可以这样配置\n\n```typescript\nconst computedFields: ComputedFields = {\n    // ...\n    showDate: {\n        type: 'date',\n        resolve: (doc) => doc.date || doc.published,\n    }\n}\n```\n\n同时，在Fileds里加入这两种字段\n\n```typescript\nexport const Blog = defineDocumentType(() => ({\n    name: 'Blog',\n    filePathPattern: 'blog/**/*.mdx',\n    contentType: 'mdx',\n    fields: {\n        title: { type: 'string', required: true },\n        date: { type: 'date', required: true },\n        published: { type: 'date', required: false },\n        // ...\n    },\n    computedFields: {\n        // ...\n    },\n}))\n```\n\n然后再去修改date的文件里，可以边看页面边调试\n\n- 把相应的 `post.date` 改为 `post.showDate` \n- 把 `const { date } = post` 改为 `const { showDate } = post`\n- 然后再把`date`插入的内容处，替换为`showDate`即可\n\n**确保替换完**上述内容之后，你就可以随意在其他md编辑器中使用你设置好的多种字段了\n\n有任何问题，欢迎咨询。\n\n👋🏻👋🏻",{"title":5,"description":13},"post/frame/contentlayer-md-metadata",[399],"Next","PUB8-fzafMfIzcjKfwA_h3BbkA-gOQhNx_krB2IUPtE",[402,406],{"title":403,"path":404,"stem":405},"OpenClaw 安装入门（Windows）","/post/zzao/openclaw/openclaw-install-windows","post/zzao/openclaw/openclaw-install-windows",{"title":407,"path":408,"stem":409},"假设你是AI，你的Skill应该是什么样的","/post/zzao/ai-skill-structure","post/zzao/ai-skill-structure",1779005086746]