top | item 16606408

Show HN: Makesite – A static site generator in 125 lines of Python

146 points| sunainapai | 8 years ago |github.com | reply

60 comments

order
[+] vram22|8 years ago|reply
A while ago I had written a tool called PySiteCreator.

It lets you create simple web sites (I originally thought of it for creating wikis, but later realized it was more general) by writing them purely in Python, using Python function calls to generate various HTML elements.

It uses a make-like approach (file timestamp checking between input and output files) and relies on a simple convention that users have to follow, of defining a Python function called create() in each .py file they write, where each .py file will be used by the tool to generate a corresponding .html file. Other than that, it places no restrictions on the user, and any arbitrary Python code can be used to generate or pull in data from anywhere, to be included in the web pages it creates.

Blog post about PySiteCreator here:

https://jugad2.blogspot.in/2009/11/early-release-of-pysitecr...

Source code here:

https://bitbucket.org/vasudevram/pysitecreator

[+] charlesdaniels|8 years ago|reply
Personally, I used Jekyll for a while before switching to a simple Makefile based approach. I write everything in Markdown, which gets compiled via Pandoc, concatenated with a header and footer. I also recently started using pygments to generate colorized inline HTML to syntax highlight code blocks.

If anyone is interested, I wrote up the process[1], although I have not updated the post with the pygments script yet.

[1] - http://cdaniels.net//2017-11-22_make-static-site.html

[+] sigil|8 years ago|reply
Fellow Jekyll refugee here. I also switched to the Makefile SSG approach for the much faster incremental rebuilds. Parallel speedup with make -j is also nice.

My SSG is called tinysite [1] [2]. Templates are jinja2. Posts are written in markdown with Pygments highlighting for fenced code blocks. Posts also have JSON frontmatter which can #include other JSON data files, and this is where it gets Make-y: all affected pages get rebuilt when a data file changes with the help of a `gcc -M`-style file dependency scanner. I use these frontmatter "data includes" for site wide metadata and for data driven pages like post indexes. There's also a dev server so you can quickly preview changes.

The biggest frustration I have with the Makefile + interpreted language approach is the slow startup time of interpreters these days. When every page requires a new interpreter process it really starts to add up, if not in incremental builds, then definitely in full rebuilds of larger sites. Some quick tests I did recently of `time $INTERPRETER -[c|e] ""`:

  node 6   ... 70ms
  ruby 2   ... 58ms
  python 2 ... 27ms
  perl 5   ...  5ms
  sh       ...  3ms
Perl compares quite favorably here, but I just can't bring myself to go back to it. I wish these other interpreters would get their startup time act together! I guess this is an argument for go / Hugo?

[1] https://github.com/acg/tinysite

[2] https://github.com/acg/alangrow.com

[+] bArray|8 years ago|reply
I do something similar, except with a `bash` script and hand writing the titles + dates. I thought about automating that, but work in different time zones so prefer to choose.

One thing I might have of interest to you is a small DNT (DoNotTrack) JS file [1] and some CSS that adds some visual markdown features to the page after the fact [2].

P.S. Your output looks like it's missing `<HTML>` and other tags? And how are you getting automated code colour highlighting?

[1] http://coffeespace.org.uk/dnt.js

[2] http://coffeespace.org.uk/style.css

[+] mwambua|8 years ago|reply
This is cool, and if I had the time I'd want to do something like this for automatically generating a google-photos style site from my Pictures directory.

Also, if you're looking for a stable Python-based static site generator... I've been pretty happy with Pelican (https://blog.getpelican.com/).

[+] edwinksl|8 years ago|reply
Agree, Pelican is easy to use and configure using Python.
[+] almata|8 years ago|reply
After using several different blogging platforms/tools, I finally decided to use instead a GitHub repo for my notes. Something really simple that lets me 1) create a note in plain Markdown, and 2) run a publi.sh script. That's all. After that, the note is already in my GitHub repo ready to be ctrl-f'ed when I'm looking for something I know I documented. In case anyone is interested I used this tool [0], but it was first time in my life creating a Bash script, so fairly assume the code is, well... you know :)

[0]: https://github.com/almata/BlogGit/blob/master/README.md

[+] Animats|8 years ago|reply
Maybe browsers should just understand Markdown. Cut out the middleman.
[+] adamisntdead|8 years ago|reply
Writing static site generators is my favourite way of learning a language. Usually covers all the basics, libraries, FS, error checking and so on
[+] pvinis|8 years ago|reply
Do you have an good example for this, yours or someone else's? I've never thought of that as a learning-a-language project.
[+] gabrielcsapo|8 years ago|reply
Shameless plug, I have been a little upset about how convoluted the static site offerings have been. So I have been building https://www.gabrielcsapo.com/sweeney/ in my free time. It needs a ton of work, but trying to keep it compact and 100% tested. The main source of inspiration is making static sites configurable enough for people to stop using Wordpress and making their clients lives incredible difficult. Really cool project @makesite!
[+] Philipp__|8 years ago|reply
Hugo is still most convenient, at least for me and my workflow. I just pull it with homebrew, created my theme/template, write blogposts in Emacs org-mode (using ox-hugo), host it on GH pages for free, and use custom domain and free tier cloudflare.

I am really enjoying bare essentials I got, very streamlined process that does the job for me. This looks interesting, I really like minimalist aspects of software, but what ain't broken don't fix it.

[+] devposter|8 years ago|reply
Hugo is nice and extremely fast. But one thing that I find unintuitive in Hugo is how the layout files are arranged. I can never remember them without referring to the documentation or the source files of an existing Hugo site everytime I need to create a new Hugo site.

For example, the base layout template needs to go to themes/<THEME>/layouts/_default/base.html but the layout for a blog needs to go to themes/<theme>/layouts/<TYPE>/single.html. Then there is list type layout too to define the blog index pages. Is the home page a single page or a list page? Can the entire home page be defined as a base template? It gets confusing.

Then the whole {{ define <BLOCK> }} and {{ block <BLOCK> }} syntax to embed one template in another is quite unintuitive as well. I think Jekyll has much more sane layout that is easy to keep in head. Also in Jekyll one can define list pages without any special naming convention just by using its templating for-loops. I find Hugo less intuitive than others but the fact that Hugo does not require me to learn Ruby is a win.

Custom written shell commands or Python code or even plain SSI includes are a great way to host static content too.

[+] paulgb|8 years ago|reply
Another free solution that may involve even less setup is Netlify's free tier, which includes 1-click HTTPS setup on a custom domain and reruns Hugo every time you push to the repo.
[+] citilife|8 years ago|reply
Alright - I like your website layout: https://defphil.com/

But to be fair, some people may want different features than the bare minimum. Also, even if Hugo is the most convenient as an org-mode user, I highly doubt it'd be the most convenient for others (who don't use org-mode lol).

Also, you should write more posts!

[+] kaushalmodi|8 years ago|reply
Hey! Ox-hugo dev here. Do you have your site source (Org source) public? I am just collecting Ox-hugo Org source repos, that I plan to publish on the ox-hugo doc site (of source, that won't happen if you don't wish, even if your source is public).

For folks, if interested in seeing an example of the Org source, and ox-hugo + Hugo generated site, here's the source[1] of my blog[2].

More: https://ox-hugo.scripter.co/#demo

[1]: https://gitlab.com/kaushalmodi/kaushalmodi.gitlab.io/raw/mas... [2]: https://scripter.co

[+] mojoe|8 years ago|reply
I use Jinja2 to template all my static sites -- it helps me host compellingsciencefiction.com straight from AWS S3 very, very cheaply.
[+] est|8 years ago|reply
generate static site with 1 line of shell command

    echo "<html>" > index.html
[+] secura|8 years ago|reply
Is this a valid HTML? https://validator.w3.org/ seems to require this as minimal HTML to validate successfully.

    <!DOCTYPE html><html><title>0</title>
I would thus fix your 1 line shell static site generator like this.

    echo '<!DOCTYPE html><html><title>0</title>' > index.html
[+] rambojazz|8 years ago|reply
You can even go more minimalist. An empty file is a site too.
[+] noobermin|8 years ago|reply
Snark aside, does it matter if most of the "site" is already in templates? Why shouldn't the templates be included in the metric?
[+] foo101|8 years ago|reply
This seems to use the commonmark library to render Markdown? Can it render Pandoc flavour of Markdown?

How widespread commonmark really is? Any popular sites using it? If I write my blog posts in commonmark is it safe to assume site generation tools 10 years from now will correctly render commonmark?

[+] Avamander|8 years ago|reply
I absolutely love Pelican with M.CSS[1], automatically deployed by my already existing TeamCity instance that triggers a rebuild on git repository changes.

[1] http://mcss.mosra.cz

[+] whalesalad|8 years ago|reply
Can’t speak to the usefulness of the code but really admire the style. Very clean, concise and lots of composition. Love it.
[+] jitans|8 years ago|reply
how stupid is to measure code in terms of lines?

Make all that a library then you can claim:

A static site generator in only 3 lines of Python

Measuring lines of codes is completely wrong. See the Scala trend were people race to find the shortest way to express something generating hard to understand code. 1) Code has to be written to be maintenable. 2) Code has to be written to be read by your coworkers. 3) The bottleneck while coding is not the keyboard.

[+] z3t4|8 years ago|reply
Unless you have put effort into squeezing as much logic as possible into each line, the less code the easier it is to maintain. With more code, more stuff can go wrong. It's not just because we are bad at writing code, we have probability against us. If the bug average is 1 bug per 100 LOC then 100 LOC will have less bugs then 10k LOC. We also have physics against us, reading and comprehending 10k LOC of code will take much longer then reading 100 LOC. With that said I do agree with you that LOC don't say much about anything. It's a stupid metric. With higher level languages, a 100 LOC file might actually be millions LOC if you include all the libraries. Them being libraries means they are mostly decoupled, which makes things better, because coupling is the root of most complexity.
[+] make3|8 years ago|reply
Please don't use the number of lines as a metric for simplicity, it really doesn't mean anything
[+] zeep|8 years ago|reply
For two programs that do the same thing coded in the same language, I would pick the one with the least amount of lines but that doesn't mean that less work went into it... Probably the opposite
[+] jitans|8 years ago|reply
As you can see we are the only one thinking this is absurd :D