LabCodeHub öffentliche Ansicht
Anmelden
Küpper / Quildrop öffentlich
Branch: main
Klonen
Verlauf
v1.0.5 185570fd erstellt vor 14 Tagen von Rüdiger Küpper · 11 Datei(en) · 125.3 MB im Ursprungs-Repo
checksums.txt 896 B
quilldrop-darwin-amd64 13.2 MB
quilldrop-darwin-arm64 12.4 MB
quilldrop-linux-386 12.3 MB
quilldrop-linux-amd64 12.9 MB
quilldrop-linux-arm64 12.1 MB
quilldrop-linux-armv6 12.3 MB
quilldrop-linux-armv7 12.3 MB
quilldrop-windows-386.exe 12.6 MB
quilldrop-windows-amd64.exe 13.2 MB
quilldrop-windows-arm64.exe 12.2 MB
R Rüdiger Küpper Commit binaries for
1783c488 vor 14 Tagen
.github fix: new version with themes + multi arch builds vor 14 Tagen
content fix: first release vor 6 Monaten
dist Commit binaries for vor 14 Tagen
internal fix: add sitemap and robots.txt vor 14 Tagen
sites fix: update quilldrop doku vor 6 Monaten
static fix: new version with themes + multi arch builds vor 14 Tagen
themes fix: new version with themes + multi arch builds vor 14 Tagen
.builder.yaml fix: add builder.yaml vor 14 Tagen
.gitignore fix: new version with themes + multi arch builds vor 14 Tagen
.releaserc fix: first commit vor 6 Monaten
CHANGELOG.md fix: remove old stuff in changelog vor 6 Monaten
config.yaml fix: add sitemap and robots.txt vor 14 Tagen
Dockerfile-images fix: images docker image vor 6 Monaten
Dockerfile-static chore(deps): update golang docker tag to v1.26 (#4) vor 6 Monaten
go.mod fix: first commit vor 6 Monaten
go.sum fix: first commit vor 6 Monaten
main.go fix: new version with themes + multi arch builds vor 14 Tagen
Makefile fix: makefile add commit-build vor 14 Tagen
qd-darwin fix: new version with themes + multi arch builds vor 14 Tagen
README-de.md fix: add sitemap and robots.txt vor 14 Tagen
README.md fix: add sitemap and robots.txt vor 14 Tagen
renovate.json fix: imagename vor 6 Monaten
README.md

QuillDrop

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.

🇩🇪 Deutsche Version

Philosophy

Write. Save. Published.

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.

Features

Dual-Mode Operation

QuillDrop supports two modes of operation in a single binary:

  • quilldrop serve — Starts a dynamic HTTP server for local development and preview. Ideal for writing and instantly testing new posts.
  • quilldrop generate — Generates a complete static website as HTML files. Perfect for deployment on Nginx, Apache, CDN, or GitHub Pages.

Markdown with YAML Frontmatter

Posts and pages are written as simple Markdown files with YAML frontmatter:

---
title: "My New Blog Post"
date: 2025-11-06 12:00:00
author: "Jane Doe"
cover: "/images/posts/2025/11/cover.webp"
tags: [Kubernetes, DevOps, Self-Hosted]
categories: [Tech]
preview: "A short preview of the post..."
draft: false
toc: true
---

# Post starts here

Regular Markdown with all the extras...

Supported frontmatter fields:

FieldDescription
titlePost title
datePublication date (multiple formats supported)
updateLast updated
authorPost author
cover / featureImageCover image (with fallback)
tagsList of tags
categoriesList of categories
previewCustom preview (otherwise auto-generated from first paragraph)
draftDraft — will not be published
tocAutomatically generate table of contents
hideHide post
topPin post to top

Extended Markdown Rendering

QuillDrop uses Goldmark as its Markdown engine with the following extensions:

  • GitHub Flavored Markdown (GFM) — Tables, strikethrough, autolinks, task lists
  • Syntax Highlighting — Over 200 programming languages with the Dracula theme via Chroma
  • Emoji Support — Shortcodes like :rocket:, :tada:, :satellite:
  • Automatic Heading IDs — For anchor linking and table of contents
  • Raw HTML — Embed HTML directly in Markdown
  • Hugo Compatibility{{</* rawhtml */>}} shortcodes are processed automatically

Responsive Design with Dark/Light Theme

The included theme offers:

  • Dark Mode as default with a light alternative theme
  • Theme Toggle with localStorage persistence (survives page reloads)
  • Futuristic Design — Dark backgrounds, cyan accents, subtle glow effects
  • Responsive Layout — Mobile-first, optimized for all screen sizes
  • Hamburger Navigation on mobile devices with fullscreen overlay and dedicated stacking context
  • Dropdown Menus for nested navigation (touch-optimized on mobile)
  • Integrated Search — Magnifying glass in the navbar with Ctrl+K shortcut
  • Typography — Inter as body font, JetBrains Mono for code and metadata

Navigation and Menu

The navigation menu is fully configured via config.yaml and supports nested dropdown menus:

menu:
  - label: "Home"
    url: "/"
  - label: "Projects"
    children:
      - label: "VM-Manager"
        url: "/sites/projects/vm-manager"
      - label: "VM-Tracker"
        url: "/sites/projects/vm-tracker"
      - label: "QuillDrop"
        url: "/sites/projects/quilldrop"
  - label: "About"
    url: "/sites/about"
  - label: "Tags"
    url: "/tags"

New menu items and submenus can be added at any time by simply extending the YAML configuration.

Pagination

The homepage displays a configurable number of posts per page (default: 5). Pagination features:

  • Smart page numbering — Shows first and last page, plus a window around the current page
  • Ellipsis for many pages (1 ... 10 11 12 13 14 ... 23)
  • Newer/Older buttons for quick navigation
  • Pretty URLs/page/2, /page/3, etc.
  • SEO-friendly: /page/1 automatically redirects to / (301)

Tags and Categories

QuillDrop supports both tags and categories for content organization:

  • Tag overview at /tags/ with post count per tag
  • Tag pages at /tags/kubernetes/ with all posts for a tag
  • Category overview at /categories/ with post count per category
  • Category pages at /categories/tech/ with all posts in a category
  • Tag and category badges on post cards and detail pages
  • Tags and categories are read from YAML frontmatter (tags, categories)

Full-Text Search

QuillDrop includes an integrated client-side search that works entirely without a backend:

  • Search index — A search-index.json with all posts is generated during build
  • Lazy loading — The search index is only loaded when the search is first opened
  • Multi-term search — Multiple search terms are combined with AND
  • Fields — Searches title, preview, tags, and categories
  • Keyboard shortcutCtrl+K / Cmd+K opens the search
  • Magnifying glass in the navbar — Click the search icon to open the search field
  • Debounce — Search results appear after 200ms typing delay
  • Maximum 8 results with highlighting of search terms
  • Escape or click outside closes the search
  • No external service, no framework — pure vanilla JavaScript

Article Navigation

At the end of each blog post, navigation to the previous and next article is displayed:

  • Newer article (← left) — Links to the chronologically newer post
  • Older article (→ right) — Links to the chronologically older post
  • On the newest article, only "Older article" is shown
  • On the oldest article, only "Newer article" is shown
  • Displays the title of the linked article

Table of Contents

Posts can activate an automatically generated table of contents:

  • Enabled via toc: true in the frontmatter
  • Supports H1, H2, and H3 headings
  • Relative indentation — The TOC detects the minimum heading level and indents relative to it
  • Automatic anchor links to the respective headings
  • Generated client-side for fast page load times

Static Pages

In addition to blog posts, QuillDrop supports static pages for:

  • Legal notice, privacy policy
  • About me / About
  • Project pages (with subpages)
  • Any additional pages

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.

RSS Feed

Automatically generated RSS 2.0 feed at /index.xml with:

  • The latest 20 posts
  • Title, link, preview, and publication date
  • RSS autodiscovery in the HTML head
  • RSS icon in the navigation
  • URL /index.xml for compatibility with existing blog setups

Sitemap

Alongside the RSS feed, a sitemap.xml following the sitemaps.org protocol 0.9 is produced — served at /sitemap.xml by the dynamic server and written by the static generator. It contains:

  • Homepage and every pagination page (/page/2/, ...)
  • All blog posts (lastmod from update, falling back to date)
  • All static pages from sites/
  • Tag and category overviews plus every single tag/category page

The sitemap can be switched on and off in the config (default: on):

sitemap:
  enabled: true   # false disables /sitemap.xml entirely

robots.txt

A robots.txt is generated as well and served at /robots.txt. It references the sitemap automatically whenever sitemap generation is enabled, and is configurable (default: on):

robots:
  enabled: true
  userAgent: "*"        # optional, defaults to "*"
  disallow:             # optional
    - /search-index.json
  allow:                # optional
    - /

Without custom allow/disallow rules an Allow: / is written, i.e. the whole site is crawlable:

User-agent: *
Allow: /

Sitemap: https://blog.kuepper.nrw/sitemap.xml

If sitemap.enabled: false or baseURL is empty, the Sitemap: line is omitted.

Cover Images

Posts can define a cover image that is displayed both on the homepage (as a post card) and on the detail view:

  • 21:9 aspect ratio on post cards with zoom-on-hover effect
  • Full width on the single post page
  • Lazy loading for optimal performance
  • Fallback from cover to featureImage

Architecture

Project Structure

quilldrop/
├── main.go                          # CLI entry point
├── config.yaml                      # Configuration
├── content/                         # Blog posts (Markdown)
│   ├── 2025-11-06-my-post.md
│   └── ...
├── sites/                           # Static pages
│   ├── about.md
│   ├── legal.md
│   └── projects/
│       └── my-project/
│           └── index.md
├── static/                          # Site assets (icons, images, ...)
│   ├── icons/
│   └── images/
├── themes/                          # Themes — one directory per theme
│   └── default/
│       ├── templates/
│       │   ├── base.html            # Base layout + navbar + search
│       │   ├── home.html            # Homepage + pagination
│       │   ├── post.html            # Single post + prev/next navigation
│       │   ├── page.html            # Static page
│       │   ├── tags.html            # Tag overview
│       │   ├── tag.html             # Tag page
│       │   ├── categories.html      # Category overview
│       │   └── category.html        # Category page
│       └── static/                  # Theme assets (merged into /static/)
│           ├── css/style.css
│           └── js/
│               ├── theme.js         # Dark/Light toggle + TOC generator
│               └── search.js        # Client-side full-text search
├── internal/
│   ├── config/config.go             # YAML config loader
│   ├── content/
│   │   ├── post.go                  # Post struct + FlexTime + Tags/Categories
│   │   ├── parser.go                # Markdown + frontmatter parser
│   │   └── page.go                  # Static pages parser
│   ├── server/server.go             # HTTP server
│   ├── generator/
│   │   ├── generator.go             # Static site generator
│   │   ├── robots.go                # robots.txt generator
│   │   └── search.go                # Search index generator (JSON)
│   └── templates/
│       ├── render.go                # Template engine + functions (loads the theme)
│       ├── rss.go                   # RSS feed generator
│       └── sitemap.go               # sitemap.xml generator
└── output/                          # Generated static files

Technology Stack

ComponentTechnology
LanguageGo (standard library + minimal dependencies)
HTTP Servernet/http (Go standard library)
Templateshtml/template, loaded from themes/<name>/templates/ at runtime
MarkdownGoldmark + GFM + Emoji + Chroma
ConfigurationYAML via gopkg.in/yaml.v3
Syntax HighlightingChroma (Dracula theme)
FontsInter + JetBrains Mono (Google Fonts)
CSSVanilla CSS with custom properties
JavaScriptVanilla JS — theme toggle, search, TOC (no framework)

Dependencies

QuillDrop intentionally has minimal dependencies — no web framework, no CSS framework, no JS framework:

  • github.com/yuin/goldmark — Markdown parser (CommonMark compliant)
  • github.com/yuin/goldmark-emoji — Emoji shortcodes
  • github.com/yuin/goldmark-highlighting/v2 — Syntax highlighting
  • github.com/alecthomas/chroma/v2 — Syntax highlighting engine
  • gopkg.in/yaml.v3 — YAML parser

Themes

Templates and their assets live outside the binary, in themes/<name>/. The same
QuillDrop binary can therefore drive any number of websites, each with its own look:

themes/
├── default/
│   ├── templates/       # required: base, home, post, page, tags, tag, categories, category
│   └── static/          # optional: CSS, JS, theme images
└── newdesign/
    ├── templates/
    └── static/

The active theme is selected in config.yaml:

themesDir: "themes"   # default
theme: "default"      # reads from themes/default/

Or temporarily via flag, e.g. to preview a redesign:

./quilldrop serve -theme newdesign
./quilldrop generate -theme newdesign

Creating a new theme:

cp -r themes/default themes/newdesign      # or: make new-theme NAME=newdesign
# edit themes/newdesign/templates/*.html and themes/newdesign/static/css/style.css
./quilldrop serve -theme newdesign -dev

Live reload: With -dev the templates are re-read from the theme directory on
every request — changes to HTML, CSS and JS become visible after a browser reload,
without restarting the server (dev mode also sends Cache-Control: no-store so the
browser does not cache assets). A broken template returns a 500 instead of a
half-rendered page; the exact error with file and line is written to the server log.
Without -dev templates are parsed once at startup, as before. New or changed
Markdown files still require a restart.

A theme must provide all eight templates (base.html, home.html, post.html,
page.html, tags.html, tag.html, categories.html, category.html);
QuillDrop aborts with a clear error if one is missing or the theme does not exist.

Static assets are merged: themes/<name>/static/ is copied first, then the
site's own static/ on top — so site files (e.g. static/icons/favicon.ico)
override theme files of the same name. Design belongs to the theme (CSS, JS),
site-specific material stays in static/ (icons, images). Both are served under
/static/; static/images/ and static/videos/ are additionally published at
/images/ and /videos/.

Configuration

All configuration is done via a single config.yaml:

title: "My Blog"
description: "Tech Blog - DevOps, Kubernetes, Self-Hosted"
author: "Jane Doe"
baseURL: "https://my-blog.com"
port: 8080
postsPerPage: 5
contentDir: "content"
sitesDir: "sites"
staticDir: "static"
outputDir: "output"
themesDir: "themes"
theme: "default"

menu:
  - label: "Home"
    url: "/"
  - label: "Tags"
    url: "/tags"
  - label: "About"
    url: "/sites/about"
OptionDefaultDescription
titleWebsite title
descriptionDescription (meta tag + hero)
authorWebsite author
baseURLBase URL for RSS, sitemap and absolute links
port8080Port for the dynamic server
postsPerPage5Number of posts per page
contentDircontentDirectory for blog posts
sitesDirsitesDirectory for static pages
staticDirstaticDirectory for site assets
outputDiroutputOutput directory for static generation
themesDirthemesDirectory containing all themes
themedefaultActive theme, read from <themesDir>/<theme>/ (override: -theme)
menu[]Navigation menu with optional submenus
sitemap.enabledtrueGenerates/serves /sitemap.xml
robots.enabledtrueGenerates/serves /robots.txt (with sitemap reference)
robots.userAgent*User-agent line in robots.txt
robots.allow[]Additional Allow: rules
robots.disallow[]Additional Disallow: rules

Quick Start

Installation

# Clone the repository
git clone https://github.com/ruedigerp/quilldrop.git
cd quilldrop

# Download dependencies
go mod download

# Build the binary
go build -o quilldrop .

Create a New Post

Create a new Markdown file in the content/ directory:

touch content/2025-12-01-my-first-post.md
---
title: "My First Post"
date: 2025-12-01 10:00:00
author: "Jane Doe"
tags: [Blog, QuillDrop]
preview: "This is my first post with QuillDrop!"
toc: false
---

# Welcome

This is my first post with **QuillDrop**.

Local Preview

# Start the dynamic server
./quilldrop serve

# Or run directly with Go
go run . serve

# With template live reload (theme development)
./quilldrop serve -dev

Then open in the browser: http://localhost:8080

Generate Static Site

# Generate HTML files
./quilldrop generate

# Generated files are in output/
ls output/

The generated files in the output/ directory can be deployed directly to a web server (Nginx, Apache, Caddy) or CDN.

URL Schema

All URLs consistently use trailing slashes to avoid server-side redirects:

URLDescription
/Homepage (latest N posts)
/page/2/Page 2 of the post list
/posts/2025-11-06-my-post/Single blog post
/tags/Tag overview
/tags/kubernetes/Posts with tag "Kubernetes"
/categories/Category overview
/categories/tech/Posts in category "Tech"
/sites/about/Static page
/sites/projects/vm-tracker/Nested project page
/index.xmlRSS feed
/sitemap.xmlSitemap for search engines (if enabled)
/robots.txtCrawler rules + sitemap reference (if enabled)
/search-index.jsonSearch index (JSON)
/static/css/style.cssStatic assets
/images/posts/2025/11/cover.webpImages

Why QuillDrop?

  • No database — The filesystem is the only data source
  • No build pipeline — A single go build and you're done
  • No JS frameworks — Vanilla JavaScript for theme, search, and TOC
  • Minimal dependencies — 5 Go packages, all focused on Markdown
  • Blazing fast — Generates 100+ posts in under 3 seconds
  • Single binary — Templates embedded, no runtime setup needed
  • Hugo compatible — Existing Hugo posts with frontmatter just work
  • Dual-mode — Development with server, production with static generator

License

QuillDrop is open source.