Als je deze blog hebt gevolgd, heb je misschien gemerkt dat mijn belangrijkste blogplatform is... Laten we het "enthousiastly engineered" noemen. PostgreSQL EN vector databases, semantisch EN full-text zoeken met GIN indexen, geautomatiseerde vertaling naar 14 talen, meerdere gehoste diensten, Hangfire job planning, Prometheus metrics, Serilog traceren, HTMX interacties, usign mijn eigen nuget pakketten, en genoeg Docker containers om een schip jaloers te maken.
Dat is volledig opzettelijk. Deze site is mijn living lab - een speeltuin waar ik experimenteer met technologieën, testen implementatie strategieën, het meten van de prestaties kenmerken, en het bouwen van herbruikbare pakketten. verondersteld Om te worden over-ontworpen omdat dat is hoe ik leer: door het oplossen van problemen die de meeste blogs niet hebben, dan het verpakken van die oplossingen als open-source bibliotheken kunnen anderen gebruiken.
Maar het zit zo: Je hebt waarschijnlijk niets van dat nodig om een blog uit te voeren.
Dat is waarom ik creëerde meestal lucid.minimalBlog - om te laten zien wat er gebeurt als je alle experimenten weghaalt en je focust op de absolute essentials. Geen database. Geen bouwpijplijn. Geen complexiteit. Gewoon bestanden markeren in een map die op het web verschijnt. Dit is hoe een blog eruit ziet als je het niet als laboratorium gebruikt.
OPMERKING: Zie het einde van het artikel voor een link naar de bron, Ik ben van plan om dit vrij te geven als een nuget-pakket Zodra ik tijd heb om ervoor te zorgen dat het 100% betrouwbaar is en het perf is niet TOO verschrikkelijk (dus zoek snel naar k6 testartikelen!).
Het hele project is ontworpen rond één principe: Hou het simpel.. Geen database, geen build pipeline, geen JavaScript framework. Gewoon ASP.NET 9.0, Markdig voor markdown parsing, en ongeveer 500 regels code totaal. Dat is het.
OPMERKING: U kunt zelfs doen deze client kant door gebruik te maken van de likes van markdown-it dan gewoon de server site kaart statische .md bestanden en maak het zelfs SIMPLER, maar... nou dit is een ASP.NET blog (een soort van).
Laten we eens kijken naar hoe het project wordt georganiseerd:
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
De kern van de blog is de MarkdownBlogService Het is opmerkelijk eenvoudig... 120 regels code die hanteren:
Dit is hoe het werkt:
De service scant een geconfigureerde map voor .md bestanden en laadt ze allemaal in het geheugen:
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()!;
}
Let op de slimme filtering: Count(c => c == '.') == 1 zorgt ervoor dat we alleen honk krijgen .md bestanden, niet vertaalde versies zoals post.ar.md of post.de.md (voor het geval u later vertalingen wilt toevoegen).
Elk markdown-bestand volgt een eenvoudige conventie:
# Post Title
Your content here...
De parser haalt deze metadata uit met behulp van reguliere expressies en de 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")
};
}
Elke methode in de service gebruikt IMemoryCache om te voorkomen dat bestanden opnieuw worden gelezen en opnieuw worden verwerkt op elk verzoek:
public IReadOnlyList<BlogPost> GetAllPosts()
{
return cache.GetOrCreate("all_posts", entry =>
{
entry.SetOptions(CacheOptions);
return LoadAllPosts();
}) ?? [];
}
Cache-inzendingen hebben een 30 minuten sliding expiration en 2 uur absolute vervaldatum. Eenvoudig, effectief.
De gehele applicatie setup is slechts 43 regels: Razor Pages, geheugen cache, output cache, twee singleton diensten, statische bestand dienen, en een MetaWeblog XML-RPC eindpunt. Alles gecached als singletons omdat er niets verandert tenzij bestanden worden gewijzigd.
De UI is pure server-rendered HTML. Geen JavaScript, geen HTMX, geen Alpine.js. De homepage bevat berichten, de postpagina rendert @Html.Raw(post.HtmlContent) met een [OutputCache] attribuut voor urenlange HTML-caching. Vier pagina's totaal, elk onder 30 regels.
Het volledige visuele ontwerp wordt behandeld door een enkel CSS-bestand met slechts 55 lijnen. Het maakt gebruik van CSS aangepaste eigenschappen voor hening en creëert een schone, donkere GitHub-geïnspireerde look:
: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 ... */
Geen preprocessor. Geen bouwstap. Geen duizenden hulpprogramma's. Alleen schone, leesbare CSS die werkt.
Voor schrijvers die de voorkeur geven aan speciale markdown editors zoals Monster markeren, het project bevat een volledige MetaWeblog API-implementatie. Deze XML-RPC API laat externe editors toe om:
De tenuitvoerlegging vindt plaats in de loop van het jaar. MetaWeblogService.cs en behandelt het volledige XML-RPC protocol, het verwerken van verzoeken en het genereren van antwoorden. Dit betekent dat u uw blogberichten kunt schrijven in uw favoriete editor en ze direct kunt publiceren naar uw blog.
Het hele configuratiebestand is slechts 14 regels:
{
"MarkdownPath": "../Mostlylucid/Markdown",
"ImagesPath": "wwwroot/images",
"MetaWeblog": {
"Username": "admin",
"Password": "changeme",
"BlogUrl": "http://localhost:5000"
},
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}
MarkdownPath - waar uw markdown bestanden wonenImagesPath - waar afbeeldingen worden opgeslagenMetaWeblog - referenties voor externe editor toegangZoals hierboven vermeld zal het spoedig beschikbaar zijn, maar nog niet:)
De blog is nu beschikbaar als een NuGet pakket, waardoor het triviaal om toe te voegen aan een ASP.NET Core applicatie:
dotnet add package mostlylucid.MinimalBlog
Dan in uw 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();
Dat is het - slechts twee methode oproepen (AddMinimalBlog en UseMinimalBlog) en je hebt een werkende blog.
Om het meegeleverde steekproefproject uit te voeren:
cd Mostlylucid.MinimalBlog
dotnet run
Bezoek http://localhost:5000 en je ziet de blog met markdown bestanden van het geconfigureerde pad.
Om een nieuwe blogpost aan te maken:
.md bestand in uw geconfigureerd MarkdownPath# Your Post Title
Your content here...
Om afbeeldingen toe te voegen, plaatst u ze gewoon in uw geconfigureerd ImagesPath directory en referentie ze in uw markdown:

Deze minimale blog bevat niet opzettelijk:
Deze functies zijn allemaal mogelijk toe te voegen, maar ze zijn niet standaard opgenomen omdat de meeste kleine blogs ze niet nodig hebben.
Ondanks zijn eenvoud, deze blog is snel:
Voor een kleine tot middelgrote blog (onder 1000 berichten) zal deze architectuur de meeste door databases ondersteunde blogplatforms overtreffen.
Gebruik Meestal lucid.MinimalBlog wanneer:
Gebruik de volledige meest lucide platform wanneer:
In de moderne web development wereld, bereiken we vaak standaard complexe oplossingen. Heb je een blog nodig? Beter een database opzetten, een ORM configureren, migraties instellen, caching toevoegen, zoeken implementeren, achtergrondtaken configureren...
Maar soms is de eenvoudige oplossing de rechts oplossing. Meestallucid.MinimalBlog bewijst dat u een functionele, snelle en onderhoudbare blog platform kunt bouwen met:
Dat is minder dan 520 regels code totaal voor een compleet blogplatform.
Het project dient als zowel een functioneel blogplatform als een herinnering: voordat je complexiteit toevoegt, vraag jezelf af of je het echt nodig hebt. Soms is een map vol markdown-bestanden alles wat je nodig hebt.
U kunt de volledige broncode vinden in de Meestallucid.MinimalBlog directory Ik zal het nuget pakket vrijgeven zodra ik tevreden ben met de code.
Gelukkig bloggen!
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.