Skip to content

karschsp/s4g

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 

Repository files navigation

Stupidly Simple Static Site Generator (S4G)

What is this?

This is stupid. And simple. And it generates static HTML sites. Using Bash. Yikes. I'm only sharing it here so the world knows how bad of an idea this is. You have been warned.

Who is this for?

Mostly me. But really anyone who likes HTML/CSS and getting stuff done without databases, package managers, toolchains, dependencies, build pipelines and the like. S4G can generate a fully-functional very simple site with just s4g init.

What can I build with it?

Not much. Mostly a blog. Maybe a photo gallery. Maybe a blog WITH a photo gallery. You could even forego the homepage "river-of-news" thing and create a completely custom homepage. If you, unlike me, are adept at CSS you can even make it look really nice. If you, unlike me, like Javascript, you can add whatever JS you'd like. Just customize the auto-generated header.html after you run s4g init the first time.

Is anyone using this?

Me. For three sites (soon to be four!). They are all stupid. Just like this project.

Setup

  • clone the repo and cd into it.
  • chmod +x s4g.sh
  • ./s4g.sh init (answer the questions, the only ones you likely care about are Site Title and Site Description. For the rest you can/should accept the defaults)
  • (optional) python3 -m http.server 8000

Bask in the glory of your new site.

Main commands

  • ./s4g.sh init - Asks you a couple questions (except for site title and site description, just accept the defaults...you'll dig it), then generates the bare bones structure of the site:

    config.yml
    sitemap.xml
    index.html
    --all-photos
      index.html
    --css
      style.css
      critical.css
    --feeds
      feed.xml
      feed.json
    --posts
      --hello-world
        index.md
      index.html
    --rss
      index.html
    --tags
      index.html
      --example
        index.html
      --intro
        index.html
    --templates
      header.html
      footer.html
    
  • ./s4g.sh scaffold - Scaffolds a post. Takes title as an argument. so, ./s4g.sh scaffold "My Summer Vacation" creates a new folder in posts called my-summer-vacation with an index.md in there. Edit that and tell us all what you did last summer, little Johnny. Then run...

  • ./s4g.sh build - Builds the site. Basically, it goes through each post in /posts, converts the .md to .html by wrapping the contents of the markdown in the header and footer templates. It also keeps track of the tags and generates tag pages. It also generates the RSS feeds, the RSS feed index page (/RSS) and the sitemap.xml. It also takes any photos included in the post and adds it to the /all-photos page(s). You'll want to run ./s4g.sh build whenever you update a .md file or style.css. Or whenever you want. Who cares?

There's nav in header.html. You need to manually edit it. I'm not going to decide for you what goes in your nav. MAKE IT YOURS! You can also edit footer.html. The only time the script writes to those files is in the init process.

If you edit your style.css (recommended), during the build process it gets a unique filename (for cache-busting purposes) and jammed into the header.

A lot of stuff is manual. That's intentional. I'm old. I like doing things the hard way.

You can then upload this entire folder to a web server somewhere or do python3 -m http.server 8000 or whatever to view your site. Note how super fast it is.

There's some other things

Metadata

Each post .md file has some metadata at the top:

---
title: my summer photos
description:
<!--HTML-->
We had some fun this summer.

![Me during hoagie fest](/posts/my-summer-photos/photos/thumbs/IMG_3535.jpeg)
date: 2025-09-27
tags: photos, summer, hoagiefest, wawa
section: photos
featured_image: IMG_3535.jpeg
hide_from_feed: 0
photo_page: 1
---

some of these fields (title, date, tags) are obvious. others warrant some explaining:

  • description will accept markdown. This is what gets output on the main /index.html and on the tag pages (like /tags/summer/index.html). You can also put straight HTML in here which may be your best bet because the parser is a little wonky...just do something like
description:
<!--HTML-->
<p class="content-body"><img src="/img/example.jpg" alt="An image" /></p>
  • section whatever you add here just gets added as a class to the body tag of that page for easier CSS targeting, if you're into that kind of thing...so <body class="photos">
  • hide_from_feed set this to 1 if you don't want this to display on the main /index.html or in the main RSS feed...useful for about pages and the like.
  • photo_page set this to 1 if you want the page to include a grid of photos (placed as a sub-folder of your post folder. So /posts/my-summer-vacation/photos/ The script will shrink them down and create a thumbs sub-folder in there. The filenames are used as captions. Not ideal, but, yeah. You could always make the grid yourself in your .md file if you want to get fancy (you can mix HTML and Markdown...probably).
  • featured_image Set this to specify the image used for Open Graph link previews. If it's not set, the fallback is SITE_IMAGE from config.xml.
  • draft Set this to 1 for this post to be ignored/not published when you run s4g.sh build.

Features

  • RSS - RSS feeds are auto-generated for the main index as well as individual tags AS WELL as the /all-photos stream. In addition, a page linking all available RSS feeds is generated at /rss. I'm a big fan of RSS.
  • Photos - As alluded to previously, setting photo_page: 1 in the post index.md metadata will create thumbnails of each photo in the photos folder in an individual post and output a list of them in the index.html of said post. You can style them however you like.
  • All photos - In addition to the above, a page is generated at /all-photos which lists (in a paginated form) all of the photos linked from posts on the site. There is also an RSS feed for this page.
  • Link previews - Each post has Open Graph metadata added to it for neato link previews when sharing on the socials...like all the cool kids have.
  • Moon phases - Let's make things fun. When s4g build runs, as it loops through the post .md files and generates the .html, it calculates the moon phase at the date of the post and outputs it at the bottom. You can hide it with CSS if you don't like this. I should probably set an optional per-post metadata setting for this, but for now, the moon phases will continue until morality improves.

Why

I'm stupid and simple. Honestly, I just like HTML and the web. And accessibility. All this stupid thing does is generate HTML files. In a really inefficient and stupid way. With Bash, because I hate Python even more than I hate Javascript.

Disclaimer

It works on my machine.

It may or may not work on yours.

Patches welcome.

About

Stupidly Simple Static Site Generator (S4G)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages