content = """# This is a markdown content"""
from markdown import markdown
with open('output.html', 'w') as f:
f.write(open('template.html').read() % {
'header': 'welcome',
'content': markdown.markdown(content),
'footer': 'amazing company inc'
})
I wanted to be able to create new layouts without touching the precompiler.
To rely only on HTML/CSS/Markdown to code the frontend.
You can't code partials within the HTML file with your solution.
content = """# This is a markdown content"""
with open('output.html', 'w') as f:
f.write(open('template.html').read() % partial({
title: 'Velkommen',
content: markdown.markdown('markdown content')
}))
My static site generator is 5500 lines of Java, because the only thing I hate more than software I didn't invent myself is technologies that are fashionable ;-)
To be fair, 10 years is still uncomfortably modern in my book. My tech needs to at least be old enough to drive a car. Ideally it should be old enough to have an existential crisis about how its life is turning out.
... and you can probably build a 100 LOC static page generator in Java as well.
My thing does a lot of weird crap, though. Like it also acts as a Gemini protocol server, you can publish from the web and it pushes every change to a git repo. It also tracks backlinks and re-publishes every page that is mentioned. It also renders from a specialized version of gemtext so there really isn't any standard libraries to use (that I'm aware of).
Posts like this demonstrate to me that JavaScript is the modern Perl. The gigantic, vibrant module ecosystem and ease of installing them* is what makes JavaScript/Node.js my default system for getting stuff done quickly.
(* = Well, it was easy, but I feel like this ESM business now means npm/yarn install doesn't Just Work™ in some cases.)
I agree. Sure there are issues but basically node/js is my scripting language. It used to be python but I do so much more JS that I just end up doing everything I can there.
This is what JSX is great at, and it's why I wrote a new web framework that basically just uses JSX for server-side views, that work the way I always thought JSX should: it just returns an object that you can then render into a string if you want or transform first. This is also how I made it so you can put <script> and <style> tags into any component, and it'll de-dup them before rendering, so that you can keep your component scripts and HTML close by each other in source.
Nice and simple. One note to the author - you could reduce your line count quite a bit and get a bunch of features for free by using Nunjucks (https://mozilla.github.io/nunjucks/) instead of parsing the template yourself. It handles your partials and variables in the same way plus a whole lot more.
I really like the fact that partials are handled as HTML-like markup instead of the HTML just happening to be within some other template system. Kudos on that design choice!
Thanks! That made it easier to handle this usecase:
<partial src="partials/layout.html">
My fancy content
</partial>
Because I can use HTML parsers. But now I'm thinking of a way to remove all dependencies, to I will have to get rid of html parser, and find a way to those substitutions without parsing HTML, with just regex replacement.
> Just like every dev writing a blog, my first question was: What is the minimum set of features to maintain it comfortably?
Then you created a program in JS that requires NodeJS to run. But cool programs written in JS don't require NodeJS when it's not necessary. They just run in the browser.
PS: Really cool static site generators that shoot for simplicity don't require you to create extra template files written in a new, made-up template language. When you want to create a new post, you give it (a) the static files from your existing site and (b) the markdown for your new post. The "templating" engine inspects your existing posts (incl. e.g. class attributes) and then copies the same document structure into a new file, except with the right stuff (timestamp, title and heading, post content...) substituted in to the places where it's supposed to go.
Something like this does the job for you...basically applies the template and whatever metadata you give to the .md file.
for file in *.md; do
pandoc --quiet --template template.html $file -o "${file%.*}.html"
done
But I wanted a flexible way to reuse components. So I need the <partial> trick to support outer and inner partials in the reusable components. For example a form that I want to reuse on some pages, or a custom call to action.
Sorry, I don't think you understand. First, I'm not looking for help finding a tool that does what I describe. Second, that Pandoc invocation doesn't do what I describe. I'm saying no template file.
Let's say you have static site today with your lost post being "2022/03/31/working-on-a-new-tool.html". To author your new post, the tool could derive the template based on what the actual, HTML-formatted version of your last post looks like, and then it would substitute the new post content into the appropriate places. For example, where your previous post has a date stamp indicating it was published on March 31, the tool would put the date of the new post. Where your previous post has the title in an H1 or whathaveyou, your new title would appear. Where the main text of your last post appears, the main text of your new post appears. This would all be written into a new file. There's no need for an explicit template file.
PS: Pandoc doesn't run in the browser, either. You're already going to have your browser open to check the output. Its runtime is both powerful enough, and it's right there, so use it. No need to bring other runtimes into this.
Yes. I'm looking to remove NodeJS dependency, but I will probably have to switch languages since JS itself doesn't let me read files from disk, to run the preprocessing.
Live Reload should be easy.
I prefer pure CSS and pure HTML. But opened an exception for Markdown, for the sake of writing posts.
I don't know what you mean by 1, I thought I achieved that with:
<partial src="partials/layout.html">
My fancy content
</partial>
tangential, but what do people generally do when they want mostly a static site, but a small amount of dynamic content/interactivity here and there? Seems like a common use-case that as sites grow they might want a little bit of not-static here and there.
Obviously not that difficult to add some javascript and APIs if you want, which avoids the need to mix in a different stack while generating the same look-and-feel. Or you can use NGINX/Apache frontend to redirect certain paths to a more traditional dynamic stack/CMS of course. Just curious if there's any "standard" approach or off-the-shelf tooling for that for (eg) Jekyll or similar.
Vercel (with or without Next) is my stack of choice for projects like this.
You can get a site running in Vercel+Next in <2m from ‘git init’.
I use it for https://potato.horse and most PoCs now, but we’ve scaled Vercel+Next to hundreds of thousands of users per day in other projects.
You could also use Netlify with Netlify functions, although I prefer the (slightly) less opinionated way of handing releases and per-commit vanity URLs Vercel offers.
Aaand if you want to get more funky with your approach, check out Astrojs (island architecture: start with static content and sprinkle the interactions on top of it).
You could also try, Elixir + Phoenix + Live View if you want to learn a new tech stack, feed your brain, and… spend a few days yak shaving. Nope, none of the 5 new versions of your blog will be live by the time you’re done, but you’ll become good friends with Erlang and co. Speaking from the experience, I use next when I want my stack to be boring.
It depends *where* said dynamic content/interactivity is desired. If its desired at the page level, such as one page is desired to be dynamic...Then i keep everything else produced by my static site generator (in my case Pelican), and then set up a subdirectory and use php. (PHP because pretty much any web host, VPS provider etc. either already comes with PHP or its pretty easy to setup. But also because i faovr php development for the web.) Your comment about leveraging redirecting to certain paths via nginx/apache is something i've done in the past also...but unless you have a nice (automated, or at least easy) workflow...that could get old fast.
...However, if what you want is dynamic content/interactivity within the context of a page that is served static from your SSG process, then I (reluctantly) resort to javascript (Sorry, my reluctance is because i'm not much of a fan of javascript...and in fact have tried to omit as much of it as reasonable from my projects.)
I'm in a totally different competition: how to get sh*t done quickly, get others to handle the hard parts and get good maintainability so that I can go home sooner?
Read Hugo/Wordpress documentation takes longer than write something like this.
I got this blog running faster that I would if I had to learn a new tool.
template.html:
generate.py: for serving it: it will be running on 127.0.0.1:8000