Quantcast
Viewing all articles
Browse latest Browse all 17

build a static website using Pandoc

Image may be NSFW.
Clik here to view.

Static websites are all the rage these days, and I get it. They are fast, secure, low maintenance and future-proof. I know the free and open source tool Pandoc can generate HTML files from Markdown, but can it be used to generate a static website?

Let’s find out!

Why not use something like Hugo or whatever other static site generator? Well, maybe you’re just trying to generate a really simple site, and you don’t want to learn a new templating language, or install a tech stack you’re not familiar with. You know HTML and Markdown syntax, that should be it, right?

Here’s how you generate an HTML file from a markdown file:

pandoc index.md -o index.html --standalone 

Which looks like this:

Image may be NSFW.
Clik here to view.

Not that fancy, but it works. You have a complete HTML file, ready to be hosted. HTML files can be edited with any text editor, or you can write a script to edit the HTML, so that’s a good start.

It’s missing some basics, though. Like a proper title, and the language meta property. But Pandoc has metadata you can add to the markdown to fix that, like this:

---
title:  'A Pandoc HTML static website demo'
lang: en
keywords: [demo, pandoc, static site]
...

Hello Pandoc static site!

We can style HTML with a stylesheet to make it look the way we want next. Let’s use PicoCSS. It’s minimal and can style plain HTML without having to add a single CSS class. I love it. I’m using a PowerShell variable here for the CSS, to make it more readable.

$CSS = "https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.lime.min.css"
pandoc index.md -o index.html --standalone --css $CSS 

Looks a lot better already, doesn’t it? Without writing a line of CSS. As a backend developer, I’m sold. I’m linking directly to the JSDelivr CDN, which might not be the best solution, but it’s the fastest here without having to maintain another file.

Image may be NSFW.
Clik here to view.

Still, not really a website yet. How about adding a header and a footer?
Pandoc also has some command line options for that. With --include-before-body you can insert HTML for a header, and using --include-after-body some HTML for a footer. I’ll keep it simple and insert a menu and a copyright footer.

pandoc index.md --standalone -o index.html \
   --standalone --css $CSS \
   --include-before-body header.html \
   --include-after-body footer.html

There’s an extra one called --include-in-header to inject any JS scripts or whatever you want in the header too.

This is starting to look like a decent web page, isn’t it?

Image may be NSFW.
Clik here to view.

But one page doesn’t make a website. Well, it might actually, but let’s say we want to do this for multiple pages. All this command line typing will become tedious. So let’s script it.
I started doing that, and then I ran into some minor snags (.md and .html files all together, also those include files mixed in, I wanted an image in there too, what a mess, …)
So after some thinking and tinkering, I came up with this folder structure for the project:

  • \site : here go your site’s Markdown files.
  • \includes: the header, footer and other bits of HTML you want to inject.
  • \_out: an output folder where your fully rendered site will end up in, created automatically by the script.

The following script, named build.ps1, will convert all your markdown files in the site folder, and places everything in the _out folder, and then do some file cleanup.

$CSS = "https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.lime.min.css"
$OUTDIR = "_out"

foreach ($file in (ls site\*.md -Recurse)) {
    $outfile = ($file -replace ".md", ".html") 
    # Run pandoc for a single file.
    pandoc $file --output $outfile --standalone --css $CSS --include-before-body includes\before-body.html --include-after-body includes\after-body.html --include-in-header includes\header-include.html --verbose 
}

# Remove the output folder if it exists.
rmdir .\$OUTDIR\ -Recurse -Force -ErrorAction Ignore
# (Re)create it.
mkdir .\$OUTDIR | out-null
# Copy all files from site, excluding the .md files.
copy .\site\* -Recurse -Destination .\$OUTDIR\ -Exclude *.md
# Remove all .html files from the site folder. 
# WARNING: Don't put html files in there. Only markdown.
del -Path .\site\ -Filter *.html -Recurse -ErrorAction Ignore

Mind that comment about deleting .html files in the site folder. Don’t put .html there, only markdown, or your files will go *poof*.

Pretty easy, isn’t it? For a basic website, this could totally be a quick and easy way to generate your static files and host them anywhere. Pandoc has even more extension points if you really want to dig in and parse the HTML structure, called filters. With that one, the options are pretty much limitless, and you can use your favorite language to write a JSON filter, if you don’t want to use the built-in Lua.

You can check the full demo site here.

“That’s great and all.” I hear you think, “But can’t I just clone a Git repo with all this stuff in? I really don’t feel like copy-pasting stuff from a blog today.”?

Well, yes you can. I put the source code for the demo site on GitHub. Knock yourself out.
Oh, and I would love to see what you came up with, so drop me a message somewhere if you can. ;)

The post build a static website using Pandoc appeared first on n3wjack's blog.


Viewing all articles
Browse latest Browse all 17

Trending Articles