This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Monday, 01 December 2025
如果你一直关注这个博客, 你可能会注意到我的主要博客平台是... 让我们把它称为“热心工程”。 PostgreSQL 和矢量数据库,语义和全文搜索 GIN 索引, 自动翻译成14种语言, 多个主机服务, 挂机工作时间安排, Prometheus 度量仪, Serilog 跟踪, HTMX 互动, 使用我自己的纽扣包, 以及足够多的多克容器 使船嫉妒。
这完全是故意的 这个网站是我的活实验室 一个操场 我在那里实验技术 测试部署策略 测量性能特征 假定 被过度设计,因为这就是我学习的方法: 通过解决大多数博客实际上并不存在的问题, 然后把这些解决方案包装成开放源码图书馆, 其他人也可以使用。
但事情是这样的: 你可能不需要 任何这些来运行一个博客。
这就是为什么我创造了 多数是混杂的。 最小的Blog 没有数据库,没有管道,没有复杂。只要在文件夹中标记文件,在网络上出现。这是博客在不将其作为实验室时的样子。
注:关于与来源的链接,见本条结尾部分,我计划将此作为附件1予以公布。 核金包包 一旦我得到时间确保它百分之百可靠, 而且它不是太可怕(所以尽快寻找 K6 测试物品! ) 。
整个项目是围绕一项原则设计的: 保持简单没有数据库,没有建设管道,没有 JavaScript 框架,只有 ASP.NET 9.0, 马克迪 用于加分分析, 还有大约500行代码总计。
注意:你甚至可以使用 标记自下调 然后只有服务器站点地图静态 .md 这个博客是 ASP. NET 博客(kinda sorta {。
让我们看看这个项目是如何组织的:
Mostlylucid.MinimalBlog/
├── Pages/
│ ├── Index.cshtml # Homepage with post list
│ ├── Post.cshtml # Individual post page
│ ├── Categories.cshtml # List of all categories
│ ├── Category.cshtml # Posts in a category
│ ├── _Layout.cshtml # Shared layout
│ ├── _ViewImports.cshtml # Shared imports
│ └── _ViewStart.cshtml # Layout selection
├── wwwroot/
│ └── css/
│ └── site.css # All the CSS you need
├── MarkdownBlogService.cs # Core blog logic
├── MetaWeblogService.cs # XML-RPC for external editors
├── Program.cs # Application setup
├── appsettings.json # Configuration
└── Mostlylucid.MinimalBlog.csproj # Project file
博客的核心是 MarkdownBlogService 类。非常简单,只是120行代码 处理:
以下是它是如何工作的:
服务扫描已配置的目录 .md 并把它们全部装入内存 :
private List<BlogPost> LoadAllPosts()
{
if (!Directory.Exists(_markdownPath)) return [];
return Directory.GetFiles(_markdownPath, "*.md", SearchOption.TopDirectoryOnly)
.Where(f => Path.GetFileName(f).Count(c => c == '.') == 1) // Only base .md files
.Select(ParseFile)
.Where(p => p is { IsHidden: false })
.OrderByDescending(p => p!.PublishedDate)
.ToList()!;
}
注意聪明的过滤: Count(c => c == '.') == 1 确保我们只有基础 .md 文件, 不是翻译版本的 post.ar.md 或 post.de.md (如果您想稍后添加译文)
每个标记文件遵循简单的常规 :
# Post Title
Your content here...
解析器使用正则表达式和 Markdig AST 提取此元数据 :
private BlogPost? ParseFile(string filePath)
{
var markdown = File.ReadAllText(filePath);
var slug = Path.GetFileNameWithoutExtension(filePath);
var document = Markdown.Parse(markdown, _pipeline);
// Extract title from first H1
var title = document.Descendants<HeadingBlock>()
.FirstOrDefault(h => h.Level == 1)?
.Inline?.FirstChild?.ToString() ?? slug;
// Extract categories:
var categoryMatch = CategoryRegex().Match(markdown);
var categories = categoryMatch.Success
? categoryMatch.Groups[1].Value.Split(',', StringSplitOptions.TrimEntries)
: [];
// Extract date:
var dateMatch = DateTimeRegex().Match(markdown);
var publishedDate = dateMatch.Success && DateTime.TryParse(dateMatch.Groups[1].Value, out var dt)
? dt : File.GetCreationTimeUtc(filePath);
return new BlogPost
{
Slug = slug,
Title = title,
Categories = categories,
PublishedDate = publishedDate,
HtmlContent = Markdown.ToHtml(markdown, _pipeline),
IsHidden = markdown.Contains("<hidden")
};
}
服务使用的每一种方法 IMemoryCache 以避免在每次请求时重读和重新标注文件:
public IReadOnlyList<BlogPost> GetAllPosts()
{
return cache.GetOrCreate("all_posts", entry =>
{
entry.SetOptions(CacheOptions);
return LoadAllPosts();
}) ?? [];
}
缓存条目有30分钟的滑动过期和2小时的绝对过期。 简单、 有效 。
整个应用程序设置只有43行: Razor Pages, 内存缓存, 输出缓存, 两个单通服务, 静态文件服务, 和一个 MetaWeblog XML- RPC 端点。 全部缓存为单通, 因为除非文件被修改, 否则不会发生任何变化 。
用户界面是纯服务器发送的 HTML 。 No JavaScript, no HTMX, no Alpine.js。 主页列表、 邮页 @Html.Raw(post.HtmlContent) 具有 a 和 [OutputCache] 小时 HTML 缓存属性。共四页,每行30行以下。
整个视觉设计由仅55行的单个 CSS 文件处理。 它使用 CSS 定制的特性处理这些设计, 并创建了干净、 黑暗的 GitHub 启发的外观 :
:root {
--bg: #0d1117;
--bg-card: #161b22;
--text: #c9d1d9;
--text-muted: #8b949e;
--accent: #58a6ff;
--border: #30363d;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.6;
max-width: 48rem;
margin: 0 auto;
padding: 2rem 1rem;
}
/* ... more styles ... */
没有预处理器,没有建筑步骤,没有数千个通用课程,只有干净的、可读的、有效的CSS。
对于那些喜欢专门减记编辑的作家来说 Markdown 怪物XML-RPC API允许外部编辑:
正在执行 MetaWeblogService.cs 并处理完整的 XML- RPC 协议, 解析请求和生成回复。 这意味着您可以在您最喜爱的编辑中写入您的博客文章, 并直接发布到您的博客中 。
整个配置文件只有 14 行 :
{
"MarkdownPath": "../Mostlylucid/Markdown",
"ImagesPath": "wwwroot/images",
"MetaWeblog": {
"Username": "admin",
"Password": "changeme",
"BlogUrl": "http://localhost:5000"
},
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}
MarkdownPath - 你的标记文件在哪里运行ImagesPath - 存放图像MetaWeblog - 外部编辑访问证书如上所述,它将提供但尚不能提供:)
这个博客现在以NuGet 软件包的形式提供,
dotnet add package mostlylucid.MinimalBlog
然后在你的 Program.cs:
builder.Services.AddRazorPages();
builder.Services.AddMinimalBlog(options =>
{
options.MarkdownPath = "Markdown";
options.ImagesPath = "wwwroot/images";
options.EnableMetaWeblog = false; // Optional, defaults to true
});
var app = builder.Build();
app.UseStaticFiles();
app.UseMinimalBlog();
app.MapRazorPages();
app.Run();
仅用两种方法调用(AddMinimalBlog 和 UseMinimalBlog你有一个工作博客。
管理包括样本项目:
cd Mostlylucid.MinimalBlog
dotnet run
访问访问访问访问 http://localhost:5000 你会看到这个博客 从配置路径上加了标记文件。
创建新博客文章:
.md 在您配置的文件中 MarkdownPath# Your Post Title
Your content here...
要添加图像,只需将其放在您的配置中 ImagesPath 并在您的标记中引用目录 :

这个最小的博客故意不包括:
这些特征都是 可能(可能) 添加,但是它们不是默认包含的, 因为大多数小博客都不需要它们。
尽管简简单简洁, 快速快速:
对于一个中小博客(不到1000个文章)来说,
使用使用 最优精华。 最小Blog 时间:
使用 完全最湿润的平台平台 时间:
在现代网络开发世界中,我们常常默认地寻求复杂的解决方案。 需要一个博客吗? 更好地建立数据库,配置ORM, 设置迁移, 添加缓存, 执行搜索, 配置背景工作...
但有时简单的解决办法是 右右右右右 MinimalBlog 证明您可以建立一个功能性、快速和可维护的博客平台, 包括:
那是 不到520行总代码 一个完整的博客平台。
此工程既是一个功能性博客平台,又是一个提醒: 在您添加复杂性之前, 请先问问自己是否真的需要它。 有时您需要的只是一个包含标记文件的文件夹 。
您可以在 The 中找到完整的源代码 最优精细化。 最小Blog 目录 我对密码一满意我就把金币包放出来
博客快乐!
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.