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 لغة، خدمات مستضيفة متعددة، جدولة الوظائف Hangfire، بروميثيوس، قياسات Serilog، تفاعلات HTMX، استخدام حزم النواة الخاصة بي، وما يكفي من حاويات Docker لجعل سفينة غيورة.
هذا كلّيّاً متعمداً. هذا الموقع هو مختبري الحي - ملعب حيث أختبر مع التقنيات، استراتيجيات نشر الاختبار، قياس خصائص الأداء، وبناء حزم قابلة لإعادة الاستخدام. مفترض لأن هذه هي الطريقة التي أتعلم بها: من خلال حل المشاكل التي لا توجد في معظم المدونات في الواقع، ثم تعبئة تلك الحلول كمكتبات مفتوحة المصدر يمكن للآخرين استخدامها.
لكن هذا هو الشيء: ربما لا تحتاج إلى أي من ذلك لتشغيل مدونة.
لهذا السبب أنا خلقت اللغم المصغري - إظهار ما يحدث عندما تقوم بإزالة كل التجارب والتركيز على الضروريات المطلقة. لا قاعدة بيانات. لا بناء خط الأنابيب. لا تعقيد. فقط وضع علامات على الملفات في مجلد، تظهر على الشبكة. هذا ما تبدو عليه المدونة عندما لا تستخدمها كمختبر.
ملاحظة: انظر نهاية المقالة للربط مع المصدر، وأنا أخطط لاطلاق هذا على أنه دعم بمجرد أن أحصل على الوقت لأتأكد أنه موثوق به 100% و هو ليس سيئاً جداً (لذا ابحثوا عن مواد اختبار k6 قريباً!)
ويتمحور المشروع برمته حول مبدأ واحد هو: *** أبقي عليه بسيطاً**لا قاعدة بيانات، لا خط أنابيب بناء، لا إطار جافاسكربت، فقط ASP.net 9.0، ماركديج للرسم التنازلي، وحوالي 500 سطر من الرمز الكلي، هذا كل شيء.
ملاحظة: يمكنك حتى أن تفعل هذا جانب العميل باستخدام مثل دال - الحد الأدنى هذا صحيح فقط .md هذه مدونة ASP.NET (نوعاً ما).
دعونا ننظر إلى كيفية تنظيم المشروع:
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...
يستخلص المكافئ هذه البيانات الفوقية باستخدام تعابير منتظمة و 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 دقيقة إنتهاء ، و ساعتين إنتهاء مطلق ، بسيط ، فعّال
إعدادات التطبيق كلها عبارة عن 43 سطرًا فقط: zazor pages، ذاكرة مخبئة، مخرجات مخبئة، اثنين من خدمات الأفردتون، خدمة الملف الساكن، و نقطة نهاية لـ MetaWeblog XML-RSC. كل شيء مخبّأ كصفحات منفردة لأن لا شيء يتغير ما لم يتم تعديل الملفات.
UI هو صافي خادم HTML لا جافاسكربت ، لا HTMX ، لا الألب. js. الـ قائمة الصفحة الرئيسية قائمة الوظائف ، الـ قائمة @Html.Raw(post.HtmlContent) مع وجود [OutputCache] 4 صفحات، كل منها تحت 30 سطراً.
التصميم البصري بالكامل يتم التعامل معه بواسطة ملف واحد لـ CSS مع فقط 55 سطر. إنه يستخدم خواص تخصيص CSS لـ و يخلق صورة نظيفة و داكنة لـ GetHub مستوحاة من مظهر:
: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 التي تعمل.
لكتاب الكتاب الذين يفضلون مُنْصَفين مُحَرِّرين مُحَرِّرين مثل مُعَجّزهذا الـ 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 - وثائق تفويض الدخول إلى محرِّر الدخول الخارجيوكما ذكر أعلاه، ستكون متاحة ولكن ليس بعد:
المدونات متاحة الآن كحزمة نوغيت، مما يجعل من السهل إضافة إلى أي تطبيق من تطبيقات 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 وسترون التدوينة التي تحتوي على ملفات من المسار المهيأ.
إنشاء تدوينة جديدة:
.md في حالة أنت MarkdownPath# Your Post Title
Your content here...
لإضافة صور، ببساطة ضعها في مُعَدّك ImagesPath دليل و مرجع لهم في هدفك:

هذا الحد الأدنى من المدونات لا يتضمن ما يلي:
هذه الملام هي كل يمكن - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - لأن معظم المدونات الصغيرة لا تحتاجها.
على الرغم من بساطتها، فإن هذه المدونة -لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا، لا.:
بالنسبة لمدوّنة صغيرة إلى متوسطة (أقل من 1000 صفحة)، هذا العمارة سوف تفوق أداء معظم منصات المدونات المدعومة بقاعدة البيانات.
غالباً لوثدي. المدوّل المُقلّي متى:
منصة متى:
في عالم تطوير الإنترنت الحديث، غالباً ما نصل إلى حلول معقدة بالافتراض. هل تحتاج إلى مدونة؟ من الأفضل أن ننشئ قاعدة بيانات، نُعِدّ قاعدة بيانات، نُعِدّ قاعدة بيانات ORM، نُنشئ الهجرات، نضيف الكاتشين، نُنفّذ البحث، نُعِّد الوظائف الأساسية...
لكن أحياناً الحل البسيط هو الحق في حق محلول. في الغالب lulucid. minimal Blog يثبت أنه يمكنك بناء منصة مدونة وظيفية وسريعة وقابلة للصيانة مع:
هذا هو أقل من ٥٢٠ ٥ سطرا من مجموع الرمز منصة كاملة للمدونات.
يعمل المشروع كمنصة وظيفية للمدونات وتذكير: قبل أن تضيف التعقيد، اسأل نفسك إذا كنت بحاجة إليه حقاً. أحياناً مجلد مليء بالملفات المرجعية هو كل ما تحتاجه.
يمكنك العثور على المصدر الكامل للرمز في مُنت مُحد مُحد مُث مُث مُث مُث مُث مُل مُف سأطلق الحزمة حالما أكون سعيداً بالرمز
مدونونة سعيدة!
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.