fix: add readme english version
R
Rüdiger Küpper
<rpr@9it.de>
committete am 19.02.2026 07:58
73c762e933e3822bc61a1b9b4674ab36d7b9e149
| @@ -1,283 +1,285 @@ | ||
| 1 | 1 | # QuillDrop |
| 2 | 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. |
|
| 3 | +**QuillDrop** is a modern, minimalist blog CMS written in Go. It combines the speed of a static site generator with the flexibility of a dynamic HTTP server — no external database, no JavaScript frameworks, no overhead. |
|
| 4 | 4 | |
| 5 | -## Philosophie |
|
| 5 | +🇩🇪 [Deutsche Version](README-de.md) |
|
| 6 | + | |
| 7 | +## Philosophy |
|
| 6 | 8 | |
| 7 | 9 | > Write. Save. Published. |
| 8 | 10 | |
| 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. |
|
| 11 | +QuillDrop follows the principle of maximum simplicity: write Markdown files, save them — done. No build tool chaos, no Node.js, no database. A single Go binary handles everything. |
|
| 10 | 12 | |
| 11 | 13 | ## Features |
| 12 | 14 | |
| 13 | -### Dual-Mode Betrieb |
|
| 15 | +### Dual-Mode Operation |
|
| 14 | 16 | |
| 15 | -QuillDrop unterstützt zwei Betriebsmodi in einem einzigen Binary: |
|
| 17 | +QuillDrop supports two modes of operation in a single binary: |
|
| 16 | 18 | |
| 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 | +- **`quilldrop serve`** — Starts a dynamic HTTP server for local development and preview. Ideal for writing and instantly testing new posts. |
|
| 20 | +- **`quilldrop generate`** — Generates a complete static website as HTML files. Perfect for deployment on Nginx, Apache, CDN, or GitHub Pages. |
|
| 19 | 21 | |
| 20 | -### Markdown mit YAML-Frontmatter |
|
| 22 | +### Markdown with YAML Frontmatter |
|
| 21 | 23 | |
| 22 | -Posts und Seiten werden als einfache Markdown-Dateien mit YAML-Frontmatter geschrieben: |
|
| 24 | +Posts and pages are written as simple Markdown files with YAML frontmatter: |
|
| 23 | 25 | |
| 24 | 26 | ```yaml |
| 25 | 27 | --- |
| 26 | -title: "Mein neuer Blogpost" |
|
| 28 | +title: "My New Blog Post" |
|
| 27 | 29 | date: 2025-11-06 12:00:00 |
| 28 | -author: "Max Mustermann" |
|
| 30 | +author: "Jane Doe" |
|
| 29 | 31 | cover: "/images/posts/2025/11/cover.webp" |
| 30 | 32 | tags: [Kubernetes, DevOps, Self-Hosted] |
| 31 | -categories: [Technik] |
|
| 32 | -preview: "Kurze Vorschau des Posts..." |
|
| 33 | +categories: [Tech] |
|
| 34 | +preview: "A short preview of the post..." |
|
| 33 | 35 | draft: false |
| 34 | 36 | toc: true |
| 35 | 37 | --- |
| 36 | 38 | |
| 37 | -# Hier beginnt der Post |
|
| 39 | +# Post starts here |
|
| 38 | 40 | |
| 39 | -Normales Markdown mit allen Extras... |
|
| 41 | +Regular Markdown with all the extras... |
|
| 40 | 42 | ``` |
| 41 | 43 | |
| 42 | -Unterstützte Frontmatter-Felder: |
|
| 44 | +Supported frontmatter fields: |
|
| 43 | 45 | |
| 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 | |
|
| 46 | +| Field | Description | |
|
| 47 | +|-------|-------------| |
|
| 48 | +| `title` | Post title | |
|
| 49 | +| `date` | Publication date (multiple formats supported) | |
|
| 50 | +| `update` | Last updated | |
|
| 51 | +| `author` | Post author | |
|
| 52 | +| `cover` / `featureImage` | Cover image (with fallback) | |
|
| 53 | +| `tags` | List of tags | |
|
| 54 | +| `categories` | List of categories | |
|
| 55 | +| `preview` | Custom preview (otherwise auto-generated from first paragraph) | |
|
| 56 | +| `draft` | Draft — will not be published | |
|
| 57 | +| `toc` | Automatically generate table of contents | |
|
| 58 | +| `hide` | Hide post | |
|
| 59 | +| `top` | Pin post to top | |
|
| 58 | 60 | |
| 59 | -### Erweitertes Markdown-Rendering |
|
| 61 | +### Extended Markdown Rendering |
|
| 60 | 62 | |
| 61 | -QuillDrop nutzt [Goldmark](https://github.com/yuin/goldmark) als Markdown-Engine mit folgenden Erweiterungen: |
|
| 63 | +QuillDrop uses [Goldmark](https://github.com/yuin/goldmark) as its Markdown engine with the following extensions: |
|
| 62 | 64 | |
| 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 |
|
| 65 | +- **GitHub Flavored Markdown (GFM)** — Tables, strikethrough, autolinks, task lists |
|
| 66 | +- **Syntax Highlighting** — Over 200 programming languages with the Dracula theme via [Chroma](https://github.com/alecthomas/chroma) |
|
| 67 | +- **Emoji Support** — Shortcodes like `:rocket:`, `:tada:`, `:satellite:` |
|
| 68 | +- **Automatic Heading IDs** — For anchor linking and table of contents |
|
| 69 | +- **Raw HTML** — Embed HTML directly in Markdown |
|
| 70 | +- **Hugo Compatibility** — `{{</* rawhtml */>}}` shortcodes are processed automatically |
|
| 69 | 71 | |
| 70 | -### Responsives Design mit Dark/Light Theme |
|
| 72 | +### Responsive Design with Dark/Light Theme |
|
| 71 | 73 | |
| 72 | -Das mitgelieferte Theme bietet: |
|
| 74 | +The included theme offers: |
|
| 73 | 75 | |
| 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 und eigenem Stacking Context |
|
| 79 | -- **Dropdown-Menus** für verschachtelte Navigation (Touch-optimiert auf Mobile) |
|
| 80 | -- **Integrierte Suche** — Lupe in der Navbar mit Ctrl+K Shortcut |
|
| 81 | -- **Typographie** - Inter als Textfont, JetBrains Mono für Code und Metadaten |
|
| 76 | +- **Dark Mode as default** with a light alternative theme |
|
| 77 | +- **Theme Toggle** with localStorage persistence (survives page reloads) |
|
| 78 | +- **Futuristic Design** — Dark backgrounds, cyan accents, subtle glow effects |
|
| 79 | +- **Responsive Layout** — Mobile-first, optimized for all screen sizes |
|
| 80 | +- **Hamburger Navigation** on mobile devices with fullscreen overlay and dedicated stacking context |
|
| 81 | +- **Dropdown Menus** for nested navigation (touch-optimized on mobile) |
|
| 82 | +- **Integrated Search** — Magnifying glass in the navbar with Ctrl+K shortcut |
|
| 83 | +- **Typography** — Inter as body font, JetBrains Mono for code and metadata |
|
| 82 | 84 | |
| 83 | -### Navigation und Menü |
|
| 85 | +### Navigation and Menu |
|
| 84 | 86 | |
| 85 | -Das Navigationsmenü wird vollständig über die `config.yaml` konfiguriert und unterstützt verschachtelte Dropdown-Menüs: |
|
| 87 | +The navigation menu is fully configured via `config.yaml` and supports nested dropdown menus: |
|
| 86 | 88 | |
| 87 | 89 | ```yaml |
| 88 | 90 | menu: |
| 89 | 91 | - label: "Home" |
| 90 | 92 | url: "/" |
| 91 | -- label: "Projekte" |
|
| 93 | +- label: "Projects" |
|
| 92 | 94 | children: |
| 93 | 95 | - label: "VM-Manager" |
| 94 | -url: "/sites/projekte/vm-manager" |
|
| 96 | +url: "/sites/projects/vm-manager" |
|
| 95 | 97 | - label: "VM-Tracker" |
| 96 | -url: "/sites/projekte/vm-tracker" |
|
| 98 | +url: "/sites/projects/vm-tracker" |
|
| 97 | 99 | - label: "QuillDrop" |
| 98 | -url: "/sites/projekte/quilldrop" |
|
| 99 | -- label: "Über mich" |
|
| 100 | -url: "/sites/ueber-mich" |
|
| 100 | +url: "/sites/projects/quilldrop" |
|
| 101 | +- label: "About" |
|
| 102 | +url: "/sites/about" |
|
| 101 | 103 | - label: "Tags" |
| 102 | 104 | url: "/tags" |
| 103 | 105 | ``` |
| 104 | 106 | |
| 105 | -Neue Menüpunkte und Untermenüs können jederzeit durch einfaches Erweitern der YAML-Konfiguration hinzugefügt werden. |
|
| 107 | +New menu items and submenus can be added at any time by simply extending the YAML configuration. |
|
| 106 | 108 | |
| 107 | 109 | ### Pagination |
| 108 | 110 | |
| 109 | -Die Startseite zeigt eine konfigurierbare Anzahl von Posts pro Seite (Standard: 5). Die Pagination bietet: |
|
| 111 | +The homepage displays a configurable number of posts per page (default: 5). Pagination features: |
|
| 110 | 112 | |
| 111 | -- **Intelligente Seitennummerierung** - Zeigt erste und letzte Seite, plus ein Fenster um die aktuelle Seite herum |
|
| 112 | -- **Ellipsis** bei vielen Seiten (1 ... 10 11 **12** 13 14 ... 23) |
|
| 113 | -- **Neuere/Ältere Buttons** für schnelle Navigation |
|
| 114 | -- **Pretty URLs** - `/page/2`, `/page/3`, etc. |
|
| 115 | -- SEO-freundlich: `/page/1` wird automatisch auf `/` umgeleitet (301) |
|
| 113 | +- **Smart page numbering** — Shows first and last page, plus a window around the current page |
|
| 114 | +- **Ellipsis** for many pages (1 ... 10 11 **12** 13 14 ... 23) |
|
| 115 | +- **Newer/Older buttons** for quick navigation |
|
| 116 | +- **Pretty URLs** — `/page/2`, `/page/3`, etc. |
|
| 117 | +- SEO-friendly: `/page/1` automatically redirects to `/` (301) |
|
| 116 | 118 | |
| 117 | -### Tags und Kategorien |
|
| 119 | +### Tags and Categories |
|
| 118 | 120 | |
| 119 | -QuillDrop unterstützt sowohl Tags als auch Kategorien zur Strukturierung von Inhalten: |
|
| 121 | +QuillDrop supports both tags and categories for content organization: |
|
| 120 | 122 | |
| 121 | -- **Tag-Übersicht** unter `/tags/` mit Anzahl der Posts pro Tag |
|
| 122 | -- **Tag-Seiten** unter `/tags/kubernetes/` mit allen Posts eines Tags |
|
| 123 | -- **Kategorie-Übersicht** unter `/categories/` mit Anzahl der Posts pro Kategorie |
|
| 124 | -- **Kategorie-Seiten** unter `/categories/technik/` mit allen Posts einer Kategorie |
|
| 125 | -- **Tag- und Kategorie-Badges** auf Post-Cards und Einzelseiten |
|
| 126 | -- Tags und Kategorien werden aus dem YAML-Frontmatter (`tags`, `categories`) ausgelesen |
|
| 123 | +- **Tag overview** at `/tags/` with post count per tag |
|
| 124 | +- **Tag pages** at `/tags/kubernetes/` with all posts for a tag |
|
| 125 | +- **Category overview** at `/categories/` with post count per category |
|
| 126 | +- **Category pages** at `/categories/tech/` with all posts in a category |
|
| 127 | +- **Tag and category badges** on post cards and detail pages |
|
| 128 | +- Tags and categories are read from YAML frontmatter (`tags`, `categories`) |
|
| 127 | 129 | |
| 128 | -### Volltextsuche |
|
| 130 | +### Full-Text Search |
|
| 129 | 131 | |
| 130 | -QuillDrop enthält eine integrierte Client-seitige Suche, die komplett ohne Backend auskommt: |
|
| 132 | +QuillDrop includes an integrated client-side search that works entirely without a backend: |
|
| 131 | 133 | |
| 132 | -- **Suchindex** — Beim Generieren wird eine `search-index.json` mit allen Posts erstellt |
|
| 133 | -- **Lazy Loading** — Der Suchindex wird erst beim ersten Öffnen der Suche geladen |
|
| 134 | -- **Multi-Term-Suche** — Mehrere Suchbegriffe werden mit UND verknüpft |
|
| 135 | -- **Felder** — Durchsucht Titel, Vorschau, Tags und Kategorien |
|
| 136 | -- **Keyboard-Shortcut** — `Ctrl+K` / `Cmd+K` öffnet die Suche |
|
| 137 | -- **Lupe in der Navbar** — Klick auf das Such-Icon öffnet das Suchfeld |
|
| 138 | -- **Debounce** — Suchergebnisse erscheinen nach 200ms Tippverzögerung |
|
| 139 | -- **Maximal 8 Treffer** mit Highlighting der Suchbegriffe |
|
| 140 | -- **Escape** oder Klick außerhalb schließt die Suche |
|
| 141 | -- Kein externer Dienst, kein Framework — reines Vanilla JavaScript |
|
| 134 | +- **Search index** — A `search-index.json` with all posts is generated during build |
|
| 135 | +- **Lazy loading** — The search index is only loaded when the search is first opened |
|
| 136 | +- **Multi-term search** — Multiple search terms are combined with AND |
|
| 137 | +- **Fields** — Searches title, preview, tags, and categories |
|
| 138 | +- **Keyboard shortcut** — `Ctrl+K` / `Cmd+K` opens the search |
|
| 139 | +- **Magnifying glass in the navbar** — Click the search icon to open the search field |
|
| 140 | +- **Debounce** — Search results appear after 200ms typing delay |
|
| 141 | +- **Maximum 8 results** with highlighting of search terms |
|
| 142 | +- **Escape** or click outside closes the search |
|
| 143 | +- No external service, no framework — pure vanilla JavaScript |
|
| 142 | 144 | |
| 143 | -### Artikel-Navigation |
|
| 145 | +### Article Navigation |
|
| 144 | 146 | |
| 145 | -Am Ende jedes Blog-Posts wird eine Navigation zum vorherigen und nächsten Artikel angezeigt: |
|
| 147 | +At the end of each blog post, navigation to the previous and next article is displayed: |
|
| 146 | 148 | |
| 147 | -- **Neuerer Artikel** (← links) — Verlinkt zum chronologisch neueren Post |
|
| 148 | -- **Älterer Artikel** (→ rechts) — Verlinkt zum chronologisch älteren Post |
|
| 149 | -- Beim neuesten Artikel wird nur "Älterer Artikel" angezeigt |
|
| 150 | -- Beim ältesten Artikel wird nur "Neuerer Artikel" angezeigt |
|
| 151 | -- Zeigt jeweils den Titel des verlinkten Artikels an |
|
| 149 | +- **Newer article** (← left) — Links to the chronologically newer post |
|
| 150 | +- **Older article** (→ right) — Links to the chronologically older post |
|
| 151 | +- On the newest article, only "Older article" is shown |
|
| 152 | +- On the oldest article, only "Newer article" is shown |
|
| 153 | +- Displays the title of the linked article |
|
| 152 | 154 | |
| 153 | -### Inhaltsverzeichnis (Table of Contents) |
|
| 155 | +### Table of Contents |
|
| 154 | 156 | |
| 155 | -Posts können ein automatisch generiertes Inhaltsverzeichnis aktivieren: |
|
| 157 | +Posts can activate an automatically generated table of contents: |
|
| 156 | 158 | |
| 157 | -- Aktivierung über `toc: true` im Frontmatter |
|
| 158 | -- Unterstützt **H1, H2 und H3** Überschriften |
|
| 159 | -- **Relative Einrückung** — Das TOC erkennt die minimale Heading-Ebene und rückt relativ dazu ein |
|
| 160 | -- Automatische Anchor-Links zu den jeweiligen Überschriften |
|
| 161 | -- Wird client-seitig generiert für schnelle Seitenladezeit |
|
| 159 | +- Enabled via `toc: true` in the frontmatter |
|
| 160 | +- Supports **H1, H2, and H3** headings |
|
| 161 | +- **Relative indentation** — The TOC detects the minimum heading level and indents relative to it |
|
| 162 | +- Automatic anchor links to the respective headings |
|
| 163 | +- Generated client-side for fast page load times |
|
| 162 | 164 | |
| 163 | -### Statische Seiten |
|
| 165 | +### Static Pages |
|
| 164 | 166 | |
| 165 | -Neben Blog-Posts unterstützt QuillDrop statische Seiten für: |
|
| 167 | +In addition to blog posts, QuillDrop supports static pages for: |
|
| 166 | 168 | |
| 167 | -- Impressum, Datenschutzerklärung |
|
| 168 | -- Über mich / About |
|
| 169 | -- Projektseiten (mit Unterseiten) |
|
| 170 | -- Beliebige weitere Seiten |
|
| 169 | +- Legal notice, privacy policy |
|
| 170 | +- About me / About |
|
| 171 | +- Project pages (with subpages) |
|
| 172 | +- Any additional pages |
|
| 171 | 173 | |
| 172 | -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. |
|
| 174 | +Pages are stored as Markdown files in the `sites/` directory. Nested directories are automatically recognized — e.g., `sites/projects/vm-tracker/index.md` becomes accessible at `/sites/projects/vm-tracker`. |
|
| 173 | 175 | |
| 174 | 176 | ### RSS Feed |
| 175 | 177 | |
| 176 | -Automatisch generierter RSS 2.0 Feed unter `/index.xml` mit: |
|
| 178 | +Automatically generated RSS 2.0 feed at `/index.xml` with: |
|
| 177 | 179 | |
| 178 | -- Den letzten 20 Posts |
|
| 179 | -- Titel, Link, Vorschau und Veröffentlichungsdatum |
|
| 180 | -- RSS-Autodiscovery im HTML-Head |
|
| 181 | -- RSS-Icon in der Navigation |
|
| 182 | -- URL `/index.xml` für Kompatibilität mit bestehenden Blog-Setups |
|
| 180 | +- The latest 20 posts |
|
| 181 | +- Title, link, preview, and publication date |
|
| 182 | +- RSS autodiscovery in the HTML head |
|
| 183 | +- RSS icon in the navigation |
|
| 184 | +- URL `/index.xml` for compatibility with existing blog setups |
|
| 183 | 185 | |
| 184 | -### Cover-Bilder |
|
| 186 | +### Cover Images |
|
| 185 | 187 | |
| 186 | -Posts können ein Cover-Bild definieren, das sowohl auf der Startseite (als Post-Card) als auch auf der Einzelansicht angezeigt wird: |
|
| 188 | +Posts can define a cover image that is displayed both on the homepage (as a post card) and on the detail view: |
|
| 187 | 189 | |
| 188 | -- **21:9 Aspect Ratio** auf Post-Cards mit Zoom-on-Hover Effekt |
|
| 189 | -- **Volle Breite** auf der Einzelpost-Seite |
|
| 190 | -- **Lazy Loading** für optimale Performance |
|
| 191 | -- **Fallback** von `cover` auf `featureImage` |
|
| 190 | +- **21:9 aspect ratio** on post cards with zoom-on-hover effect |
|
| 191 | +- **Full width** on the single post page |
|
| 192 | +- **Lazy loading** for optimal performance |
|
| 193 | +- **Fallback** from `cover` to `featureImage` |
|
| 192 | 194 | |
| 193 | -## Architektur |
|
| 195 | +## Architecture |
|
| 194 | 196 | |
| 195 | -### Projektstruktur |
|
| 197 | +### Project Structure |
|
| 196 | 198 | |
| 197 | 199 | ``` |
| 198 | 200 | quilldrop/ |
| 199 | -├── main.go # CLI Entry Point |
|
| 200 | -├── config.yaml # Konfiguration |
|
| 201 | -├── content/ # Blog-Posts (Markdown) |
|
| 202 | -│ ├── 2025-11-06-mein-post.md |
|
| 201 | +├── main.go # CLI entry point |
|
| 202 | +├── config.yaml # Configuration |
|
| 203 | +├── content/ # Blog posts (Markdown) |
|
| 204 | +│ ├── 2025-11-06-my-post.md |
|
| 203 | 205 | │ └── ... |
| 204 | -├── sites/ # Statische Seiten |
|
| 205 | -│ ├── ueber-mich.md |
|
| 206 | -│ ├── impressum.md |
|
| 207 | -│ └── projekte/ |
|
| 208 | -│ └── mein-projekt/ |
|
| 206 | +├── sites/ # Static pages |
|
| 207 | +│ ├── about.md |
|
| 208 | +│ ├── legal.md |
|
| 209 | +│ └── projects/ |
|
| 210 | +│ └── my-project/ |
|
| 209 | 211 | │ └── index.md |
| 210 | -├── static/ # Statische Assets |
|
| 212 | +├── static/ # Static assets |
|
| 211 | 213 | │ ├── css/style.css |
| 212 | 214 | │ ├── js/ |
| 213 | -│ │ ├── theme.js # Dark/Light Toggle + TOC Generator |
|
| 214 | -│ │ └── search.js # Client-seitige Volltextsuche |
|
| 215 | +│ │ ├── theme.js # Dark/Light toggle + TOC generator |
|
| 216 | +│ │ └── search.js # Client-side full-text search |
|
| 215 | 217 | │ └── images/ |
| 216 | 218 | ├── internal/ |
| 217 | -│ ├── config/config.go # YAML Config Loader |
|
| 219 | +│ ├── config/config.go # YAML config loader |
|
| 218 | 220 | │ ├── content/ |
| 219 | -│ │ ├── post.go # Post Struct + FlexTime + Tags/Categories |
|
| 220 | -│ │ ├── parser.go # Markdown + Frontmatter Parser |
|
| 221 | -│ │ └── page.go # Statische Seiten Parser |
|
| 222 | -│ ├── server/server.go # HTTP Server |
|
| 221 | +│ │ ├── post.go # Post struct + FlexTime + Tags/Categories |
|
| 222 | +│ │ ├── parser.go # Markdown + frontmatter parser |
|
| 223 | +│ │ └── page.go # Static pages parser |
|
| 224 | +│ ├── server/server.go # HTTP server |
|
| 223 | 225 | │ ├── generator/ |
| 224 | -│ │ ├── generator.go # Static Site Generator |
|
| 225 | -│ │ └── search.go # Search-Index Generator (JSON) |
|
| 226 | +│ │ ├── generator.go # Static site generator |
|
| 227 | +│ │ └── search.go # Search index generator (JSON) |
|
| 226 | 228 | │ └── templates/ |
| 227 | -│ ├── render.go # Template Engine + Functions |
|
| 228 | -│ ├── rss.go # RSS Feed Generator |
|
| 229 | -│ ├── base.html # Base Layout + Navbar + Suche |
|
| 230 | -│ ├── home.html # Homepage + Pagination |
|
| 231 | -│ ├── post.html # Einzelner Post + Prev/Next Navigation |
|
| 232 | -│ ├── page.html # Statische Seite |
|
| 233 | -│ ├── tags.html # Tag-Übersicht |
|
| 234 | -│ ├── tag.html # Tag-Seite |
|
| 235 | -│ ├── categories.html # Kategorie-Übersicht |
|
| 236 | -│ └── category.html # Kategorie-Seite |
|
| 237 | -└── output/ # Generierte statische Dateien |
|
| 229 | +│ ├── render.go # Template engine + functions |
|
| 230 | +│ ├── rss.go # RSS feed generator |
|
| 231 | +│ ├── base.html # Base layout + navbar + search |
|
| 232 | +│ ├── home.html # Homepage + pagination |
|
| 233 | +│ ├── post.html # Single post + prev/next navigation |
|
| 234 | +│ ├── page.html # Static page |
|
| 235 | +│ ├── tags.html # Tag overview |
|
| 236 | +│ ├── tag.html # Tag page |
|
| 237 | +│ ├── categories.html # Category overview |
|
| 238 | +│ └── category.html # Category page |
|
| 239 | +└── output/ # Generated static files |
|
| 238 | 240 | ``` |
| 239 | 241 | |
| 240 | -### Technologie-Stack |
|
| 242 | +### Technology Stack |
|
| 241 | 243 | |
| 242 | -| Komponente | Technologie | |
|
| 243 | -|-----------|-------------| |
|
| 244 | -| Sprache | Go (Standard Library + minimale Dependencies) | |
|
| 245 | -| HTTP Server | `net/http` (Go Standard Library) | |
|
| 246 | -| Templates | `html/template` mit `embed.FS` | |
|
| 244 | +| Component | Technology | |
|
| 245 | +|-----------|------------| |
|
| 246 | +| Language | Go (standard library + minimal dependencies) | |
|
| 247 | +| HTTP Server | `net/http` (Go standard library) | |
|
| 248 | +| Templates | `html/template` with `embed.FS` | |
|
| 247 | 249 | | Markdown | Goldmark + GFM + Emoji + Chroma | |
| 248 | -| Konfiguration | YAML via `gopkg.in/yaml.v3` | |
|
| 249 | -| Syntax Highlighting | Chroma (Dracula Theme) | |
|
| 250 | +| Configuration | YAML via `gopkg.in/yaml.v3` | |
|
| 251 | +| Syntax Highlighting | Chroma (Dracula theme) | |
|
| 250 | 252 | | Fonts | Inter + JetBrains Mono (Google Fonts) | |
| 251 | -| CSS | Vanilla CSS mit Custom Properties | |
|
| 252 | -| JavaScript | Vanilla JS — Theme Toggle, Suche, TOC (kein Framework) | |
|
| 253 | +| CSS | Vanilla CSS with custom properties | |
|
| 254 | +| JavaScript | Vanilla JS — theme toggle, search, TOC (no framework) | |
|
| 253 | 255 | |
| 254 | 256 | ### Dependencies |
| 255 | 257 | |
| 256 | -QuillDrop hat bewusst minimale Abhängigkeiten - **kein Web-Framework**, **kein CSS-Framework**, **kein JS-Framework**: |
|
| 258 | +QuillDrop intentionally has minimal dependencies — **no web framework**, **no CSS framework**, **no JS framework**: |
|
| 257 | 259 | |
| 258 | -- `github.com/yuin/goldmark` - Markdown Parser (CommonMark-konform) |
|
| 259 | -- `github.com/yuin/goldmark-emoji` - Emoji Shortcodes |
|
| 260 | -- `github.com/yuin/goldmark-highlighting/v2` - Syntax Highlighting |
|
| 261 | -- `github.com/alecthomas/chroma/v2` - Syntax Highlighting Engine |
|
| 262 | -- `gopkg.in/yaml.v3` - YAML Parser |
|
| 260 | +- `github.com/yuin/goldmark` — Markdown parser (CommonMark compliant) |
|
| 261 | +- `github.com/yuin/goldmark-emoji` — Emoji shortcodes |
|
| 262 | +- `github.com/yuin/goldmark-highlighting/v2` — Syntax highlighting |
|
| 263 | +- `github.com/alecthomas/chroma/v2` — Syntax highlighting engine |
|
| 264 | +- `gopkg.in/yaml.v3` — YAML parser |
|
| 263 | 265 | |
| 264 | 266 | ### Embedded Assets |
| 265 | 267 | |
| 266 | -Alle HTML-Templates werden via Go's `//go:embed` Directive direkt in das Binary eingebettet. Das bedeutet: |
|
| 268 | +All HTML templates are embedded directly into the binary via Go's `//go:embed` directive. This means: |
|
| 267 | 269 | |
| 268 | -- **Einzelnes Binary** - Keine externen Template-Dateien nötig |
|
| 269 | -- **Schneller Start** - Kein Dateisystem-Zugriff für Templates |
|
| 270 | -- **Einfaches Deployment** - Ein Binary + Config + Content = fertig |
|
| 270 | +- **Single binary** — No external template files needed |
|
| 271 | +- **Fast startup** — No filesystem access for templates |
|
| 272 | +- **Easy deployment** — One binary + config + content = done |
|
| 271 | 273 | |
| 272 | -## Konfiguration |
|
| 274 | +## Configuration |
|
| 273 | 275 | |
| 274 | -Die gesamte Konfiguration erfolgt über eine einzige `config.yaml`: |
|
| 276 | +All configuration is done via a single `config.yaml`: |
|
| 275 | 277 | |
| 276 | 278 | ```yaml |
| 277 | -title: "Mein Blog" |
|
| 279 | +title: "My Blog" |
|
| 278 | 280 | description: "Tech Blog - DevOps, Kubernetes, Self-Hosted" |
| 279 | -author: "Max Mustermann" |
|
| 280 | -baseURL: "https://mein-blog.de" |
|
| 281 | +author: "Jane Doe" |
|
| 282 | +baseURL: "https://my-blog.com" |
|
| 281 | 283 | port: 8080 |
| 282 | 284 | postsPerPage: 5 |
| 283 | 285 | contentDir: "content" |
| @@ -289,118 +291,118 @@ menu: | ||
| 289 | 291 | url: "/" |
| 290 | 292 | - label: "Tags" |
| 291 | 293 | url: "/tags" |
| 292 | -- label: "Über mich" |
|
| 293 | -url: "/sites/ueber-mich" |
|
| 294 | +- label: "About" |
|
| 295 | +url: "/sites/about" |
|
| 294 | 296 | ``` |
| 295 | 297 | |
| 296 | -| Option | Default | Beschreibung | |
|
| 298 | +| Option | Default | Description | |
|
| 297 | 299 | |--------|---------|-------------| |
| 298 | -| `title` | - | Titel der Website | |
|
| 299 | -| `description` | - | Beschreibung (Meta-Tag + Hero) | |
|
| 300 | -| `author` | - | Autor der Website | |
|
| 301 | -| `baseURL` | - | Basis-URL für RSS und absolute Links | |
|
| 302 | -| `port` | `8080` | Port für den dynamischen Server | |
|
| 303 | -| `postsPerPage` | `5` | Anzahl Posts pro Seite | |
|
| 304 | -| `contentDir` | `content` | Verzeichnis für Blog-Posts | |
|
| 305 | -| `sitesDir` | `sites` | Verzeichnis für statische Seiten | |
|
| 306 | -| `outputDir` | `output` | Ausgabeverzeichnis für statische Generierung | |
|
| 307 | -| `menu` | `[]` | Navigationsmenü mit optionalen Untermenüs | |
|
| 308 | - | |
| 309 | -## Schnellstart |
|
| 300 | +| `title` | — | Website title | |
|
| 301 | +| `description` | — | Description (meta tag + hero) | |
|
| 302 | +| `author` | — | Website author | |
|
| 303 | +| `baseURL` | — | Base URL for RSS and absolute links | |
|
| 304 | +| `port` | `8080` | Port for the dynamic server | |
|
| 305 | +| `postsPerPage` | `5` | Number of posts per page | |
|
| 306 | +| `contentDir` | `content` | Directory for blog posts | |
|
| 307 | +| `sitesDir` | `sites` | Directory for static pages | |
|
| 308 | +| `outputDir` | `output` | Output directory for static generation | |
|
| 309 | +| `menu` | `[]` | Navigation menu with optional submenus | |
|
| 310 | + | |
| 311 | +## Quick Start |
|
| 310 | 312 | |
| 311 | 313 | ### Installation |
| 312 | 314 | |
| 313 | 315 | ```bash |
| 314 | -# Repository klonen |
|
| 316 | +# Clone the repository |
|
| 315 | 317 | git clone https://github.com/ruedigerp/quilldrop.git |
| 316 | 318 | cd quilldrop |
| 317 | 319 | |
| 318 | -# Dependencies laden |
|
| 320 | +# Download dependencies |
|
| 319 | 321 | go mod download |
| 320 | 322 | |
| 321 | -# Binary bauen |
|
| 323 | +# Build the binary |
|
| 322 | 324 | go build -o quilldrop . |
| 323 | 325 | ``` |
| 324 | 326 | |
| 325 | -### Neuen Post erstellen |
|
| 327 | +### Create a New Post |
|
| 326 | 328 | |
| 327 | -Eine neue Markdown-Datei im `content/`-Verzeichnis anlegen: |
|
| 329 | +Create a new Markdown file in the `content/` directory: |
|
| 328 | 330 | |
| 329 | 331 | ```bash |
| 330 | -touch content/2025-12-01-mein-erster-post.md |
|
| 332 | +touch content/2025-12-01-my-first-post.md |
|
| 331 | 333 | ``` |
| 332 | 334 | |
| 333 | 335 | ```markdown |
| 334 | 336 | --- |
| 335 | -title: "Mein erster Post" |
|
| 337 | +title: "My First Post" |
|
| 336 | 338 | date: 2025-12-01 10:00:00 |
| 337 | -author: "Max Mustermann" |
|
| 339 | +author: "Jane Doe" |
|
| 338 | 340 | tags: [Blog, QuillDrop] |
| 339 | -preview: "Das ist mein erster Post mit QuillDrop!" |
|
| 341 | +preview: "This is my first post with QuillDrop!" |
|
| 340 | 342 | toc: false |
| 341 | 343 | --- |
| 342 | 344 | |
| 343 | -# Willkommen |
|
| 345 | +# Welcome |
|
| 344 | 346 | |
| 345 | -Das ist mein erster Post mit **QuillDrop**. |
|
| 347 | +This is my first post with **QuillDrop**. |
|
| 346 | 348 | |
| 347 | 349 | ``` |
| 348 | 350 | |
| 349 | -### Lokale Vorschau |
|
| 351 | +### Local Preview |
|
| 350 | 352 | |
| 351 | 353 | ```bash |
| 352 | -# Dynamischen Server starten |
|
| 354 | +# Start the dynamic server |
|
| 353 | 355 | ./quilldrop serve |
| 354 | 356 | |
| 355 | -# Oder direkt mit Go |
|
| 357 | +# Or run directly with Go |
|
| 356 | 358 | go run . serve |
| 357 | 359 | ``` |
| 358 | 360 | |
| 359 | -Dann im Browser: [http://localhost:8080](http://localhost:8080) |
|
| 361 | +Then open in the browser: [http://localhost:8080](http://localhost:8080) |
|
| 360 | 362 | |
| 361 | -### Statische Seite generieren |
|
| 363 | +### Generate Static Site |
|
| 362 | 364 | |
| 363 | 365 | ```bash |
| 364 | -# HTML-Dateien generieren |
|
| 366 | +# Generate HTML files |
|
| 365 | 367 | ./quilldrop generate |
| 366 | 368 | |
| 367 | -# Generierte Dateien befinden sich in output/ |
|
| 369 | +# Generated files are in output/ |
|
| 368 | 370 | ls output/ |
| 369 | 371 | ``` |
| 370 | 372 | |
| 371 | -Die generierten Dateien im `output/`-Verzeichnis können direkt auf einen Webserver (Nginx, Apache, Caddy) oder CDN deployed werden. |
|
| 373 | +The generated files in the `output/` directory can be deployed directly to a web server (Nginx, Apache, Caddy) or CDN. |
|
| 372 | 374 | |
| 373 | -## URL-Schema |
|
| 375 | +## URL Schema |
|
| 374 | 376 | |
| 375 | -Alle URLs verwenden konsequent Trailing Slashes, um serverseitige Redirects zu vermeiden: |
|
| 377 | +All URLs consistently use trailing slashes to avoid server-side redirects: |
|
| 376 | 378 | |
| 377 | -| URL | Beschreibung | |
|
| 379 | +| URL | Description | |
|
| 378 | 380 | |-----|-------------| |
| 379 | -| `/` | Startseite (letzte N Posts) | |
|
| 380 | -| `/page/2/` | Seite 2 der Post-Liste | |
|
| 381 | -| `/posts/2025-11-06-mein-post/` | Einzelner Blog-Post | |
|
| 382 | -| `/tags/` | Tag-Übersicht | |
|
| 383 | -| `/tags/kubernetes/` | Posts mit Tag "Kubernetes" | |
|
| 384 | -| `/categories/` | Kategorie-Übersicht | |
|
| 385 | -| `/categories/technik/` | Posts in Kategorie "Technik" | |
|
| 386 | -| `/sites/ueber-mich/` | Statische Seite | |
|
| 387 | -| `/sites/projekte/vm-tracker/` | Verschachtelte Projektseite | |
|
| 388 | -| `/index.xml` | RSS Feed | |
|
| 389 | -| `/search-index.json` | Suchindex (JSON) | |
|
| 390 | -| `/static/css/style.css` | Statische Assets | |
|
| 391 | -| `/images/posts/2025/11/cover.webp` | Bilder | |
|
| 392 | - | |
| 393 | -## Warum QuillDrop? |
|
| 394 | - | |
| 395 | -- **Keine Datenbank** - Dateisystem als einzige Datenquelle |
|
| 396 | -- **Keine Build-Pipeline** - Ein `go build` und fertig |
|
| 397 | -- **Keine JS-Frameworks** - Vanilla JavaScript für Theme, Suche und TOC |
|
| 398 | -- **Minimale Dependencies** - 5 Go-Packages, alle fokussiert auf Markdown |
|
| 399 | -- **Blitzschnell** - Generiert 100+ Posts in unter 3 Sekunden |
|
| 400 | -- **Einzelnes Binary** - Templates eingebettet, kein Runtime-Setup |
|
| 401 | -- **Hugo-kompatibel** - Bestehende Hugo-Posts mit Frontmatter funktionieren |
|
| 402 | -- **Dual-Mode** - Entwicklung mit Server, Produktion mit Static Generator |
|
| 403 | - | |
| 404 | -## Lizenz |
|
| 405 | - | |
| 406 | -QuillDrop ist Open Source. |
|
| 381 | +| `/` | Homepage (latest N posts) | |
|
| 382 | +| `/page/2/` | Page 2 of the post list | |
|
| 383 | +| `/posts/2025-11-06-my-post/` | Single blog post | |
|
| 384 | +| `/tags/` | Tag overview | |
|
| 385 | +| `/tags/kubernetes/` | Posts with tag "Kubernetes" | |
|
| 386 | +| `/categories/` | Category overview | |
|
| 387 | +| `/categories/tech/` | Posts in category "Tech" | |
|
| 388 | +| `/sites/about/` | Static page | |
|
| 389 | +| `/sites/projects/vm-tracker/` | Nested project page | |
|
| 390 | +| `/index.xml` | RSS feed | |
|
| 391 | +| `/search-index.json` | Search index (JSON) | |
|
| 392 | +| `/static/css/style.css` | Static assets | |
|
| 393 | +| `/images/posts/2025/11/cover.webp` | Images | |
|
| 394 | + | |
| 395 | +## Why QuillDrop? |
|
| 396 | + | |
| 397 | +- **No database** — The filesystem is the only data source |
|
| 398 | +- **No build pipeline** — A single `go build` and you're done |
|
| 399 | +- **No JS frameworks** — Vanilla JavaScript for theme, search, and TOC |
|
| 400 | +- **Minimal dependencies** — 5 Go packages, all focused on Markdown |
|
| 401 | +- **Blazing fast** — Generates 100+ posts in under 3 seconds |
|
| 402 | +- **Single binary** — Templates embedded, no runtime setup needed |
|
| 403 | +- **Hugo compatible** — Existing Hugo posts with frontmatter just work |
|
| 404 | +- **Dual-mode** — Development with server, production with static generator |
|
| 405 | + | |
| 406 | +## License |
|
| 407 | + | |
| 408 | +QuillDrop is open source. |