CMS/Erstes-Wiki
Das Vorhaben, ein eigenes CMS auf Basis von ASP.NET Core MVC zu entwickeln, das sich an etablierten Systemen wie MediaWiki, TYPO3, Drupal, XWiki, wiki.js oder Bookstack orientiert, ist anspruchsvoll, aber ein hervorragendes Projekt. ASP.NET Core eignet sich aufgrund seiner Performance und modularen Architektur ideal dafür.
Das Kernkonzept: Trennung von Inhalten und Darstellung
Das System trennt – wie auch andere bekannte Content-Management-Systeme (CMS) – die Inhalte (Texte) von der Darstellung (Layout, Design, Templates). Dadurch können Inhalte unabhängig vom Aussehen gepflegt und wiederverwendet werden.
Datenspeicherung: Markdown-Inhalte sollen in der Datenbank gespeichert und in einem anderen Feld sofort als HTML gerendert werden (EF Core).
Verarbeitung: Ein Service, der Markdown in HTML umwandelt (z. B. mit der Bibliothek Markdig).
Rendering: ASP.NET Core MVC-Views, die das generierte HTML in ein Layout einbetten.
Die technische Architektur (Schritt für Schritt)
Routing & Dynamische Seiten
Dein CMS kennt die URLs nicht im Voraus. Du brauchst einen Catch-all Route Handler, der alle Anfragen außer statischen Dateien abfängt.
Catch-all Route
In ASP.NET Core MVC bezeichnet eine "Catch-all Route" eine Routing-Regel, die alle Anfragen abfängt, die nicht explizit durch andere Routen definiert sind. Sie wird häufig verwendet, um dynamische Seiten oder ein CMS zu realisieren, bei dem die URLs nicht im Voraus bekannt sind.
Beispiel in C#:
app.MapControllerRoute(
name: "cms",
pattern: "{*slug}",
defaults: new { controller = "Page", action = "Index" });
Hierbei fängt die Route alle Pfade ab ("{*slug}") und leitet sie an den Controller "Page" und die Action "Index" weiter. So können beliebige URLs verarbeitet werden, z.B. für Wiki- oder CMS-Seiten.
Controller
using Microsoft.AspNetCore.Mvc;
public class PageController : Controller
{
public IActionResult Index(string slug)
{
if (string.IsNullOrEmpty(slug))
{
ViewBag.Title = "Startseite";
ViewBag.Content = "Willkommen auf der Startseite!";
}
else
{
// Slug in Segmente (Unterseiten) aufteilen
var segmente = slug.Split('/', StringSplitOptions.RemoveEmptyEntries);
// Beispiel: Titel aus letztem Segment, Pfad anzeigen
ViewBag.Title = segmente.Last();
ViewBag.Path = string.Join(" → ", segmente);
ViewBag.Content = $"Inhalt für die Seite: {slug}";
}
return View();
}
}