1. tux_
  2. blogcpp




A static blog generator, written in C++17.

First things first: How can I get it?

  1. You can use SourceTree, just add this repository's URL, clone it and you're done.
  2. You can use SmartHg, just add this repository's URL, clone it and you're done.
  3. You can use TortoiseHg, just add this repository's URL, clone it and you're done.
  4. You can use the command-line Mercurial client: hg clone https://bitbucket.org/tux_/blogcpp.


Because there are not enough static site generators yet.

No, seriously, why?

  • Just like other static site generators, blogcpp is virtually unbreakable by intruders as your server is not required to host anything but static HTML files - even JavaScript and CSS are, depending on your theme, entirely optional.
  • Unlike other static site generators, blogcpp is written in modern C++, resulting in a fast build speed, reducing the need for workarounds like incremental builds or advanced caching mechanisms while compiling. Still, blogcpp tries to use as many CPU cores as possible to achieve the maximum speed on your machine.
  • blogcpp aims to provide a decent feature set without requiring too much configuration; in fact, it would work right out of the box if your website was example.com (which is, admittedly, rather unlikely).

Current version

The latest released version is version 4.


  • Markdown support: Write your articles and pages in Markdown, get HTML.
  • Theming support: You don't like the default theme? Well, nor do I. Go on and do it better!
  • OEmbed support: Just post an OEmbed-enabled link (e.g. Twitter or YouTube) and blogcpp will embed the media for you.
  • RSS feeds for new articles, tags and categories.
  • Configurable article permalinks.
  • Sticky articles: Just put Sticky: On on top of your article file.
  • Emoji support: Write :-) and get a real smiling face instead.
  • Commenting support: Even a static blog needs a community. ;-)
  • OpenGraph support if you feel like sharing stuff on Facebook or whatever.
  • Syntax highlighting via highlight.js.
  • much more is planned - see the roadmap for a clue.

Used libraries

blogcpp uses the following third-party libraries (in 3rdparty/):

Some code was added from other people's suggestions:

Not included in this repository (because of their size), but still required external libraries:


How can I use blogcpp?

The easier way:

Set up your blog.cfg file first, follow the documentation in the blog.cfg-example file in this repository. Then type blogcpp --new-article to start a new article or blogcpp --new-page to start a new page. When you're done, run blogcpp and everything will be there soon.

The nerd way:

Set up your blog.cfg file first, follow the documentation in the blog.cfg-example file in this repository. Then start to add Markdown-formatted posts (in /posts) and/or pages (in /pages) formatted like this:

Author: Your name here.
Date: 2016-01-01 12:00:00
Title: This is the title.
Tags: tag 1;tag 2;tag 3
Categories: some;random;categories


(Everything that follows will be a part of the contents.)

You can additionally set Markdown: Off to disable Markdown parsing for this specific post or page. Note that pages don't have categories, every category added to a page will be ignored.

  • If you want your newly created article (for logical reasons, only posts are supported) to be "sticked" to the top of your index page, just add Sticky: On into its header part.
  • Articles will always be sorted by their creation date; you can indicate the latest change (which will be displayed or not, depending on your theme) with Changed: yyyy-mm-dd hh:mm:ss somewhere above or below the Date: field.
  • If you don't want to have emojis on this post or page without removing them everywhere, just add Emojis: Off.
  • In case you want to have a specific OpenGraph image for this page or article, you can set OpenGraphImage: http://my/host/image.png or whatever you want it to show.
  • You can also disable comments per post (pages don't have comments): Comments: Off.

When you're done, run blogcpp and everything will be there soon.

OK, but how can I compile blogcpp first?

If you're on Windows, you can just get a static binary. It's not hard to compile blogcpp yourself though:

You'll need a C++17 compiler (on Windows: Visual Studio 2015 or higher or Clang), blogcpp makes heavy use of the new <filesystem> class and other oddities. Also, the ICU libraries and headers as well as libcurl need to be in your include and library paths. (Visual Studio users can get the ICU libraries here.)

Then, after everything is in place:

  1. Compile 3rdparty/XML/tinyxml2.cpp, 3rdparty/NLTemplate/NLTemplate.cpp, 3rdparty/curl/HTTPDownloader.cpp, EmojiParserClass.cpp, MediaEmbedderClass.cpp, MarkdownParserClass.cpp, ContentsGeneratorClass.cpp, ExcerptExtractorClass.cpp, CommentIntegrationClass.cpp, and blogcpp.cpp into one object file.
  2. Link to the libcurl_a, sicuin, sicuio, sicuuc and sicudt libraries. (Drop the leading "s" if you don't want to have a static linking.)
  3. On Windows, additionally link to shell32.lib and user32.lib.

You can refer to the build_windows.cmd file in this repository for details. Starting from version 3, CMake files are also provided.

Optional preprocessor definitions while linking:

  • CURL_STATICLIB and U_STATIC_IMPLEMENTATION: Required for static linking of ICU and libcurl (highly recommended).
  • WITH_DEBUGLOG: Prints verbose debug output to /debuglog.txt.
  • WITH_OEMBED: blogcpp supports the OEmbed standard. This will - in some cases - affect the page generation speed. (If not used, blogcpp supports simple replacements for YouTube and Vimeo only.)

Which directories need to be there?

Here's a site's minimal directory structure:


Of course, the capital letters mean that the values are indeed variables. By default, TPLNAME is default, INDIR is site and OUTDIR is outdir. Please use the configuration file when building your site in order to change these values.

The name is stupid!

Well, I am a developer, not an economist. I do software, not shiny product names. However, blogcpp is path-agnostic (as long as it finds its usual path structure). You think blogcpp is a stupid name? mv blogcpp klaus and blog with klaus!

Also, please consider to ask a real question next time.

How does syntax highlighting work?

Four spaces at the beginning of a line mark the beginning of a code block. blogcpp tries to determine the language of the code automatically. If you want to set the language explicitly, you can use the Pelican syntax for code blocks; example:

print("This is Python code.")

Which parameters are supported?

You can call blogcpp with the following parameters:

  • -h / --help: Prints this list of parameters.
  • -v / --version: Prints the version number of blogcpp.
  • -q / --quiet: Generates your site and shuts up while doing so.
  • --new-article: Generates a new article stub and opens it in your default editor.
  • --new-page: Generates a new page stub and opens it in your default editor.
  • --config [filename]: Uses a different configuration file than blog.cfg. The file must exist.

Which emojis are supported?

Given that you have actually enabled Emoji support in your blog.cfg file and not disabled it for the page or article you want to process, the following smiley codes will automatically be replaced:

Code Emoji
;-) 😉
:-D 😀
:'( 😭
:-| 😐
>:) 😈
>:-) 😈
>:( 😠
>:-( 😠
:-* 😘
:-O 😮
:-o 😮
:-S 😕
:-s 😕
:-# 😶
0:-) 😇
:o) 🤡
<_< 😒
^^ 😊
^_^ 😊
m( 🤦

Which comment systems does blogcpp support?

While blogcpp does not have its own commenting system, you can easily integrate existing external commenting systems via your blog.cfg (please refer to the blog.cfg-example file in this repository). Currently supported are:

  • *Disqus* (comments = disqus, you need to set your commentdata to your Disqus shortname)
  • *isso* (comments = isso, you need to set your commentdata to your isso folder)
  • *Hashover* (comments = hashover, you need to set your commentdata to your Hashover folder) -- currently, version 2.0 only
  • Google Plus comments (comments = google, no additional settings required)
  • *Discourse* (comments = discourse, you need to set your commentdata to your Discourse domain)

Can I use raw HTML in my Markdown-enabled article or page?

Yes, you can! Everything between <rawhtml> and </rawhtml> will be ignored by blogcpp's Markdown parser.

How can I disable Markdown parsing for a certain article or page?

Just add "Markdown: Off" to the meta part of your input file.

Which files does a template need to work?

blogcpp needs index.txt, post.txt, page.txt and archives.txt in order to be able to process your site correctly. All other template files are optional. CSS and image files can be put into a subfolder named static, blogcpp will automatically copy this folder to your output directory then.