Show HN: Makesite – A static site generator in 125 lines of Python
github.com
github.com
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:
If anyone is interested, I wrote up the process[1], although I have not updated the post with the pygments script yet.
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?
I am unclear on your dnt script? What does it do? I don't have any facilities on my site to track users at all as it stands.
I will probably be mooching parts of your CSS though, thanks for posting it here!
Edit: you are correct, I seem to have forgotten to include <HTML> tags... I should probably fix that.
[1] https://gist.github.com/charlesdaniels/ac5fa6e3e77aef5ff5c85...
Thank you. I was hoping you had figured out how to get it going in `pandoc`, tried it myself to no avail but just assumed I had done something wrong.
>I am unclear on your dnt script? What does it do? I don't have any facilities on my site to track users at all as it stands.
No, but I can imagine it useful if you did want to put a relevant YouTube video or Tweet embedded in, but wanted to respect DNT. It's worked pretty well so far.
>I will probably be mooching parts of your CSS though, thanks for posting it here!
No problem! Some parts to make the font size a little better for mobiles too at the top :)
>Edit: you are correct, I seem to have forgotten to include <HTML> tags... I should probably fix that.
Yeah, not a massive deal but who knows, could break something in the future!
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?I am honestly surprised to find Python is so slow in terms of start up time. This made me wonder if it was generating / searching for .pyc files, but a quick test revealed this is not the case:
sh-4.3$ ls
nop.py nop.sh
sh-4.3$ hexdump -C nop.py
sh-4.3$ hexdump -C nop.sh
sh-4.3$ time python3 nop.py
real 0m0.064s
user 0m0.048s
sys 0m0.016s
sh-4.3$ time sh nop.sh
real 0m0.002s
user 0m0.002s
sys 0m0.000s
sh-4.3$ python3 -m compileall .
Listing '.'...
Compiling './nop.py'...
sh-4.3$ time python3 nop.py
real 0m0.062s
user 0m0.057s
sys 0m0.004s
sh-4.3$ python3 __pycache__/nop.cpython-35.pyc
sh-4.3$ time python3 __pycache__/nop.cpython-35.pyc
real 0m0.060s
user 0m0.048s
sys 0m0.012s
I would add that shell can be surprisingly fast for certain tasks when used correctly. It's very easy to write slow (ba)sh code though, so most shell scripts wind up being fairly non-performent.Edit: formatting.
Also, if you're looking for a stable Python-based static site generator... I've been pretty happy with Pelican (https://blog.getpelican.com/).
[0]: https://github.com/almata/BlogGit/blob/master/README.md
For example, Go: https://gohugo.io/
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.
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.
That said, anything more and a handful of pages (and especially something blog-y) needs search. Else the UX could take on too much friction.
A couple weeks ago I saw something about a tool Facebook OS'ed for doing project documentation. I believe that was static and had search. I think. Unfortunately, I didn't go so far as to see if you could fake a (not for docs) website with it.
I've added search functionality to static sites before and the various JavaScript libraries available for this like lunrjs.com are super fast and easy to integrate. You can create a static search index at build time from a JSON file of your core content (probably a few 100KB compressed for many sites) and the search as you type functionality is instant which can be a better UX than other solutions.
[1]: https://discourse.gohugo.io/t/site-search-implemented-using-... [2]: https://scripter.co/search/
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!
Ox-hugo that the OP mentioned is just an Emacs package that exports Org to Markdown + front-matter (without having to manually specify many of be front matter data in the Org source.. most of it is auto derived.).
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
echo "<html>" > index.html <!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 touch i > index.html
And there's ofcourse: <<eof > index.html
<html>
<p>hello, world! from
$(whoami)</p>
</html>
eof
See also: m4. > index.html
You win. >index.htm
Two characters shorter and will work fine on most HTTP servers ;-)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?
https://githubengineering.com/a-formal-spec-for-github-markd...
CommonMark, a pure Python Markdown parser and renderer:
https://jugad2.blogspot.in/2014/09/commonmark-pure-python-ma...
One interesting point from them was this:
[ Reddit user bracewel, who seems to be a CommonMark team member, said on the Py Reddit thread:
eventually we'd like to add a few more renderers, PDF/RTF being the first.... ]
Funny how they're fundamentally not that different.
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.