all repos — site @ aeac067ecb8e004a09c61c83996dfc7e31a14342

source for my site, found at icyphox.sh

pages/blog/site-changes.md (view raw)

  1---
  2template:
  3slug: site-changes
  4title: Site changes
  5subtitle: New stuff at the {back,front}end
  6date: 2020-05-27
  7---
  8
  9The past couple of days, I've spent a fair amount of time tweaking this
 10site. My site's build process involves
 11[vite](https://github.com/icyphox/vite) and a bunch of
 12[scripts](https://github.com/icyphox/site/tree/master/bin). These
 13scripts are executed via vite's pre- and post-build actions. The big
 14changes that were made were performance improvements in the
 15`update_index.py` script, and the addition of `openring.py`, which you
 16can see at the very bottom of this post!
 17
 18## speeding up index page generation
 19
 20The old script -- the one that featured in [Hacky
 21scripts](/blog/hacky-scripts) -- was absolutely ridiculous, and not to
 22mention _super_ slow. Here's what it did:
 23
 24- got the most recent file (latest post) by sorting all posts by
 25  `mtime`.
 26- parsed the markdown frontmatter and created a markdown table entry
 27  like: 
 28
 29```python
 30line = f"| [{meta['title']}]({url}) | `{meta['date']}` |"
 31```
 32- updated the markdown table (in `_index.md`) by in-place editing the
 33  markdown, with the line created earlier -- for the latest post.
 34- finally, I'd have to _rebuild_ the entire site since this markdown
 35  hackery would happen at the very end of the build, i.e, didn't
 36  actually get rendered itself. 
 37
 38That...probably didn't make much sense to you, did it? Don't bother.
 39I don't know what I was thinking when I wrote that mess. So with how it
 40_was_ done aside, here's how it's done now:
 41
 42- the metadata for all posts are nicely fetched and sorted using
 43  `python-frontmatter`.
 44- the metadata list is fed into Jinja for use in templating, and is
 45  rendered very nicely using a simple `for` expression:
 46
 47```
 48{% for p in posts %}
 49  <tr>
 50    <td align="left"><a href="/blog/{{ p.url }}">{{ p.title }}</a></td>
 51    <td align="right">{{ p.date }}</td>
 52  </tr>
 53{% endfor %}
 54```
 55
 56A neat thing I learnt while working with Jinja, is you can use
 57`DebugUndefined` in your `jinja2.Environment` definition to ignore
 58uninitialized template variables. Jinja's default behaviour is to remove
 59all uninitialized variables from the template output. So for instance,
 60if you had:
 61
 62```html
 63<body>
 64    {{ body }}
 65</body>
 66
 67<footer>
 68    {{ footer }}
 69</footer>
 70```
 71
 72And only `{{ body }}` was initialized in your `template.render(body=body)`,
 73the output you get would be:
 74
 75```html
 76<body>
 77    Hey there!
 78</body>
 79<footer>
 80
 81</footer>
 82```
 83
 84This is annoying if you're attempting to generate your template across
 85multiple stages, as I was. Now, I initialize my Jinja environment like
 86so:
 87
 88```python
 89from jinja2 import DebugUndefined
 90
 91env = jinja2.Environment(loader=template_loader,undefined=DebugUndefined)
 92```
 93
 94I use the same trick for `openring.py` too. Speaking of...let's talk
 95about `openring.py`!
 96
 97## the new webring thing at the bottom
 98
 99After having seen Drew's [openring](https://git.sr.ht/~sircmpwn/openring),
100my [NIH](https://en.wikipedia.org/wiki/Not_invented_here) kicked in and I wrote
101[`openring.py`](https://github.com/icyphox/openring.py). It pretty much
102does the exact same thing, except it's a little more composable with
103vite. Currently, it reads a random sample of 3 feeds from a list of
104feeds provided in a `feeds.txt` file, and updates the webring with those
105posts. Like a feed-bingo of sorts. ;)
106
107I really like how it turned out -- especially the fact that I got my CSS
108grid correct in the first try!