| |
@@ -0,0 +1,358 @@ |
|
1 |
+# QuillDrop |
|
2 |
+ |
|
3 |
+**QuillDrop** ist ein modernes, minimalistisches Blog-CMS, geschrieben in Go. Es kombiniert die Geschwindigkeit eines Static Site Generators mit der Flexibilität eines dynamischen HTTP-Servers - ohne externe Datenbank, ohne JavaScript-Frameworks, ohne Overhead. |
|
4 |
+ |
|
5 |
+## Philosophie |
|
6 |
+ |
|
7 |
+> Write. Save. Published. |
|
8 |
+ |
|
9 |
+QuillDrop folgt dem Prinzip der maximalen Einfachheit: Markdown-Dateien schreiben, speichern - fertig. Kein Build-Tool-Chaos, kein Node.js, keine Datenbank. Ein einzelnes Go-Binary erledigt alles. |
|
10 |
+ |
|
11 |
+## Features |
|
12 |
+ |
|
13 |
+### Dual-Mode Betrieb |
|
14 |
+ |
|
15 |
+QuillDrop unterstützt zwei Betriebsmodi in einem einzigen Binary: |
|
16 |
+ |
|
17 |
+- **`quilldrop serve`** - Startet einen dynamischen HTTP-Server für lokale Entwicklung und Vorschau. Ideal zum Schreiben und sofortigen Testen neuer Posts. |
|
18 |
+- **`quilldrop generate`** - Generiert eine komplette statische Website als HTML-Dateien. Perfekt für Deployment auf Nginx, Apache, CDN oder GitHub Pages. |
|
19 |
+ |
|
20 |
+### Markdown mit YAML-Frontmatter |
|
21 |
+ |
|
22 |
+Posts und Seiten werden als einfache Markdown-Dateien mit YAML-Frontmatter geschrieben: |
|
23 |
+ |
|
24 |
+```yaml |
|
25 |
+--- |
|
26 |
+title: "Mein neuer Blogpost" |
|
27 |
+date: 2025-11-06 12:00:00 |
|
28 |
+author: "Max Mustermann" |
|
29 |
+cover: "/images/posts/2025/11/cover.webp" |
|
30 |
+tags: [Kubernetes, DevOps, Self-Hosted] |
|
31 |
+categories: [Technik] |
|
32 |
+preview: "Kurze Vorschau des Posts..." |
|
33 |
+draft: false |
|
34 |
+toc: true |
|
35 |
+--- |
|
36 |
+ |
|
37 |
+# Hier beginnt der Post |
|
38 |
+ |
|
39 |
+Normales Markdown mit allen Extras... |
|
40 |
+``` |
|
41 |
+ |
|
42 |
+Unterstützte Frontmatter-Felder: |
|
43 |
+ |
|
44 |
+| Feld | Beschreibung | |
|
45 |
+|------|-------------| |
|
46 |
+| `title` | Titel des Posts | |
|
47 |
+| `date` | Veröffentlichungsdatum (mehrere Formate unterstützt) | |
|
48 |
+| `update` | Letzte Aktualisierung | |
|
49 |
+| `author` | Autor des Posts | |
|
50 |
+| `cover` / `featureImage` | Cover-Bild (mit Fallback) | |
|
51 |
+| `tags` | Liste von Tags | |
|
52 |
+| `categories` | Liste von Kategorien | |
|
53 |
+| `preview` | Benutzerdefinierte Vorschau (sonst automatisch aus erstem Absatz) | |
|
54 |
+| `draft` | Entwurf - wird nicht veröffentlicht | |
|
55 |
+| `toc` | Inhaltsverzeichnis automatisch generieren | |
|
56 |
+| `hide` | Post verstecken | |
|
57 |
+| `top` | Post oben anpinnen | |
|
58 |
+ |
|
59 |
+### Erweitertes Markdown-Rendering |
|
60 |
+ |
|
61 |
+QuillDrop nutzt [Goldmark](https://github.com/yuin/goldmark) als Markdown-Engine mit folgenden Erweiterungen: |
|
62 |
+ |
|
63 |
+- **GitHub Flavored Markdown (GFM)** - Tabellen, Strikethrough, Autolinks, Task-Listen |
|
64 |
+- **Syntax Highlighting** - Über 200 Programmiersprachen mit dem Dracula-Theme via [Chroma](https://github.com/alecthomas/chroma) |
|
65 |
+- **Emoji-Support** - Shortcodes wie `:rocket:`, `:tada:`, `:satellite:` |
|
66 |
+- **Automatische Heading-IDs** - Für Ankerverlinkung und Inhaltsverzeichnis |
|
67 |
+- **Raw HTML** - Einbettung von HTML direkt im Markdown |
|
68 |
+- **Hugo-Kompatibilität** - `{{</* rawhtml */>}}` Shortcodes werden automatisch verarbeitet |
|
69 |
+ |
|
70 |
+### Responsives Design mit Dark/Light Theme |
|
71 |
+ |
|
72 |
+Das mitgelieferte Theme bietet: |
|
73 |
+ |
|
74 |
+- **Dark Mode als Default** mit einem hellen Alternativ-Theme |
|
75 |
+- **Theme Toggle** mit localStorage-Persistenz (bleibt nach Reload erhalten) |
|
76 |
+- **Futuristisches Design** - Dunkle Hintergrunde, Cyan-Akzente, subtile Glow-Effekte |
|
77 |
+- **Responsive Layout** - Mobile-first, optimiert für alle Bildschirmgrößen |
|
78 |
+- **Hamburger-Navigation** auf mobilen Geräten mit Fullscreen-Overlay |
|
79 |
+- **Dropdown-Menus** für verschachtelte Navigation |
|
80 |
+- **Typographie** - Inter als Textfont, JetBrains Mono für Code und Metadaten |
|
81 |
+ |
|
82 |
+### Navigation und Menü |
|
83 |
+ |
|
84 |
+Das Navigationsmenü wird vollständig über die `config.yaml` konfiguriert und unterstützt verschachtelte Dropdown-Menüs: |
|
85 |
+ |
|
86 |
+```yaml |
|
87 |
+menu: |
|
88 |
+ - label: "Home" |
|
89 |
+ url: "/" |
|
90 |
+ - label: "Projekte" |
|
91 |
+ children: |
|
92 |
+ - label: "VM-Manager" |
|
93 |
+ url: "/sites/projekte/vm-manager" |
|
94 |
+ - label: "VM-Tracker" |
|
95 |
+ url: "/sites/projekte/vm-tracker" |
|
96 |
+ - label: "QuillDrop" |
|
97 |
+ url: "/sites/projekte/quilldrop" |
|
98 |
+ - label: "Über mich" |
|
99 |
+ url: "/sites/ueber-mich" |
|
100 |
+ - label: "Tags" |
|
101 |
+ url: "/tags" |
|
102 |
+``` |
|
103 |
+ |
|
104 |
+Neue Menüpunkte und Untermenüs können jederzeit durch einfaches Erweitern der YAML-Konfiguration hinzugefügt werden. |
|
105 |
+ |
|
106 |
+### Pagination |
|
107 |
+ |
|
108 |
+Die Startseite zeigt eine konfigurierbare Anzahl von Posts pro Seite (Standard: 5). Die Pagination bietet: |
|
109 |
+ |
|
110 |
+- **Intelligente Seitennummerierung** - Zeigt erste und letzte Seite, plus ein Fenster um die aktuelle Seite herum |
|
111 |
+- **Ellipsis** bei vielen Seiten (1 ... 10 11 **12** 13 14 ... 23) |
|
112 |
+- **Neuere/Ältere Buttons** für schnelle Navigation |
|
113 |
+- **Pretty URLs** - `/page/2`, `/page/3`, etc. |
|
114 |
+- SEO-freundlich: `/page/1` wird automatisch auf `/` umgeleitet (301) |
|
115 |
+ |
|
116 |
+### Tags und Kategorien |
|
117 |
+ |
|
118 |
+- **Tag-Übersicht** unter `/tags` mit Anzahl der Posts pro Tag |
|
119 |
+- **Tag-Seiten** unter `/tags/kubernetes` mit allen Posts eines Tags |
|
120 |
+- **Tag-Badges** auf Post-Cards und Einzelseiten |
|
121 |
+ |
|
122 |
+### Statische Seiten |
|
123 |
+ |
|
124 |
+Neben Blog-Posts unterstützt QuillDrop statische Seiten für: |
|
125 |
+ |
|
126 |
+- Impressum, Datenschutzerklärung |
|
127 |
+- Über mich / About |
|
128 |
+- Projektseiten (mit Unterseiten) |
|
129 |
+- Beliebige weitere Seiten |
|
130 |
+ |
|
131 |
+Seiten werden als Markdown-Dateien im `sites/`-Verzeichnis abgelegt. Verschachtelte Verzeichnisse werden automatisch erkannt - z.B. wird `sites/projekte/vm-tracker/index.md` unter `/sites/projekte/vm-tracker` erreichbar. |
|
132 |
+ |
|
133 |
+### RSS Feed |
|
134 |
+ |
|
135 |
+Automatisch generierter RSS 2.0 Feed unter `/feed.xml` mit: |
|
136 |
+ |
|
137 |
+- Den letzten 20 Posts |
|
138 |
+- Titel, Link, Vorschau und Veröffentlichungsdatum |
|
139 |
+- RSS-Autodiscovery im HTML-Head |
|
140 |
+- RSS-Icon in der Navigation |
|
141 |
+ |
|
142 |
+### Cover-Bilder |
|
143 |
+ |
|
144 |
+Posts können ein Cover-Bild definieren, das sowohl auf der Startseite (als Post-Card) als auch auf der Einzelansicht angezeigt wird: |
|
145 |
+ |
|
146 |
+- **21:9 Aspect Ratio** auf Post-Cards mit Zoom-on-Hover Effekt |
|
147 |
+- **Volle Breite** auf der Einzelpost-Seite |
|
148 |
+- **Lazy Loading** für optimale Performance |
|
149 |
+- **Fallback** von `cover` auf `featureImage` |
|
150 |
+ |
|
151 |
+## Architektur |
|
152 |
+ |
|
153 |
+### Projektstruktur |
|
154 |
+ |
|
155 |
+``` |
|
156 |
+quilldrop/ |
|
157 |
+├── main.go # CLI Entry Point |
|
158 |
+├── config.yaml # Konfiguration |
|
159 |
+├── content/ # Blog-Posts (Markdown) |
|
160 |
+│ ├── 2025-11-06-mein-post.md |
|
161 |
+│ └── ... |
|
162 |
+├── sites/ # Statische Seiten |
|
163 |
+│ ├── ueber-mich.md |
|
164 |
+│ ├── impressum.md |
|
165 |
+│ └── projekte/ |
|
166 |
+│ └── mein-projekt/ |
|
167 |
+│ └── index.md |
|
168 |
+├── static/ # Statische Assets |
|
169 |
+│ ├── css/style.css |
|
170 |
+│ ├── js/theme.js |
|
171 |
+│ └── images/ |
|
172 |
+├── internal/ |
|
173 |
+│ ├── config/config.go # YAML Config Loader |
|
174 |
+│ ├── content/ |
|
175 |
+│ │ ├── post.go # Post Struct + FlexTime |
|
176 |
+│ │ ├── parser.go # Markdown + Frontmatter Parser |
|
177 |
+│ │ └── page.go # Statische Seiten Parser |
|
178 |
+│ ├── server/server.go # HTTP Server |
|
179 |
+│ ├── generator/generator.go # Static Site Generator |
|
180 |
+│ └── templates/ |
|
181 |
+│ ├── render.go # Template Engine + Functions |
|
182 |
+│ ├── rss.go # RSS Feed Generator |
|
183 |
+│ ├── base.html # Base Layout |
|
184 |
+│ ├── home.html # Homepage + Pagination |
|
185 |
+│ ├── post.html # Einzelner Post |
|
186 |
+│ ├── page.html # Statische Seite |
|
187 |
+│ ├── tags.html # Tag-Übersicht |
|
188 |
+│ └── tag.html # Tag-Seite |
|
189 |
+└── output/ # Generierte statische Dateien |
|
190 |
+``` |
|
191 |
+ |
|
192 |
+### Technologie-Stack |
|
193 |
+ |
|
194 |
+| Komponente | Technologie | |
|
195 |
+|-----------|-------------| |
|
196 |
+| Sprache | Go (Standard Library + minimale Dependencies) | |
|
197 |
+| HTTP Server | `net/http` (Go Standard Library) | |
|
198 |
+| Templates | `html/template` mit `embed.FS` | |
|
199 |
+| Markdown | Goldmark + GFM + Emoji + Chroma | |
|
200 |
+| Konfiguration | YAML via `gopkg.in/yaml.v3` | |
|
201 |
+| Syntax Highlighting | Chroma (Dracula Theme) | |
|
202 |
+| Fonts | Inter + JetBrains Mono (Google Fonts) | |
|
203 |
+| CSS | Vanilla CSS mit Custom Properties | |
|
204 |
+| JavaScript | Vanilla JS (kein Framework) | |
|
205 |
+ |
|
206 |
+### Dependencies |
|
207 |
+ |
|
208 |
+QuillDrop hat bewusst minimale Abhängigkeiten - **kein Web-Framework**, **kein CSS-Framework**, **kein JS-Framework**: |
|
209 |
+ |
|
210 |
+- `github.com/yuin/goldmark` - Markdown Parser (CommonMark-konform) |
|
211 |
+- `github.com/yuin/goldmark-emoji` - Emoji Shortcodes |
|
212 |
+- `github.com/yuin/goldmark-highlighting/v2` - Syntax Highlighting |
|
213 |
+- `github.com/alecthomas/chroma/v2` - Syntax Highlighting Engine |
|
214 |
+- `gopkg.in/yaml.v3` - YAML Parser |
|
215 |
+ |
|
216 |
+### Embedded Assets |
|
217 |
+ |
|
218 |
+Alle HTML-Templates werden via Go's `//go:embed` Directive direkt in das Binary eingebettet. Das bedeutet: |
|
219 |
+ |
|
220 |
+- **Einzelnes Binary** - Keine externen Template-Dateien nötig |
|
221 |
+- **Schneller Start** - Kein Dateisystem-Zugriff für Templates |
|
222 |
+- **Einfaches Deployment** - Ein Binary + Config + Content = fertig |
|
223 |
+ |
|
224 |
+## Konfiguration |
|
225 |
+ |
|
226 |
+Die gesamte Konfiguration erfolgt über eine einzige `config.yaml`: |
|
227 |
+ |
|
228 |
+```yaml |
|
229 |
+title: "Mein Blog" |
|
230 |
+description: "Tech Blog - DevOps, Kubernetes, Self-Hosted" |
|
231 |
+author: "Max Mustermann" |
|
232 |
+baseURL: "https://mein-blog.de" |
|
233 |
+port: 8080 |
|
234 |
+postsPerPage: 5 |
|
235 |
+contentDir: "content" |
|
236 |
+sitesDir: "sites" |
|
237 |
+outputDir: "output" |
|
238 |
+ |
|
239 |
+menu: |
|
240 |
+ - label: "Home" |
|
241 |
+ url: "/" |
|
242 |
+ - label: "Tags" |
|
243 |
+ url: "/tags" |
|
244 |
+ - label: "Über mich" |
|
245 |
+ url: "/sites/ueber-mich" |
|
246 |
+``` |
|
247 |
+ |
|
248 |
+| Option | Default | Beschreibung | |
|
249 |
+|--------|---------|-------------| |
|
250 |
+| `title` | - | Titel der Website | |
|
251 |
+| `description` | - | Beschreibung (Meta-Tag + Hero) | |
|
252 |
+| `author` | - | Autor der Website | |
|
253 |
+| `baseURL` | - | Basis-URL für RSS und absolute Links | |
|
254 |
+| `port` | `8080` | Port für den dynamischen Server | |
|
255 |
+| `postsPerPage` | `5` | Anzahl Posts pro Seite | |
|
256 |
+| `contentDir` | `content` | Verzeichnis für Blog-Posts | |
|
257 |
+| `sitesDir` | `sites` | Verzeichnis für statische Seiten | |
|
258 |
+| `outputDir` | `output` | Ausgabeverzeichnis für statische Generierung | |
|
259 |
+| `menu` | `[]` | Navigationsmenü mit optionalen Untermenüs | |
|
260 |
+ |
|
261 |
+## Schnellstart |
|
262 |
+ |
|
263 |
+### Installation |
|
264 |
+ |
|
265 |
+```bash |
|
266 |
+# Repository klonen |
|
267 |
+git clone https://github.com/ruedigerp/quilldrop.git |
|
268 |
+cd quilldrop |
|
269 |
+ |
|
270 |
+# Dependencies laden |
|
271 |
+go mod download |
|
272 |
+ |
|
273 |
+# Binary bauen |
|
274 |
+go build -o quilldrop . |
|
275 |
+``` |
|
276 |
+ |
|
277 |
+### Neuen Post erstellen |
|
278 |
+ |
|
279 |
+Eine neue Markdown-Datei im `content/`-Verzeichnis anlegen: |
|
280 |
+ |
|
281 |
+```bash |
|
282 |
+touch content/2025-12-01-mein-erster-post.md |
|
283 |
+``` |
|
284 |
+ |
|
285 |
+```markdown |
|
286 |
+--- |
|
287 |
+title: "Mein erster Post" |
|
288 |
+date: 2025-12-01 10:00:00 |
|
289 |
+author: "Max Mustermann" |
|
290 |
+tags: [Blog, QuillDrop] |
|
291 |
+preview: "Das ist mein erster Post mit QuillDrop!" |
|
292 |
+toc: false |
|
293 |
+--- |
|
294 |
+ |
|
295 |
+# Willkommen |
|
296 |
+ |
|
297 |
+Das ist mein erster Post mit **QuillDrop**. |
|
298 |
+ |
|
299 |
+## Code-Beispiel |
|
300 |
+ |
|
301 |
+```go |
|
302 |
+fmt.Println("Hello QuillDrop!") |
|
303 |
+``` |
|
304 |
+``` |
|
305 |
+ |
|
306 |
+### Lokale Vorschau |
|
307 |
+ |
|
308 |
+```bash |
|
309 |
+# Dynamischen Server starten |
|
310 |
+./quilldrop serve |
|
311 |
+ |
|
312 |
+# Oder direkt mit Go |
|
313 |
+go run . serve |
|
314 |
+``` |
|
315 |
+ |
|
316 |
+Dann im Browser: [http://localhost:8080](http://localhost:8080) |
|
317 |
+ |
|
318 |
+### Statische Seite generieren |
|
319 |
+ |
|
320 |
+```bash |
|
321 |
+# HTML-Dateien generieren |
|
322 |
+./quilldrop generate |
|
323 |
+ |
|
324 |
+# Generierte Dateien befinden sich in output/ |
|
325 |
+ls output/ |
|
326 |
+``` |
|
327 |
+ |
|
328 |
+Die generierten Dateien im `output/`-Verzeichnis können direkt auf einen Webserver (Nginx, Apache, Caddy) oder CDN deployed werden. |
|
329 |
+ |
|
330 |
+## URL-Schema |
|
331 |
+ |
|
332 |
+| URL | Beschreibung | |
|
333 |
+|-----|-------------| |
|
334 |
+| `/` | Startseite (letzte N Posts) | |
|
335 |
+| `/page/2` | Seite 2 der Post-Liste | |
|
336 |
+| `/posts/2025-11-06-mein-post` | Einzelner Blog-Post | |
|
337 |
+| `/tags` | Tag-Übersicht | |
|
338 |
+| `/tags/kubernetes` | Posts mit Tag "Kubernetes" | |
|
339 |
+| `/sites/ueber-mich` | Statische Seite | |
|
340 |
+| `/sites/projekte/vm-tracker` | Verschachtelte Projektseite | |
|
341 |
+| `/feed.xml` | RSS Feed | |
|
342 |
+| `/static/css/style.css` | Statische Assets | |
|
343 |
+| `/images/posts/2025/11/cover.webp` | Bilder | |
|
344 |
+ |
|
345 |
+## Warum QuillDrop? |
|
346 |
+ |
|
347 |
+- **Keine Datenbank** - Dateisystem als einzige Datenquelle |
|
348 |
+- **Keine Build-Pipeline** - Ein `go build` und fertig |
|
349 |
+- **Keine JS-Frameworks** - Vanilla JavaScript, unter 90 Zeilen |
|
350 |
+- **Minimale Dependencies** - 5 Go-Packages, alle fokussiert auf Markdown |
|
351 |
+- **Blitzschnell** - Generiert 100+ Posts in unter 3 Sekunden |
|
352 |
+- **Einzelnes Binary** - Templates eingebettet, kein Runtime-Setup |
|
353 |
+- **Hugo-kompatibel** - Bestehende Hugo-Posts mit Frontmatter funktionieren |
|
354 |
+- **Dual-Mode** - Entwicklung mit Server, Produktion mit Static Generator |
|
355 |
+ |
|
356 |
+## Lizenz |
|
357 |
+ |
|
358 |
+QuillDrop ist Open Source. |