Skip to content

Command Line Reference

This guide documents all BlogMore command-line options and commands.

Basic Usage

blogmore <command> [arguments] [options]

Commands

BlogMore provides several commands:

  • build - Generate the static site
  • serve - Generate and serve the site locally with auto-reload
  • publish - Build and publish the site to a git branch
  • lint - Check the site for common issues (broken links, etc.)
  • drafts - List the path to all posts marked as drafts
  • dump - Dump site content (posts, categories, tags, or series) to stdout as JSON (defaults to posts)
  • cache - Manage the BlogMore cache

Command Aliases

Several commands have aliases for convenience:

  • build, generate, gen - All equivalent
  • serve, test - Both start the development server

Global Options

--version

Display the BlogMore version and exit.

blogmore --version

Build Command

Generate a static site from Markdown posts.

Synopsis

blogmore build <content_dir> [options]
blogmore generate <content_dir> [options]
blogmore gen <content_dir> [options]

Arguments

content_dir (optional if specified in config file) : Directory containing your Markdown blog posts. BlogMore scans this directory recursively for .md files.

blogmore build posts/

Options

-c, --config <path>

Path to a YAML configuration file. If not specified, BlogMore automatically searches for blogmore.yaml or blogmore.yml in the current directory (.yaml takes precedence).

blogmore build posts/ --config custom-config.yaml

-t, --templates <path>

Directory containing custom Jinja2 templates. If not specified, uses the bundled default templates.

blogmore build posts/ --templates my-templates/

Custom templates should follow the structure of the default templates: - base.html - index.html - post.html - archive.html - tag.html - category.html - static/style.css

-o, --output <path>

Output directory for the generated site. Default: output/

blogmore build posts/ --output public/

--site-title <title>

Title of your blog site. Default: My Blog

blogmore build posts/ --site-title "Dave's Blog"

--site-subtitle <subtitle>

Subtitle or tagline for your site. Optional.

blogmore build posts/ \
  --site-title "Dave's Blog" \
  --site-subtitle "Thoughts on Python and technology"

--site-url <url>

Base URL of your site. Used for generating absolute URLs in RSS/Atom feeds and canonical URLs. Optional but recommended.

blogmore build posts/ --site-url "https://davep.org/blog"

--include-drafts

Include posts marked with draft: true in frontmatter. By default, drafts are excluded.

blogmore build posts/ --include-drafts

--clean-first

Remove the output directory before generating the site. Useful to ensure no stale files remain.

blogmore build posts/ --clean-first

--posts-per-feed <number>

Maximum number of posts to include in RSS and Atom feeds. Default: 20

blogmore build posts/ --posts-per-feed 50

--default-author <name>

Default author name for posts that don't specify an author field in frontmatter.

Example:

blogmore build posts/ --default-author "Dave Pearson"

--default-author-url <url>

Default author URL for posts that don't specify an author_url field in frontmatter.

Example:

blogmore build posts/ --default-author-url "https://davep.org/"

--extra-stylesheet <url>

URL of an additional stylesheet to include. Can be an absolute URL or a path relative to your site root. This option can be used multiple times to include multiple stylesheets.

blogmore build posts/ \
  --extra-stylesheet "https://fonts.googleapis.com/css2?family=Inter" \
  --extra-stylesheet "/assets/custom.css"

--icon-source <filename>

Filename of the source icon image in the extras/ directory. BlogMore will generate favicons and platform-specific icons from this image.

blogmore build posts/ --icon-source "my-logo.png"

If not specified, BlogMore auto-detects common icon filenames: icon.png, icon.jpg, source-icon.png, app-icon.png.

When a source icon is provided or detected, BlogMore generates 18 optimised icon files for iOS, Android, Windows, and standard favicons.

See Metadata and Sidebar — Site icons for detailed usage.

Enable client-side full-text search. When set, BlogMore generates a search_index.json file containing every post's title, URL, date, and plain-text content, and a /search.html page that performs in-browser search as the reader types. A Search link is also added to the navigation bar. No external services are required.

Search is disabled by default. Pass this flag to opt in.

blogmore build posts/ --with-search

When search is later disabled (flag omitted), any stale search.html, search_index.json, and search.js files from a previous build are automatically removed.

--with-sitemap

Generate an XML sitemap (sitemap.xml) in the root of the output directory. The sitemap conforms to the Sitemaps protocol and includes an entry for every HTML page generated for the site, except search.html.

Sitemap generation is disabled by default. Pass this flag to opt in.

blogmore build posts/ --with-sitemap

A --site-url should be provided so that sitemap entries contain absolute URLs. If omitted, entries will fall back to https://example.com.

--with-stats

Generate a blog statistics page. When set, BlogMore generates a /stats.html page (path configurable via the stats_path configuration option) containing posting-pattern histograms, word count and reading-time summaries, blog lifespan, tag and category counts, unique external link count, and a table of the top 20 most-linked external domains. A Stats link is added to the navigation bar automatically.

Stats generation is disabled by default. Pass this flag to opt in.

blogmore build posts/ --with-stats

--with-calendar

Generate a calendar view of all posts. When set, BlogMore generates a calendar.html page (path configurable via the calendar_path configuration option) displaying the full history of the blog as a reverse-chronological year calendar. Days with posts link to the daily archive, months link to the monthly archive, and years link to the yearly archive. A Calendar link is added to the navigation bar automatically.

Calendar generation is disabled by default. Pass this flag to opt in.

blogmore build posts/ --with-calendar

--with-graph

Generate an interactive post-relationship graph page. When set, BlogMore generates a graph.html page (path configurable via the graph_path configuration option) using the force-graph library. The graph visualises posts, tags, and categories as nodes with edges showing their relationships. A Graph link is added to the navigation bar automatically.

Graph generation is disabled by default. Pass this flag to opt in.

blogmore build posts/ --with-graph

--with-read-time

Show estimated reading time on each post. When enabled, BlogMore calculates the approximate time to read each post (based on 200 words per minute) and displays it next to the post date on all post listings and individual post pages.

Read time display is disabled by default. Pass this flag to opt in.

blogmore build posts/ --with-read-time

--with-gfi

Calculate and display the Gunning Fog Index on the statistics page. When set, BlogMore calculates readability scores of all posts and displays averages and tables on the statistics page.

Gunning Fog Index calculation is disabled by default. Pass this flag to opt in.

blogmore build posts/ --with-gfi

Enable automated build-time related posts calculation. When enabled, BlogMore uses a pure-Python TF-IDF and Cosine Similarity engine to automatically calculate and list contextually relevant posts for each entry, with zero runtime overhead for readers.

Related posts calculation is disabled by default. Pass this flag to opt in.

blogmore build posts/ --with-related

--socials-title

Override the title displayed above the social media icons section in the sidebar. By default the section is labelled "Social".

Default: Social

blogmore build posts/ --socials-title "Connect"

Override the title displayed above the links section in the sidebar. By default the section is labelled "Links".

Default: Links

blogmore build posts/ --links-title "Elsewhere"

--minify-css

Minify the generated CSS and write it as styles.min.css instead of style.css. This reduces the size of the stylesheet delivered to visitors.

CSS minification is disabled by default. Pass this flag to opt in.

blogmore build posts/ --minify-css

--minify-js

Minify the generated JavaScript and write it as theme.min.js instead of theme.js. If search is enabled (--with-search), search.js is also minified and written as search.min.js. The original unminified files are not written when this flag is set.

JavaScript minification is disabled by default. Pass this flag to opt in.

blogmore build posts/ --minify-js

--minify-html

Minify all generated HTML output. When enabled, every .html file produced by BlogMore is minified before being saved. Unlike --minify-css and --minify-js, the output file name is not changed — only the content is minified.

HTML minification is disabled by default. Pass this flag to opt in.

blogmore build posts/ --minify-html

Examples

Basic site generation:

blogmore build posts/

Generate with custom options:

blogmore build posts/ \
  --output public/ \
  --site-title "My Tech Blog" \
  --site-url "https://example.com" \
  --default-author "Jane Smith"

Clean build with drafts included:

blogmore build posts/ --clean-first --include-drafts

Serve Command

Start a local development server that watches for changes and automatically rebuilds your site.

Synopsis

blogmore serve [content_dir] [options]
blogmore test [content_dir] [options]

Arguments

content_dir (optional) : Directory containing Markdown posts. If provided, BlogMore will generate the site before serving. If omitted, serves an existing site from the output directory without regeneration.

# Generate and serve with auto-rebuild
blogmore serve posts/

# Serve an existing site without generation
blogmore serve

Serve-Specific Options

-p, --port <number>

Port number for the local server. Default: 8000

blogmore serve posts/ --port 3000

--no-watch

Disable watching for file changes. The site will be generated once (if content_dir is provided) but won't automatically rebuild on changes.

blogmore serve posts/ --no-watch

Common Options

The serve command also accepts all the build command options: - -c, --config - -t, --templates - -o, --output - --site-title - --site-subtitle - --site-url - --include-drafts - --clean-first - --posts-per-feed - --default-author - --default-author-url - --extra-stylesheet - --icon-source - --with-search - --with-sitemap - --with-stats - --with-calendar - --with-graph - --minify-css - --minify-js - --minify-html - --with-read-time - --with-gfi - --with-related - --socials-title - --links-title

Examples

Basic development server:

blogmore serve posts/

Custom port with drafts:

blogmore serve posts/ --port 3000 --include-drafts

Serve existing site without watching:

blogmore serve --output public/ --no-watch

Full configuration:

blogmore serve posts/ \
  --port 8080 \
  --output build/ \
  --site-title "Dev Blog" \
  --include-drafts

Publish Command

Build your site and publish it to a git branch, typically for GitHub Pages.

Synopsis

blogmore publish <content_dir> [options]

Prerequisites

  • You must be in a git repository
  • Git must be installed and available in your PATH
  • You should have a remote repository configured

Arguments

content_dir (optional if specified in config file) : Directory containing your Markdown blog posts.

blogmore publish posts/

Publish-Specific Options

--branch <branch-name>

Git branch to publish to. Default: gh-pages

blogmore publish posts/ --branch main

--remote <remote-name>

Git remote to push to. Default: origin

blogmore publish posts/ --remote upstream

Common Options

The publish command also accepts all the build command options: - -c, --config - -t, --templates - -o, --output - --site-title - --site-subtitle - --site-url - --include-drafts - --clean-first - --posts-per-feed - --default-author - --default-author-url - --extra-stylesheet - --icon-source - --with-search - --with-sitemap - --with-stats - --with-calendar - --with-graph - --minify-css - --minify-js - --minify-html - --with-read-time - --with-gfi - --with-related - --socials-title - --links-title

How It Works

When you run publish, BlogMore:

  1. Builds your site using the build command options
  2. Verifies you're in a git repository
  3. Creates a git worktree for the target branch in a temporary directory
  4. Creates the branch if it doesn't exist
  5. Clears the branch and copies your built site into it
  6. Creates a .nojekyll file (required for GitHub Pages)
  7. Commits the changes with a timestamp
  8. Pushes to the specified remote

Examples

Publish to GitHub Pages:

blogmore publish posts/ --branch gh-pages

Publish with custom configuration:

blogmore publish posts/ \
  --branch main \
  --site-url "https://example.com" \
  --clean-first

Publish to a different remote:

blogmore publish posts/ --remote upstream --branch pages

Lint Command

Check your site content for common issues like broken internal links or malformed frontmatter.

Synopsis

blogmore lint [content_dir] [options]
blogmore check [content_dir] [options]

Arguments

content_dir (optional) : Directory containing your Markdown blog posts.

Examples

Check the site for issues:

blogmore lint posts/

Drafts Command

List the path to all the posts in your content directory that are marked as drafts (draft: true in frontmatter).

Synopsis

blogmore drafts [content_dir] [options]

Arguments

content_dir (optional) : Directory containing your Markdown blog posts.

Examples

List all draft posts:

blogmore drafts posts/

Dump Command

Dump site content to stdout as JSON. This is a utility command to export site data for integration with custom external tools or scripts.

Synopsis

blogmore dump <subcommand> [content_dir] [options]

To maintain backward compatibility, running blogmore dump without a subcommand defaults to dump posts.

Subcommands

posts

Dump all blog posts to stdout as a JSON array in posting time order (oldest first). This includes all available properties of each post.

Synopsis
blogmore dump posts [content_dir] [options]
Arguments

content_dir (optional) : Directory containing your Markdown blog posts.

Output Properties

Each post in the dumped JSON array is represented by an object containing the following properties:

Property Type Description
id string The relative path identifier of the source file from the content directory (e.g., my-post.md).
path string The absolute path to the source Markdown file.
title string The title of the post, parsed from frontmatter.
content string The raw Markdown content of the post.
html_content string The parsed HTML content of the post.
date string or null The publication date and time of the post in ISO format, or null if not specified.
category string or null The category of the post, or null if not specified.
tags array of string A list of tags associated with the post.
series array of string A list of series names that the post belongs to.
draft boolean Whether the post is marked as a draft.
metadata object The raw frontmatter metadata parsed from the Markdown file.
url_path string or null The custom URL path generated or configured for this post, or null if using default URL rules.
related_posts array of string A list of post IDs (relative paths) that are related to this post.
internal_links array of string A list of post IDs (relative paths) of internal blog posts referenced in this post.
external_links array of string A list of unique external URLs linked from this post.
slug string The filename stem used as the URL slug.
url string The final URL path of the post, starting with /.
safe_category string or null The category name sanitized for use in URLs/filenames, or null if not set.
safe_tags array of string A list of tag names sanitized for use in URLs/filenames.
sorted_tag_pairs array of array A list of [display_name, safe_name] pairs for the post's tags, sorted alphabetically.
safe_series array of string A list of series names sanitized for use in URLs/filenames.
series_pairs array of array A list of [display_name, safe_name] pairs for the post's series, sorted alphabetically.
description string The post's description, either from frontmatter or extracted from the first paragraph.
prose_text string The plain text prose of the post, excluding HTML tags and code blocks.
word_count integer The number of words in the post's prose.
reading_time integer The estimated reading time in whole minutes (minimum 1 minute).
gfi float The Gunning Fog Index readability score for the post's prose (0.0 if empty).
modified_date string or null The modified date and time of the post in ISO format, or null if not set in metadata.
Examples

Dump all posts to a JSON file explicitly:

blogmore dump posts posts/ > blog_dump.json

Or using the default subcommand:

blogmore dump posts/ > blog_dump.json

categories

Dump all categories found in the posts in the content directory to stdout as a JSON structure. The structure is a list of pairs, where the first item is the URL-safe slug for the category, and the second is the most common text (display name casing) for that category. The categories are sorted case-insensitively by their display name, matching the category cloud page.

Synopsis
blogmore dump categories [content_dir] [options]
Arguments

content_dir (optional) : Directory containing your Markdown blog posts.

Examples

Dump all categories to a JSON file:

blogmore dump categories posts/ > categories_dump.json

tags

Dump all tags found in the posts in the content directory to stdout as a JSON structure. The structure is a list of pairs, where the first item is the URL-safe slug for the tag, and the second is the most common text (display name casing) for that tag. The tags are sorted case-insensitively by their display name, matching the tag cloud page.

Synopsis
blogmore dump tags [content_dir] [options]
Arguments

content_dir (optional) : Directory containing your Markdown blog posts.

Examples

Dump all tags to a JSON file:

blogmore dump tags posts/ > tags_dump.json

series

Dump all series found in the posts in the content directory to stdout as a JSON structure. The structure is a list of pairs, where the first item is the URL-safe slug for the series, and the second is the most common text (display name casing) for that series. The series are sorted case-insensitively by their display name, matching the series index page.

Synopsis
blogmore dump series [content_dir] [options]
Arguments

content_dir (optional) : Directory containing your Markdown blog posts.

Examples

Dump all series to a JSON file:

blogmore dump series posts/ > series_dump.json

Manage or analyze external links found in your blog posts. This command does nothing on its own.

Synopsis

blogmore links <subcommand> [content_dir] [options]

Subcommands

dump

Dump all external links found in posts to stdout in CSV format. The first field is the link, and the second field is the path to the post containing it. If the same external link appears multiple times in a single post, it is listed only once for that post. If a link appears in multiple posts, it is listed once for each post.

blogmore links dump [content_dir] [options]

check

Check the reachability and status of all external links found in posts. It verifies whether external domains can be contacted and if the links resolve successfully.

To minimize bandwidth usage, it uses HEAD requests first. If a HEAD request returns HTTP 403 or 405, it falls back to a GET request requesting only the first 1024 bytes.

If a link returns HTTP 429 (Too Many Requests), that entire domain is assumed to be off limits and skipped for the rest of the checking session. Results are cached within a session so each unique link is only checked once.

blogmore links check [content_dir] [options]
Options

--delay <seconds> : Introduce a delay (float, e.g. 0.5 or 1.0) in seconds between checking each unique link to avoid rate-limiting. Default is 0.0.

--verbose, -v : Print verbose output, including successfully resolved (reachable) links with an OK status.

Arguments

content_dir (optional) : Directory containing your Markdown blog posts.

Examples

Dump all external links in the posts directory:

blogmore links dump posts/

Check all external links with a 0.5 seconds delay between requests:

blogmore links check posts/ --delay 0.5

Cache Command

Manage the BlogMore cache directory.

Synopsis

blogmore cache <subcommand>

Subcommands

location

Show the absolute path to the BlogMore cache directory on your system.

blogmore cache location

clear

Remove all files and directories from the BlogMore cache. This is useful if you want to force BlogMore to re-download cached metadata (like FontAwesome metadata).

blogmore cache clear

Configuration File Priority

When both a configuration file and command-line options are present, command-line options always take precedence.

Example:

# blogmore.yaml
site_title: "Config Title"

# Command-line overrides config file
blogmore build posts/ --site-title "CLI Title"
# Result: site_title will be "CLI Title"

Path Expansion

All path arguments support tilde (~) expansion for home directory:

blogmore build ~/blog/posts/ --output ~/public_html/blog/

Exit Codes

BlogMore uses standard exit codes:

  • 0 - Success
  • 1 - Error (with message printed to stderr)

Environment Variables

BlogMore does not currently use environment variables for configuration. All configuration is done through command-line arguments or configuration files.

Getting Help

Display help for BlogMore:

blogmore --help

Display help for a specific command:

blogmore build --help
blogmore serve --help
blogmore publish --help

Common Workflows

Daily Writing Workflow

# Start development server
blogmore serve posts/ --include-drafts

# Write and edit posts...
# Browser automatically refreshes on save

# When ready to publish
blogmore publish posts/

Using Configuration Files

Create blogmore.yaml:

content_dir: posts
output: public
site_title: "My Blog"
site_url: "https://example.com"
default_author: "Your Name"

Then use simplified commands:

blogmore build
blogmore serve
blogmore publish

Multiple Sites

Use different config files for different sites:

blogmore build --config personal-blog.yaml
blogmore build --config work-blog.yaml

See Also