Back to "three locid. MinimalBlog - Наскільки простим може бути блог ASP. NET?"

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

ASP.NET Blogging Markdown

three locid. MinimalBlog - Наскільки простим може бути блог ASP. NET?

Monday, 01 December 2025

Вступ

Якщо ви стежите за цим блогом, ви, можливо, помітили, що моя основна платформа... назвемо її "спроектованою" "з ентузіазмом." Бази даних PostgreSQL і векторні бази даних, семантичний і повнотекстовий пошук з індексами GIN, автоматичним перекладом на 14 мов, багатьма серфінговими службами, плануванням роботи Hangfire, метричними стандартами Promeus, серілогічним слідкуванням, взаємодією HTMX, усування власних пакунків з noget, і достатньо контейнерів Docker, щоб змусити корабель заздрити.

Це цілком навмисно. Цей сайт - це моя жива лабораторія, де я експериментую з технологіями, тестовими стратегіями, вимірюю характеристики швидкодії та будую придатні пакунки. гадана бути переінструктаженим, тому що саме так я вчуся: вирішенням проблем, яких більшість блогів насправді не мають, а потім пакувати ці рішення як бібліотеки з відкритим кодом, які можуть використовувати інші.

Але ось в чому справа: Вам, мабуть, нічого з цього не потрібно для ведення блогу.

Ось чому я створив threelucid. MinimalBlog - щоб побачити, що відбувається, коли ви позбуваєтеся всіх експериментів і зосередитесь на абсолютно важливих програмах. Немає бази даних. Без складності. Просто позначте файли у теці, що з' являються у мережі. Ось так виглядає блог, якщо ви не використовуєте його як лабораторію.

ЗАУВАЖЕННЯ: ви можете прочитати в кінці статті посилання на джерело, я планую видати його як Пакунок nuget як тільки я отримаю час, щоб переконатися, що він на 100% надійний, і він не є TOO жахливою (так що пошукайте статті для тестування k6 найближчим часом!).

Філософія: Менше є

Весь проект розроблено навколо одного принципу: зробити це просто. Без бази даних, без трубопроводу для збирання, без оболонки JavaScript. Тільки ASP. NET 9. 0, Markdig для обробки з міткою і близько 500 рядків коду загалом. ЗАУВАЖЕННЯ: Ви навіть можете зробити цей клієнт поруч, використовуючи подібні типи markdown- it а потім просто залишити статичну карту сайта сервера .md files і make it even SIMPLER but... well this is a ASP.NET blog (cana shose a ⇩).

Структура проекту

Погляньмо, як організовано цей проект:

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

Серце: Помітка внизу BlogService

Основою блогу є MarkdownBlogService Клас. Це на диво прості 120 рядків коду, які працюють над:

  1. Читання файлів з каталогу з міткою
  2. Аналіз метаданих (напис, категорії, дата оприлюднення)
  3. Перетворення розмітки у HTML за допомогою Markdig
  4. Зафіксовування всього у пам' яті

Ось як це працює:

Завантаження дописів

Служба сканує налаштований каталог для .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...

Обробник видобуває ці метадані за допомогою формальних виразів і AST Markdig:

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- годинний абсолютний термін. Просте, ефективне.

Налаштування програми: Program.cs

Все налаштування програми складається лише з 43 рядків: Сторінок Razor, кешу пам' яті, кешу виводу, двох служб однотонів, статичних файлів і кінцевої точки XML- RPC. Все кешовано як однотони, оскільки нічого не змінюється, якщо не буде змінено файли.

Інтерфейс користувача: прості сторінки Razor

UI - це чистий HTML, що виконується сервером. Немає JavaScript, немає HTMX, немає альпійських. js. Домівки - це дописи на домашній сторінці @Html.Raw(post.HtmlContent) з an [OutputCache] attribute для годинного кешування HTML. Загалом чотири сторінки, кожна з яких менша за 30 рядків.

Стилінг: 55 рядків CSS

У всьому візуальному дизайні працює лише один файл CSS з 55 рядками. Програма використовує нетипові властивості 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, який працює.

Можливість бонуса: MetaWeblog API

Для авторів, які надають перевагу призначеному редакторам з маркуванням, на зразок Markdown Monster, Проект складається з повнофункціональної реалізації API MetaWeblog. Цей API XML- RPC дозволяє зовнішні редактори:

  • Список дописів
  • Створити дописи
  • Редагування існуючих дописів
  • Вилучити дописи
  • Вивантажити зображення
  • Отримати категорії

Реалізація в 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 - там, де живуть ваші файли markdown
  • ImagesPath - де зберігаються зображення
  • MetaWeblog - реєстраційні дані для доступу до зовнішнього редактора

Використання як пакунка NuGet

Як згадувалося вище, SOON буде доступний, але ще не:)

Тепер блог доступний як пакунок NuGet, що робить тривіальним додавання до будь- якої програми ASP. NET:

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 і ви побачите блог з позначенням файлів за вказаним шляхом.

Створення вмісту

Для створення допису блогу:

  1. Створити новий .md файл у налаштованому вами файлі MarkdownPath
  2. Додати стандартні метадані:
    # Your Post Title
    
    
    
    
    Your content here...
    
  3. Зберегти файл
  4. Кеш закінчиться протягом 30 хвилин (або перезавантажить програму)

Щоб додати зображення, просто розташуйте їх у налаштованих вами зображеннях ImagesPath каталог і посилання на них у вашому markdown:

![Alt text](your-image.jpg)

Чого бракує (за призначенням)

Цей мінімальний блог навмисно не включає:

  • Коментарі - За потреби використовувати службу з третьою частиною
  • Пошук - Тримайте ваш вміст впорядкованим за категоріями
  • Мітки - Категорії достатньо для маленьких блогів
  • RSS/ Atom - Дуже просто додати, якщо потрібно.
  • Розпізнавання - MetaWeblog API використовує лише базовий автентифікаційний інтерфейс
  • Аналітичні явища - Якщо бажаєте, додайте фрагмент JavaScript
  • Оптимізація SEO - Працює з базовими мета- мітками
  • Повторні зображення - Переглядач ним керує
  • Перемикач темних/ освітлених тем - Однієї теми достатньо

Всі ці можливості можливе щоб додати, але вони типово не включені, тому що більшість маленьких блогів їх не потребують.

Символи швидкодії

Незважаючи на простоту, цей блог швидкий:

  • Кечування пам' яті означає без вводу/ виводу файла після першого завантаження
  • Кечування виводу означає не використовувати Razor після першого запиту
  • Немає бази даних означає, що немає запиту над
  • Немає JavaScript означає швидше завантаження сторінки
  • Простий CSS означає мінімальна обробка таблиці стилів

Для невеличкого блогу середньостатистичного (до 1000 дописів) ця архітектура перевищитиме більшість платформ блогів з базою даних.

Коли слід використовувати цей параметр/ повнофункціональний блог

Користування В основному, minimalBlog коли:

  • Ви починаєте персональний блог
  • У вас менше 500 постів.
  • Вам не потрібно багато мов
  • Ви хочете, щоб все було просто
  • Вам зручно у позначенні файлів
  • Ви просто хочете писати і публікувати

Використовувати платформа з великими значеннями коли:

  • Ви використовуєте свій блог як Лабораторія навчання для нових технологій
  • Ви хочете експериментувати з стратегіями впровадження, моніторингом та оптимізацією швидкодії
  • Вам потрібні специфічні можливості, зокрема багатомовна підтримка, повнотекстовий пошук або коментарі
  • Ви будуєте пакунки і потребуєте тестування у реальному світі
  • Ви фіксуєте складні технічні реалізації
  • Подорож будування платформи така ж цінна, як і зміст, в якому вона знаходиться.

Виключення: простота як можливість

У сучасному світі для веб- розробки, типово, ми часто досягаємо складних рішень. Вам потрібен блог? Краще налаштувати базу даних, налаштуйте ORM, налаштуйте міграцію, додайте кешування, реалізацію пошуку, налаштування фонових завдань...

Але іноді простим рішенням є праворуч розв' язання проблеми. Більшість з них. МінімалBlog доводить, що ви можете будувати функціональну, швидку і придатну для збереження платформу блогів за допомогою:

  • 342 рядки C# Description of a condition. Do not translate key words (# V1S #, # V1 #,) (MackdownBlogService + MetaWeblogService + Program.cs)
  • ~1220 рядків розмітки Razor (4 сторінки)
  • 55 рядків CSS
  • 1 Залежність від NuGet (Марквиг)

Це менше ніж 520 рядків коду загалом для повної платформи для ведення блогів.

Проект слугує як функціональною платформою блогу, так і нагадуванням: перед додаванням складності запитайте себе, чи вона вам справді потрібна. Іноді у теці, де є багато файлів, є все, що вам потрібно.

Ви можете знайти повний код у Каталог здебільшого minimalBlog Я випущу пакунок nuget, як тільки я буду задоволений кодом.

Счастливого блога!

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.