pages/blog/site-changes.md (view raw)
1---
2template:
3url: 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!