ArtCraft 新闻内容系统实战指南:基于 Markdown + Frontmatter 的博客文章发布与富媒体嵌入全解析
人工智能AI 应用媒体生成桌面应用【免费下载链接】artcraftArtCraft is an intentional crafting engine for artists, designers, and filmmakers项目地址https://gitcode.com/GitHub_Trending/ar/artcraft点击查看免费下载ArtCraftcrates/api_clients 所支撑的 AI 创作引擎在其前端提供了一套完整、开源的新闻/博客内容发布体系创作者只需在指定目录中放置带 YAML frontmatter 的.md文件构建脚本就会自动将其编译为news.json供应用内新闻列表、文章详情页与网站动态墙消费。本文以 NEWS_POSTS.md 为骨架结合generate-news-json.mjs构建脚本、markdown.ts渲染器与NewsIndex/NewsPost页面源码完整讲解文章创建、frontmatter 规范、构建流程以及youtube()、video()、image()等富媒体嵌入语法让你能够独立为 ArtCraft 应用发布图文并茂、支持视频/GIF 的新闻内容。一、内容体系概览从 Markdown 到 news.json 再到 UI新闻内容体系由三层组成全部位于 frontend/libs/markdown-content 与 frontend/scripts 下层位置职责内容源src/lib/content/news/*.md每篇新闻文章含 frontmatter 元数据与 Markdown 正文构建脚本generate-news-json.mjs扫描内容目录解析 frontmatter按日期降序输出news.json消费端NewsIndex/NewsPost/help-menu读取 JSON 渲染新闻列表与文章详情整体工作流原文档工作原理的 5 个步骤均可从源码逐一印证generate-news-json.mjs 读取../libs/markdown-content/src/lib/content/news下所有.md文件通过内置的parseFrontmatter解析 YAML 头与正文生成按日期新到旧排序的 JSON 数组见第 56-60 行sortnew Date(b.date).getTime() - new Date(a.date).getTime()写入网站public/目录下的news.json应用通过fetch或打包数据消费该 JSON 渲染新闻流。二、创建一篇新闻文章目录、命名与 Frontmatter 规范2.1 存放位置与文件命名所有新闻文章必须放在frontend/libs/markdown-content/src/lib/content/news/目录下仓库中现有示例welcome.md 与 world-models-for-film.md。文件命名遵循URL-friendly原则文件名去掉.md后缀会直接成为文章的 URL slug例如my-new-feature.md对应/news/my-new-feature。这一逻辑在 generate-news-json.mjs 中体现为const slug filename.replace(/\.md$/, )在 content.ts 中体现为pathToFilenamemarkdown.ts中的 slugify 函数还提供了将标题转成 slug 的备用实现小写化、空白/下划线转-、剔除非法字符、合并连续连字符。2.2 Frontmatter 模板原文档完整继承每篇.md文件顶部必须包含如下 YAML frontmatter--- title: Your Post Title abstract: A brief description of the post (shown in the news list) date: YYYY-MM-DD thumbnail: https://optional-image-url.com/image.png ---字段说明原文档字段表完整保留字段是否必填说明title是显示在新闻列表与文章头部的标题abstract是新闻列表预览中显示的短描述date是发布日期格式YYYY-MM-DDthumbnail否可选的头部图片 URL解析细节与源码对照parseFrontmattergenerate-news-json.mjs 与 markdown.ts 中各有等价实现按如下规则工作以---\n开头才视为含 frontmatter否则整篇都作为正文body以\n---\n定位 frontmatter 结束边界逐行按第一个:切分 key/value自动去除首尾空白自动剥离 value 外层单双引号.../...统一处理\r\n为\n兼容 Windows 换行。因此abstract等值即使不加引号也能正确解析但包含冒号的长文本建议仍加引号以规避:截断问题。2.3 一篇完整示例文章原文档示例继承并保留--- title: Welcome to the ArtCraft Blog abstract: We are excited to launch our new blog where we will share updates and tutorials. date: 2026-01-16 thumbnail: https://example.com/blog-header.png --- # Hello World! Welcome to the official **ArtCraft Blog**. This is where well be posting about: - **New Features**: Be the first to know about the latest tools. - **Tutorials**: Learn how to get the most out of ArtCraft. - **Community Showcases**: Highlighting amazing work created by our users. ## Stay Tuned We have a lot of exciting things in the pipeline!仓库中已落地的真实范例 welcome.md 与示例几乎一致world-models-for-film.md 则是一篇实战级长文同时使用了youtube()、loop_autoplay()与 markdown 图片语法是学习富媒体嵌入的最佳参考。三、构建新闻流自动构建与手动构建3.1 开发服务器自动构建原文档给出的自动方式是在 dev server 下运行npx nx dev artcraft-website需要注意当前仓库快照的实际布局前端应用目录为frontend/apps/artcraft其package.json中dev脚本为vite dev且脚本 generate-news-json.mjs 中OUTPUT_FILE指向../apps/artcraft-website/public/news.json——运行构建脚本时会通过fs.mkdirSync(outputDir, { recursive: true })自动创建缺失目录。因此若artcraft-website应用不在本地建议直接采用下面的手动构建方式输出结果同样可被消费端读取。3.2 手动构建推荐在仓库根目录执行cd frontend node scripts/generate-news-json.mjs脚本成功后会输出提示Generated news.json at .../apps/artcraft-website/public/news.json with N posts.其中N为扫描到的文章数量。脚本还包含一个健壮性检查若新闻目录不存在会打印News directory not found: ...并以退出码 1 终止generate-news-json.mjs避免静默产出空 JSON。3.3 输出文件格式生成的news.json是JSON.stringify(posts, null, 2)美化后的数组每个元素结构如下对应 generate-news-json.mjs 的字段映射[ { slug: welcome, title: Welcome to the ArtCraft Blog, description: We are excited to launch our new blog..., date: 2026-01-16, thumbnail: https://example.com/blog-header.png, body: # Hello World!\n\nWelcome to the official **ArtCraft Blog**... } ]注意映射关系frontmatter 的abstract在 JSON 中输出为description字段thumbnail为空时输出undefinedJSON 序列化后该字段会被省略。排序上只有两条记录都有date时才参与日期比较缺失日期的记录保持原扫描顺序。四、消费端原理新闻在应用内如何被读取与渲染4.1 打包数据bundled与运行时拉取fetch双通道在应用侧新闻有两条加载路径均可从源码印证打包数据content.ts 使用 Vite 的import.meta.glob(../content/news/*.md, { query: ?raw, eager: true })在构建期把所有 Markdown 原文打包进产物再由getNewsPosts()统一解析、排序getNewsPostBySlug(slug)按 slug 查找单篇content.ts。运行时拉取help-menu.tsx 中的NewsView组件先以getNewsPosts()作为兜底数据随后异步fetch(${baseUrl}/news.json)尝试拉取最新内容开发环境baseUrl为http://localhost:4200生产环境为https://getartcraft.com请求失败时仅console.warn并回退到打包数据。4.2 列表页与详情页NewsIndex.tsx 渲染新闻列表遍历getNewsPosts()每项展示title、date与description点击通过Link跳转到${basePath}/${item.slug}列表为空时显示 No updates yet. Check back soon!。NewsPost.tsx 渲染单篇通过useParams或propSlug获取 slug用useMemo(() markdownToHtml(post.body), [post])将正文转 HTML再以dangerouslySetInnerHTML注入article-content容器页内style块为渲染出的 HTML 提供了完整的排版样式h1-h4、段落、列表、引用块、代码块、图片圆角边框等其中.youtube-embed通过padding-bottom: 56.25%实现 16:9 自适应 iframe。五、富媒体嵌入语法全解原文档语法 渲染器源码级剖析所有自定义语法均由 markdown.ts 中的markdownToHtml()逐行解析。理解解析规则有助于规避语法写了却不生效的坑这些指令要求独占一行ltrim匹配后无多余字符且优先于普通段落处理。5.1 YouTube 视频youtube()支持传入视频 ID 或完整 URL原文档三种写法均有效youtube(dQw4w9WgXcQ) youtube(https://www.youtube.com/watch?vdQw4w9WgXcQ) youtube(https://youtu.be/dQw4w9WgXcQ)渲染器extractYouTubeIdmarkdown.ts按以下优先级提取 ID输入本身即为 11 位[a-zA-Z0-9_-]的裸 ID直接返回匹配 URL 正则youtube.com/watch?v、youtu.be/、youtube.com/embed/、youtube.com/v/匹配youtube.com/shorts/短片格式。最终渲染为带allowaccelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share的响应式 iframe若无法提取 ID会输出pInvalid YouTube video: .../p占位而非报错。5.2 普通视频video()支持 mp4、webm 等格式URL 可绝对可相对video(https://example.com/my-video.mp4) video(/videos/demo.webm)解析逻辑isVideoUrl依据扩展名白名单[.mp4, .webm, .ogg, .mov, .m4v, .avi]判断markdown.tsURL 先去 query 再判扩展名getVideoMimeType决定source的 type——.webm→webm、.ogg→ogg、.mov/.m4v→mp4其余默认mp4markdown.ts。5.3 循环自动播放视频loop_autoplay()这是原文档示例文章 world-models-for-film.md 中实际使用的语法文中用三条循环播放视频展示 World Model 生成的场景。渲染为带autoplay loop muted playsinline属性的video——muted是浏览器允许自动播放的必要条件loop_autoplay(https://example.com/demo.mp4)5.4 标准 Markdown 图片语法 管道符尺寸在原文档中图片尺寸通过|管道符追加在 URL 后 渲染器会将urlAndSize.split(|)拆出 URL 与尺寸markdown.ts若检测到视频扩展名则自动转成视频嵌入——这也是用图片语法嵌入视频的原理原文档Regular Videos一节提到的方式。对于独占一行的图片语法走的是另一个分支markdown.ts同样支持|尺寸与视频自动识别。5.5 专用标签image()与gif()image(https://example.com/image.png, 300) gif(https://example.com/animation.gif, 400x300)由正则^(image|gif)\(([^,)])(?:,\s*([^)]))?\)$匹配markdown.ts注意参数用英文逗号分隔URL 内不应包含逗号。5.6 尺寸格式与渲染细节支持三种尺寸写法原文档完整继承仅宽度300默认单位像素或50%宽高同时指定400x300。底层parseSizemarkdown.ts将字符串按x拆分为宽/高renderImagemarkdown.ts进一步处理数值自动补px后缀%/px原样保留默认行为不指定尺寸时图片占容器宽度100%且所有图片有max-width: 100%约束以防溢出博客容器自动居中当宽度小于 100%即显式指定了更小尺寸时通过margin-left/right: auto自动水平居中附带默认样式border-radius: 0.75rem、白色 10% 透明度描边、上下2rem外边距。六、发布实战 Tips原文档完整继承文件名即 Slug文件名不含.md就是文章 URL发布前务必确定好稳定、可读的 slug自动排序新闻流按date从新到旧排序无需手动维护顺序generate-news-json.mjs 与 content.ts 中均有实现完整 Markdown 支持标题、列表、粗体、斜体、引用块、图片、代码块均可正常渲染行内渲染器renderInlinemarkdown.ts支持**粗体**、*斜体*、行内图片与链接链接自动套用下划线 hover 样式热重载新增/修改文章后需重启 dev server或手动运行一次node scripts/generate-news-json.mjs重新生成news.jsonhelp-menu 中的NewsView每次打开都会重新 fetch因此手动生成后即可看到最新内容。七、结语一条写作 → 构建 → 渲染的完整发布链路ArtCraft 的新闻系统是一套把内容创作与前端渲染解耦的轻量方案内容侧只需维护结构化的 Markdown frontmatter构建侧由 generate-news-json.mjs 完成解析、排序与序列化渲染侧由 markdown.ts 的解析器将标准 Markdown 与youtube/video/loop_autoplay/image等专用语法统一转换为受控的 HTML最终通过 NewsIndex、NewsPost 或 help-menu 的 NewsView 呈现给用户。掌握了本文所述的 frontmatter 规范、构建命令与富媒体语法你就可以像维护普通 Markdown 文档一样持续为 ArtCraft 应用输出图文并茂、支持视频演示的新闻与博客内容。赞分享人工智能AI 应用媒体生成桌面应用【免费下载链接】artcraftArtCraft is an intentional crafting engine for artists, designers, and filmmakers项目地址https://gitcode.com/GitHub_Trending/ar/artcraft点击查看免费下载相关推荐wxParse智慧媒体新闻内容的富文本发布系统wxParse智慧媒体新闻内容的富文本发布系统 痛点直击小程序富文本发布的5大核心难题 你是否还在为微信小程序中的富文本展示而头疼作为新闻媒体从业者你可小程序移动开发富文本前端NiceGUI内容管理系统终极指南快速构建博客与新闻发布平台NiceGUI内容管理系统终极指南快速构建博客与新闻发布平台 想要用Python快速搭建功能完整的博客系统或新闻发布平台吗NiceGUI内容管理系统正是你需前端Web框架UI组件使用 Gatsby Starter Blog 编写 Markdown 博客文章frontmatter 与正文渲染实战使用 Gatsby Starter Blog 编写 Markdown 博客文章frontmatter 与正文渲染实战 本文以 Gatsby 官方博客起始模板前端静态站点Web框架上一篇QRemeshify终极指南5分钟掌握Blender四边面重构神器下一篇2025年最新B站视频下载工具完整使用指南轻松获取4K高清资源创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考