Compare commits

...

277 Commits

Author SHA1 Message Date
f9f6542597 Undelete flying toasters theme song 2025-08-14 21:59:59 -05:00
e962fd1ebe Implement guestbook 2025-08-14 21:54:26 -05:00
23bee4569d Delete old error pages 2025-08-14 21:54:09 -05:00
087aa4ee5a Add now burning entry 2025-08-14 21:53:53 -05:00
85b4e2e994 Move error pages 2025-08-14 21:53:37 -05:00
65b68b3600 Add post 2025-08-10 20:38:29 -05:00
7e4c8fdebc Now burning entries 2025-08-10 20:38:22 -05:00
e40d145225 Tweak flying toasters page title 2025-07-29 16:11:13 -05:00
bf3d60fdc2 Implement flying toasters 2025-07-29 16:08:47 -05:00
b444b59533 Add The 74 to the blogroll 2025-07-29 14:41:04 -05:00
2ac26f935a Add now burning entries 2025-07-29 14:40:46 -05:00
af04f61821 Change site default time zone to fix RSS issue 2025-07-16 12:54:09 -05:00
8a48f677f6 Update Eleventy 2025-07-16 12:53:40 -05:00
a3f1d04921 Disable structured data for now-burning
Broken with new version of eleventy, and probably not necessary anyway.
2025-07-16 12:53:28 -05:00
4fa562d0fe Fix YAML syntax errors 2025-07-16 12:52:35 -05:00
5df418eb2e Add entries to blogroll 2025-07-16 12:50:36 -05:00
6fe844486e Update /wish 2025-07-16 12:50:23 -05:00
d38da8fc37 Add category list and header links to blogroll 2025-07-16 12:50:07 -05:00
46f83c4c24 Remove id attr. from opml 2025-07-16 12:49:19 -05:00
81e76f3da0 Update changelog 2025-07-16 12:47:59 -05:00
92fd1289d1 Add entries 2025-07-16 12:47:33 -05:00
47b31e38a2 Edit 2025-07-13 23:24:42 -05:00
c63c5fc53a Update 2025-07-13 23:01:48 -05:00
94023ca08a Add post 2025-07-13 22:53:20 -05:00
5e174152da Update blogroll 2025-07-13 17:46:07 -05:00
bba85933ec Add blog post 2025-07-13 17:33:00 -05:00
7e9c86117c Add masto ID 2025-07-13 17:11:03 -05:00
6405d9e23a Update changelog 2025-07-13 17:07:21 -05:00
04cadecd1d Change blog name 2025-07-13 17:07:14 -05:00
a1217cf4e2 Update /about 2025-07-13 17:07:05 -05:00
fd584e37ee Add post 2025-07-12 21:02:08 -05:00
6f623db77f Update blogroll 2025-07-12 21:02:00 -05:00
88b9446e28 Now Burning entries 2025-07-12 21:01:47 -05:00
26c535c7c6 Update blogroll 2025-07-02 16:50:50 -05:00
1df625911b Update blogroll 2025-07-02 15:26:14 -05:00
579b00c520 Fix accidental borking of /now/ postlist 2025-07-02 15:20:23 -05:00
e490fa9f28 Add now burnign entry 2025-07-02 15:06:25 -05:00
16b9b06d7e Add /now/ entry 2025-07-02 15:06:14 -05:00
648c6d48b1 Update blogroll 2025-07-02 13:31:43 -05:00
cf88fe5ab8 Add now burning entries 2025-07-02 13:31:33 -05:00
82eaa31b61 Add new entry to blogroll 2025-06-26 12:45:26 -05:00
2a7946d260 Add now burning entries 2025-06-26 12:45:12 -05:00
fc4c791e5a Add info box 2025-06-24 12:13:05 -05:00
7b9cd3a156 Implement info boxes; add now-burning entries 2025-06-24 12:05:00 -05:00
e8eb8c9bc9 Small fixes, new now-burning posts 2025-06-09 11:42:36 -05:00
3871a05833 Implement now burning 2025-06-06 19:19:07 -05:00
698fe4b7c6 Fix quote 2025-05-06 16:34:14 -05:00
bb8197af28 Add post 2025-05-06 14:45:30 -05:00
236a7ccbd5 Spacing tweaks 2025-05-06 14:45:22 -05:00
ab831e429a Add <abbr> filter 2025-05-06 14:44:42 -05:00
286d3b7bdf Add masto IDs 2025-05-04 16:16:41 -05:00
37fde394a0 Add article 2025-05-04 16:04:40 -05:00
54c02ac7a6 Small article edit 2025-05-04 16:04:30 -05:00
b90aca5a10 Type improvements 2025-04-19 20:34:29 -05:00
83a28b4929 Update changelog. 2025-04-19 19:52:22 -05:00
4a133c6ece Add article 2025-04-19 19:51:07 -05:00
3033111803 Remove page animation, small tweaks 2025-04-19 19:50:57 -05:00
902382b027 Add alt="" to navigator icons 2025-04-19 19:50:10 -05:00
2312514f3f Tweak article copy 2025-04-19 19:49:39 -05:00
87a0627f24 Fix dark mode navigator icon color on hover 2025-04-08 19:38:43 -05:00
1494d22859 Merge pull request 'Tag page updates, changelog' (#5) from lessImages into main
Reviewed-on: #5
2025-04-08 19:30:42 -04:00
0054aa67de Tag page updates, changelog 2025-04-08 18:29:40 -05:00
f9ba790868 Merge pull request 'navigator' (#4) from navigator into main
Reviewed-on: #4
2025-04-08 17:54:54 -04:00
16df9ede8e Update navigator item border 2025-04-08 16:52:50 -05:00
8762c9c977 Implement navigator 2025-04-08 16:47:21 -05:00
7f2dd128c3 Add article 2025-04-08 13:08:33 -05:00
bffdb88170 Edit blogroll 2025-04-03 16:20:21 -05:00
59ba9d7f93 Update blogroll 2025-04-03 11:57:29 -05:00
185dc98e89 Fix title 2025-04-03 11:53:04 -05:00
3c3b74a571 Add posts 2025-03-28 20:36:05 -05:00
28f58173bd Update /tags/ header 2025-03-28 20:35:56 -05:00
c123c068e3 Update changelog 2025-03-28 20:35:48 -05:00
3c67472adc Update blogroll 2025-03-28 20:35:40 -05:00
94ec8fa443 Update blogroll and wish pages 2025-03-12 11:05:25 -05:00
bdb4dbc46e Add masto ID 2025-02-22 19:13:24 -06:00
c38cb78b05 Add Maroma article 2025-02-22 19:10:27 -06:00
857f856e05 Update /wish 2025-02-21 10:08:42 -06:00
2b59cd2475 Update /wish 2025-02-20 12:12:08 -06:00
92638b30af Update blogroll 2025-02-17 11:39:46 -06:00
457c905ba7 Add masto id 2025-02-14 00:27:28 -06:00
860cfc8d8c Add article, minor fixes 2025-02-14 00:22:43 -06:00
e43efcaed8 Update /me 2025-02-11 16:12:36 -06:00
f4b0dff348 Fix my goddamn blogroll 2025-02-07 16:39:53 -06:00
b9124f18ab Add friendica to /me 2025-02-06 10:14:55 -06:00
bd05208aee Deprecate cowsay of the day 2025-02-06 10:14:38 -06:00
a25d8ef163 Update changelog 2025-02-04 18:43:36 -06:00
2de19c8882 Fix typo 2025-02-04 18:43:27 -06:00
793b6482b2 Re-implement open graph etc 2025-02-04 18:42:57 -06:00
9e62744415 Add article 2025-02-04 18:42:36 -06:00
a915341e5c Big update: add quiz function, new post 2025-02-02 17:40:57 -06:00
a98006f918 Fix buttonContainer issue 2025-01-24 15:35:43 -06:00
8bbb071a34 Update README 2025-01-24 14:28:40 -06:00
de0e840578 Fix another XML issue 2025-01-24 14:27:03 -06:00
35367c5b6f Update changelog 2025-01-24 14:26:47 -06:00
8a78ee2b9f Improve now page 2025-01-24 14:20:16 -06:00
ec4c5d259b Fix xsl error
How dare I try to use an <hr>?!
2025-01-24 14:05:00 -06:00
1c3ab2d1fb Fix button margin 2025-01-24 13:47:10 -06:00
a9acf53d90 Fix link 2025-01-24 13:39:47 -06:00
5c117de06f Add gallery to index. 2025-01-23 15:34:14 -06:00
54797ddb2b Add gallery 2025-01-23 15:33:59 -06:00
153b178c40 UI updates 2025-01-23 14:24:51 -06:00
ef37d7622d Update changelog 2025-01-23 14:23:00 -06:00
7c06d746d4 Styling tweaks 2025-01-23 14:22:51 -06:00
a2dd293bf0 Update wishlist 2025-01-23 14:22:35 -06:00
aaae71adf9 Deprecate comment embedding in favor of button 2025-01-23 14:21:53 -06:00
f758f1c973 Change postlist header 2025-01-23 14:20:46 -06:00
4a4b2464da Re-size post image 2025-01-23 14:20:24 -06:00
7063473cd7 Add entry to blogroll 2025-01-23 14:20:08 -06:00
9defa3baf2 Add now entry 2025-01-23 14:19:42 -06:00
b83e4132ee Add post 2025-01-23 14:19:33 -06:00
c615de4b0b Add "essays" tag 2024-12-18 23:15:34 -06:00
e8185fb3a7 Add post 2024-12-18 23:15:20 -06:00
6e21b47f30 Update changelog 2024-12-16 23:44:36 -06:00
78f6392e87 Update peertube instance 2024-12-16 23:44:22 -06:00
e3c6a95680 Add mastodon ID to post 2024-12-16 23:41:50 -06:00
0e22c8028f Add article 2024-12-16 23:33:21 -06:00
3244e9a889 Update peertube urls 2024-12-16 23:33:11 -06:00
39ee777d1b Add entry to blogroll 2024-12-15 18:42:48 -06:00
c935223848 Add link to site stats 2024-12-15 15:31:16 -06:00
5b46c84afb Add /wish 2024-12-14 20:20:33 -06:00
b0106e6666 A heap of changes, whoops 2024-12-11 13:15:47 -06:00
7bdc97f0c6 change 2024-12-09 20:42:03 -06:00
12558a1a2d Small, unimportant change 2024-12-09 20:40:43 -06:00
1e1df2fb4b Update synopsis 2024-12-09 20:34:01 -06:00
c060e0efb7 Add article 2024-12-09 20:32:34 -06:00
82d1c3cd67 Figure styling for video embeds 2024-12-09 20:32:25 -06:00
fe242632d6 Add new tags 2024-12-09 20:32:05 -06:00
ea264309f7 Type fix 2024-12-03 19:11:25 -06:00
7916f91751 Update post 2024-12-02 18:36:12 -06:00
115c9497df Add post 2024-12-02 18:32:37 -06:00
686239ea03 Implement image galleries 2024-12-02 17:42:20 -06:00
51a1693265 Minor tweaks to h3 and sup 2024-11-12 18:47:17 -06:00
0ad1596646 Add black metal article 2024-11-12 18:47:00 -06:00
11b4d84044 Add loops link to /me 2024-11-12 12:47:28 -06:00
e7ebe8d22d Tweak link button styling 2024-11-12 12:47:08 -06:00
09a3a32a83 Update blogroll 2024-11-11 10:20:18 -06:00
82db6b1ba2 Allow unescaped HTML markup in blogroll descriptions 2024-11-11 10:20:08 -06:00
8849f10e88 Add Inverse 2024-11-05 11:09:36 -06:00
00be4291f2 Add The Pudding to blogroll 2024-10-25 13:08:43 -05:00
5cc54bf34e Add animal justice blog feed 2024-10-24 10:44:48 -05:00
fbff81a7da Update Kate Editor link 2024-10-24 10:42:27 -05:00
9fbf30bf16 Add Ed Zitron to blogroll 2024-10-24 10:42:16 -05:00
41ae3fc47b Add Liberation News to blogroll 2024-10-24 10:36:52 -05:00
68a7454e72 New post 2024-10-23 23:26:04 -05:00
8ad99a35d4 Add audio embed feature 2024-10-23 22:40:08 -05:00
a908843984 Add audio embed feature 2024-10-23 22:39:32 -05:00
bfdb9f8419 Update /me 2024-10-23 18:19:12 -05:00
a7ec4e9335 Add now post 2024-10-06 19:04:23 -05:00
c6ea0176a3 Add <strong> styling for <figcaption> 2024-10-06 18:30:28 -05:00
bdcda7f2db Fix blog name 2024-09-30 06:34:08 -05:00
5d475f4bf3 Add new post 2024-09-29 15:10:57 -05:00
0fbfbc0b78 Fix link 2024-09-26 10:13:07 -05:00
cb8999f50a Add some feeds to the blogroll 2024-09-25 13:51:55 -05:00
d0a1785f23 Add link to opml per opml.org 2024-09-25 13:26:18 -05:00
f3c58d09da Update .gitignore 2024-09-25 13:25:40 -05:00
7095d8850b Tidy up, style blogroll 2024-09-25 13:06:12 -05:00
0284950ba5 Add about/privacy 2024-09-25 13:05:10 -05:00
7754b310c3 Add /about/colophon 2024-09-25 13:05:01 -05:00
4add841e55 Add base in which <p> spans all columns by default 2024-09-25 13:04:41 -05:00
3ff627cdc8 Remove netlify.toml as I don't use netlify 2024-09-25 13:03:53 -05:00
b7e997515e Update buttons on index 2024-09-25 13:03:36 -05:00
75aa8e4a33 Add category 2024-09-25 13:03:14 -05:00
fb06d54ea5 Add buttons to /blog/ 2024-09-25 13:03:01 -05:00
cb33208e54 Add blogroll features 2024-09-25 13:02:36 -05:00
6328a531a7 Add sitemap page for humans 2024-09-25 13:01:59 -05:00
1ba8841d32 Update /about/ copy 2024-09-25 13:01:29 -05:00
bc18e89d8d Update README with blogroll and opml feature 2024-09-25 13:00:42 -05:00
f8610fe915 Update license copyright year 2024-09-25 13:00:18 -05:00
b4c2a76949 Add post 2024-09-21 18:00:09 -05:00
a44a1c4431 Update default post image 2024-09-21 17:59:58 -05:00
5bf446c5c2 Fix typo 2024-09-21 17:59:42 -05:00
5e324f2afd Nest some stuff 2024-09-21 17:59:28 -05:00
dd2c327613 Fix footnote hr selector 2024-09-20 23:59:01 -05:00
21b66dd28f Style footnotes 2024-09-20 23:57:00 -05:00
6dc2db4c52 Fix prettier config 2024-09-20 23:55:41 -05:00
acb55c80a1 Move punctuation after links 2024-09-20 23:55:16 -05:00
2cf0c6ce1d Add post 2024-09-20 23:54:51 -05:00
d328e79da9 metadata tweak 2024-08-23 17:40:12 -05:00
34c37f37e1 Minor page updates 2024-08-23 17:33:33 -05:00
3ec15ed8e2 Tweaks to structured data 2024-08-23 17:33:22 -05:00
5389651b27 add masto id 2024-08-20 17:52:49 -05:00
afd8a3ca6e stuff 2024-08-20 17:49:47 -05:00
3cf4345042 Add post 2024-08-20 17:49:32 -05:00
c153a2a60d Abandon hope of getting 11ty image plugin working 2024-08-19 18:24:11 -05:00
7c40b754db Update matrix user 2024-08-19 12:43:16 -05:00
4a476a0207 Prevent layout shift 2024-08-13 23:07:16 -05:00
21377ff19f Ensure text visibility while fonts load 2024-08-13 22:47:47 -05:00
092c806226 Fix active page li color 2024-08-13 22:46:19 -05:00
c5121f01ca Fix accessibility issue
Fix <li> inside <a> so screenreader can parse nav
2024-08-13 22:34:00 -05:00
d64b6e15cd Merge pull request 'Blah' (#3) from responsive-images into main
Reviewed-on: #3
2024-08-13 22:58:26 -04:00
0b9b30f6c2 Blah 2024-08-13 21:57:03 -05:00
e4f4a0ba26 Add masto ID 2024-08-05 09:26:26 -05:00
db56e011eb Add article 2024-08-04 21:02:38 -05:00
54bd9ad9ec Fix typo 2024-08-04 21:02:31 -05:00
3d672ce033 Edit index page 2024-08-04 21:02:11 -05:00
2c93d9199e Styling updates; Add author image to posts
mastodon comments inside cards, added fleuron to indicate end of article
2024-08-04 19:01:05 -05:00
621ad15006 Add more closely cropped author profile pic 2024-08-04 18:58:35 -05:00
345a62ea47 Add article 2024-08-04 18:58:07 -05:00
cdb82fe827 Article correction 2024-07-31 10:48:24 -05:00
7f80d0615c Fix fluid scaling 2024-07-28 23:34:11 -05:00
2913703074 Fix punctuation 2024-07-28 23:33:56 -05:00
777d33a4bb Add article 2024-07-28 23:33:37 -05:00
0cdf1e297b Add masto ID to "poison" 2024-07-16 18:48:48 -05:00
b09aa47d06 Add new post 2024-07-16 18:35:01 -05:00
7b00d49d43 Style blockquotes 2024-07-16 18:34:51 -05:00
62f6268651 Fix mastodon comment author URL 2024-07-16 18:34:31 -05:00
0387793868 update readme 2024-07-09 12:58:50 -05:00
ed1acf8cc8 update readme 2024-07-09 12:33:53 -05:00
bd04a9be19 Fix broken link 2024-07-09 12:30:44 -05:00
77067c7e01 update readme 2024-07-09 12:24:21 -05:00
ccdaea6d80 update readme 2024-07-09 12:19:41 -05:00
836463ad92 Move docs to wiki; update readme 2024-07-09 12:15:30 -05:00
54ec74c6ed Add toot embedding 2024-07-09 11:39:02 -05:00
e55fa73d92 Remove bottom margin from card component 2024-07-09 11:37:17 -05:00
4569060d41 Upgrade 11ty version 2024-07-09 11:36:40 -05:00
a7c7d31552 Update documentation 2024-07-09 11:36:16 -05:00
0536a3aeb7 Update JS to ES modules 2024-07-09 11:36:02 -05:00
a0dc421189 Add article 2024-06-23 20:04:32 -05:00
cf18f89e10 fix typo and add commenting to post 2024-06-14 09:18:17 -05:00
6379ce0041 Add article 2024-06-11 19:40:05 -05:00
07f3be8083 Add post 2024-05-09 00:11:05 -05:00
3de856f413 Add new /now entry 2024-04-13 21:50:15 -05:00
59484d8363 Refactor /now to use built in postslist include 2024-04-13 21:49:58 -05:00
a6bd281946 Add the latest /now entry to index page 2024-04-13 21:49:30 -05:00
049ba826dc Add option to hide author info
Allows use of post layout for /about-feeds, which fixes a layout issue
2024-04-13 21:49:01 -05:00
b1b57c7b6a Update Metadata 2024-04-13 21:47:34 -05:00
bfb31ba036 Fix typo 2024-04-13 19:06:35 -05:00
e0e09bcea1 add a post 2024-04-13 19:03:17 -05:00
8100e05cc3 Update /about 2024-04-13 19:02:23 -05:00
0aee314908 Style <th> 2024-04-13 19:02:10 -05:00
779cce9f9d Fix my HTML and integrate prettier 2024-03-29 14:19:01 -05:00
12baf5df2e Fix header sizes 2024-03-29 12:01:08 -05:00
dfa3989409 Remove cli-tools tag 2024-03-29 12:00:55 -05:00
e3061b9f5b Block AI shit 2024-03-29 12:00:38 -05:00
7582ac5218 Fix <code> background-color in dark mode 2024-03-19 10:17:42 -05:00
2039c3d886 Add plasma panel article 2024-03-18 20:00:00 -05:00
08021fa945 Better <code> styling 2024-03-18 19:59:45 -05:00
948fab0bb9 Smartquotes 2024-03-05 13:53:01 -06:00
a6f3143466 Simplify comment button text 2024-03-05 13:45:30 -06:00
859272b2a5 Implement smartquotes 2024-03-05 13:40:56 -06:00
ea72be3b17 Somehow this got deleted...? 2024-03-05 13:39:43 -06:00
2707a856d9 fix /me h1 line-height 2024-02-26 22:59:34 -06:00
35a5e436c6 Poasts 2024-02-26 22:52:14 -06:00
569b541eec Fix <pre> 2024-02-26 21:32:07 -06:00
26821b48ef Merge pull request 'Major styling update - mastodon comments' (#2) from utopia into main
Reviewed-on: #2
2024-02-26 21:33:32 -05:00
fcc91a17d4 Major styling update 2024-02-26 20:59:34 -06:00
69d7cd1da6 Implement mastodon comments 2024-02-04 19:36:44 -06:00
aa60dc5e32 Update Geekring links 2024-01-24 13:26:09 -06:00
2cb641cebb Add article 2024-01-24 13:00:06 -06:00
9d84151ee5 Refactor and modularize 2024-01-23 11:38:50 -06:00
1265d3d4a9 Fix icon colors 2024-01-22 22:30:05 -06:00
07ddc100c0 Add 403 page 2024-01-21 11:26:22 -06:00
efcac82d6a Add kmines theme article 2024-01-20 19:15:06 -06:00
920ec5ab9a Generate a separate feed for every tag 2024-01-20 17:59:54 -06:00
3d4020d2ae Implement now page, add new post "Patience" 2024-01-10 10:52:37 -06:00
3140ef0b72 Add next / previous cards to posts 2024-01-02 16:48:28 -06:00
bd2b505a5e Update README.md 2023-09-22 13:14:38 -04:00
9d599f9bd4 fix tag page styling 2023-08-29 15:32:15 -05:00
ffbe6918f8 Sort tags alphabetically 2023-08-29 15:31:50 -05:00
be4cbac363 Styling tweaks 2023-08-21 19:22:39 -05:00
790d9fcbba Add h2 to /blog/ 2023-08-21 19:22:10 -05:00
9d23167be7 Add default author if none specified in post 2023-08-21 19:21:48 -05:00
d3b1b3a020 Add about-feeds images 2023-08-21 18:28:50 -05:00
01ab774c48 add orange RSS logo for easy <img> use 2023-08-21 18:28:39 -05:00
1b8af40052 Add about feeds page 2023-08-21 18:28:19 -05:00
25529178d0 Improve XML feed styling 2023-08-21 18:27:53 -05:00
0e991b1dee Refactor CSS 2023-08-21 18:27:24 -05:00
f48cfb997c Remove template markup 2023-08-21 18:26:57 -05:00
d7dadd01d7 Change post image 2023-08-21 18:26:36 -05:00
5e24e8f234 Fix post image URL and add description 2023-08-21 18:26:16 -05:00
75eb02a75a Adjust truncated character number 2023-08-21 18:24:59 -05:00
2a4e7c719b Refactor CSS 2023-08-20 18:15:08 -05:00
96740f9809 Update /about/ 2023-08-15 09:31:02 -05:00
b76f1cd53d Add robots.txt - block chatgpt 2023-08-15 09:30:40 -05:00
ca908fdf0f Fix mobile image display 2023-08-09 19:55:58 -05:00
85a5bde512 Fix a thing 2023-08-09 19:55:45 -05:00
d51a0dd6ca Add QOwnNotes article 2023-08-09 19:55:17 -05:00
467 changed files with 10652 additions and 1299 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
_site/ _site/
node_modules/ node_modules/
package-lock.json package-lock.json
.kateproject.notes

View File

@ -1,17 +1,13 @@
TODO: TODO:
Integrate est. read time
Integrate % done in article
Investigate pagination for /blog/ Investigate pagination for /blog/
Integrate recipe structured data for recipe type articles Integrate recipe structured data for recipe type articles
No line breaks in inline code fences No line breaks in inline code fences
Style inline code fences with background Style inline code fences with background
Integrate ins plugin Integrate ins plugin
Add "Now" to RSS feed.
Performance / Accessibility: Performance / Accessibility:
--------------------------------------- ---------------------------------------
Lazy load images Lazy load images
Remove unecessary fonts
change font-display to "swap"
Caching
Add explicit image dimensions? Add explicit image dimensions?

View File

@ -1,6 +1,6 @@
GPL3 License GPL3 License
Copyright (c) 2023 Nathan Upchurch Copyright (c) 2023-2024 Nathan Upchurch
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,6 +1,33 @@
# nathanupchurch.com - Based on eleventy-base-blog v8 # My 11ty Blog
My blog, originally based on the very helpful eleventy-base-blog v8, although it has come a long way from its humble beginnings. For documentation, check [the wiki](https://upchur.ch/gitea/n_u/nathanupchurch.com/wiki).
### Implementation Notes ## Features
### Design
* Fluid type and spacing systems for responsive pages with zero breakpoints
* Dark mode
* Graceful but unobtrusive page transitions
* Pretty variable typefaces
* Pretty 401 and 403 error pages
- `content/blog/` has the blog posts but really they can live in any directory. They need only the `posts` tag to be included in the blog posts [collection](https://www.11ty.dev/docs/collections/). ### Fediverse Integration
- Use the `eleventyNavigation` key (via the [Eleventy Navigation plugin](https://www.11ty.dev/docs/plugins/navigation/)) in your front matter to add a template to the top level site navigation. This is in use on `content/index.njk` and `content/about/index.md`. * Mastodon [toot embedding](https://upchur.ch/gitea/n_u/nathanupchurch.com/wiki/Home#embed-a-toot-from-mastodon-using-the-toot-shortcode)
* Link to post discussion on Mastodon
### Indieweb
* [Auto-generated linktree-style page](https://upchur.ch/gitea/n_u/nathanupchurch.com/wiki#me) for the blog owner with support for custom attributes such as: `rel="me"`
* Built in support for [webring links](https://upchur.ch/gitea/n_u/nathanupchurch.com/wiki#webrings)
* Auto-generated, **styled** RSS feeds
* All blog posts
* Each individual tag
* /now page that nicely handles posts tagged with "now"
* Blogroll generated from _data/blogroll.js, with an automatically updated .opml so that visitors can import every blog in the list
* Image galleries
### Fun
* Image galleries
* Quizzes
### Quality of Life
* Copyright notice, default post image, alt text, and author details defined in `metadata.js`.
* "Read Next" highlighting the previous blog post at the bottom of every post
* robots.txt tells AI scrapers to GTFO

838
_data/blogroll.js Normal file
View File

@ -0,0 +1,838 @@
export default {
categories: [
{
name: "Climate Change",
blogs: [
{
title: "Grist",
feedUrl: "https://grist.org/feed/",
url: "https://grist.org/",
description:
'Grist is dedicated to highlighting climate solutions and uncovering environmental injustices. (Thanks to <a href="https://werd.io/2024/non-profit-newsrooms-that-speak-to-power">werd.io</a> for the recommendation.)',
},
],
},
{
name: "Collectives / Compilations",
blogs: [
{
title: "Bear Blog Discover",
feedUrl: "https://bearblog.dev/discover/feed/?lang=en",
url: "https://bearblog.dev/discover/",
description:
"ʕ•ᴥ•ʔ Bear is a privacy-first, no-nonsense, super-fast blogging platform. Bear's discovery feed lists trending articles from the Bear blogosphere.",
},
{
title: "Freethought Blogs",
feedUrl: "https://freethoughtblogs.com/feed/",
url: "https://freethoughtblogs.com/",
description:
"Freethoughtblogs is an open platform for freethought writers. We are skeptics and critics of dogma and authoritarianism, and in addition, we recognize that the nonexistence of deities entails a greater commitment to human values, and in particular, an appreciation of human diversity and equality. We are for feminism, against racism, for diversity, against inequity. Our network of blogs is designed to encourage independent thinking and individual autonomy — freethoughtblogs.com is a vehicle for giving vocal secularists a venue for discussion of their values and interests.",
},
],
},
{
name: "Comics",
blogs: [
{
title: "Graphic Rage with Aubrey Hirsch",
feedUrl: "https://aubreyhirsch.substack.com/feed",
url: "https://aubreyhirsch.substack.com/",
description:
"Im a writer, illustrator, and creator of feminist comics! If youre an avid reader, you may have seen my work in Vox, TIME or The Washington Post. I also write a monthly comic for Roxane Gays newsletter, The Audacity. In this space, I do a little bit of everything, but you can expect to see a lot of comics about gender, justice, aging, and life as a woman in America.",
},
{
title: "Incidental Comics",
feedUrl:
"http://www.incidentalcomics.com/feeds/posts/default?alt=rss",
url: "http://www.incidentalcomics.com",
description: "Nice comics about words, et cetera.",
},
{
title: "XKCD",
feedUrl: "https://xkcd.com/rss.xml",
url: "https://xkcd.com",
description: "Does XKCD needs an introduction?",
},
],
},
{
name: "Design",
blogs: [
{
title: "Adam Silver",
feedUrl: "https://adamsilver.io/atom.xml",
url: "https://adamsilver.io/",
description:
"Adam Silver is a designer and frontend engineer from London, UK.",
},
{
title: "Autumn Kotsiuba",
feedUrl: "https://autumnkotsiuba.wixsite.com/portfolio/blog-feed.xml",
url: "https://autumnkotsiuba.wixsite.com",
description: "Autumn blogs about UX content design.",
},
{
title: "Abduzeedo",
feedUrl: "https://abduzeedo.com/rss.xml",
url: "https://abduzeedo.com/",
description:
"Abduzeedo is a collective of individual writers sharing articles about design, photography, and UX. It was founded by Fabio Sasso in 2006 as a personal blog, later growing to become a digital publication with several writers from all over the world, working independently.",
},
{
title: "Admire the Web",
feedUrl:
"https://feeds.feedburner.com/AdmireTheWeb-TheVeryBestWebDesignInspiration",
url: "https://admiretheweb.com/",
description: "Web design inspiration.",
},
{
title: "Alphabettes",
feedUrl: "https://www.alphabettes.org/feed/",
url: "https://www.alphabettes.org/",
description:
"Alphabettes.org is a showcase for work, commentary, and research on lettering, typography, and type design. Our loose network is here to support and promote the work of all women and nonbinary people in our fields.",
},
{
title: "Creative Review",
feedUrl: "https://www.creativereview.co.uk/feed/",
url: "https://www.creativereview.co.uk/",
description:
"Creative Review has been bringing the creative community together since 1980, first as a print magazine and now across more platforms than ever.",
},
{
title: "Dave Smyth",
feedUrl: "https://davesmyth.com/commonplace-feed",
url: "https://davesmyth.com",
description:
"Dave Smyth is a designer and developer interested in privacy, type and ethics.",
},
{
title: "Design By Women",
feedUrl: "https://designby-women.com/feed/",
url: "https://designby-women.com/",
description:
"Founded by graphic designer Mary Hemingway in June 2020, Design by Women aims to showcase and celebrate women, gender expansive and gender non-conforming creatives currently working in the design industry and to inspire emerging under-represented creatives to pursue a career in design.",
},
{
title: "DIELINE",
feedUrl: "https://thedieline.com/feed/",
url: "https://thedieline.com/",
description:
"DIELINE is a creative platform dedicated to serving the global packaging community.",
},
{
title: "Friends of Type",
feedUrl: "https://friendsoftype.com/feed/",
url: "https://friendsoftype.com/feed/",
description:
"Friends of Type features original typographic design and lettering fresh visual content practically every day.",
},
{
title: "Grumpy Website",
feedUrl: "https://grumpy.website/feed.xml",
url: "https://grumpy.website",
description: "Grumpy takes on UI mistakes.",
},
{
title: "Identity Designed",
feedUrl: "https://identitydesigned.com/feed/",
url: "https://identitydesigned.com/",
description:
"Identity Designed is a website and book series devoted to the design of visual identities.",
},
{
title: "It's Nice That",
feedUrl: "http://feeds2.feedburner.com/itsnicethat/SlXC",
url: "https://www.itsnicethat.com/",
description:
"Our mission is to inspire the global creative community. We share stories, offer insights and bring people together to help them make more of their creativity.",
},
{
title: "I Love Typography",
feedUrl: "https://ilovetypography.com/feed",
url: "https://ilovetypography.com/",
description: "Talking about type.",
},
{
title: "Jamie Clarke Type",
feedUrl: "https://jamieclarketype.com/rss.xml",
url: "https://jamieclarketype.com",
description:
"Im an independent type designer and lettering artist based near Bristol, UK. I draw letters for clients worldwide and have almost three decades of experience as a designer and typographer.",
},
{
title: "Libre Arts",
feedUrl: "https://librearts.org/index.xml",
url: "https://librearts.org",
description: "News on FLOSS creative software.",
},
{
title: "Logo Design Love",
feedUrl: "https://www.logodesignlove.com/feed",
url: "https://www.logodesignlove.com/",
description:
"Logo Design Love is a website and book devoted to logos, symbols, icons, and marks.",
},
{
title: "PRINT Magazine",
feedUrl: "https://www.printmag.com/feed/",
url: "https://www.printmag.com/",
description:
"Where creative people gather to inspire and build design dialogue.",
},
{
title: "Print.pm",
feedUrl: "https://print.pm/rss",
url: "https://print.pm/",
description: "Daily inspiration for print lovers.",
},
{
title: "Siteinspire",
feedUrl: "https://www.siteinspire.com/websites/feed",
url: "https://www.siteinspire.com/",
description: "A showcase of the webs finest design + talent.",
},
{
title: "The Design Blog",
feedUrl: "https://thedsgnblog.com/rss",
url: "https://thedsgnblog.com",
description:
"The Design Blog is a carefully curated platform for design and creative inspiration featuring works of designers, studios, and creatives from around the world.",
},
{
title: "Toxel",
feedUrl: "https://feeds.feedburner.com/toxel",
url: "https://www.toxel.com/",
description:
"Toxel.com is a daily design, inspiration and technology blog dedicated to showcasing the best creative products and designs from all over the world.",
},
{
title: "TypeOff.",
feedUrl: "https://www.typeoff.de/rss",
url: "https://www.typeoff.de",
description:
"A blog from Dan Reynolds, a design researcher based in Wuppertal, Germany.",
},
{
title: "UX Daily",
feedUrl: "https://www.interaction-design.org/rss/site_news.xml",
url: "https://www.interaction-design.org",
description: "The Worlds Largest Free Online Resource on UX Design.",
},
{
title: "Visuelle",
feedUrl: "https://visuelle.co.uk/feed/",
url: "https://visuelle.co.uk",
description:
"Graphic Design and everything in between. Curated by David Bennett Creative Director at opx.studio.",
},
],
},
{
name: "Food & Beverage",
blogs: [
{
title: "A Tea Addict's Journal",
feedUrl: "https://marshaln.com/feed/",
url: "https://marshaln.com",
description:
"This blog got started in 2006 on Xanga as an attempt to write down what I thought about the teas I was drinking. At that point I had been a serious tea drinker for at least six or seven years, but until then, I never really thought much about it. I thought that by writing down my thoughts, it would help me organize my ideas about tea, and in doing so, I hoped to reach an audience who were like minded tea drinkers. My hunch that there were a lot more tea drinkers out there in the West was right, and through this blog I have met quite a number of like-minded individuals, some of whom have become very good friends. I hope that, if nothing else, my musings here will help you find a better tea experience lifes too short to be drinking bad tea.",
},
{
title: "Cocktail Doodle",
feedUrl: "https://cocktaildoodle.substack.com/feed",
url: "https://cocktaildoodle.substack.com",
description:
"A charming (but perhaps abandoned) blog from cocktail expert Luke Andrews.",
},
{
title: "Cwyn's Death by Tea",
feedUrl: "https://deathbytea.blogspot.com/feeds/posts/default",
url: "https://deathbytea.blogspot.com/",
description: "Straight up tea talk.",
},
{
title: "Essence of Tea Blog",
feedUrl: "https://essenceoftea.com/blogs/blog.atom",
url: "https://essenceoftea.com/blogs/blog",
description:
"We are tea lovers - a couple, David Collen and Yingxi Chen, who shared a wish to make good teas available to fellow tea lovers around the world.",
},
{
title: "Sarah's Vegan Kitchen",
feedUrl: "https://sarahsvegankitchen.com/feed/",
url: "https://sarahsvegankitchen.com",
description:
"Sarah has years of recipes including complex staples like vegan cultured butter.",
},
{
title: "Tea DB",
feedUrl: "https://teadb.org/feed/",
url: "https://teadb.org/",
description:
"TeaDB is a website and podcast started by friends and tea lovers James Schergen and Denny Chapin. James and Denny are business partners professionally, running websites in tea-unrelated industries (AllTreatment, TheraThink). We invite you to learn alongside us in our tea journeys!",
},
{
title: "white2tea",
feedUrl: "https://white2tea.com/blogs/blog.atom",
url: "https://white2tea.com/blogs/blog",
description:
"white2tea was created by passionate Puer devotees with over two decades of experience.",
},
],
},
{
name: "General Interest",
blogs: [
{
title: "Big Think",
feedUrl: "https://bigthink.com/feed",
url: "https://bigthink.com",
description: "Big thoughts on big issues.",
},
{
title: "Clients from Hell",
feedUrl: "https://notalwaysright.com/tag/clients-from-hell/feed",
url: "https://notalwaysright.com/tag/clients-from-hell",
description:
"Cathartic stories about clients behaving badly from notalwaysright.com.",
},
{
title: "kottke.org",
feedUrl: "https://feeds.kottke.org/main",
url: "https://kottke.org",
description: "Home of fine hypertext products since 1998.",
},
{
title: "Neatorama",
feedUrl: "https://www.neatorama.com/feed",
url: "https://www.neatorama.com/",
description: "Yep, Neatorama's still around!",
},
{
title: "The Pudding",
feedUrl: "https://pudding.cool/rss.xml",
url: "https://pudding.cool",
description:
"The Pudding is a digital publication that explains ideas debated in culture with visual essays.",
},
{
title: "The Reframe",
feedUrl: "https://www.the-reframe.com/rss/",
url: "https://www.the-reframe.com/",
description:
"Essays on politics and narrative fiction from A.R. Moxon.",
},
{
title: "Webcurios",
feedUrl: "https://webcurios.co.uk/feed",
url: "https://webcurios.co.uk",
description:
"A regular(-ish) newsletterblogtypething all about stuff on the internet that its author finds interesting and thinks you might too.",
},
],
},
{
name: "Health",
blogs: [
{
title: "ADDitude",
feedUrl: "https://www.additudemag.com/feed/",
url: "https://www.additudemag.com/",
description:
"The worlds most trusted resource for families and adults living with ADHD and related conditions, and for the professionals who work with them.",
},
{
title: "The Gauntlet",
feedUrl: "https://www.thegauntlet.news/feed",
url: "https://www.thegauntlet.news",
description:
"A newsletter covering the current science on, and commentary related to, the unmitigated spread of COVID.",
},
],
},
{
name: "Incense, Fragrance, and Perfumery",
blogs: [
{
title: "Apothecary's Garden Blog",
feedUrl: "https://apothecarysgarden.com/blogs/blog.atom",
url: "https://apothecarysgarden.com/blogs/blog",
description:
"Explore the world of natural aromatics, and the communities that bring them to us.",
},
{
title: "Ayala Moriel Parfums - SmellyBlog",
feedUrl: "https://ayalamoriel.com/blogs/smellyblog.atom",
url: "https://ayalamoriel.com/blogs/smellyblog",
description:
"Ayala Moriel Parfums is an independent artisan perfume house dedicated to the art of natural perfumery.",
},
{
title: "A whiff of Ambrosia",
feedUrl: "https://whiffofambrosia.wordpress.com/feed/",
url: "https://whiffofambrosia.wordpress.com/",
description: "Incense reviews and more. (Abandoned?)",
},
{
title: "Dr. Incense",
feedUrl: "https://dr-incense.com/blogs/dr-incense-blog.atom",
url: "https://dr-incense.com/blogs/dr-incense-blog",
description:
"Traditional incense maker and founder of the Incense Culture Association of Singapore, and Nanyang Culture Academy.",
},
{
title: "Glass Petal Smoke",
feedUrl: "https://glasspetalsmoke.blogspot.com/feeds/posts/default",
url: "https://glasspetalsmoke.blogspot.com/",
description:
"Decoder of flavors and fragrances. Creator of Smell & Tell programming.",
},
{
title: "Incense Apprentice",
feedUrl: "https://incenseapprentice.substack.com/feed",
url: "https://incenseapprentice.substack.com",
description: "Exploring incense making with Sara Gray.",
},
{
title: "Incense In The Wind",
feedUrl: "https://incenseinthewind.blogspot.com/feeds/posts/default",
url: "https://incenseinthewind.blogspot.com/",
description: "Incense reviews, rankings, and information.",
},
{
title: "Justine the Incenseur",
feedUrl: "https://justinetheincenseur.substack.com/feed",
url: "https://justinetheincenseur.substack.com/",
description:
"I am Justine Crane, natural perfumer and incenseur. I created the course content at the Natural Perfume Academy online, and the owner/operator of the Scented Djinn Apothecary & Thurifercorum. Im also half of the in-person teaching duo, The Rebel Perfumers, with my teaching partner, Cher Lynn of Essential Oil Apothecary. Im using this space to write about everything natural perfume and incense related. There will be some shameless plugging of my businesses, as well as tons of information about NP and incense. Lets do this.",
},
{
title: "Kikoh Incense",
feedUrl: "https://kikohincense.com/blogs/news.atom",
url: "https://kikohincense.com/blogs/news",
description:
"Detailed descriptions of incense listening sessions from the Kikoh Incense web store.",
},
{
title: "KyaraZen",
feedUrl: "https://www.kyarazen.com/feed/",
url: "https://www.kyarazen.com/",
description:
"Very informative (but perhaps abandoned) blog from world-renowned incense maker KyaraZen.",
},
{
title: "Olfactory Rescue Service",
feedUrl: "https://olfactoryrescueservice.wordpress.com/feed",
url: "https://olfactoryrescueservice.wordpress.com",
description:
"The ultimate retail incense resource providing incense writing and reviews.",
},
{
title: "Ratnagandh",
feedUrl: "https://ratnagandh.wordpress.com/feed/",
url: "https://ratnagandh.wordpress.com/",
description: "Short incense reviews.",
},
{
title: "Rauchfahne",
feedUrl: "https://blog.rauchfahne.de/en/feed/",
url: "https://blog.rauchfahne.de/en/",
description:
"Incense reviews and writing in German and English from incense maker, enthusiast, and industry insider Irene.",
},
{
title: "Reed's Handmade Incense Blog",
feedUrl: "https://reedshandmadeincense.com/blog/feed/",
url: "https://reedshandmadeincense.com/blog/",
description:
"Writing on incense, tea, and other topics from the Reed's Handmade Incense web store.",
},
{
title: "The Parfum Apothecary - Learning & Culture",
feedUrl:
"https://www.theparfumapothecary.com/blogs/learning-culture.atom",
url: "https://www.theparfumapothecary.com/blogs/learning-culture",
description: "Writing on perfume and its history. (Abandoned?)",
},
],
},
{
name: "LGBTQ+",
blogs: [
{
title: "Assigned Media",
feedUrl: "https://www.assignedmedia.org/?format=rss",
url: "https://www.assignedmedia.org/",
description:
"Mainstream coverage of transgender life is falling short, while transphobic propaganda on the right grows louder and more insistent every day. Assigned publishes factual, up to date, responsible coverage of trans issues, allowing trans people and our allies to separate the truth from the lies and build a response to anti-trans hate that achieves dignity and equality for trans people in the US and beyond.",
},
{
title: "Uncloseted Media",
feedUrl: "https://www.unclosetedmedia.com/feed",
url: "https://www.unclosetedmedia.com/",
description:
"Uncloseted Media is a new Investigative media organization committed to providing you with objective, nonpartisan, rigorous, LGBTQ-focused journalism that examines Americas anti-LGBTQ ecosystem and elevates the voices of everyday American heroes.",
},
],
},
{
name: "News: International",
blogs: [
{
title: "Bellingcat",
feedUrl: "https://www.bellingcat.com/feed/",
url: "https://www.bellingcat.com/",
description:
'Bellingcat is an independent investigative collective of researchers, investigators and citizen journalists brought together by a passion for open source research. (Thanks to <a href="https://werd.io/2024/non-profit-newsrooms-that-speak-to-power">werd.io</a> for the recommendation.)',
},
{
title: "openDemocracy",
feedUrl: "https://www.opendemocracy.net/en/feed",
url: "https://www.opendemocracy.net/",
description:
"High-quality journalism which challenges power, inspires change and builds leadership among groups underrepresented in the media. (Predominantly U.K. focused)",
},
{
title: "Rest of World",
feedUrl: "https://restofworld.org/feed/latest",
url: "https://restofworld.org/",
description:
"Rest of World is a nonprofit publication that challenges expectations about whose experiences with technology matter. We connect the dots across a rapidly evolving digital world, through on-the-ground reporting in places typically overlooked and underestimated.",
},
{
title: "Techdirt",
feedUrl: "https://www.techdirt.com/feed/",
url: "https://www.techdirt.com",
description:
"Started in 1997 by Floor64 founder Mike Masnick and then growing into a group blogging effort, the Techdirt blog relies on a proven economic framework to analyze and offer insight into news stories about changes in government policy, technology and legal issues that affect companies ability to innovate and grow.",
},
{
title: "Usermag",
feedUrl: "https://www.usermag.co/feed",
url: "https://www.usermag.co/",
description:
"We document the people and movements that shape the internet from weird online phenomena, to under-the-radar trends, to platform developments, to policy initiatives, to the powerful forces that shape our online world. It's about who has power on the internet and how that power is being wielded.",
},
],
},
{
name: "News: U.S.A.",
blogs: [
{
title: "Popular Information",
feedUrl: "https://popular.info/feed",
url: "https://popular.info/",
description: "News for people who give a damn.",
},
{
title: "Prism",
feedUrl: "https://prismreports.org/feed/",
url: "https://prismreports.org",
description:
"Prism is an independent and nonprofit news outlet led by journalists of color. We report from the ground up and at the intersections of injustice. Together, our journalists go where justice requires. Activists, thought leaders, decision-makers, and all those who believe in justice for all come to Prism for deep reporting and honest insights on the most pressing injustices of our time—delivered through the lens of those who are most impacted.",
},
{
title: "Reveal from the Center for Investigative Reporting",
feedUrl: "https://revealnews.org/feed",
url: "https://revealnews.org/",
description:
"Democracy faces an unprecedented threat from an authoritarian movement built on lies and contempt for the rule of law. The first and most critical defense of democracy—a robust, independent free press—has been missing in action. Corporate and billionaire media owners have shied away from confrontation, engaged in false equivalence, and sought to curry favor with Donald Trump. It is hardly surprising that readers and viewers are fleeing from these outlets. Americans need an alternative. The Contrarian is that alternative: unflinching, unapologetic, and unwavering in its commitment to truth-telling.",
},
{
title: "The 74",
feedUrl: "https://www.the74million.org/feed/",
url: "https://www.the74million.org/",
description:
"The 74 is a nonprofit news organization covering Americas education system from early childhood through college and career.",
},
{
title: "The Contrarian",
feedUrl: "https://themarkup.org/feeds/rss.xml",
url: "https://contrarian.substack.com/",
description:
'The Markup investigates how powerful institutions are using technology to change our society. (Thanks to <a href="https://werd.io/2024/non-profit-newsrooms-that-speak-to-power">werd.io</a> for the recommendation.)',
},
{
title: "The Markup",
feedUrl: "https://themarkup.org/feeds/rss.xml",
url: "https://themarkup.org",
description:
'The Markup investigates how powerful institutions are using technology to change our society. (Thanks to <a href="https://werd.io/2024/non-profit-newsrooms-that-speak-to-power">werd.io</a> for the recommendation.)',
},
],
},
{
name: "Personal Blogs",
blogs: [
{
title: "Andy Bell",
feedUrl: "https://andy-bell.co.uk/feed.xml",
url: "https://andy-bell.co.uk",
description:
"Designer, front-end developer and the founder of Set Studio and Piccalilli.",
},
{
title: "Bardo Burner",
feedUrl: "https://bardoburner.com/feed/",
url: "https://bardoburner.com",
description:
"Way back when blogs were called e-zines the mid-90s we made one called Bardo Burner… Sadly, our day-to-day lives got in the way of that labour of love and we jacked it in after a couple of years. Here we are again, reviving the old name just because, but this time primarily exploring issues related to healthy, sustainable living, which for us is strongly rooted in veganism… youll find articles here covering everything from cruelty-free cake and vegan restaurants to yoga and Pilates.",
},
{
title: "Darek Kay",
feedUrl: "https://darekkay.com/atom.xml",
url: "https://darekkay.com",
description:
"Front-end developer and an accessibility advocate, currently working at IBM.",
},
{
title: "Dom Corriveau",
feedUrl: "https://blog.ctms.me/index.xml",
url: "https://blog.ctms.me/",
description:
"Thoughts, opinions, wild speculation, and haphazard technical advice from Dom.",
},
{
title: "Ed Zitron's Where's Your Ed At",
feedUrl: "https://www.wheresyoured.at/rss/",
url: "https://www.wheresyoured.at/",
description: " The Words of Ed Zitron, a PR person and writer.",
},
{
title: "Ellie Kennard",
feedUrl: "https://www.elliekennard.ca/feed",
url: "https://www.elliekennard.ca",
description: "Photography and thoughts in story form.",
},
{
title: "Garbage Collector",
feedUrl: "https://blog.zedas.fr/index.xml",
url: "https://zedas.fr/",
description:
"The little space of a writer, tinkerer, and a coffee addict.",
},
{
title: "Later On",
feedUrl: "https://leisureguy.ca/rss",
url: "https://leisureguy.ca",
description:
"Writing on wet shaving, politics, whole food plant based diets, and more.",
},
{
title: "Luke Andrews",
feedUrl: "https://world.hey.com/lukeandrews/feed.atom",
url: "https://world.hey.com/lukeandrews",
description: "A sparse (abandoned?) blog from Luke Andrews.",
},
{
title: "MediaActivist",
feedUrl: "https://www.mediaactivist.com/rss/",
url: "https://www.mediaactivist.com/",
description:
"The website of Jay Baker (they/he), a long-time guerrilla journalist and documentarian.",
},
{
title: "Ploum.net",
feedUrl: "https://ploum.net/atom_en.xml",
url: "https://ploum.net/index_en.html",
description:
"Writing on tech and free / libre and open source philosophy.",
},
{
title: "Rosnovsky Park",
feedUrl: "https://rosnovsky.us/feed/feed.xml",
url: "https://rosnovsky.us/",
description:
"Writing on web development, hiking, and random hobbies from the venerable benefactor, founder, and admin of the lounge.town Mastodon instance.",
},
{
title: "Simone",
feedUrl: "https://simone.org/rss",
url: "https://simone.org/",
description:
"Explore modern life via thought-provoking essays, pictures, and conversations.",
},
{
title: "Steven Kennard : Turned Art, Sculpture and Photography",
feedUrl: "https://stevenkennard.com/blog/rss",
url: "https://stevenkennard.com/blog",
description:
"Steven Kennard is a woodturner, sculptor and photographer living and working in Nova Scotia, Canada.",
},
{
title: "Stories by Ellen Feinberg",
feedUrl: "https://ellensusie59.medium.com/feed",
url: "https://ellensusie59.medium.com",
description: "Uptown Chicago gal. Irreverent/Irrelevant/Sarcastic.",
},
{
title: "Thefoggiest.dev",
feedUrl: "https://thefoggiest.dev/feed",
url: "https://thefoggiest.dev",
description: "The personal blog of Diederick de Vries of Amsterdam.",
},
],
},
{
name: "Politics: U.S.A.",
blogs: [
{
title: "Liberation News",
feedUrl: "https://www.liberationnews.org/feed/",
url: "https://www.liberationnews.org/",
description: "Newspaper of the Party for Socialism and Liberation.",
},
{
title: "ProPublica",
feedUrl: "https://www.propublica.org/feeds/propublica/main/",
url: "https://www.propublica.org/",
description:
'ProPublica is an independent, nonprofit newsroom that produces investigative journalism with moral force. (Thanks to <a href="https://werd.io/2024/non-profit-newsrooms-that-speak-to-power">werd.io</a> for the recommendation.)',
},
{
title: "The Appeal",
feedUrl: "https://theappeal.org/theappeal",
url: "https://theappeal.org",
description:
"The Appeal is a nonprofit news organization that envisions a world in which systems of support and care, not punishment, create public safety. The Appeals journalism exposes the harms of a criminal legal system entrenched in centuries of systemic racism. We equip people with the information necessary to make change, and we elevate solutions that emerge from the communities most affected by policing, jails, and prisons in the U.S.",
},
{
title: "The 19th",
feedUrl: "https://19thnews.org/feed/",
url: "https://19thnews.org/",
description:
'An independent, nonprofit newsroom reporting on gender, politics and policy. (Thanks to <a href="https://werd.io/2024/non-profit-newsrooms-that-speak-to-power">werd.io</a> for the recommendation.)',
},
{
title: "The Marshall Project",
feedUrl: "https://www.themarshallproject.org/rss/recent.rss",
url: "https://www.themarshallproject.org/",
description:
'The Marshall Project seeks to create and sustain a sense of national urgency about the U.S. criminal justice system. (Thanks to <a href="https://werd.io/2024/non-profit-newsrooms-that-speak-to-power">werd.io</a> for the recommendation.)',
},
],
},
{
name: "Tech",
blogs: [
{
title: "9to5Linux",
feedUrl: "https://9to5linux.com/rss",
url: "https://9to5linux.com/",
description: "Linux news, reviews, tutorials, and more",
},
{
title: "Aftermath",
feedUrl: "https://aftermath.site/feed",
url: "https://aftermath.site/",
description:
"Aftermath is an independent, worker-owned website about video games and internet culture",
},
{
title: "It's FOSS",
feedUrl: "https://itsfoss.com/feed/",
url: "https://itsfoss.com/",
description: "Making You a Better Linux User.",
},
{
title: "LinuxInsider",
feedUrl: "https://www.linuxinsider.com?rss=1",
url: "https://www.linuxinsider.com",
description: "Linux News & Information From Around the World.",
},
{
title: "LOW←TECH MAGAZINE",
feedUrl: "https://solar.lowtechmagazine.com/posts/index.xml",
url: "https://solar.lowtechmagazine.com/posts/",
description:
"This is a solar-powered website, which means it sometimes goes offline.",
},
{
title: "Planet KDE",
feedUrl: "https://planet.kde.org/global/atom.xml",
url: "https://planet.kde.org/",
description:
"A feed aggregator that collects what the contributors to the KDE community are writing on their respective blogs.",
},
{
title: "Pluralistic",
feedUrl: "https://pluralistic.net/feed/",
url: "https://pluralistic.net/",
description: "Daily links from Cory Doctorow.",
},
{
title: "TorrentFreak",
feedUrl: "http://torrentfreak.com/feed",
url: "http://torrentfreak.com/",
description: "Breaking File-sharing, Copyright and Privacy News.",
},
{
title: "Werd I/O",
feedUrl: "https://werd.io/feed",
url: "https://werd.io",
description:
"Writing at the intersection of technology, democracy, and society by Ben Werdmuller.",
},
{
title: "We Distribute",
feedUrl: "https://wedistribute.org/rss",
url: "https://wedistribute.org",
description: "Connecting threads across the Web.",
},
],
},
{
name: "Veganism",
blogs: [
{
title: "Animal Justice",
feedUrl: "https://animaljustice.ca/category/blog/feed",
url: "https://animaljustice.ca/category/blog",
description:
"Read the latest news from the fight for stronger laws and better enforcement for animals in Canada.",
},
{
title: "Vegan Horizon",
feedUrl: "https://veganhorizon.substack.com/feed",
url: "https://veganhorizon.substack.com",
description:
"The vegan newsletter you've been waiting for! Brave, disruptive, to the point.",
},
],
},
{
name: "Web Development",
blogs: [
{
title: "CSS Tricks",
feedUrl: "https://css-tricks.com/feed",
url: "https://css-tricks.com",
description:
"Tips, Tricks, and Techniques on using Cascading Style Sheets.",
},
{
title: "Chris Coyier",
feedUrl: "https://chriscoyier.net/feed/",
url: "https://chriscoyier.net",
description: "Web craftsman, blogger, author, speaker.",
},
{
title: "Jim Nielsens Blog",
feedUrl: "https://blog.jim-nielsen.com/feed.xml",
url: "https://blog.jim-nielsen.com",
description:
"20+ years at the intersection of design & code on the web.",
},
{
title: "Own Your Web",
feedUrl: "https://buttondown.email/ownyourweb/rss",
url: "https://buttondown.com/ownyourweb",
description:
"A newsletter by Matthias Ott about designing, building, creating, and publishing for and on the Web.",
},
],
},
],
};

363
_data/galleries.js Normal file
View File

@ -0,0 +1,363 @@
export default [
{
title: "Pop Tart Flavor Memes",
description:
"One day, almost certainly when I ought to have been doing something more important, I discovered a meme format featuring Pop Tart boxes edited to have outlandish flavors on the packaging. Naturally, I had to collect as many as I could find. Here's what I've got:",
synopsis: "Some very unusual Pop Tart flavors…",
url: "/img/gallery/poptarts/",
date: new Date("November 26, 2024"),
galleryImage: "pop_tart_flavor_2.webp",
galleryImageAlt: "",
pictures: [
{
title: "Frosted New England Clam Chowder",
filename: "pop_tart_flavor_1.webp",
altText: "",
thumbAltText: "Frosted New England Clam Chowder",
caption: "",
},
{
title: "Frosted Tree Bark",
filename: "pop_tart_flavor_2.webp",
altText: "",
thumbAltText: "Frosted Tree Bark",
caption: "",
},
{
title: "Frosted Boot Leather",
filename: "pop_tart_flavor_3.webp",
altText: "",
thumbAltText: "Frosted Boot Leather",
caption: "I've dropped this bad boy on a twitter thread or two.",
},
{
title: "Frosted Kermit",
filename: "pop_tart_flavor_4.webp",
altText: "",
thumbAltText: "Frosted Kermit",
caption: "Is it worth it?",
},
{
title: "Frosted Bare Chest",
filename: "pop_tart_flavor_5.webp",
altText: "",
thumbAltText: "Frosted Bare Chest",
caption: "",
},
{
title: "Frosted Lysol Wipes",
filename: "pop_tart_flavor_6.webp",
altText: "",
thumbAltText: "Frosted Lysol Wipes",
caption: "",
},
{
title: "Mine Tarts",
filename: "pop_tart_flavor_7.webp",
altText: "Minecraft Frosted Grass Block",
thumbAltText: "Minecraft Frosted Grass Block",
caption: "",
},
{
title: "Frosted Earth Worms",
filename: "pop_tart_flavor_8.webp",
altText: "",
thumbAltText: "Frosted Earth Worms",
caption: "",
},
{
title: "Frosted Ground Beef",
filename: "pop_tart_flavor_9.webp",
altText: "",
thumbAltText: "Frosted Ground Beef",
caption: "",
},
{
title: "Frosted Black Coffee",
filename: "pop_tart_flavor_10.webp",
altText: "",
thumbAltText: "Frosted Black Coffee",
caption: "Unironically: I'd eat this.",
},
{
title: "Frosted Gasoline",
filename: "pop_tart_flavor_11.webp",
altText: "",
thumbAltText: "Frosted Gasoline",
caption: "",
},
{
title: "Frosted Tide Pods",
filename: "pop_tart_flavor_12.webp",
altText: "",
thumbAltText: "Frosted Tide Pods",
caption: `I once saw a lady drop a container of Tide Pods in the supermarket; without thinking I blurted out: "Oop, five second rule!" and didn't even get a laugh. Brutal.`,
},
{
title: "Frosted Hot Dog Water",
filename: "pop_tart_flavor_13.webp",
altText: "",
thumbAltText: "Frosted Hot Dog Water",
caption:
"Frankly, I'd sooner have the frosted lysol wipe Pop Tarts. 🤮",
},
{
title: "NY Style Sewer Rat",
filename: "pop_tart_flavor_14.webp",
altText: "",
thumbAltText: "NY Style Sewer Rat",
caption: "",
},
{
title: "Frosted Caviar",
filename: "pop_tart_flavor_15.webp",
altText: "",
thumbAltText: "Frosted Caviar",
caption: "",
},
{
title: "Frosted Elmer's Glue",
filename: "pop_tart_flavor_16.webp",
altText: "",
thumbAltText: "Frosted Elmer's Glue",
caption: "",
},
{
title: "Crusty!",
filename: "pop_tart_flavor_17.webp",
altText: "Crusty! Cement Flavor",
thumbAltText: "Crusty! Cement Flavor",
caption: "",
},
{
title: "Frosted Nuclear Waste",
filename: "pop_tart_flavor_18.webp",
altText: "Frosted Nuclear Waste: Made with real waste!",
thumbAltText: "Frosted Nuclear Waste: Made with real waste!",
caption: "",
},
{
title: "Frosted Beans",
filename: "pop_tart_flavor_19.webp",
altText: "",
thumbAltText: "Frosted Beans",
caption: "I'd give it a shot.",
},
{
title: "Shower Pack",
filename: "pop_tart_flavor_20.webp",
altText:
"Shower Pack, 3 in 1 formula! Shampoo, conditioner, and body wash.",
thumbAltText:
"Shower Pack, 3 in 1 formula! Shampoo, conditioner, and body wash.",
caption: "",
},
{
title: "Limited Edition",
filename: "pop_tart_flavor_21.webp",
altText: "Limited Edition: Just the Crust",
thumbAltText: "Limited Edition: Just the Crust",
caption: "",
},
{
title: "Frosted McDonald's Sprite",
filename: "pop_tart_flavor_22.webp",
altText: "Frosted",
thumbAltText: "Frosted",
caption: "",
},
{
title: "Frosted Fresh Cut Grass",
filename: "pop_tart_flavor_23.webp",
altText: "",
thumbAltText: "Frosted Fresh Cut Grass",
caption: "",
},
{
title: "Frosted Windex",
filename: "pop_tart_flavor_24.webp",
altText: "",
thumbAltText: "Frosted Windex",
caption: "",
},
{
title: "Frosted Popcorn Ceiling",
filename: "pop_tart_flavor_25.webp",
altText: "",
thumbAltText: "Frosted Popcorn Ceiling",
caption: "",
},
{
title: "Frosted Sharkboy & Lavagirl",
filename: "pop_tart_flavor_26.webp",
altText: "",
thumbAltText: "Frosted Sharkboy & Lavagirl",
caption: "",
},
{
title: "Frosted The Sun",
filename: "pop_tart_flavor_27.webp",
altText: "",
thumbAltText: "Frosted The Sun",
caption: "I don't know why, but I feel like these would be delicious.",
},
{
title: "Frosted Axe",
filename: "pop_tart_flavor_28.webp",
altText: "Frosted Axe body Spray",
thumbAltText: "Frosted Axe body Spray",
caption: "I would simply die.",
},
{
title: "Frosted Miracle Whip",
filename: "pop_tart_flavor_29.webp",
altText: "",
thumbAltText: "Frosted Miracle Whip",
caption: "",
},
{
title: "Frosted Water",
filename: "pop_tart_flavor_30.webp",
altText: "",
thumbAltText: "Frosted Water",
caption: "I'd give it a shot.",
},
{
title: "Encrusted",
filename: "pop_tart_flavor_31.webp",
altText: "Encrusted Play-Doh",
thumbAltText: "Encrusted Play-Doh",
caption: "They'd smell delicious at least.",
},
{
title: "Frosted Aluminum Foil",
filename: "pop_tart_flavor_32.webp",
altText: "",
thumbAltText: "Frosted Aluminum Foil",
caption: "",
},
{
title: "Frosted Orange Juice and Toothpaste",
filename: "pop_tart_flavor_33.webp",
altText: "",
thumbAltText: "Frosted Orange Juice and Toothpaste",
caption: "Honestly, this may be the worst of them all.",
},
],
},
{
title: "Shots from April 2024",
description:
"Sol and I went out for a walk down the street with a couple of cameras.",
synopsis:
"Sol and I went out for a walk down the street with a couple of cameras.",
url: "/img/gallery/april2024/",
date: new Date("January 23, 2025"),
galleryImage: "april_2024_4.webp",
galleryImageAlt: "",
pictures: [
{
title: "Sol shoots some flowers.",
filename: "april_2024_1.webp",
altText:
"A person in a beanie staring down a camera viewfinder at some tulips.",
thumbAltText:
"A person in a beanie staring down a camera viewfinder at some tulips.",
caption: "",
},
{
title: "We were being watched…",
filename: "april_2024_2.webp",
altText: "Some cats staring at us through a window screen.",
thumbAltText: "Some cats staring at us through a window screen.",
caption: "Somehow I don't mind these nosy neighbors.",
},
{
title: "A pole.",
filename: "april_2024_3.webp",
altText: "A closeup of a black painted pole with stickers on it.",
thumbAltText: "A closeup of a black painted pole with stickers on it.",
caption: "",
},
{
title: "Love this storefront.",
filename: "april_2024_4.webp",
altText:
"A storefront painted vividly with lots of colors, dots and flowers.",
thumbAltText:
"A storefront painted vividly with lots of colors, dots and flowers.",
caption: "",
},
{
title: "Another pole.",
filename: "april_2024_5.webp",
altText: "A wide, beige painted pole covered in ads and notices.",
thumbAltText: "A wide, beige painted pole covered in ads and notices.",
caption: "",
},
{
title: "Can't get enough of that pole.",
filename: "april_2024_6.webp",
altText:
"A mushroom-like green canopy on top of the beige pole, with lettering spelling out Roscoe Village.",
thumbAltText:
"A mushroom-like green canopy on top of the beige pole, with lettering spelling out Roscoe Village.",
caption: "",
},
{
title: "The infamous Chicago Rat Hole.",
filename: "april_2024_7.webp",
altText:
"An impression in the sidewalk of what is likely a squirrel; it is filled with coins and rocks left as tribute.",
thumbAltText:
"An impression in the sidewalk of what is likely a squirrel; it is filled with coins and rocks left as tribute.",
caption: "That has to be a squirrel.",
},
{
title: "A courtesy to cyclists.",
filename: "april_2024_8.webp",
altText:
"A crusty old parking meter with a ghost sticker and graffiti on it. Inside of the meter window reads: Meter remains as a courtesy to cyclists. Please pay at pay box.",
thumbAltText:
"A crusty old parking meter with a ghost sticker and graffiti on it. Inside of the meter window reads: Meter remains as a courtesy to cyclists. Please pay at pay box.",
caption: "",
},
{
title: "A brick building.",
filename: "april_2024_9.webp",
altText:
"The front of a red brick building with two potted plants in front of the door. The wall has many of those little square glass-tiles to allow in light while affording privacy.",
thumbAltText:
"The front of a red brick building with two potted plants in front of the door. The wall has many of those little square glass-tiles to allow in light while affording privacy.",
caption: "",
},
{
title: "Weed.",
filename: "april_2024_10.webp",
altText:
"A closeup of a dandelion ready to have its seeds blown into the wind.",
thumbAltText:
"A closeup of a dandelion ready to have its seeds blown into the wind.",
caption: "",
},
{
title: "Another creative storefront",
filename: "april_2024_11.webp",
altText:
"A storefront with painted illustrations of a woman giving a baby a bath, and several stylized women carrying baskets of fruit and flowers on their heads.",
thumbAltText:
"A storefront with painted illustrations of a woman giving a baby a bath, and several stylized women carrying baskets of fruit and flowers on their heads.",
caption: "",
},
{
title: "A robin crossing the street.",
filename: "april_2024_12.webp",
altText:
"A robin runs across the street, casting a long shadow for such a small fellow.",
thumbAltText:
"A robin runs across the street, casting a long shadow for such a small fellow.",
caption: "",
},
],
},
];

View File

@ -1,72 +1,160 @@
module.exports = { export default {
title: "Nathan Upchurch", title: "Nathan Upchurch",
logo: "/img/logo_favicon.svg", logo: "/img/logo.svg",
url: "https://nathanupchurch.com/", url: "https://nathanupchurch.com/",
language: "en", language: "en",
description: "The personal website and blog of Nathan Upchurch.", description:
"The personal website and blog of Nathan Upchurch, where I write about incense, free and open source software, design, vegan cooking, music, and all sorts of other topics that I find interesting.",
author: { author: {
givenName: "Nathan",
familyName: "Upchurch",
name: "Nathan Upchurch", name: "Nathan Upchurch",
email: "blog@upchur.ch", email: "blog@upchur.ch",
url: "https://nathanupchurch.com/me", url: "https://nathanupchurch.com/me",
profilePic: "/img/CN20191025_301_Srt_SQUARE.jpg" profilePic: "/img/CN20191025_301_Srt_SQUARE_crop.jpg",
}, },
defaultPostImageURL: "/img/vasilina-sirotina-1NMPvajSt9Q-unsplash_copy.avif", blogrollUrl: "/blogroll/nathanUpchurchBlogroll.opml",
defaultPostImageAlt: "The default post image: a close picture of the dark green leaves of a plant.", copyrightNotice: "© Nathan Upchurch 2022 - 2025",
defaultPostImageURL: "/img/logo_post.svg",
defaultPostImageAlt: "The logo for this blog: a capital letter N.",
mastodonHost: "lounge.town",
mastodonUser: "nathanu",
navigatorLinks: [
{
iconURL: "/img/icons/breeze/typewriter.svg",
linkDisplay: "Blog",
linkURL: "/blog/",
},
{
iconURL: "/img/icons/breeze/view-list-text.svg",
linkDisplay: "Blogroll",
linkURL: "/blogroll/",
},
{
iconURL: "/img/icons/breeze/view-preview.svg",
linkDisplay: "Galleries",
linkURL: "/galleries/",
},
{
iconURL: "/img/icons/breeze/story-editor.svg",
linkDisplay: "Guestbook",
linkURL: "/guestbook/",
},
{
iconURL: "/img/icons/breeze/news-subscribe.svg",
linkDisplay: "Life Updates",
linkURL: "/now/",
},
{
iconURL: "/img/burn.svg",
linkDisplay: "Now Burning",
linkURL: "/now-burning/",
},
{
iconURL: "/img/icons/breeze/document-edit-sign.svg",
linkDisplay: "Quizzes",
linkURL: "/quizzes/",
},
{
iconURL: "/img/icons/breeze/map-globe.svg",
linkDisplay: "Sitemap",
linkURL: "/sitemap/",
},
{
iconURL: "/img/icons/breeze/tag.svg",
linkDisplay: "Topics",
linkURL: "/tags/",
},
{
iconURL: "/img/icons/breeze/kstars_supernovae.svg",
linkDisplay: "Wishes",
linkURL: "/wish/",
},
],
postlistHeaderText: "Latest blog posts:",
socialLinks: [ socialLinks: [
{ {
title: "My Blog", title: "My Blog",
linkURL: "https://nathanupchurch.com", linkURL: "https://nathanupchurch.com",
linkDisplay: "My Blog", linkDisplay: "My Blog",
iconURL: "/img/logo_favicon_dark.svg" iconURL: "/img/logo.svg",
},
{
title: "Friendica",
linkURL: "https://friendica.world/profile/nathan",
customAttribute: `rel="me"`,
linkDisplay: "Friendica",
iconURL: "/img/friendica.svg",
}, },
{ {
title: "Mastodon", title: "Mastodon",
linkURL: "https://lounge.town/@nathanu", linkURL: "https://lounge.town/@nathanu",
customAttribute: `rel="me"`, customAttribute: `rel="me"`,
linkDisplay: "Mastodon", linkDisplay: "Mastodon",
iconURL: "/img/mastodon.svg" iconURL: "/img/mastodon.svg",
}, },
{ {
title: "Email Me", title: "Email Me",
linkURL: "Mailto:blog@upchur.ch", linkURL: "Mailto:blog@upchur.ch",
linkDisplay: "Email", linkDisplay: "Email",
iconURL: "/img/envelope.svg" iconURL: "/img/envelope.svg",
}, },
{ {
title: "Matrix", title: "Matrix",
linkURL: "https://matrix.to/#/@nathanu:matrix.org", linkURL: "https://matrix.to/#/@nathan:upchur.ch",
linkDisplay: "Matrix", linkDisplay: "Matrix",
iconURL: "/img/matrix-org.svg" iconURL: "/img/matrix-org.svg",
},
{
title: "Signal",
linkURL:
"https://signal.me/#eu/j-om4cfsGXtfKo0UX28EQfEL_Gd1KpJr8nQpI9Smhdsb-r98eT5F6obQ1BcYZCcW",
linkDisplay: "Signal",
iconURL: "/img/Signal-Logo-White.svg",
}, },
{ {
title: "BookWyrm", title: "BookWyrm",
linkURL: "https://ramblingreaders.org/user/NathanU", linkURL: "https://ramblingreaders.org/user/NathanU",
linkDisplay: "BookWyrm", linkDisplay: "BookWyrm",
iconURL: "/img/book.svg" iconURL: "/img/book.svg",
}, },
{ {
title: "Pixelfed", title: "Pixelfed",
linkURL: "https://pixelfed.social/@nathanu", linkURL: "https://pixelfed.social/@nathanu",
linkDisplay: "Pixelfed", linkDisplay: "Pixelfed",
iconURL: "/img/pixelfed.svg" iconURL: "/img/pixelfed.svg",
}, },
{ {
title: "Lemmy", title: "Lemmy",
linkURL: "https://lemmy.ml/u/NathanUp", linkURL: "https://lemmy.ml/u/NathanUp",
linkDisplay: "Lemmy", linkDisplay: "Lemmy",
iconURL: "/img/Lemmy_logo.svg" iconURL: "/img/Lemmy_logo.svg",
}, },
{ {
title: "PeerTube", title: "PeerTube",
linkURL: "https://dalek.zone/a/nathan_upchurch/", linkURL: "https://makertube.net/a/nathan/video-channels",
linkDisplay: "PeerTube", linkDisplay: "PeerTube",
iconURL: "/img/peertube.svg" iconURL: "/img/peertube.svg",
}, },
{ {
title: "Keyoxide Identity Profile", title: "Keyoxide Identity Profile",
linkURL: "https://keyoxide.org/31E809FAEA1532AC91BBDCF1EC499D3513F69340", linkURL: "https://keyoxide.org/31E809FAEA1532AC91BBDCF1EC499D3513F69340",
linkDisplay: "Keyoxide Identity Profile", linkDisplay: "Keyoxide Identity Profile",
iconURL: "/img/keyoxide.svg" iconURL: "/img/keyoxide.svg",
} },
] ],
} webrings: [
{
name: "Fediring",
ringURL: "https://fediring.net/",
previousURL: "https://fediring.net/previous?host=nathanupchurch.com",
nextURL: "https://fediring.net/next?host=nathanupchurch.com",
},
{
name: "Geekring",
ringURL: "https://geekring.net/",
previousURL: "http://geekring.net/site/350/previous",
nextURL: "http://geekring.net/site/350/next",
},
],
};

16
_includes/footer.njk Normal file
View File

@ -0,0 +1,16 @@
<footer>
<p>{% if metadata.copyrightNotice %}<span class="copyright-notice">{{ metadata.copyrightNotice }}</span>{% endif %}
{% if metadata.webrings %}<br>
{% for webring in metadata.webrings %}
<span class="webring">
{% if webring.previousURL %}<a href="{{ webring.previousURL }}">←</a>{% endif %}
{% if webring.ringURL %}<a href="{{ webring.ringURL }}">{{ webring.name }}</a>{% endif %}
{% if webring.nextURL %}<a href="{{ webring.nextURL }}">→</a>{% endif %}
</span>
{% endfor %}
{% endif %}
<a href="/sitemap/">Sitemap</a>
<a href="/special/flying-toasters" style="color: var(--background-color); text-decoration: none;">Fly</a>
</p>
</footer>

View File

@ -0,0 +1,29 @@
<section class="postlist">
<div class="postlist-item-container">
{% for gallery in galleries | reverse %}
{% if not numberOfGalleriesToShow or loop.index <= numberOfGalleriesToShow %}
<article class="postlist-item">
<a href="../gallery/{{ gallery.title | slugify }}" class="postlist-link">
<div class="post-image-container">
<img class="post-image" {% if gallery.galleryImage %} src="{{ gallery.url }}{{ gallery.galleryImage }}" alt="{{ gallery.galleryImageAlt }}" {% else %} src="{{ metadata.defaultPostImageURL }}" alt="{{ metadata.defaultPostImageAlt }}"{% endif %}>
</div>
</a>
<div class="post-copy">
<a href="../gallery/{{ gallery.title | slugify }}" class="postlist-link">
<h3>
{{ gallery.title }}
</h3>
</a>
{% if not hideGalleryDescriptions %}<p>{{ gallery.synopsis | truncate(105) | safe }}</p>{% endif %}
<div class="post-metadata">
<div class="post-metadata-copy">
<p>Posted on the&nbsp;<time class="postlist-date" datetime="{{ gallery.date | htmlDateString}}">{{ gallery.date | niceDate("LLLL yyyy") }}</time></p>
</div>
</div>
</div>
</article>
<hr>
{% endif %}
{% endfor %}
</div>
</section>

12
_includes/header.njk Normal file
View File

@ -0,0 +1,12 @@
<a href="#skip" class="visually-hidden">Skip to main content</a>
<header>
<a
href="/"
class="home-link">
<img
class="logo"
src="{{ metadata.logo }}"
alt="{{ metadata.title }}">
</a>
{% if not hideNav %}{% include "nav.njk" %}{% endif %}
</header>

29
_includes/incenseList.njk Normal file
View File

@ -0,0 +1,29 @@
<section class="postlist microblog-list">
{% if postlistHeaderText %}<h2>{{ postlistHeaderText }}</h2>{% endif %}
<div class="postlist-item-container">
{% for post in postslist | reverse %}
<article class="postlist-item">
<div class="post-copy">
<h3>
{% if post.data.title %}{{ post.data.title | safe }}{% else %}?{% endif %}{% if post.data.manufacturer %}, {{ post.data.manufacturer | safe }}{% endif %}
</h3>
<div class="post-metadata">
<div class="post-metadata-copy">
<p>
<time datetime="{{ post.date | htmlDateString }}">{{ post.date | niceDate }}{% if post.data.time %}—{{ post.data.time }}{% endif %}</time>
</p>
</div>
</div>
{% if post.content %}
<div class="microblog-comment">
{{ post.content | safe }}
</div>
{% endif %}
</div>
</article>
<hr>
{% endfor %}
</div>
</section>

View File

@ -0,0 +1,7 @@
---
layout: layouts/base.njk
---
<h1>403 Forbidden</h1>
<p class="nodropcap page-block">*Ahem* <a href="/">Go to the home page</a>.</p>
{{ content | safe }}

View File

@ -1,6 +1,5 @@
--- ---
layout: layouts/base.njk layout: layouts/base.njk
showPostListHeader: yep
--- ---
<h1>404</h1> <h1>404</h1>
<p class="nodropcap page-block">Sorry, it looks like that link is broken. <a href="/">Go to the home page</a>.</p> <p class="nodropcap page-block">Sorry, it looks like that link is broken. <a href="/">Go to the home page</a>.</p>

View File

@ -1,100 +1,20 @@
<!doctype html> <!doctype html>
<html lang="{{ metadata.language }}"> <html lang="{{ metadata.language }}">
<head> <head>
<meta charset="utf-8"> {% include "metadata.njk" %}
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" type="text/css" href="/css/index.css" />
<title>{{ title or metadata.title }}</title> <link rel="stylesheet" type="text/css" href="/css/webfonts/webfonts.css" />
<link rel="icon" type="image/x-icon" href="/img/logo_favicon.svg"> <link rel="stylesheet" type="text/css" href="/css/code.css" />
<meta name="description" content="{{ description or metadata.description }}"> {% include "structuredData.njk" %}
<link rel="alternate" href="/feed/feed.xml" type="application/atom+xml" title="{{ metadata.title }}">
<link rel="alternate" href="/feed/feed.json" type="application/json" title="{{ metadata.title }}">
<meta name="generator" content="{{ eleventy.generator }}">
{#- Bundle CSS #}
{%- css %}{% include "public/css/index.css" %}{% endcss %}
{%- css %}{% include "public/css/webfonts/webfonts.css" %}{% endcss %}
{%- css %}{% include "public/css/dropcap.css" %}{% endcss %}
<style>{% getBundle "css" %}</style>
{% if title %}
<!-- Structured Data -->
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Article",
"headline": "{{ title }}",
"author": {
"@type": "Person",
"name": "{{ metadata.author.name }}"
},
"datePublished": "{{ date }}",
"description": "{% if synopsis %}{{ synopsis}}{% endif %}",
"image": "{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}",
"url": "{{ page.url | htmlBaseUrl(metadata.url) }}",
"articleBody": "{{ content | striptags }}"
}
</script>
<!-- Open Graph -->
<meta property="og:type" content="article" />
<meta property="og:title" content="{{ title }}" />
<meta property="og:description" content="{{ synopsis}}" />
<meta property="og:url" content="{{ page.url | htmlBaseUrl(metadata.url) }}" />
<meta property="og:image" content="{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}" />
<!-- Twitter card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{{ title }}" />
<meta name="twitter:description" content="{{ synopsis}}" />
<meta name="twitter:image" content="{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}" />
{% endif %}
{% include "umami.html" %} {% include "umami.html" %}
</head> </head>
<body> <body>
<a href="#skip" class="visually-hidden">Skip to main content</a> {% include "header.njk" %}
<header>
<a href="/" class="home-link"><img src="{{ metadata.logo }}" alt="{{ metadata.title }}"></a>
<nav>
<h2 class="visually-hidden">Top level navigation menu</h2>
<ul class="nav">
{%- for entry in collections.all | eleventyNavigation %}
<a class="nav-item" href="{{ entry.url }}"{% if entry.url == page.url %} aria-current="page"{% endif %}><li {% if entry.url == page.url %} data-currentpage="true"{% endif %}>{{ entry.title }}</li></a>
{%- endfor %}
<a class="nav-item" href="/feed/feed.xml">
<li subscribe">
<!-- RSS Logo -->
<svg class="nav-icon" viewBox="0 0 155 155" width="153.349" height="152.909" version="1.0" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(-427.323 -373.814)">
<ellipse
style="opacity:1;fill-opacity:1;fill-rule:nonzero;"
transform="matrix(.86996 0 0 .86996 135.156 330.529)"
cx="360.357" cy="200.643" rx="24.643" ry="23.929"
/>
<path
style="fill-opacity:1;fill-rule:evenodd;"
d="m427.835 455.057-.073-30.273c64.706 3.375 100.619 49.673 101.5 101.94h-30.318c-.503-45.942-31.74-69.996-71.11-71.667z"
/>
<path
style="fill-opacity:1;fill-rule:evenodd;"
d="m428.201 404.571-.878-30.757C526.75 378.43 580 450.582 580.67 526.724l-31.197-.44c1.365-48.704-34.665-120.267-121.273-121.713Z"
/>
</g>
</svg>Subscribe
</li>
</a>
</ul>
</nav>
</header>
<main id="skip"> <main id="skip">
<section>
{{ content | safe }} {{ content | safe }}
</section>
</main> </main>
{% include "footer.njk" %}
<footer></footer>
<!-- Current page: {{ page.url | htmlBaseUrl }} -->
</body> </body>
</html> </html>

View File

@ -1,35 +0,0 @@
<!doctype html>
<html lang="{{ metadata.language }}" class="barebones">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title or metadata.title }}</title>
<link rel="icon" type="image/x-icon" href="/img/logo_favicon.svg">
<meta name="description" content="{{ description or metadata.description }}">
<meta name="generator" content="{{ eleventy.generator }}">
{#- Bundle CSS #}
{%- css %}{% include "public/css/index.css" %}{% endcss %}
{%- css %}{% include "public/css/webfonts/webfonts.css" %}{% endcss %}
{%- css %}{% include "public/css/dropcap.css" %}{% endcss %}
<style>{% getBundle "css" %}</style>
{% include "umami.html" %}
</head>
<body class="barebones">
<a href="#skip" class="visually-hidden">Skip to main content</a>
<header>
<a href="/" class="home-link"><img src="{{ metadata.logo }}" alt="{{ metadata.title }}"></a>
</header>
<main id="skip">
{{ content | safe }}
</main>
<footer></footer>
<!-- Current page: {{ page.url | htmlBaseUrl }} -->
</body>
</html>

View File

@ -2,7 +2,7 @@
layout: layouts/base.njk layout: layouts/base.njk
showPostListHeader: yep showPostListHeader: yep
--- ---
<h1>The personal website and blog of Nathan Upchurch.</h1> <h1>I'm Nathan; welcome&nbsp;friend.</h1>
<p class="nodropcap page-block">Welcome to my personal website and blog, where I write about tech, free and open source software, design, vegan cooking, incense, music, and all sorts of <a href="/tags">other topics</a> that I find interesting.</p> <p class="nodropcap page-block">My name is Nathan Upchurch, and this is my personal website and blog, where I write about all sorts of <a href="/tags">things</a> that I find interesting. On this website, you can learn more <a href="about">about me</a>, sign my <a href="guestbook">guestbook</a>, see <a href="now">what Ive been up to lately</a>, <a href="blog">read my blog</a>, look at some <a href="galleries">pictures</a>, or explore the <a href="sitemap">sitemap</a> to see what else you can do here.</p>
{{ content | safe }} {{ content | safe }}

View File

@ -1,13 +1,15 @@
--- ---
layout: layouts/baseBareBones.njk layout: layouts/linksPage.njk
--- ---
{%- css %}{% include "public/css/links.css" %}{% endcss %} <div class="links-container">
<img class="profilePic" src="{{ metadata.author.profilePic }}"> <img class="profilePic" src="{{ metadata.author.profilePic }}">
<h1 class="socialTitle">Nathan Upchurch</h1> <h1 class="socialTitle">Nathan Upchurch</h1>
<p class="page-block nodropcap">Here's where you can find me on the internet:</p> <p class="page-block nodropcap">Here's where you can find me on the internet:</p>
<div class="socialLinks">
<ul class="socialLinks">
{% for link in metadata.socialLinks %} {% for link in metadata.socialLinks %}
<a {% if link.customAttribute %} {{ link.customAttribute | safe }} {% endif %} href="{{ link.linkURL }}"><li><img src="{{ link.iconURL }}" />{{ link.linkDisplay }}</li></a> <a class="link-button" {% if link.customAttribute %} {{ link.customAttribute | safe }} {% endif %} href="{{ link.linkURL }}">
<button type="button"><img src="{{ link.iconURL }}" />{{ link.linkDisplay }}</button>
</a>
{% endfor %} {% endfor %}
</ul> </div>
</div>

View File

@ -0,0 +1,17 @@
<!doctype html>
<html lang="{{ metadata.language }}" class="barebones">
<head>
{% include "metadata.njk" %}
<link rel="stylesheet" type="text/css" href="/css/me.css" />
<link rel="stylesheet" type="text/css" href="/css/index.css" />
<link rel="stylesheet" type="text/css" href="/css/webfonts/webfonts.css" />
{% include "umami.html" %}
</head>
<body class="barebones">
{% include "header.njk" %}
<main id="skip">
{{ content | safe }}
</main>
</body>
</html>

View File

@ -1,28 +1,44 @@
--- ---
layout: layouts/base.njk layout: layouts/base.njk
--- ---
{# Only include the syntax highlighter CSS on blog posts #} <article class="post">
{%- css %}{% include "public/css/code.css" %}{% endcss %} <h1>{{ title | safe }}</h1>
<h1>{{ title }}</h1> {% if not hideMetadata %}
<div class="post-metadata">
{% if author %}
{% if author.profilePic %}
<img class="profilePic" src="{{ author.profilePic }}">
{% endif %}
<div class="post-metadata-copy">
<p>{% if author.url %}<a href="{{ author.url }}">{% endif %}
{% if author.name %}By {{ author.name }}{% endif %}{% if author.url %}</a>&nbsp;•&nbsp;{% endif %}<time datetime="{{ page.date | htmlDateString }}">{{ page.date | niceDate }}</time></p>
<ul class="post-metadata"> {% else %}
<li><time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time></li> {% if metadata.author.profilePic %}
<img class="profilePic" src="{{ metadata.author.profilePic }}">
{% endif %}
<div class="post-metadata-copy">
<p>{% if metadata.author.url %}<a href="{{ metadata.author.url }}">{% endif %}
{% if metadata.author.name %}By {{ metadata.author.name }}{% endif %}{% if metadata.author.url %}</a>&nbsp;•&nbsp;{% endif %}<time datetime="{{ page.date | htmlDateString }}">{{ page.date | niceDate }}</time></p>
{% endif %}
<ul>
{%- for tag in tags | filterTagList %} {%- for tag in tags | filterTagList %}
{%- set tagUrl %}/tags/{{ tag | slugify }}/{% endset %} {%- set tagUrl %}/tags/{{ tag | slugify }}/{% endset %}
<li><a href="{{ tagUrl }}" class="post-tag">{{ tag }}</a></li> <li>
<a
href="{{ tagUrl }}"
class="post-tag">
{{ tag }}&nbsp;
</a>
</li>
{%- endfor %} {%- endfor %}
</ul> </ul>
</div>
</div>
{% endif %}
{{ content | safe }} {{ content | safe }}
</article>
{%- if collections.posts %} {% include "mastodonComments.njk" %}
{%- set previousPost = collections.posts | getPreviousCollectionItem %}
{%- set nextPost = collections.posts | getNextCollectionItem %}
{%- if nextPost or previousPost %}
<ul class="links-nextprev">
{%- if previousPost %}<li>Previous: <a href="{{ previousPost.url }}">{{ previousPost.data.title }}</a></li>{% endif %}
{%- if nextPost %}<li>Next: <a href="{{ nextPost.url }}">{{ nextPost.data.title }}</a></li>{% endif %}
</ul>
<p>Questions? Comments? <a href="../../me">contact me</a>.</p>
{%- endif %}
{%- endif %}

View File

@ -0,0 +1,53 @@
---
layout: layouts/post.njk
structuredData: none
---
{{ content | safe }}
<section class="quiz">
<form onsubmit="handleQuizSubmit(); return false">
{% for question in questions %}
{% set q = loop.index %}
<div class="questionBox">
<p class="quizQuestion">{{ q }}. {{ question.title }}</p>
{% if question.image %}
<figure>
<a href="{{ question.image }}">
<img src="{{ question.image }}" alt="{{ question.imageAlt }}">
</a>
{% if question.imageCaption %}
<figcaption>{{ question.imageCaption }}</figcaption>
{% endif %}
</figure>
{% endif %}
<div class="answersBox">
{% for answer in question.answers %}
<div class="answerBox">
<input class="answer" type="radio" value="{{ answer.points }}" id="q{{ q }}a{{ loop.index }}" name="{{ q }}" required>
<label for="q{{ q }}a{{ loop.index }}">{{ answer.name }}</label>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
<script src="/js/quiz.js"></script>
<button>Submit</button>
</form>
</section>
{% for consequence in consequences %}
<dialog class="consequence" data-points-threshold="{{ consequence.points }}">
<h2>{{ consequence.title }}</h2>
<p>{{ consequence.spiel }}</p>
{% if consequence.image %}
<img src="{{ consequence.image }}" alt="{{ consequence.imageAlt }}">
{% endif %}
<details>
<summary>Score Details</summary>
<p class="scoreDetails"></p>
</details>
<form method="dialog">
<button>Thanks</button>
</form>
</dialog>
{% endfor %}

View File

@ -0,0 +1,12 @@
{% if mastodon_id %}
<section class="" id="comment-section">
<div class="continue-discussion">
<a class="link-button" href="https://{{ metadata.mastodonHost }}/@{{ metadata.mastodonUser }}/{{ mastodon_id }}">
<button type="button">
<img src="/img/mastodon.svg">
Discuss on Mastodon &#187;
</button>
</a>
</div>
</section>
{% endif %}

11
_includes/metadata.njk Normal file
View File

@ -0,0 +1,11 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title or metadata.title }}</title>
<link rel="icon" type="image/x-icon" href="/img/logo_favicon.svg">
<link rel="blogroll" type="text/xml" href="{{ metadata.blogrollUrl }}">
<meta name="description" content="{{ description or metadata.description }}">
<meta name="robots" content="noai, noimageai">
<meta name="generator" content="{{ eleventy.generator }}">
<link rel="alternate" href="/feed/feed.xml" type="application/atom+xml" title="{{ metadata.title }}">
<link rel="alternate" href="/feed/feed.json" type="application/json" title="{{ metadata.title }}">
<script type="module" src="/js/main.js"></script>

10
_includes/nav.njk Normal file
View File

@ -0,0 +1,10 @@
<nav>
<h2 class="visually-hidden">Top level navigation menu</h2>
<ul class="nav">
{%- for entry in collections.all | eleventyNavigation %}
<li class="nav-item" {% if entry.url == page.url %} aria-current="page" data-currentpage="true"{% endif %}><a href="{{ entry.url }}">{{ entry.title }}</a></li>
{%- endfor %}
<li class="subscribe nav-item"><a href="/feed/feed.xml">{% include "rssLogo.njk" %}Feed</a>
</li>
</ul>
</nav>

10
_includes/navigator.njk Normal file
View File

@ -0,0 +1,10 @@
<section class="navigator">
{% for link in metadata.navigatorLinks %}
<div class="navigatorItem">
<a href="{{ link.linkURL }}">
<img alt="" src="{{ link.iconURL }}">
<p>{{ link.linkDisplay }}</p>
</a>
</div>
{% endfor %}
</section>

62
_includes/nextLast.njk Normal file
View File

@ -0,0 +1,62 @@
{% if collections.posts %}
{% set previousPost = collections.posts | getPreviousCollectionItem %}
{% set nextPost = collections.posts | getNextCollectionItem %}
{% if nextPost or previousPost %}
<section class="links-nextprev">
<h2>Read Next</h2>
<div class="postlist-item-container">
{% if previousPost %}
<article class="postlist-item{% if post.url == url %} postlist-item-active{% endif %}">
<a href="{{ previousPost.url }}" class="postlist-link">
<div class="post-image-container">
<img class="post-image" {% if previousPost.data.imageURL %} src="{{ previousPost.data.imageURL }}" alt="{{ previousPost.data.imageAlt }}" {% else %} src="{{ metadata.defaultPostImageURL }}" alt="{{ metadata.defaultPostImageAlt }}"{% endif %}>
</div>
</a>
<div class="post-copy">
<a href="{{ previousPost.url }}" class="postlist-link">
<p>Previous Article:</p>
<h3>
{% if previousPost.data.title %}{{ previousPost.data.title }}{% else %}<code>{{ previousPost.url }}</code>{% endif %}
</h3>
</a>
<time class="postlist-date" datetime="{{ previousPost.date | htmlDateString }}">{{ previousPost.date | readableDate("LLLL yyyy") }}</time>
{% if previousPost.data.synopsis %}
<p>{{ previousPost.data.synopsis | truncate(105) | safe }}</p>
{% else %}
<p>{{ previousPost.content | truncate(105) | safe }}</p>
{% endif %}
</div>
</article>
{% if not nextPost %}
</div>
</section>
{% endif %}
{% endif %}
{% if nextPost %}
<article class="postlist-item{% if post.url == url %} postlist-item-active{% endif %}">
<a href="{{ nextPost.url }}" class="postlist-link">
<div class="post-image-container">
<img class="post-image" {% if nextPost.data.imageURL %} src="{{ nextPost.data.imageURL }}" alt="{{ nextPost.data.imageAlt }}" {% else %} src="{{ metadata.defaultPostImageURL }}" alt="{{ metadata.defaultPostImageAlt }}"{% endif %}>
</div>
</a>
<div class="post-copy">
<a href="{{ nextPost.url }}" class="postlist-link">
<p>Next Article:</p>
<h3>
{% if nextPost.data.title %}{{ nextPost.data.title }}{% else %}<code>{{ nextPost.url }}</code>{% endif %}
</h3>
</a>
<time class="postlist-date" datetime="{{ nextPost.date | htmlDateString }}">{{ nextPost.date | readableDate("LLLL yyyy") }}</time>
{% if nextPost.data.synopsis %}
<p>{{ nextPost.data.synopsis | truncate(105) | safe }}</p>
{% else %}
<p>{{ nextPost.content | truncate(105) | safe }}</p>
{% endif %}
</div>
</article>
</div>
</section>
{% endif %}
{% endif %}
{% endif %}

View File

@ -1,23 +1,63 @@
<section class="postlist"> <section class="postlist{% if postListTypeMicroblog %} microblogList{% endif %}">
{% if showPostListHeader %}<h2>Latest Posts</h2>{% endif %} {% if postlistHeaderText %}<h2>{{ postlistHeaderText }}</h2>{% endif %}
<div class="postlist-item-container"> <div class="postlist-item-container">
{% for post in postslist | reverse %} {% for post in postslist | reverse %}
<article class="postlist-item{% if post.url == url %} postlist-item-active{% endif %}"> <article class="postlist-item{% if post.url == url %} postlist-item-active{% endif %}">
{% if not postListTypeMicroblog %}
<a href="{{ post.url }}" class="postlist-link"> <a href="{{ post.url }}" class="postlist-link">
<div class="post-image-container"> <div class="post-image-container">
<img class="post-image" {% if post.data.imageURL %} src="{{ post.data.imageURL }}" alt="{{ post.data.imageAlt }}" {% else %} src="{{ metadata.defaultPostImageURL }}" alt="{{ metadata.defaultPostImageAlt }}"{% endif %}> <img class="post-image" {% if post.data.imageURL %} src="{{ post.data.imageURL }}" alt="{{ post.data.imageAlt }}" {% else %} src="{{ metadata.defaultPostImageURL }}" alt="{{ metadata.defaultPostImageAlt }}"{% endif %}>
</div> </div>
</a> </a>
{% endif %}
<div class="post-copy"> <div class="post-copy">
{% if not postListTypeMicroblog %}
<a href="{{ post.url }}" class="postlist-link"> <a href="{{ post.url }}" class="postlist-link">
{% endif %}
<h3> <h3>
{% if post.data.title %}{{ post.data.title }}{% else %}<code>{{ post.url }}</code>{% endif %} {% if post.data.title %}{{ post.data.title | safe }}{% else %}?{% endif %}
</h3> </h3>
{% if not postListTypeMicroblog %}
</a> </a>
<time class="postlist-date" datetime="{{ post.date | htmlDateString }}">{{ post.date | readableDate("LLLL yyyy") }}</time> {% endif %}
{% if post.data.synopsis %}<p>{{ post.data.synopsis | truncate(110) | safe }}</p>{% else %}{{ post.content | truncate(140) | safe }}{% endif %}
<div class="post-metadata">
<div class="post-metadata-copy">
<p>
{% if not postListTypeMicroblog %}
{% if post.data.author %}
{% if post.data.author.url %}
<a href="{{ post.data.author.url }}">
{% endif %}
{% if post.data.author.name %}
By {{ post.data.author.name }}
{% endif %}
{% if post.data.author.url %}</a>&nbsp;•&nbsp;
{% endif %}
{% else %}<a href="{{ metadata.author.url }}">By {{ metadata.author.name }}</a>&nbsp;•&nbsp;
{% endif %}
{% endif %}
<time datetime="{{ post.date | htmlDateString }}">{{ post.date | niceDate }}{% if post.data.time %}—{{ post.data.time }}{% endif %}</time>
</p>
<ul>
{%- for tag in post.data.tags | filterTagList %}
{%- set tagUrl %}/tags/{{ tag | slugify }}/{% endset %}
<li>
<a
href="{{ tagUrl }}"
class="post-tag">
{{ tag }}&nbsp;
</a>
</li>
{%- endfor %}
</ul>
</div>
</div>
</div> </div>
</article> </article>
<hr>
{% endfor %} {% endfor %}
</div> </div>
</section> </section>

19
_includes/rssLogo.njk Normal file
View File

@ -0,0 +1,19 @@
<!-- RSS Logo -->
<svg class="nav-icon" viewBox="0 0 155 155" width="153.349" height="152.909" version="1.0" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(-427.323 -373.814)">
<ellipse
style="opacity:1;fill-opacity:1;fill-rule:nonzero;"
transform="matrix(.86996 0 0 .86996 135.156 330.529)"
cx="360.357" cy="200.643" rx="24.643" ry="23.929"
/>
<path
style="fill-opacity:1;fill-rule:evenodd;"
d="m427.835 455.057-.073-30.273c64.706 3.375 100.619 49.673 101.5 101.94h-30.318c-.503-45.942-31.74-69.996-71.11-71.667z"
/>
<path
style="fill-opacity:1;fill-rule:evenodd;"
d="m428.201 404.571-.878-30.757C526.75 378.43 580 450.582 580.67 526.724l-31.197-.44c1.365-48.704-34.665-120.267-121.273-121.713Z"
/>
</g>
</svg>
<!-- /RSS Logo -->

After

Width:  |  Height:  |  Size: 779 B

View File

@ -0,0 +1,36 @@
{% if title and structuredData != "none" %}
<!-- Structured Data -->
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "BlogPosting",
"articleBody": "{{ content | striptags }}"
"author": {
"@type": "Person",
"familyName": "{{ metadata.author.familyName }}",
"givenName": "{{ metadata.author.givenName }}",
"image": "{{ metadata.url }}{{ metadata.author.profilePic }}",
"name": "{{ metadata.author.name }}",
"url": "{{ metadata.author.url }}"
},
"datePublished": "{{ date }}",
"description": "{% if synopsis %}{{ synopsis}}{% endif %}",
"headline": "{{ title }}",
"image": "{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}",
"inLanguage": "{{ metadata.language }}",
"name": "{{ title }}",
"url": "{{ page.url | htmlBaseUrl(metadata.url) }}",
}
</script>
<!-- Open Graph -->
<meta property="og:type" content="article" />
<meta property="og:title" content="{{ title }}" />
<meta property="og:description" content="{{ synopsis}}" />
<meta property="og:url" content="{{ page.url | htmlBaseUrl(metadata.url) }}" />
<meta property="og:image" content="{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}" />
<!-- Twitter card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{{ title }}" />
<meta name="twitter:description" content="{{ synopsis}}" />
<meta name="twitter:image" content="{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}" />
{% endif %}

View File

@ -1,5 +0,0 @@
---
layout: layouts/404.njk
permalink: 404.html
eleventyExcludeFromCollections: true
---

View File

@ -1,19 +0,0 @@
---
layout: layouts/home.njk
permalink: 404.html
eleventyExcludeFromCollections: true
---
# Content not found.
Go <a href="/">home</a>.
<!--
Read more: https://www.11ty.dev/docs/quicktips/not-found/
This will work for both GitHub pages and Netlify:
* https://help.github.com/articles/creating-a-custom-404-page-for-your-github-pages-site/
* https://www.netlify.com/docs/redirects/#custom-404
-->

71
content/about-feeds.md Normal file
View File

@ -0,0 +1,71 @@
---
layout: layouts/post.njk
title: Nathan Upchurch | About Feeds
structuredData: none
hideMetadata: yep
---
# How to use feeds.
<p><!-- a <p> just to stop the dropcap from happening --></p>
Get all the latest content from your favorite creators with no algorithm, no spam, and no spying. This page is based on [Matt Webb](https://interconnected.org)'s *[About Feeds](https://aboutfeeds.com/)*.
[![A screenshot of the akregator newsreader showing lists of feed categories in a left sidebar, an inbox full of posts from feeds, and a post display window - much like a desktop email client.](../img/akregator.png "Akregator, the newsreader I use on my desktop, showing a list of posts from feeds I've subscribed to.")](../img/akregator.png)
## What is a feed?
* A "web feed," or an "RSS feed," is a stream of all latest content from a blog or a website. You can subscribe to these feeds using a newsreader app.
* Many websites such as news sites and blogs already have feeds. You'll often see a link at the top or bottom of the page that says "RSS," "Feed," or an icon like this: <img src="../img/RSS-Orange.svg" style="height: .75rem;">.
* Whenever you see a website with a feed, that means you can subscribe to that site.
## Why use feeds?
* Subscribing to feeds is a quick way to access news and content from many different sources in one place: your newsreader.
* With feeds, there's no spam, no social media drama, and no algorithm choosing what you see — just a curated collection of all the content you want to see, for free.
## How do I get a newsreader app?
**To subscribe to feeds, you'll need a newsreader app.** Once you've subscribed to a feed, your newsreader will check it regularly and show you the latest in an inbox, a bit like email.
There are many different newsreader apps to choose from. Below are a few you could try; find more by searching "RSS Feed Reader" on the internet, or in the app store on your device.[^1]
* Feeder (Android — [Google Play](https://play.google.com/store/apps/details?id=com.nononsenseapps.feeder.play), [F-Droid](https://f-droid.org/packages/com.nononsenseapps.feeder/))
* [Fluent Reader (Windows, macOS)](https://hyliu.me/fluent-reader/)
* [Raven (GNU/Linux, Windows, macOS)](https://ravenreader.app/)
* [NetNewsWire (macOS, iOS)](https://ravenreader.app/)
* [FreshRSS (Online)](https://www.freshrss.org/)
* [Akregator (GNU/Linux)](https://apps.kde.org/akregator/)
* [RSSOwl (GNU/Linux, Windows, macOS)](https://www.rssowl.org/)
* [RSS Guard (GNU/Linux, Windows, macOS, BSD, OS/2)](https://github.com/martinrotter/rssguard)
It doesn't matter which you choose; newsreaders usually make it fairly easy to export your list of subscriptions and move them to another app in the future.
## How do I use my new newsreader app to subscribe to a feed?
[![A screenshot of the akregator newsreader with an "add feed dialog" visible.](../img/akregator_add_feed.png "Adding a feed to my newsreader.")](../img/akregator_add_feed.png)
1. Get the Feed URL. To get this, go to the website you want to subscribe to and find that RSS link or the feed icon. Then...
* On **desktop**, right click on the link and choose "Copy Link Address" or similar.
* On **mobile**, tap and hold the link until a menu comes up. Choose "Copy Link" or similar.
2. Add the URL to your newsreader; go to your newsreader app and look for something like "Subscribe," "Add Web Feed," or maybe you'll just see a "+" icon. Once you've found this, paste in the feed URL and you're done!
## What next?
* Find more to read: Browse [Blogroll](https://blogroll.org) and [ooh.directory](https://ooh.directory), both hand-curated directories of blogs, organised by topic.
* Why not start a blog of your own? [Get Blogging!](https://getblogging.org) is a guide to the practicalities of starting a blog.
[^1]: Please note that I haven't tested all of these options personally; your mileage may vary.

View File

@ -0,0 +1,18 @@
---
layout: layouts/base.njk
title: Nathan Upchurch | Colophon
structuredData: none
---
# Colophon
## What I used to build this website
I built this website in plain-old HTML, CSS, and a touch of vanilla JavaScript using [Zach Leatherman](https://www.zachleat.com/)'s [11ty static site generator](https://www.11ty.dev/) and Mozilla's [Nunjucks templating language](https://mozilla.github.io/nunjucks/). I used free and open source variable typefaces [Fraunces](https://fraunces.undercase.xyz/), designed by Phaedra Charles and Flavia Zimbardi[^1], and [Manrope](https://www.gent.media/manrope), designed by Mikhail Sharanda[^2].
The handy calculators on [utopia.fyi](https://utopia.fyi), created by James Gilyead and Trys Mudford, helped me implement fluid typography and spacing, which has allowed me to make this website responsive without using a single media query. The future is upon us.
Icons on the index page navigator section are from the [Breeze icon set](https://develop.kde.org/frameworks/breeze-icons/) made by the fine folks at [KDE](https://kde.org/).
If you'd like to inspect the source for this site, you can [find the repo here](https://upchur.ch/gitea/n_u/nathanupchurch.com).
[^1]: With contributions by Ethan Cohen, and Andy Clymer.
[^2]: With contributions by Mirko Velimirovic.

View File

@ -1,8 +1,25 @@
--- ---
layout: layouts/base.njk layout: layouts/base.njk
title: Nathan Upchurch | About
eleventyNavigation: eleventyNavigation:
key: About key: About
order: 3 order: 2
--- ---
# About the author, Nathan Upchurch. <article>
<p class="page-block nodropcap">I'm a prolific vegan home cook, classical trombonist, a <abbr title="Free/Libre Open Source Software">FLOSS</abbr> enthusiast, daily GNU/Linux user and unabashed <a href="https://kde.org/">KDE</a> stan, speaker of subpar elementary Spanish, incense enthusiast, writer, electronics hobbyist, designer, programmer, music producer, print lover, and human with too many interests and too little time. This is my personal website and blog. <br><br>Because this is my <em>personal</em> website, I'm not here to talk about work, but I will link my professional bio here when I've gotten around to making it. If you would like to say something nice, you can find me on <a href="https://mastodon.social/@nathanu">Mastodon</a>.<br><br>This website is made with <a href="https://www.11ty.dev/">11ty</a>, <a href="https://www.gent.media/manrope">Manrope</a>, <a href="https://github.com/clauseggers/Playfair">Playfair Display</a>, and plain-old HTML & CSS. I don't collect any of your data, full-stop. All webfonts, icons, and images are hosted locally (Instead of by Google, for instance, or any other company which might<a href="https://www.firstpost.com/world/how-google-uses-fonts-to-track-what-users-do-online-and-sell-data-to-advertisers-12496552.html"> use them to track you</a>).<br><hr>Find more blogs at <a href="https://blogroll.org">blogroll.org</a>, or <a href="https://ooh.directory/">ooh.directory</a>. | <a href="https://keyoxide.org/31E809FAEA1532AC91BBDCF1EC499D3513F69340">Keyoxide profile</a></p> <h1>About me and my&nbsp;website.</h1>
<p class="page-block nodropcap">Im a prolific vegan home cook, classical trombonist, incense maker, a <abbr title="Free/Libre Open Source Software">FLOSS</abbr> enthusiast, designer, programmer, music producer, print lover, and human with too many interests and too little time.<br><br>
This is my little corner of the internet where I talk about whatever I like without worrying about maintaining a personal brand, or constraining my writing to topics which might help advance my career or establish me as a thought leader. Im here to express myself and have fun writing about topics I enjoy.<br><br>
If youd like to learn more about my professional accomplishments and work, Ill link my professional website here when I get around to it.</p>
<a href="./colophon/">
<button type="button">Colophon »</button>
</a>
<a href="../me/">
<button type="button">Contact »</button>
</a>
<a href="./privacy/">
<button type="button">Privacy »</button>
</a>
</article>

View File

@ -0,0 +1,10 @@
---
layout: layouts/base.njk
title: Nathan Upchurch | Privacy
structuredData: none
---
# Privacy Statement
## Data collection and use
I dont collect any of your personal information, full-stop. All webfonts, icons, and images are hosted locally (these things can sometimes be used to [track people across the internet](https://www.firstpost.com/world/how-google-uses-fonts-to-track-what-users-do-online-and-sell-data-to-advertisers-12496552.html) otherwise). I use [umami](https://umami.is), an open source, privacy-respecting analytics tool, to see [how many people visit this website](https://umami.upchur.ch/share/7P3yYsqAsvpdlb03/nathanupchurch.com).

12
content/ai.md Normal file
View File

@ -0,0 +1,12 @@
---
layout: layouts/base.njk
title: Nathan Upchurch | AI
structuredData: none
---
# AI Statement
## Is AI used for this website?
Absolutely no prose, code, or image that comprises a part the content of this website, nor any code that comprises the website itself was generated from AI products, also known as 'ocean-boiling plagiarism machines'. You may rest assured that this will not change.
## AI Permissions
I do my utmost to ensure that my work is not hoovered wholesale and regurgitated by AI products by including an [ai.txt file](/ai.txt) and disallowing known crawlers in my [robots.txt file](/robots.txt), but just in case it will ever become meaningful in any legal sense, I'd like to make it clear here that I do not grant permission for any content on this website to be used as training data for any AI project, or for any portion of this website to be scraped by bots associated with AI projects.

View File

@ -1,14 +1,20 @@
--- ---
layout: layouts/base.njk layout: layouts/base.njk
eleventyNavigation: title: "The Stochastic Bletherist | The Personal Blog of Nathan Upchurch"
key: Blog structuredData: none
order: 2 postlistHeaderText: "Whats New:"
--- ---
<h1>Nathan Upchurchs Personal Blog: Latest Posts.</h1> <h1>The Stochastic Bletherist</h1>
<p class="page-block nodropcap"> <p class="page-block nodropcap">
Looking for something in particular? Have a look at <a href="/tags/">this convenient list of post categories</a> to filter results by topic. The personal blog of Nathan Upchurch, where he writes about everything from <a href="/tags/storytime">personal stories</a> to <a href="/tags/gnu-linux">tech</a>, <a href="/tags/vegan-cooking">food</a>, and <a href="/tags/incense">incense</a>.<br />
</p>
<a href="/tags/">
<button type="button">Topics »</button>
</a>
<a href="../blogroll/">
<button type="button">Blogroll »</button>
</a>
</p>
{% set postslist = collections.posts %} {% set postslist = collections.posts %}
{% include "postslist.njk" %} {% include "postslist.njk" %}

View File

@ -0,0 +1,286 @@
---
title: "Poaster: Solving SSG Microblogging Ergonomics with Ruby and KDialog"
description: "Trying to make it a little less brutal to make small, frequent posts on SSGs."
date: 2025-06-08
tags:
- Site Updates
- Eleventy
- KDE
synopsis: "Trying to make it a little less brutal to make small, frequent posts on SSGs."
imageURL: "/img/poaster/poaster_icon.svg"
imageAlt: "An icon featuring a red toaster with the Ruby diamond on it popping out a sheet with the Markdown logo on it as though it were toast."
mastodon_id: "114650833104413858"
---
Anyone familiar with my blog will know that I like to write about incense. A reader wrote to me some time ago asking about what sticks I've been enjoying lately, and it occurred to me that it might be a nice thing to have a "now listening" type feature on my website, so that fellow incense heads could get a sense of the types of incense I like. After all, while I write plenty of incense reviews, they represent only a small percentage of the sticks, cones, powders, woods, and resins I'm burning or heating from day to day. (If you're here for my incense content, feel free to skip this one and head to [/now-burning](/now-burning) to see the new feature!)
## The issue of ergonomics
While it would have been simple enough for me to build a microblogging feature into my [Eleventy](https://www.11ty.dev/) website, the trouble was *wanting to use it* after it was built. Unlike using a {{ "CMS" | abbr("Content Management System") | safe }} such as WordPress to make a website, I knew of no nice interface for Eleventy, or for that matter any {{ "SSG" | abbr("Static Site Generator") | safe }}, that would help me create a post and publish it online without opening an {{ "IDE" | abbr("Integrated Development Environment") | safe }}[^1] and using the command line. Instead, the process looks something like this:
[![A screenshot of a complicated looking text editor with a terminal widget at the bottom beside a copy of my website running on localhost.](/img/poaster/ergonomics_fail.webp "I don't necessarily want to feel like a [hackerman](https://knowyourmeme.com/memes/hackerman) every time I decide to make a tiny status update. Also, I just noticed that I totally screwed up the frontmatter for that post.")](/img/poaster/ergonomics_fail.webp)
As big of a nerd as I am, I'm just not going to want to do that multiple times a day for what amounts to a status post. This lead me to *scour* the internet looking for a solution: something that I could run on my own desktop or laptop that could build my site locally and push changes to my website, hosted the old fashioned way: as a bunch of text files sitting on a server accessible via {{ "SFTP" | abbr("SSH File Transfer Protocol") | safe }}. No needless complexity like running Eleventy on the server, or using a host like Netlify.[^2] Surely there'd be something, right? Surely, the realm of SSGs can't be without at least one nice, local user interface that people can use without being a web developer?
## An attempt to fix the problem
In the end, I did find one answer to the problem: [Publii](https://getpublii.com/). Publii seems to be made predominantly with end-users in mind, however. It's not just a local[^3] CMS, it's an SSG in its own right, which does me no good as I can't make it work with my website[^4]. So after coming up with nothing *I* could use, I gave the idea a rest for a while until I had the epiphany that I could solve the problem with a simple script using KDE's [KDialog](https://invent.kde.org/utilities/kdialog) to provide a rudimentary UI. So that's what I did.
The idea was simple: a [wizard](https://en.wikipedia.org/wiki/Wizard_(software))-like experience that guides the user through the creation of a microblog / status post. Post types and the data they collect should be customized by the user via a JSON configuration file. After the post data is collected from the user, the script should execute a user-defined build command as well as a user-defined command to sync the static files to the server.
## Building "Poaster"
For some reason, I decided to write my script in Ruby, a language for which I once completed a course before promptly forgetting everything I knew about it. I would have had a much easier time using JavaScript and Node, which I am much more familiar with and have successfully used for similar purposes. Why I did not is anyone's guess. All this to say: please do not make (too much) fun of my shitty little script, which I have dubbed "Poaster."
I started with the JSON configuration file, `/Poaster/config/config.json`:
```json
{
"buildCommand": "npx @11ty/eleventy",
"postTypes": [
{
"name": "Now Burning",
"postUnitName": "incense",
"contentEnabled": true,
"frontMatter": [
{
"name": "title"
},
{
"name": "manufacturer"
},
{
"name": "date"
},
{
"name": "time"
}
],
"postDirectory": "/post/output/dir"
}
],
"uploadCommand": "rsync -av --del /local/path/to/site/output
username@my.server:/remote/path/to/public/site/files",
"siteDirectory": "/local/path/to/site/repo"
}
```
Here, the user can specify as many post types as they like, each with their own output directory. Each post type can also collect as many pieces of frontmatter as the user cares to specify.
The first thing the script needed to do was ask the user which post type they want to create, so I referenced the [KDialog tutorial](https://develop.kde.org/docs/administration/kdialog/) and wrote a method to handle that `/Poaster/lib/spawn_radio_list.rb`:
``` ruby
def spawn_radio_list(title, text, options_arr)
command = %(kdialog --title "#{title}" --radiolist "#{text}")
options_arr.each_with_index do |option, i|
command += %( #{i} "#{option}" off)
end
`#{command}`
end
```
I wrote a few more methods in `/Poaster/lib` to spawn toast notifications, input boxes, create directories if they don't exist, and write files:
`/Poaster/lib/spawn_toast.rb`:
``` ruby
def spawn_toast(title, text, seconds)
`kdialog --title "#{title}" --passivepopup "#{text}" #{seconds}`
end
```
`/Poaster/lib/spawn_input_box.rb`:
``` ruby
def spawn_input_box(title, text)
`kdialog --title "#{title}" --inputbox "#{text}"`
end
```
`/Poaster/lib/ensure_dir_exists.rb`:
``` ruby
def ensure_dir_exists(directory_path)
unless Dir.exist?(directory_path)
FileUtils.mkdir_p(directory_path)
spawn_toast 'Directory Created', %(Poaster created #{directory_path}.), 10
end
end
```
`/Poaster/lib/write_file.rb`:
``` ruby
def write_file(directory, name, extension, content)
post_file = File.new(%(#{directory}/#{name}.#{extension}), 'w+')
post_file.syswrite(content)
post_file.close
end
```
All I had to do then was tie it all together in `/Poaster/poaster.rb`:
``` ruby
#!/usr/bin/env ruby
require 'json'
require 'fileutils'
require './lib/spawn_input_box'
require './lib/spawn_radio_list'
require './lib/spawn_toast'
require './lib/ensure_dir_exists'
require './lib/write_file'
config_data = JSON.parse(File.read('./config/config.json'))
dialog_title_prefix = 'Poaster'
# Populate types_arr with post types
post_types_arr = []
config_data['postTypes'].each do |type|
post_types_arr.push(type['name'])
end
# Display post list dialog to user
post_type = config_data['postTypes'][Integer(spawn_radio_list(dialog_title_prefix, 'Select a post type:', post_types_arr))]
# Set the word we will use to refer to the post
post_unit = post_type['postUnitName']
# Collect frontmatter from user
frontmatter = []
post_type['frontMatter'].each do |item|
frontmatter.push({ item['name'] => spawn_input_box(%(#{dialog_title_prefix} - Enter Frontmatter'), %(Enter #{post_unit} #{item['name']}:)) })
end
# Collect post content from user
post_content = spawn_input_box %(#{dialog_title_prefix} - Enter Content), %(Enter #{post_unit} content:)
# Make sure the output folder exists
post_directory = post_type['postDirectory']
ensure_dir_exists(post_directory)
# Create post string
post = %(---\n)
post_id = ''
frontmatter.each_with_index do |item, i|
post += %(#{item.keys[0]}: #{item[item.keys[0]]})
post_id += %(#{item[item.keys[0]].chomp}#{i == frontmatter.length - 1 ? '' : '_'})
end
post += %(---\n#{post_content})
# Write post string to file and notify user
post_file_name = %(#{post_type['name']}_#{post_id.chomp})
post_extension = 'md'
write_file post_directory, post_file_name, post_extension, post
spawn_toast 'File Created', %(Poaster created #{post_file_name}#{post_extension} at #{post_directory}.), 10
# Run build and upload commands
`cd #{config_data['siteDirectory']} && #{config_data['buildCommand']} && #{config_data['uploadCommand']}`
```
## Burning now
There is a lot that this script should do that it doesn't, but for now, it's still a handy wee utility for SSG users on GNU/Linux systems running KDE who want to make creating quick status-type posts a little less painful. Just make sure KDialog is installed (as well as Ruby, naturally), clone [the repo](https://upchur.ch/gitea/n_u/Poaster), create `/Poaster/config/config.json` to meet your needs using the example as a reference and you're off to the races! I've even made a silly little toaster icon using assets from some of the KDE MimeType icons that you can use if you want to make a `.desktop` file so that you can click an icon on your app launcher to start the script.
[![A screenshot showing Poaster in my app launcher.](/img/poaster/app-menu.webp "Isn't that nice?")](/img/poaster/app-menu.webp)
My `poaster.desktop` file looks something like this:
``` bash
[Desktop Entry]
Exec=/path/to/poaster.rb
GenericName[en_US]=Create a post with Poaster.
GenericName=Create a post with Poaster.
Icon=/path/to/poaster_icon.svg
Name=Poaster
NoDisplay=false
Path=/path/to/repo/
StartupNotify=true
Terminal=false
Type=Application
```
Here's the script in action:
<figure><div style="position: relative;"><iframe title="A video showing Poaster being launched from the terminal. The script brings up a series of text input boxes for each piece of frontmatter specified in the configuration file." width="560" height="315" src="https://makertube.net/videos/embed/p8oopZXaLNUXNpBQGY9q4k" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe></div><figcaption>The ease! The convenience!</figcaption></figure>
To build the new "now burning" incense microblog feature, I created two new pages. [/now-burning](/now-burning) shows the latest entry:
``` html
---
layout: layouts/base.njk
title: "Nathan Upchurch | Now Burning: What incense I'm burning at the moment."
structuredData: none
postlistHeaderText: "What I've been burning:"
---
{% raw %}{% set burning = collections.nowBurning | last %}
<h1>Now Burning:</h1>
<article class="post microblog-post">
<img class="microblog-icon" src="/img/censer.svg">
<div class="microblog-status">
<h2 class="">{{ burning.data.title }}{% if burning.data.manufacturer %}, {{ burning.data.manufacturer }}{% endif %}, {{ burning.date | niceDate }}, {{ burning.data.time }}</h2>
{% if burning.content %}
<div class="microblog-comment">
{{ burning.content | safe }}
</div>
{% endif %}{% endraw %}
</div>
</article>
<a href="/once-burned/">
<button type="button">Previous Entries »</button>
</a>
```
…and [/once-burned](/once-burned) shows past entries:
``` html
---
layout: layouts/base.njk
title: "Nathan Upchurch | Once Burned: Incense I've burning in the past."
structuredData: none
---
{% raw %}{% set burning = collections.nowBurning | last %}
<h1>Previous “Now Burning” Entries:</h1>
{% set postsCount = collections.nowBurning | removeMostRecent | length %}
{% if postsCount > 0 %}
{% set postslist = collections.nowBurning | removeMostRecent %}
{% set showPostListHeader = false %}
{% include "incenseList.njk" %}
{% else %}
<p>Nothings here yet!</p>
{% endif %}{% endraw %}
<a href="/now-burning/">
<button type="button">Latest »</button>
</a>
```
…using a post-listing include built specifically for microblogging:
``` html
<section class="postlist microblog-list">
{% raw %}{% if postlistHeaderText %}<h2>{{ postlistHeaderText }}</h2>{% endif %}
<div class="postlist-item-container">
{% for post in postslist | reverse %}
<article class="postlist-item">
<div class="post-copy">
<h3>
{% if post.data.title %}{{ post.data.title | safe }}{% else %}?{% endif %}{% if post.data.manufacturer %}, {{ post.data.manufacturer | safe }}{% endif %}
</h3>
<div class="post-metadata">
<div class="post-metadata-copy">
<p>
<time datetime="{{ post.date | htmlDateString }}">{{ post.date | niceDate }}{% if post.data.time %}—{{ post.data.time }}{% endif %}</time>
</p>
</div>
</div>
{% if post.content %}
<div class="microblog-comment">
{{ post.content | safe }}
</div>
{% endif %}
</div>
</article>
<hr>
{% endfor %}{% endraw %}
</div>
</section>
```
And that's about it! There's a lot to do to make the script a little less fragile, such as passing along build / upload error messages, allowing for data validation via regex, et cetera. I'm sure I'll get to it at some point. If Poaster is useful to you, however, and you'd like to submit a patch to improve it, [please do let me know](../../me/).
[^1]: Yes, I am aware that [Kate](https://kate-editor.org/) isn't *technically*
an IDE.
[^2]: At risk of sounding crabbit and behind the times, I don't know why web
development has to be so damned complicated these days. Like, an entire fancy
for-profit infrastructural platform that exists just to host static websites?
It seems nuts to me.
[^3]: Thank christ. Why does everything need to run in the cloud when we
already have computers at home?
[^4]: I did however use it to very quickly set up a nice looking blog site for
my partner.

View File

@ -0,0 +1,58 @@
---
title: "Grand Dame: A Breakthrough Incense Blend?"
description: "An attempt at a lavender incense stick goes remarkably well thanks to an unusual technique."
date: 2024-07-28
tags:
- Incense
- Incense Making
synopsis: "An attempt at a lavender incense stick goes remarkably well thanks to an unusual technique."
imageURL: /img/sending-incense-samples.webp
imageAlt: An uncapped fountain pen on top of a pretty, gold-foiled pad of paper beside some envelopes with stamps featuring coffee drinks on them.
mastodon_id: "112867886475498806"
---
I wrote two letters today, sealing each into a cotton envelope alongside a colorful cardboard straw, taped at both ends, containing two minuscule sticks of incense. I'm very excited about what's in those straws: incense sticks resulting from a blend I've dubbed *Grand Dame.*
---
*A quick note:
You can [see everything I've written on incense here,](../../tags/incense/) or [subscribe to just incense posts via RSS.](../../feeds/incense.xml)*
*Correction: When this article was first published, I wrongly attributed the suggestion that Yi-Xin's "Heart of Lavender" isn't likely to use lavender essential oil to Irene of [rauchfahne.de](https://blog.rauchfahne.de/en/) who has since let me know that it wasn't her who suggested this.*
---
[![An uncapped fountain pen on top of a pretty, gold-foiled pad of paper beside some envelopes with stamps featuring coffee drinks on them.](/img/sending-incense-samples.webp "If you're going to snail-mail, you might as well do it in style.")](/img/sending-incense-samples.webp)
These sticks are interesting for a couple of reasons. First, they make use of ambrette seeds, which are mentioned in places such as [incensemaking.com,](https://incensemaking.com/aromatics/musk-seeds/) but there's precious little information available about people *actually using them* in incense. The sticks also involve an experimental technique that I used to try to achieve a lavender fragrance similar to that in Yi-Xin's *Heart of Lavender.*
## Ambrette
Ambrette seeds, or musk seeds, are used in perfumery as a natural alternative to animal musk. Far be it from me to deprive an innocent creature of any of its organs, no matter how fragrant, I have been curious about this ingredient for some time as a way to imbue incense with a measure of animalic depth and complexity.
One of the factors that makes traditional incense making so difficult is that most plants reek to high heaven when burned unless you very precisely control the ratio of the ingredient and the temperature at which it burns. Knowing that tonka beans are notorious for smelling less than rosy when used in too high a concentration, I treated the ambrette seeds with a similar trepidation. Through experimentation, I've found that ambrette seeds make their presence well known at as little as two percent of a total blend.
Ambrette seed really does need to be a part of a blend. Upon lighting, it's one of the first ingredients you'll notice, and as a stick of *Grand Dame* was burning while I wore a mask during a visit to Dave of [The World Makes Scents](https://theworldmakesscents.com/) in his workshop (a great time that I plan to write about soon - thanks Dave!), the ambrette was one of the few notes that made it through the tight fibers of a KN95. In isolation, the burning musk seeds aren't pretty, but I really think they add something special to the blend as a whole.
## The Experiment
I've been a bit obsessed with Yi-Xin's [*Heart of Lavender*](https://craft-incense.com/products/lavenwood) since I first tried it. You see, creating floral incense is notoriously difficult; burning flowers rarely produce a fragrance that's even remotely pleasant, and when they do, it's still tricky to get the blend right. As Ken of Yi-Xin wrote on the *Heart of Lavender* product page:
>Blending lavender flowers into incense basically makes the scent quite herbaceous and sharp. So it took a lot of tweaking and some special techniques to get correct.
He also hints at one of these special techniques:
>Firstly, the base ingredient is a specially processed Stanford Cedar material that integrated lavender in a very unique way
Whatever Ken is doing to those ingredients, it produces a beautiful lavender stick which somehow circumvents the sharpness he describes altogether. It's practically *juicy* — floral, but fruity and tart like a plum. As an incense maker, how you could know that this is possible and *not* try to do it is beyond me, so I came up with an idea and tested my hypothesis in *Grand Dame.* The best guess I could muster as to how he'd managed to avoid that familiar scent of burning plant material that is usually part and parcel of, well, burning plant material, was that he must have either omitted it entirely or significantly reduced the quantity used. If I recall, someone mentioned to me at one point that *Heart of Lavender* didn't strike them as containing any significant quantity of essential oil, and I had forgotten that hydrosols exist, which left me with the idea that perhaps Ken had used a tincture.
I started out by soaking whole dried lavender flowers in [Pisco,](https://catanpisco.com/) which smelled incredible. I soon did a little reading on tinctures, however, and found that I was going about it all wrong. The proof of the Pisco and the ratio of flowers to Pisco were both too low, and I'd need to wait several weeks to see how my tincture had turned out in any case. At this point, I bought an ounce of lavender tincture to experiment with. I combined the entire bottle with six grams of stunning powdered [Juniperus Virginiana from The World Makes Scents;](https://theworldmakesscents.com/products/premium-super-fine-red-cedar-powder-juniperus-virginiana) after stirring well and letting the mixture sit for twenty-four hours, I removed the lid from the jar and allowed the liquid to evaporate. The result of a quick burn test was thrilling: the trail of cedar produced the beautiful, fruity lavender fragrance that I'd hoped for.
Now that I had some lavender fragranced wood, I decided to make some sticks from it. To the cedar, I added benzoin for sweetness and for its fixative properties, acacia gum to help modulate burn temperature and to strengthen the sticks, cinnamon, borneol, a small amount of powdered lavender, the ambrette seed, and guar gum to bind. In my opinion, the sticks turned out very well.
Weeks later, I reflected on the original purpose of my tincture experiment while taking a look at the last of my *Heart of Lavender* sticks from Yi-Xin. As I did, I realised something: these sticks are *dark.* There had to be a significant amount of lavender flowers in them.
[![A dark stick of "Heart of Lavender" seen through a printer's loupe.](/img/heart-of-lavender.webp "There's no way this doesn't contain a significant amount of lavender flowers.")](/img/heart-of-lavender.webp)
Here is a comparison between *Grand Dame* and *Heart of Lavender*:
[![The two sticks seen through a printer's loupe. Mine is significantly lighter in color.](/img/incense-stick-comparison.webp "Left: Grand Dame; Right: Heart of Lavender. Quite a difference. ")](/img/incense-stick-comparison.webp)
With that, while it produces a lovely stick, I think my tincture idea is out of the window. Knowing that Ken was taught by [Kyarazen,](https://www.kyarazen.com/) who writes on traditional Chinese incense techniques as does his student [Dr. Incense,](https://dr-incense.com/) I wonder whether the cedar and lavender might have been processed by [steaming](https://dr-incense.com/blogs/dr-incense-blog/traditional-processing-of-aloeswood) them together. At any rate, despite my disappointment at failing to discover how Ken of Yi-Xin made his lavender incense so good, I did manage to find a way of achieving a similar result, and I'm keen to hear what some of my fellow incense-heads think providing those samples arrive in good condition. It continues to be an interesting line of enquiry as tinctures are expensive, even when you make them yourself, so I'd be grateful to discover a more frugal alternative. I've also started some more tinctures to play with, one with osmanthus and another using jasmine. I'll let you know how those work out.

View File

@ -0,0 +1,23 @@
---
title: "A Plebeians Review of The Witcher 3: Wild Hunt"
description: "I tried really, really hard to get into this game."
date: 2025-05-04
tags:
- Gaming
- Game Review
synopsis: "I tried really, really hard to get into this game."
imageURL: /img/witcher_3/witcher3_en_screenshot_screenshot_13_1920x1080_1433341624.webp
imageAlt: "A screenshot of Geralt's scowling face."
mastodon_id: "114451612149600574"
---
The Witcher 3: Wild Hunt is a fantasy RPG in which you play as ~~Ged~~ ~~Gerd~~ ~~Gerald~~ Geralt, a super masculine generic-white-man protagonist who grumbles everything he says like Batman. Hopefully you like Geribald, because you don't get to customize him in any way. You'll control Gabriel from a third-person perspective, awkwardly hovering over his right shoulder as he trudges around wherever it is that he lives. The map is large, so in order to spare you too much trudgery Giovanni has a horse that he can ride insofar as it doesn't get stuck on any rocks, stumps, shrubbery, or especially stout blades of grass. The horse is named after an insect of some kind.
As he rides about the scenery, Grayson will run into all sorts of gurgling monsters that he will attempt to defeat by swinging one of his two swords at them: one silver, which is good for some monsters, and one steel, which is good for others, for some reason. He also has a crossbow with a fire-rate that may well be slower than his refractory period[^1]. Oh, and Gavin is also a witcher, not to be confused with something so compelling as a witch. This means that he can sometimes shoot different colored lights from his hand, and has some sort of smell-o-vision a la [Dog's Life for PS2](https://www.youtube.com/watch?v=GcHKPjCGAX4). Combat is mostly an exercise in clicking wildly while watching needlessly acrobatic sword-swinging animations play.
I am told that the *proper* way to play this game is on the hardest difficulty, wherein the player will have the pleasure of milling about collecting various herbs and other ingredients in order to create a variety of potions and sword…oils…(?) without which completing the game is impossibly difficult. After repeatedly dying during an introductory mission escorting some sort of demon baby ten meters up a dirt path I chose instead to set the game difficulty to "Just the Story," which somehow still finds me killed time and time again on missions that the game recommends for players at or below my level.
Unlike, say, Skyrim, talking to NPCs rarely nets Gerardo more than a wet cough, so quests are to be found at job-boards posted at each human settlement. You might think that this would discourage exploration and lower the sense of immersion in the game, but after thirteen hours of game-play to date I can say with confidence that yes, in fact it does. So in a world seemingly devoid of any interesting discoveries to be made, if guiding Roach the horse from obstruction to obstruction across the landscape while vaguely sad music plays isn't enough to keep you interested in the open world of The Witcher 3, you can skip the rather beautiful scenery altogether via the fast-travel system.
When the few of us who aren't utterly enamored with this game say anything to that effect, we're often dismissed as pedestrian and told that it's *all about the story,* so let's get into that. What I know so far is that Gideon's adopted daughter was nicked by some folk in hoods. Why? I couldn't tell you. I'm stuck trying to kill a werewolf in "Just the Story" mode so that I can progress the story. Maybe I need to craft a sword-oil or something. Honestly, I don't know that I can be bothered.
[^1]: I hear we'll find out later in the game.

View File

@ -0,0 +1,70 @@
---
title: "An Evening with “Americas Best Incense:” Wild Berry"
description: "I review $40 worth of Wild Berry incense in an evening."
date: 2025-08-09
tags:
- Incense
- Incense Review
synopsis: "I review $40 worth of Wild Berry incense in an evening."
imageURL: "/img/wildBerry/wild_berry_incense_sticks.webp"
imageAlt: "Several packs of incense sticks with a ruler on top showing a stick length significantly below eleven inches, as well as some three plus inches of uncoated bamboo stick."
mastodon_id: "115007567342939989"
---
In a [recent post](https://incenseinthewind.blogspot.com/2025/08/rasbihari-lal-absolute-oud.html?sc=1754495465540#c8441585320216937517), our friend Steve of Incense in The Wind described those with an aversion to perfume-dipped incense sticks as *prejudiced*. This has invited some self reflection. Dear reader, I think I may have been called out[^1].
It is true that I typically enjoy incense made out of, well, incense, but hell, maybe it's time to challenge this *blatant elitism*! After all, aren't incense sticks carefully constructed from sawdust, Elmer's glue, and various mysterious liquids named after [illicit substances](https://web.archive.org/web/20210910075942/https://www.stoutmonk.com/image/cache/data/Flute-Cannabish-250x250.jpg) and [public figures](https://web.archive.org/web/20250116044541/https://www.theculturalexchangeshop.com/details.php?id=4933) just as valid?! It's time to check my privilege, confront my prejudices, and find out. Yes, my friend, I've had the Ossetra caviar slapped out of my mouth, and no sooner than the blini landed on my Persian rug (crème fraîche down) have I set off to my nearest [Waffle House](https://knowyourmeme.com/memes/subcultures/waffle-house) for a real, honest, down-to-earth, working-man's meal. Folks, I am *excited* about this one. In this article we're putting down our highfalutin Japanese sticks and exploring “Americas Best Incense[^2]:” [Wild Berry](https://wild-berry.com/).
Wild Berry sells an *incredible* variety of fragrances, and I've chosen six of them: some fruits, some resins, and some fragrances that I'd expect to be more like compositions rather than single notes. When placing the order, I noticed that the website sold resealable bags for a dollar or two. Not wanting to waste money, and figuring they wouldn't mind parting with ten cents worth of plastic for a $40 order, I entered a note asking whether they could throw in a few, provided the bags the incense came in by default couldn't be resealed.
As I brought my laundry basket downstairs earlier today I checked the front porch for parcels. Jackpot. I've got the apartment to myself and nothing better to do, so I figure I'll order a takeaway, binge-watch some [Foundation](https://www.rottentomatoes.com/tv/foundation), and try some of "America's Best" incense sticks while my laundry thumps around in the drier. I open the box, plonk it on the coffee table and began to rifle through the selection. Not a resealable bag in sight. Great; now the smell of this stuff is going to be slowly leeching into my apartment for time immemorial. I do however get a sticker and five sample sticks of "Mango Passion."
[![Several packs of incense sticks with a ruler on top showing a stick length significantly below eleven inches, as well as some three plus inches of uncoated bamboo stick.](/img/wildBerry/wild_berry_incense_sticks.webp "Not a resealable bag in sight.")](/img/wildBerry/wild_berry_incense_sticks.webp)
The "eleven inch" sticks all come markedly short of eleven inches, and they each have some three-plus inches of bare bamboo stick. Some appear to be machine extruded while others show a coating gradient typical with powder-coated sticks. Strange. I start with a strawberry cone:
## Strawberry (Cones)
I'm *sure* I had these before. I have a feeling they may have been among the incense I picked up from a gas station near my school that I used to frequent not only for [the drinks with the wee glass lizards on them](https://www.reddit.com/media?url=https%3A%2F%2Fi.redd.it%2Feaqi1o3yv2441.jpg)[^3], but for their gargantuan incense display. The cones have surprisingly little fragrance before they are burned. Upon lighting, they produce a large amount of smoke. There is a sweet, strikingly artificial, strawberry-like fragrance in the burn. It's reminds me of a strawberry juice-box or fruit snack that's 99% apple juice with a hint of strawberry essence. But mostly, I smell the charcoal and some accelerant. The smell is nostalgic, but not good by any stretch. My throat is already feeling slightly irritated; an inauspicious start. Moving on swiftly.
## Coconut
These have a very strong fragrance on the stick. It's sweet and acidic, almost more like a piña colada that coconut. It smells quite delicious. This fragrance is also inducing some nostalgia for me. On lighting, an aggressively sooty flame leaps to cover the first centimeter or so of the stick; oil appears to emerge from the stick directly beneath the flame. The fragrance upon extinguishing the flame is shocking. It's *foul*: vaporized wax, burning plastic, and some odd fishy note with a hint of artificial coconut. It's the kind of smell that makes you feel that your lifespan is being reduced. I put the stick out in short order.
## Frankincense
I was keen to try this one; I wanted to know how close it would be to its namesake. Not remotely, as it happens. You ever walk into a Joann or Michaels craft store around Christmas? That's what this stick smells like. Sickly sweet, artificially spicy—a bit like like rum-raisin ice-cream and men's spray-on deodorant with a hint of Play-Doh. Since that coconut stick put the fear of god into me, I've decided to start burning these sticks far, far away from where I'm sitting. The kitchen will do. I place the burner on wooden prep table in my kitchen. I hold my breath while lighting and quickly scuttle off back to the couch to watch Brother Day try to keep the empire afloat. I have no doubt the fragrance will find me there. To my surprise, this rather powerful fragrance actually comes through reasonably well in the burn; it's definitely not as abominable as the coconut. Still, I have to put it out before long.
Around this point my takeaway arrives, so I decide to take a break. I cast my eyes onto the open package as I eat. It smells like someone's eating a fruit salad in a perfume shop. I consider moving it.
## Dragon's Blood
Like frankincense, my collection of something like 100 fragrant materials in various jars, bags, bottles, and tubes includes dragon's blood. That's the thing about resins: they're real substances that people own, and so if you name an incense stick after them, people are going to know when you're fibbing. This stick smells like baking spice and tart fruit, which is confusingly close to how I might describe actual dragon's blood resin, but it still somehow smells nothing like it. There is also a benzoin-like sweetness on the unlit stick. The fragrance in the burn is mercifully close to that of the unlit stick, but like the others, it comes along with a boat-load of off-notes. As with the Frankincense, this very strong fragrance quickly became too much.
I'm feeling a touch dejected. I knew this incense was going to be bad, but I had hoped it would be bad in a fun way, like a fast-food hamburger, or a toy from a cereal box. So far it's just been a bit depressing.
## Orange Creamsicle
But, dear reader, hope springs eternal; the fragrance on this stick is fantastic. It's synthetic and too strong in a fun way, like candy. It's actually quite impressive—there's a sharp orange note, more orange oil than flesh, with a creamy, lactonic vanilla ice-cream note. As for the burn, well, if you buy these just stick them in a jar and pretend they're part of a reed diffuser. The off-notes are tremendous. Orange oil becomes bitter, burning pith. The experience is sickeningly underlined by an eerily unchanged vanilla ice-cream note like a music box playing sweetly amid artillery fire.
## Opium (Sticks)
Wow; this is bringing me right back to my teenage bedroom. The fragrance on the unlit stick is powerful: a trepidatious sniff draws a cough from my battle-worn lungs. By now, I'm too tired to attempt to work out the constituent notes of this composition, but it's not bad. It actually comes through surprisingly cleanly, at least compared to the others I've tried so far[^4]. I wonder whether the sheer strength of this stick isn't just overpowering any lurking off-notes waiting to soak into the carpet. In any case, I might go so far as to burn this one again on purpose. Outdoors, of course, but still.
## Strawberry (Sticks)
At this point, my nasal passages are beginning to feel as though I've [french-inhaled](https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExbTVyeWJ3ZTI3aWlnbG9nOHR0eGdyM29hOTRzeW5rbGUxdnIwZmFtciZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/xTiTnlbIZkWZDrKqgo/giphy.gif) my way through a pack of [menthol Newports](https://en.wikipedia.org/wiki/Newport_(cigarette)#/media/File:Newport_cigarettes.jpg). I steel myself; I will press on. Although disappointed by the strawberry cones, I somehow still have hope for the sticks. The smell is markedly more complex. It's a combination of strawberry candy and a rather uncanny impression of the sad, cucumbery strawberries they grow here in the U.S. I swear I can even smell the little green leaf at the top. When lit, however, this stick offers major off-notes with a hint of strawberry candy, like a fire in a sweet-shop.
## Opium (Cones)
Now so close to the end, my mind and body are crying out for rest. Like the sticks, this is a competent composition that has enough strength to overpower the stink that seems to be inherent in this brand. Beyond the smell, I find it interesting how wildly inconsistently these Wild Berry cones are shaped. From a company that puts out such volume, I expected production to be such an exercise in precision and efficiency that there would be no room for even the slightest deviation; I've seen more consistent output from even very small incense makers. I wonder why this is as I whisk away the censer containing the burning cone into another room.
[![A bunch of wonky incense cones on top of the plastic bag they came in with a label reading "Opium (Type)"](/img/wildBerry/wild_berry_opium_incense_cones.webp "Helpfully labeled \"Opium \(Type\)\" in case you thought you were **really** getting your money's worth.")](/img/wildBerry/wild_berry_opium_incense_cones.webp)
## Free Sample: Mango Passion
As I reach my final task, my spirits are low; my nose a ragged wanderer on his sun-blistered belly, inching towards a verdant oasis after untold hours in the quivering heat, prostrate before the silent might of the dunes. I light a stick.
How dearly I wish these sticks had been a handful of resealable bags. The fragrance of the unlit stick is pleasant enough: bright passion fruit and mango, per the name. It actually manages to come through relatively intact in the burn too, but all of those unpleasant smells we've come to expect alongside it really ruin the experience. This time the fire is in a Garnier Fructis production facility. With this out of the way, I am free.
## Conclusion
I don't expect you to believe me, but I *did not* intend this article to be a hit-piece. I had anticipated a [Review Brah](https://en.wikipedia.org/wiki/TheReportOfTheWeek) style affair, where I got to sample some inelegant but fine enough incense sticks in fun fragrances. I had hoped that together we could take a dip into what would turn out to be the murky but cool waters of American commodity incense and emerge refreshed, if a touch muddy. Instead, I feel that we've come away with [brain-eating amobea](https://www.cdc.gov/naegleria/about/index.html).
While Wild Berry's fragrances have left me distressed and unsatisfied, this experience has also left me with many questions. Beyond its products, I find that I've developed a lingering fascination surrounding the company itself. Wild Berry isn't just another big anonymous incense-maker, it has *lore*. From the company's [Duloc](https://youtu.be/p1zQHvvgXOs?si=CuLazpB9jRuXpNBW&t=31)-style [wooden puppet display](https://www.youtube.com/watch?v=F6Kf-ocYmBI), to zany antics such as [dragging employees around on pallet jacks](https://youtu.be/IJHtDyMV03o?si=pfMNMX6R6UYxrs_W&t=35), the more I learn the greater my curiosity. Why do precisely none of the [company vlogs](https://www.youtube.com/playlist?list=PLJEWn3HV8JpN4MDB_srqcB8LQitKtEcBX) show anyone burning incense in their offices? What are they hiding in those five unavailable videos? What on earth is [going on here](https://www.youtube.com/@123WIldberry/), and what is a "[Buxom Busam](https://www.youtube.com/watch?v=zStV6vwjQYk)?"
As for the incense itself, I'm flummoxed. How can something of such irredeemably poor quality be so ubiquitous? I admit I have come to deeply resent spending $40 on incense I've described in terms of war, but I also can't help but feel that this endeavor has made me party to one of the great mysteries of our time. Filled with a sense of both wonder and horror in the face of it, I've found myself staring at a [rotating](https://en.wikipedia.org/wiki/File:8-cell-orig.gif) [tesseract](https://en.wikipedia.org/wiki/Tesseract), beautiful in its incomprehensibility. And who knows? After a bout of therapy to overcome the trauma I've experienced tonight, I may eventually be able to put some of these sticks into service on the porch as bug-repellent.
[^1]: Obligatory disclaimer assuring you that I'm being tongue-in-cheek and I am in no way salty at anyone.
[^2]: The scare quotes are, I kid you not, included in their official branding.
[^3]: I typically try not to make too much of a show of my impeccable taste, but I fear that may be impossible in this instance.
[^4]: A very, very low bar.

View File

@ -0,0 +1,59 @@
---
title: "Black Metal: Fraught Genre, Incredible Tunes"
description: Learning to appreciate extreme metal, problems in the scene, and some killer black metal tunes.
date: 2024-11-12
tags:
- Music
synopsis: Learning to appreciate extreme metal, problems in the scene, and some killer black metal tunes.
imageURL: /img/black_metal.webp
imageAlt: A very creepy picture of a priest in the dark holding a bible with his hand on the head of a man lying on a table wearing a gas mask and a straitjacket.
mastodon_id: "113472856465004642"
---
The beauty of extreme metal genres eludes many a music lover. I was one of them, until in 2007 a friend and I were able to snag some free tickets to Ozzfest by drinking far too many cans of Monster. I'd been into some slightly heavier music; I'm still a big Rammstein fan, but I just didn't *get* all of that screaming nonsense… until I saw it live.
The power of music is its ability to make you feel: opening you up like a tin can, cramming you full of new emotions and bolstering existing ones, allowing them to override the habitual suppression you've long since stopped noticing; more than mere entertainment, in this way, listening to music becomes a means of exploring, experiencing, and feeling themes and emotions on your terms. As the bass from those gargantuan sub-woofers tears through your body like the drums of a pipe band alongside amplified human screams, growls, and gurgles—the sounds of anger, fear, anguish, and death: seeing a metal act in the flesh *does* something to you.
On that summer day in Texas, I was stricken with an appreciation for metal that I've had ever since. Black metal and death metal populate my music collection alongside tenor trombone concertos, DJ Screw, and drum and bass bangers to this day.
## The big problem with black metal
If you're new to the genre it's important to know, however, that black metal is not without controversy. It's common knowledge that much extreme metal is anti-religious (a position to which I am not unsympathetic) and deliberately provocative to the faithful, as you will see below (Christians: you have been warned), but it is often an unpleasant surprise to those new to the scene that black metal has, to put it frankly, a nazi problem.
Devastatingly satirized by [Neckbeard Deathcamp](https://neckbearddeathcamp.bandcamp.com/), the problem is so widespread that [reddit](https://www.reddit.com/r/LetsTalkMusic/comments/tncgjc/metalheads_how_do_i_find_out_if_the_band_i_found/) [is](https://www.reddit.com/r/MetalForTheMasses/comments/17dt56y/best_nonnsbm_black_metal_bands/) [laden](https://www.reddit.com/r/musicsuggestions/comments/w2rdfl/black_metal_thats_not_racist/) [with](https://www.reddit.com/r/MetalForTheMasses/comments/198cmzz/what_are_some_non_nazi_black_metal_bands/) [threads](https://www.reddit.com/r/MetalForTheMasses/comments/1e0krm6/what_are_some_black_metal_bands_that_dont_have/) started by people looking for safe picks to listen to. While you may, somehow, be able to "separate the art from the artist," it is especially important to avoid supporting white supremacist black metal groups in any way: mere word of mouth leads to revenue, and neo-nazis in the black metal scene use those funds to directly support recruitment and violence.[^1] Seriously, don't even talk about these bands with people; they don't deserve the attention, and [giving it to them can be dangerous](https://www.splcenter.org/fighting-hate/intelligence-report/2000/arrest-german-neo-nazi-reveals-growing-internationalization-white-power-music-scene).[^2]
With all that said, there is plenty of black metal made by good people, and it isn't especially hard to find. Reddit's [/r/rabm subreddit](https://www.reddit.com/r/rabm/) highlights explicitly leftist bands, so check there for some *definitely* safe choices, and before you go booking tickets to see that cool new band you found on Spotify[^3], it might be worth looking them up on [the metal archives](https://www.metal-archives.com/), specifically checking the "themes" section, reading their lyrics, and sniffing around reddit a bit.
## Is it worth the effort?
Absolutely. Extreme metal as a whole is known to host some of the most incredible musicians of the modern era; they say that the best drummers in the world either play jazz or death metal; metal guitarists are conspicuously excellent, and vocals that might sound like the consequence of some terrible disease require a great deal of skill to reproduce safely. A wide range of subgenres means that there's something for everyone in the world of extreme metal, whether you'd prefer to visit your city's orchestra or a basement math-rock show. Here are some killer black metal tunes that I'm rather fond of:
### Blacker Than Black - Mora Prokaza
{% audio "Blacker Than Black", "Mora Prokaza", "/audio/black_metal/session_Blacker Than Black.mp3", "/audio/black_metal/mora_prokaza_by_chance_album_cover.webp" %}
The most normal track on Mora Prokaza's incredibly bizarre album *By Chance*, *Blacker than Black* is a gentle introduction to the rapped vocal style of the album, without the unique instrumentation and distinctly un-metal song structures found in other tracks.
### I'm Not Yours - Mora Prokaza
{% audio "I'm Not Yours", "Mora Prokaza", "/audio/black_metal/session_I'm Not Yours.mp3", "/audio/black_metal/mora_prokaza_by_chance_album_cover.webp" %}
This is what Mora Prokaza's *By Chance* is all about: 808 sub bass, repetitive rapped black metal vocals compressed into percussive triplets, instrumentation incongruous with either black metal or trap: this album is nuts, and I'm here for it.
### The Thousand Tombs of Western Promise - Wayfarer
{% audio "The Thousand Tombs of Western Promise", "Wayfarer", "/audio/black_metal/session_The Thousand Tombs of Western Promise.mp3", "/audio/black_metal/wayfarer_american_gothic_album_cover.webp" %}
A distinctly American take on the genre, Wayfarer integrates blues with black metal in a way that's immensely satisfying and brings a sweeping musicality to their songs that can often be found missing outside of classically influenced, orchestral-leaning acts.
### Tyrannical - Rotting Christ
{% audio "Tyrannical", "Rotting Christ", "/audio/black_metal/session_Tyrannical.mp3", "/audio/black_metal/rotting_christ_sanctus_diavolos_album_cover.webp" %}
From one of my favorite albums of all time, *Tyrannical* is a fine example of one of the qualities I appreciate most in the Greek black metal genre mainstay Rotting Christ; the group is capable of creating music without ego. This track is pure vibes — individual musicians are always secondary to the goals of the composition, and the results are magical.
### Athanati Este - Rotting Christ
{% audio "Athanati Este", "Rotting Christ", "/audio/black_metal/session_Athanati Este.mp3", "/audio/black_metal/rotting_christ_sanctus_diavolos_album_cover.webp" %}
Athanati Este is a sludgy soundscape of staccato riffage punctuated by religious sounding chants and traditional percussion. The layering and treatment of the vocals, alongside the bells, really contributes to a nicely filled frequency range, which I appreciate.
### The Perpetual Horrors - Naglfar
{% audio "The Perpetual Horrors", "Naglfar", "/audio/black_metal/session_The Perpetual Horrors.mp3", "/audio/black_metal/naglfar_pariah_album_cover.webp" %}
Finally, a more traditional black metal tune. Just listen to that double bass pedal go, those impeccable vocals… there are those who will deride anything that doesn't sound like passing traffic recorded through an inch of styrofoam as metalcore; I am not among them. The musicality here is incredible; *The Perpetual Horrors* brings you along for a ride in a five-minute track that never gets boring.
### VI - Au-Dessus
{% audio "VI", "Au-Dessus", "/audio/black_metal/session_VI.mp3", "/audio/black_metal/au-dessus_end_of_chapter_album_cover.webp" %}
Starting with a droning vocal harmony, a repeating guitar riff, and gently syncopated drums, *VI* undulates between a more traditional black metal track, and a dramatic hard rock tone a la the chorus of Hurt's *Rapture*. Emphasis stays with the instrumentation, the vocals kept low in the mix as though they're coming from somewhere else. The effect is a full slow-moving soundscape that is, like Rotting Christ's *Tyrannical*, simply a vibe.
[^1]: This applies for supporting any sort of bigot: buying or even indirectly encouraging the purchase of anything that puts money into the hands of a bigot supports not only their lifestyle, but their activities, and amplifies their reach.
[^2]: So if you know something I don't about any of the bands I've featured here, do let me know so that I can remove them.
[^3]: It's better to buy music outright than use streaming services that barely pay artists, restrict how you use the music you pay for, and stand in the way of the preservation of music as a part of human culture. See [defectivebydesign.org/spotify](https://www.defectivebydesign.org/spotify) for more information.

View File

@ -0,0 +1,50 @@
---
title: "The Blog Questions Challenge"
description: Why I do this whole blogging thing.
date: 2025-03-12
tags:
- Meta
synopsis: Why I do this whole blogging thing.
---
If you haven't seen this going around the internet, you might be spending too little time on [the indieweb](https://indieweb.org/)! The blog questions challenge asks bloggers to talk about how and why they do what they do. Here's mine.
## Why did you start blogging in the first place?
As is common among those with ADHD, I've long felt that I have quite a lot to say and not enough people in my life who have the patience and willingness to sit through endless lengthy monologues; I have a lot of thoughts on a lot of things! Years ago I had a website where I published some of my ghastly teenage poetry—I think I write now for the same reason I did then: sometimes it just feels like I'll burst if I don't.
## What platform are you using to manage your blog and why did you choose it?
I'm using [Eleventy, AKA 11ty](https://www.11ty.dev/), which is a static site generator. A static site generator is a program that lets you code templates for your website, describe how it should work, and then it spits out pages based on your setup so that you don't have to code each new page or post. Static sites don't rely on a server running a content management system; they're literally just a bunch of files that you can host anywhere. They're fast and unhackable.
I chose Eleventy specifically because it's very flexible, and because I'm comfortable with JavaScript.
## Have you blogged on other platforms before?
I've used WordPress in the past, and I use it at work. It makes the editing experience nice and simple (something that is not true with Eleventy), but it also feels fragile and unwieldy to me so I try to avoid it where I can.
## How do you write your posts? For example, in a local editing tool, or in a panel/dashboard that's part of your blog?
I am a big fan of [KDE](https://kde.org/)'s [Kate](https://kate-editor.org/) text editor. No Electron bloat or Microsoft spyware, lots of great tools and plugins, and it's fast as all get out. Honestly, I'm a bit of a Kate evangelist, because I want to see more people working on plugins and language support for it rather than VS Code.
I must admit, I don't always want to use a code editor for blog posts, especially for longer, more involved posts and essays. So when this mood takes me, I'll use [Ghostwriter](https://ghostwriter.kde.org/). Another fabulous KDE project, Ghostwriter is a simple Markdown editor with neat features like distraction-free and fullscreen modes, and writing statistics like word-count and reading-ease.
## When do you feel most inspired to write?
Honestly, I can never predict when the urge will take me, or when hyperfocus will drive me onwards into the wee hours. Sometimes I'll have something cooking for a while, and I'll get swept away with it when I happen upon a text file where I've outlined the idea. Historically, I'm more productive in every way in the evening, but as I've been fiercely battling my circadian rhythm now for several years in the hopes of adapting to a more workplace friendly schedule, I'm occasionally raring to go in the morning provided I've had a good 9-12 hours of sleep.
## Do you publish immediately after writing, or do you let it simmer a bit as a draft?
Usually, finishing a post has me feeling like I've just run the gauntlet, so I'm itching to upload as soon as possible. If it's a longer piece or I've noticed my focus failing, I'll sometimes either have my partner give it a read or I'll sleep on it and re-read before running my `update-website` Zsh alias.
## What are you generally interested in writing about?
Lately mostly incense and computer stuff, but I'd also like to write some longer pieces on some of my core beliefs and opinions. For instance, I'm working on an essay about my feelings toward religion and spirituality. These types of posts are long, involved, and have to be done with some delicacy as they always carry the possibility of upsetting people, so it's going to take some time to get them out.
## Who are you writing for?
In general, I don't think I'm writing for any person or group in particular, including myself. With some posts, I'm just trying to put out a viewpoint that I haven't seen others write about, such as my [post on a tool that allows people to strip the storytelling from recipe blogs](https://nathanupchurch.com/blog/let-us-waffle/). When I write things like that, I'm writing to add what I think is a unique view to an ongoing conversation. For other things, I'm writing because [I think it's important that the information is made available](https://nathanupchurch.com/blog/making-incense/), or to [show support to a project or cause](https://nathanupchurch.com/blog/scribus-1-7-0-from-strength-to-strength/).
I think that writing [incense reviews](https://nathanupchurch.com/blog/maroma-incense-of-auroville-sandalwood-cedarwood/), however, is mostly for myself. I was once [a cocktail bartender](https://makertube.net/w/boNV8AQcufwtaZVg9vUh1Q). When I started out at a high-end Chicago cocktail lounge, the beverage director would ask the bar-back to bring us two Glencairn glasses, each containing a pour of one of the 500+ spirits on the wall behind the bar. He'd then ask me to write down what the spirit was, how long it had been aged, the proof, and five tasting notes. Once you've tasted enough spirits it's not terribly hard to do, so I became quite good at it, but I always found the process quite stressful nonetheless. I worked in coffee for some time after that, and I found coffee cuppings even more anxiety-inducing[^1] because the strong fragrances would burn my nose out almost immediately. When swishing spirits around in my mouth, I don't ever feel that my ability to distinguish flavor notes diminishes, but fragrance can be fleeting as the brain compensates for the presence of whatever aromatics are floating into your sniffer. For the same reasons, I find reviewing incense quite difficult. Posting reviews gives me a reason to keep at it, to keep learning and expanding my 'olfactory library,' and to improve at picking out and identifying notes. It also helps me to be more objective and analytical when testing my own incense.
## What's your favourite blog post?
I'm quite proud of *[What Do We Expect from Fragrance? Natural Incense in an Unnatural World ](../what-do-we-expect-from-fragrance/)*. It sums up my views on how fragrance is used and abused in our time, and where incense fits into all of this.
## Any future plans for your blog? Maybe a redesign, a move to another platform, or adding a new feature?
I never actually sat down and planned out a design for my website; I just started writing code, so I'm forever self-conscious of the design of my site. At some point I may sit down and actually put together a concept and execute on it. Will that satisfy me? Who knows.
## Who's next?
To avoid unduly burdening anyone individually, I'm going to do as [Alistair Shepherd](https://alistairshepherd.uk/writing/blog-questions-challenge/) did and say that if you haven't done one of these yet and you'd like to: you're up!
[^1]: Coffee is harder than cocktails full stop. Once you've got the hang of the basic cocktail categories and their builds, you're singing, whereas coffee is temperamental, and more technically difficult on every level. I promise you that the job of your favorite barista at any decent shop is much more difficult than that of any fancy cocktail bartender.

View File

@ -1,4 +1,4 @@
module.exports = { export default {
tags: [ tags: [
"posts" "posts"
], ],

View File

@ -8,8 +8,8 @@ tags:
- Code Tutorial - Code Tutorial
- SVG - SVG
synopsis: In this tutorial, we'll learn how to make a configurable SVG graphic of a grid of circles in random colors and sizes with p5.js. synopsis: In this tutorial, we'll learn how to make a configurable SVG graphic of a grid of circles in random colors and sizes with p5.js.
imageURL: /img/terminal.svg imageURL: /img/circle-grid-post-image.webp
imageAlt: A stylized illustration of a terminal prompt. imageAlt: A grid of multicolored circles.
--- ---
Processing is a fantastic language for creative programming and learning how to code, allowing programmers of all skill levels to quickly and simply create complex graphics, data visualizations, and generative art. Its Javascript implementation, p5.js, is perfect for those already familiar with Javascript, or who want to use processing to make graphics for the web without the complexity of SVG, or the insanity of using CSS for complex graphics. Today we're going to build [a simple but pretty graphic using P5](#et-voila). Processing is a fantastic language for creative programming and learning how to code, allowing programmers of all skill levels to quickly and simply create complex graphics, data visualizations, and generative art. Its Javascript implementation, p5.js, is perfect for those already familiar with Javascript, or who want to use processing to make graphics for the web without the complexity of SVG, or the insanity of using CSS for complex graphics. Today we're going to build [a simple but pretty graphic using P5](#et-voila).
@ -76,8 +76,8 @@ function setup() {
} }
``` ```
Now if we click the play icon at the top left of the Processing IDE, a browser window should open and load a page showing our sketch so far. We ought to see a viewport entirely covered with one large black canvas. Now if we click the play icon at the top left of the Processing IDE, a browser window should open and load a page showing our sketch so far. We ought to see a viewport entirely covered with one large black canvas.
[![The LibreWolf web browser opened to localhost. The viewport is entirely black.](../../img/circle-grid-canvas.webp)](../../img/circle-grid-canvas.webp)
[![The LibreWolf web browser opened to localhost. The viewport is entirely black.](../../img/circle-grid-canvas.webp "A good start!")](../../img/circle-grid-canvas.webp)
## Random results ## Random results
To meet conditions two and three of our goal, we'll need a way to get random numbers. Let's write a quick function inside `setup()` to provide us with random integers: To meet conditions two and three of our goal, we'll need a way to get random numbers. Let's write a quick function inside `setup()` to provide us with random integers:
``` javascript ``` javascript
@ -214,7 +214,9 @@ We can check that everything is working by calling our new function at the botto
``` javascript ``` javascript
generateCircleLine(10, 10, 20, 0, 5, 10, 10, 'x', [[255,255,255]]); generateCircleLine(10, 10, 20, 0, 5, 10, 10, 'x', [[255,255,255]]);
``` ```
[![The LibreWolf web browser opened to localhost. The viewport is black, with a single row of ten white circles in varying sizes in the top-left corner.](../../img/circle-grid-line.webp)](../../img/circle-grid-line.webp)
[![The LibreWolf web browser opened to localhost. The viewport is black, with a single row of ten white circles in varying sizes in the top-left corner."](../../img/circle-grid-line.webp "We have a line!")](../../img/circle-grid-line.webp)
And look at that! We have a line! And look at that! We have a line!
## Repeating rows ## Repeating rows
@ -287,7 +289,8 @@ generateCircleGrid(
); );
``` ```
...to see the result: ...to see the result:
[![The LibreWolf web browser opened to localhost. The viewport is filled with circles of varying sizes in various shades of blue.](../../img/circle-grid-grid.webp)](../../img/circle-grid-grid.webp)
[![The LibreWolf web browser opened to localhost. The viewport is filled with circles of varying sizes in various shades of blue.](../../img/circle-grid-grid.webp "Beautiful!")](../../img/circle-grid-grid.webp)
## SVG export ## SVG export
Looking back on our goals, we've accomplished all but one: SVG export. Happily, there's [a library](https://github.com/zenozeng/p5.js-svg) that makes this trivial. All we need to do is link the script in the `<head>` of index.html, Looking back on our goals, we've accomplished all but one: SVG export. Happily, there's [a library](https://github.com/zenozeng/p5.js-svg) that makes this trivial. All we need to do is link the script in the `<head>` of index.html,
@ -447,5 +450,7 @@ function draw() {
## Et voilà ## Et voilà
And we're done! Now you can tweak the parameters and make grids with all sorts of colors and size variations, and even export and edit them in Inkscape! And we're done! Now you can tweak the parameters and make grids with all sorts of colors and size variations, and even export and edit them in Inkscape!
[![The LibreWolf web browser opened to localhost. The viewport is filled with circles of varying sizes in various shades of blue. There is a button reading "Save SVG" in the bottom right corner.](../../img/circle-grid-complete.webp)](../../img/circle-grid-complete.webp)
[![The LibreWolf web browser opened to localhost. The viewport is filled with circles of varying sizes in various shades of blue. There is a button reading "Save SVG" in the bottom right corner.](../../img/circle-grid-complete.webp "The finished article.")](../../img/circle-grid-complete.webp)
If you'd like to make this project even better, maybe consider implementing a GUI to adjust your grid paramaters, or adding some interactivity. If you'd like to make this project even better, maybe consider implementing a GUI to adjust your grid paramaters, or adding some interactivity.

View File

@ -0,0 +1,43 @@
---
title: "Red Cedar & Frankincense"
description: I make a simple, three-ingredient, red cedar and frankincense batch of incense sticks.
date: 2024-05-08
tags:
- Incense
- Incense Making
- Incense Builds (Recipes)
synopsis: I make a simple, three-ingredient, red cedar and frankincense batch of incense sticks.
imageURL: /img/cedar_frank.webp
imageAlt: A bunch of coreless incense sticks on top of some cedar planks next to a pile of frankincense tears.
mastodon_id: "112409293978326719"
---
I've seen a recurring theme on the internet among (all three of us) incense makers: sometimes you just get tired of relegating [not-quite-combustible](../gourmand-sandalwood-incense-a-perplexing-failure/) sticks to the 'use on the incense heater' pile, or making sticks that *almost* smell nice, but don't quite. After a few knock-backs like this, going back to basics and making something simple really keeps your ego from getting too bruised. That's partially why I decided to make these red cedar and frankincense sticks. In addition, I'm a huge fan of [Yi-Xin Craft Incense's](https://craft-incense.com/) white cedar and frankincense, and I'd also read that resins can really sing when used in surprisingly low quantities, so I was keen to try this out.
[![A bunch of coreless incense sticks on top of some cedar planks next to a pile of frankincense tears. The cedar planks have part og the Whole Foods logo branded on them.](/img/cedar_frank.webp "Yes, dear reader, those are pieces of a Whole Foods cedar grilling plank.")](/img/cedar_frank.webp)
If you know me in meat-space, you'll likely know that I'm an avid classical trombonist. While it is obviously true that [playing Rimsky-Korsakov's *Flight of the Bumblebee* on a tenor trombone](https://inv.tux.pizza/watch?v=dfTHNpOge0Q) isn't easy, sometimes the most difficult pieces are [those that](https://inv.tux.pizza/watch?v=xKCcFxBP2o0) look [quite simple](https://inv.tux.pizza/watch?v=tcbFpgkHNc0) on paper. It's surely a feat of technical prowess to play many short notes in rapid succession, but to play even a single note in a tone quality that people will want to listen to for several seconds at a time takes an entirely different set of skills — also honed over years — and if jazz music and small-town brass bands have taught us anything, it's that technical prowess in a brass player is no guarantee of tone quality.
So it is with simple incense. In a two or three ingredient build, all flaws are laid bare for insufflation and observation. While I'm pleased with this batch overall, there are some problems with these sticks. But first:
## The Build
|Ingredient|Grams|% of Build|
|----------|------|-----------|
|Western Red Cedar|8|58%|
|Hojari Frankincense Resin (Boswellia Sacra)|2.2|16%|
|Joss Powder (Litsea Glutinosa)|3.5|26%|
As I mentioned earlier, I'd read somewhere that using smaller quantities of resins can bring out their best; this held true. At 16%, the Hojari Frankincense really presents well after two weeks of curing. With B. Sacra, you know you've done well when those citrus and eucalyptus notes you're used to on the heater come out in the burn. At the ratios listed above, the cedar and frankincense are pretty well balanced: neither takes precedence over the other. If anything, I would prefer that the frankincense tip the scale ever so slightly in its favor; I might try 17-18% next time.
## Problems
Whoever fooled the world into thinking that [joss powder](https://scents-of-earth.com/joss-powder-litsea-glutinosa-superior-vietnam/) was "near odorless" is either hyposmic, a liar, or a hyposmic liar. It's not just the frankincense that sings in this build, so too does the joss. Admittedly, 26% is rather a large chunk of the total build for joss powder, so I only have myself to blame here.
[![A flat round censer filled with ash. Atop the ash, a shaped trail of incense powder is burning.](/img/incense_seal.webp "A Chinese style incense seal made with unfortunately coarse powder.")](/img/incense_seal.webp)
When you burn a properly executed Chinese style incense seal, the lack of binder leaves you with a very pure fragrance; one of the hallmarks of Yi-Xin's work is the near absence of any detectable binder, which gives the it that clean quality, as though you're burning an incense seal instead of a joss stick. I haven't managed to achieve this with my cedar and frankincense, largely because instead of patiently cutting slivers from my cedar plank and putting them through my hand-crank flour mill, I dumped a big chunk of it into my Vitamix dry container and let 2.2 peak horsepower of blender handle the matter. This resulted in a very fluffy cedar powder which was difficult to bind and even more difficult to extrude. (It's also bad practice in general because when you introduce heat via machine processing you begin to lose aromatics.) I do wonder whether the joss powder could by further reduced by using it in combination with a gum binder, such as tragacanth.
Irene of [Rauchfahne](https://blog.rauchfahne.de/en/) recommends resting your incense dough after hydration, which I also did not do. It seems that [patience](../patience/) does not come naturally to me.
## Conclusion
I'd burn this stuff on purpose. Problems aside, these sticks are plesant, good even, but they are not *great* in the same way as those made in middle-of-nowhere Hawaii by Yi-Xin's [onewheeling artisan](https://www.instagram.com/kencannata/reel/C5hslbrL9tB/). Feel free to give the build a try; get that binder down a bit, grind your cedar sensibly, and you may wind up with something special.

View File

@ -3,6 +3,7 @@ title: Free Software is the Future for SMEs and Small Nonprofits
description: Tech giants aren't meeting the needs of SMEs and nonprofits. Combined with digital privacy concerns, a perfect storm is brewing for increased adoption of free and open source software for these organizations. description: Tech giants aren't meeting the needs of SMEs and nonprofits. Combined with digital privacy concerns, a perfect storm is brewing for increased adoption of free and open source software for these organizations.
date: 2022-10-28 date: 2022-10-28
tags: tags:
- Essays
- FOSS/FLOSS - FOSS/FLOSS
- Digital Privacy - Digital Privacy
synopsis: Tech giants aren't meeting the needs of SMEs and nonprofits. Combined with digital privacy concerns, a perfect storm is brewing for increased adoption of free and open source software for these organizations. synopsis: Tech giants aren't meeting the needs of SMEs and nonprofits. Combined with digital privacy concerns, a perfect storm is brewing for increased adoption of free and open source software for these organizations.

188
content/blog/galleries.md Normal file
View File

@ -0,0 +1,188 @@
---
title: Adding Image Galleries to My Website
description: At last, I've gotten around to implementing image galleries.
date: 2024-12-02
tags:
- Site Updates
- Eleventy
synopsis: At last, I've gotten around to implementing image galleries.
imageURL: /img/isabella-fischer-X2l9M6jsS7E-unsplash.webp
imageAlt: Some very tasty looking pop tarts with pink icing and sprinkles.
mastodon_id: "113586087349853099"
---
I've been meaning to add an image gallery feature to this website for ages, and I'm happy to finally announce that I've done it! If you'd like to see my very first image gallery in action, [here's a gallery of PopTart memes I've collected](../../gallery/pop-tart-flavor-memes/). If you're a massive nerd and would like to read about how I implemented this feature on my [Eleventy](https://www.11ty.dev/) website, read on.
Note: this is a fast and loose description of the process. It should be helpful if you're trying to do this yourself, but don't expect to be able to copy and paste my implementation. See [the repo](https://upchur.ch/gitea/n_u/nathanupchurch.com) to copy and paste my spaghetti.
## Specifying new galleries
First of all, I had to decide how new galleries would be specified so that Eleventy could work its magic. There are a few approaches here, such as utilizing template frontmatter, directories of images, or using a data file in my site's `_data` directory. After weighing up the pros and cons, I decided to use the latter option, even though it's not the most ergonomic. So I created `_data/galleries.js`, which looks like this[^1]:
``` javascript
export default [
{
title: "",
description: "",
synopsis: "",
url: "",
date: new Date(""),
galleryImage: "",
galleryImageAlt: "",
pictures: [
{
title: "",
filename: "",
altText: "",
thumbAltText: "",
caption: "",
},
],
},
];
```
## Gallery index pagination
Now that I know how I'll go about specifying my galleries, I need to paginate the gallery index pages; the pages that feature thumbnails of each image in the gallery and allow the user to navigate to the images. To do this, I created `content/galleries.njk`:
``` html
---{% raw %}
pagination:
data: galleries
size: 1
alias: gallery
layout: layouts/base.njk
tags: gallery
eleventyComputed:
title: "{{ gallery.title }}"
permalink: "/gallery/{{ gallery.title | slugify }}/"
description: "{{ gallery.description }}"
---
<h1>{{ gallery.title }}</h1>
<p>{{ gallery.description }}</p>
<section>
{% for picture in gallery.pictures %}
<a href="/gallery/{{ gallery.title | slugify }}/{{ picture.filename | slugify }}/">
<div>
<img alt="{{ gallery.thumbAltText }}" class="gallery-image" src="{{ gallery.url }}{{ picture.filename }}">
</div>
</a>
{% endfor %}{% endraw %}
</section>
```
By ensuring that each gallery index page is tagged "gallery," they will automatically be grouped into a new collection by that name, which is important so that I can filter galleries out from post lists and other things throughout my site.
## Generating image pages
I considered using a lightbox / modal sort of arrangement for viewing images, but I decided against it as it can be tricky to get accessibility right for these patterns, and I wanted to avoid using JavaScript if possible. What I chose to do instead was to create a page for each image, which would feature buttons to navigate to the next / previous image, and to return to the gallery. The first step was to create a collection containing all gallery images in my Eleventy config file:
``` javascript
// Collections
eleventyConfig.addCollection("galleryImages", (collection) => {
const galleries = collection.getAll()[0].data.galleries;
let galleryImages = [];
galleries.forEach((gallery) => {
gallery.pictures.forEach((picture, i, arr) => {
picture.containingGallery = `${gallery.title}`;
picture.baseUrl = `${gallery.url}`;
i ? (picture.previousImage = arr[i - 1].filename) : null;
i + 1 != arr.length ? (picture.nextImage = arr[i + 1].filename) : null;
galleryImages.push(picture);
});
});
```
You may notice that I did a little jiggery-pokery in that callback function to provide information about each image that isn't included in `_data/galleries.js` because it would have been a pain to include or would have unecessarily inflated the tile size, specifically: the filenames of images before and after the current image (should they exist), and the URL of the gallery that the image belongs to. We can use this information to have our image pages generated in the same directory as their parent gallery index, and to generate next / previous buttons to help the user navigate through the gallery. This information is added to the `galleryImages` collection object in memory so that we can use it when we paginate the image pages using `content/galleryImage.njk`:
``` html{% raw %}
---
pagination:
data: collections.galleryImages
size: 1
alias: picture
layout: layouts/base.njk
eleventyComputed:
title: "Image: {{ picture.title }}"
permalink: "/gallery/{{ picture.containingGallery | slugify }}/{{ picture.filename | slugify }}/"
description: "{{ picture.title }} from gallery: {{ picture.containingGallery}}"
---
<article>
<h1>{{ picture.title }}</h1>
<div>
{% if picture.previousImage %}
<a href="../{{ picture.previousImage | slugify }}">
<button type="button">Previous</button>
</a>
{% endif %}
<a href="/gallery/{{ picture.containingGallery | slugify }}/">
<button type="button">Gallery</button>
</a>
{% if picture.nextImage %}
<a href="../{{ picture.nextImage | slugify }}">
<button type="button">Next</button>
</a>
{% endif %}
</div>
<figure>
<a href="{{ picture.baseUrl }}/{{ picture.filename }}">
<img src="{{ picture.baseUrl }}/{{ picture.filename }}" alt="{{ picture.altText }}">
</a>
{% if picture.caption %}
<figcaption>
{{ picture.caption }}
</figcaption>
{% endif %}
</figure>
</article>{% endraw %}
```
Et voilà; we have galleries! But before we can call this project done, it would be nice to have a page that lists all galleries on the site for the benefit of visitors. For this, I created `/content/galleries/index.njk`:
``` html{% raw %}
---
layout: layouts/base.njk
eleventyNavigation:
key: Pics
order: 4
---
<h1>Image Galleries</h1>
<p>
Some pictures I thought would be worth posting.
</p>
<section>
<div>
{% for gallery in galleries %}
<article>
<a href="../gallery/{{ gallery.title | slugify }}" class="postlist-link">
<div>
<img {% if gallery.galleryImage %} src="{{ gallery.url }}{{ gallery.galleryImage }}" alt="{{ gallery.galleryImageAlt }}" {% else %} src="{{ metadata.defaultPostImageURL }}" alt="{{ metadata.defaultPostImageAlt }}"{% endif %}>
</div>
</a>
<div>
<a href="../gallery/{{ gallery.title | slugify }}" class="postlist-link">
<h3>
{{ gallery.title }}
</h3>
</a>
<time datetime="{{ gallery.date | htmlDateString}}">{{ gallery.date | readableDate("LLLL yyyy") }}</time>
<p>{{ gallery.synopsis | truncate(105) | safe }}</p>
</div>
</article>
{% endfor %}
</div>
</section>
```{% endraw %}
Note that `readableDate()` and `htmlDateString` are custom filters that came with the [Eleventy Base Blog template](https://github.com/11ty/eleventy-base-blog) that I based my website on. They require Luxon:
``` javascript
eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => {
// Formatting tokens for Luxon: https://moment.github.io/luxon/#/formatting?id=table-of-tokens
return DateTime.fromJSDate(dateObj, { zone: zone || "utc" }).toFormat(
format || "dd LLLL yyyy",
);
});
eleventyConfig.addFilter("htmlDateString", (dateObj) => {
// dateObj input: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat("yyyy-LL-dd");
});
```
You may be thinking that this all seems a convoluted, and I agree! If you know of a simpler way to accomplish this functionality, do feel free to let me know, but for now, I'm just happy that I finally have the ability to add image galleries to this website.
[^1]: Thanks to those who answered [my cry for help](https://lounge.town/@nathanu/113574428382435982)!

View File

@ -0,0 +1,35 @@
---
title: A Perplexing Failure
description: Failing to make the most delicious batch of incense ever.
date: 2024-04-13
tags:
- Incense
- Incense Making
- Incense Builds (Recipes)
synopsis: My grand designs crumble as I fail to make the most delicious batch of incense ever devised.
imageURL: /img/_DSC0079_copy.avif
imageAlt: A small pile of short smooth brown incense sticks on a piece of MDF.
mastodon_id: "112266582201922869"
---
This January, I had grand visions for a sweet, gourmand batch of incense sticks. I'd start with a creamy base of sandalwood, combine it with plenty of guggul resin for that touch of caramel, a dash of warm cinnamon, and a sprinkling of sweet, vanillic tonka bean; these things were going to smell like dessert, like baking cookies, like your high-school English teacher's classroom when her most cloyingly sweet scented candle had been burning for the past four hours.
Things seemed to be going well while making the sticks; the dough smelled incredible, and extrusion was a dream — long, straight noodles that could be manipulated without breaking came one after another. I didn't sense that something might be wrong until I saw the sticks after they'd dried overnight, when I noticed that they were very smooth, compact, and *hard.* They didn't burn, either, which [isn't necessarily the death-knell](../patience) for a batch of incense sticks, but neither is it a good sign.
[![A small pile of short smooth brown incense sticks on a piece of MDF.](/img/_DSC0079_copy.avif "The sticks in question.")](/img/_DSC0079_copy.avif)
It's now three months since the sticks were extruded; they haven't shown any signs of improvement, and I'm left scratching my head. The ingredient ratios in the build I used were based on those of a successful batch; by all estimations, this batch had everything it needed to combust! It may or may not smell nice, but surely, I thought, the batch will burn! Alas, my hubris was met with disappointment. Here's the build I used:
|Ingredient|Grams|% of Build|
|----------|------|-----------|
|Tonka Bean|0.3|5%|
|Cinnamon|0.75|11%|
|Guggul Resin|1.5|23%|
|Sandalwood|3|46%|
|Joss Powder (Litsea Glutinosa)|1|15%|
My best guess as to why this build didn't work out has to do with the cinnamon. I know that some cinnamon varieties are mucilaginous, producing a mucilage (plant slime), when mixed with water. Knowing that gum binders, such as xanthan gum, can cause combustion issues in incense when used in higher concentrations, I suspect that the combination of 15% joss powder plus another 11% of the mucilaginous cinnamon somehow bound the sticks too tightly, preventing combustion.
[![A tiny MHP30 circuit board heater with a little tin of incense powder on top. The heater is shown beside a mostly used blackwing pencil and a fountain pen; it's barely wider than the length of the blackwing ferrule and eraser.](/img/_DSC0014_copy.avif "This dusty wee MHP30 circuit board heater makes a great warmer for incense powders, woods, and resins. The pencil beside it may give you some idea as to just how small it is.")](/img/_DSC0014_copy.avif)
Hypotheses aside, I may never know why exactly this build failed. It's always a shame when a batch turns out to be a complete flop after you've put so much time into carefully grinding and sifting precious aromatics, then kneading, extruding and drying neat little noodles of incense — waiting weeks or months to see whether your hopes for them have come to fruition. But all is not lost after all: when I break up the sticks into small pieces and put them on my mini ~~circuit board,~~ erm, *incense* heater, the fragrance is everything I had thought it might be. I'll content myself with that as I wait for yesterday's batch of rose and myrrh to cure.

View File

@ -0,0 +1,29 @@
---
title: "Incense Review: Hono Sandalwood"
description: "Checking out some sticks from a local store selling Japanese incense."
date: 2025-04-19
tags:
- Incense
- Incense Review
synopsis: "Checking out some sticks from a local store selling Japanese incense."
imageURL: /img/hono_sandalwood/hono_sandalwood_square.webp
imageAlt: "A closeup photo of the small hono Sandalwood box atop a neat row of incense sticks, beside a small shiny white ceramic burner. The burner is plain, and square, with a small hole in the middle in which to insert an incense stick."
mastodon_id: "114367576630950761"
---
I'm forever keeping my eyes peeled for brick-and-mortar stores in my city that sell decent incense, particularly Japanese incense. As such, I was delighted to discover [Five Elements Home](https://www.fiveelementshome.com/) in the beautiful Chicago neighborhood of Andersonville. On my first visit to the store, I darted right past the beautiful imported Japanese ceramics and textiles to the incense section.
My taste in incense is fairly traditional. I tend to enjoy incense that makes use of natural, whole-plant ingredients, and compositions based around classic aromatic woods, spices, herbs, and resins. I did feel a touch let down then upon discovering that the collection at Five Elements Home is decidedly modern. On display are hibi incense matches, paper incense, and sticks with fragrances such as coffee, citrus, and white peach, which are impossible to make with traditional ingredients and processes. As a result, while my partner and I have visited on a few occasions since to buy tea, it was only recently that I decided to take a gamble on some of the incense on offer. I picked up a couple of boxes, including an adorable wee box of hono Sandalwood.
The box, which folds open like a tiny carton of cigarettes, contains thirty little sticks and a small ceramic burner not unlike the ones that come in various Nippon Kodo offerings. Only eight centimeters long apiece, the short sticks are very fragrant out of the box: spice, sandalwood, and a hint of something rather cool—camphor, perhaps? The sticks smell like everything you want in a traditional Japanese style incense stick, but the pungency gives me pause.
[![A closeup photo of the small hono Sandalwood box atop a neat row of incense sticks, beside a small shiny white ceramic burner. The burner is plain, and square, with a small hole in the middle in which to insert an incense stick.](/img/hono_sandalwood/hono_sandalwood_w.webp "I do enjoy the packaging format, and the little burner is a nice inclusion.")](/img/hono_sandalwood/hono_sandalwood_w.webp)
In the burn, Hono Sandalwood opens with an unfortunately powerful hit of burnt sugar. I always try to withhold judgment on a stick until the first ash has fallen; off-notes upon lighting are not at all uncommon.[^1] Still, the strength of this off-note stunned me for a moment. What followed was was mostly spice (predominantly clove, to my nose) and a strong creamy note of Indian sandalwood.[^2] The cooling aspect of the unlit sticks was lost, which came as no surprise as the amount of camphor needed to come through in the burn, although still minuscule, tends to make unlit sticks sing of that characteristic 'frozen-onions' fragrance that borneol imparts.[^3] There is a subtle sweetness present, which I assume is just from the sandalwood as I don't detect the round, vanillic complexity of benzoin.
This is not a stick I want to sit next to as it burns. The fragrance is powerful, and accompanied by the sort of off-notes I'd expect from a cheaper oil-based incense. That burnt-sugar note I mentioned earlier continues quietly throughout the burn also. The fragrance easily fills my office, and it lingers in the room for a while after the stick is extinguished. From a distance, it's not unpleasant; the fragrance itself is inoffensive. I'm actually quite happy to have one of these burning at the far end of the room; my qualm is only that if I was happy to contend with all of these off-notes, I could achieve a similar result by burning a centimeter of a much cheaper Indian style sandalwood stick, rather than paying eighteen US dollars for a very small box of very small sticks of Japanese incense.
One of the gentlemen manning the store mentioned to me that everything in in stock was imported directly to the store from Japan, and is otherwise largely unavailable in the U.S. I love this idea, but still—while these hono sticks aren't going to gather dust in my incense drawer—I expect I may find myself wishing I could have just picked up a box of Shunkohdo Sarasoju for my sandalwood fix instead.
[^1]: For example Baieido's Kobunboku, a favorite at the moment, emits a brief note when lit that reminds me of cigarettes.
[^2]: Reminiscent of Nippon Kodo's Kayuragi Sandalwood sticks, which are also almost certainly oil-based, but I very much enjoy nonetheless.
[^3]: Looking at you again, Kobunboku.

View File

@ -0,0 +1,31 @@
---
title: "Incense Cigarettes? Reviewing Boy Viennas 11:11 Incense Sticks"
description: "Taking a look at Boy Vienna's viral cigarette incense sticks."
date: 2025-05-08
tags:
- Incense
- Incense Review
imageURL: /img/boy_vienna_11_11/boy_vienna_11_11_incense_cigarette_sticks_2.webp
imageAlt: "What appears to be a pack of cigarettes labeled 11:11. There is also a card featuring the brand name Boy Vienna and a temporary tattoo featuring an image of a lipstick-print and the brand name."
synopsis: "Taking a look at Boy Vienna's viral cigarette incense sticks."
mastodon_id: "114462578542598320"
---
[Boy Vienna](https://boyvienna.com/) is a brand from fashion designer and multi-media artist [Afaf Fi Seyam](https://www.instagram.com/zeopatra) that has been receiving attention on [TikTok](https://www.tiktok.com/@boyvienna/video/7366977382508514603) and [Instagram](https://www.instagram.com/zeopatra/reel/DAyIy2Lv0RQ/) for its incense cigarettes. I knew I was going to have to try these sticks the minute they found their way onto my screen—it would seem that [everyone else felt the same way](https://www.instagram.com/zeopatra/p/DJHP0a3NnlI/), as when I made my way to the web store most of Boy Vienna's incense varieties were sold out. For 35 {{ "USD" | abbr("United States Dollars") | safe }}, I was able to snag a box of the 11:11 variety, listed as containing a blend of sage, lavender, and rosemary.
[![What appears to be a pack of cigarettes labeled 11:11. There is also a card featuring the brand name Boy Vienna and a temporary tattoo featuring an image of a lipstick-print and the brand name.](/img/boy_vienna_11_11/boy_vienna_11_11_incense_cigarette_sticks_2.webp "The pack also came with a wee temporary tattoo. Fun!")](/img/boy_vienna_11_11/boy_vienna_11_11_incense_cigarette_sticks_2.webp)
Knowing what I do about incense making, I didn't expect much from these fragrance-wise; I'm not too proud to admit that the novelty of the format and packaging was the main draw here, and barring some qualms about the typesetting, I'm here for it. It's cute. The box looks good on my coffee table, and the format is fun. But speaking of appearances, I do wish I could have gotten my hands on a box from Boy Vienna's [collaboration with athletic apparel brand Wolven](https://web.archive.org/web/20250506164206/https://wolventhreads.com/cdn/shop/files/Incense_0001_IMG_99913_1080x.jpg?v=1705074215), which reminds me of the [Sobranie Black Russian](https://web.archive.org/web/20250506164824/https://cdn.shopify.com/s/files/1/0786/5205/products/pin_514254851190026968_grande.jpg?v=1535441863) and [Djarum Black Kretek clove cigarettes](https://web.archive.org/web/20220216044852/https://www.ciggiesworld.ch/wp-content/uploads/2017/07/Djarum-Black-Kretek-Clove-Cigarette-Wallpaper.jpg) I once (regrettably) enjoyed using to rupture my alveoli.
[![A scan of a page from an old book, showing several illustrations of incense cigarettes made from reeds and decorated with string and woven textiles.](/img/boy_vienna_11_11/boy_vienna_11_11_incense_cigarette_sticks_1.webp "While this is a novel form of incense today, there is actually a history of incense cigarettes in the Americas, per Walter Hough's Censers and Incense of Mexico and Central America.")](/img/boy_vienna_11_11/boy_vienna_11_11_incense_cigarette_sticks_1.webp)
The cigarette format also comes with some distinct advantages. If you do happen to have an ashtray laying around, these sticks will be very convenient. Not having an appropriate burner on hand can be a problem for even those who use incense regularly. Because all of my burners are meant for much smaller Japanese and Chinese style sticks, on the odd occasion I have an Indian-style agarbatti stick to burn I inevitably find myself scrambling around the house looking for some way to secure it. The cigarette-format sticks also light easily, burn consistently, and the ash falls within a small area which helps to keep things clean.
[![A lit incense cigarette held by a pair of ceramic-tipped tweezers.](/img/boy_vienna_11_11/boy_vienna_11_11_incense_cigarette_sticks_4.webp "Unfortunately(?), I don't have an ashtray handy.")](/img/boy_vienna_11_11/boy_vienna_11_11_incense_cigarette_sticks_4.webp)
I was impressed with the fragrance from the trio of herbs immediately upon opening the package; they are clearly high quality ingredients. The lavender especially sings—it's downright juicy. As for the burn, well it turns out that much of that characteristic cigarette smell comes from the paper. This hit me as soon as I lit a stick (which felt very strange without putting the cigarette to my lips). If you've ever burned a bundle of sage, burning a stick of 11:11 is not far removed from the experience. Sage is the predominant note, with occasional bursts of lavender and a good measure of rosemary, with a screaming acrid note of burning-plant matter and cigarettes. Far too much for my small living room, these sticks are very smoky, both in terms of the smell and the literal smoke output, while also being bright, turpenous, and somehow leathery. It reminds me at once of the tail-end of a long night out after one too many pints, while also evoking a cruise down a sunny Texan country road in a hot car with leather seats alongside a friend who indulges too often in both cigarettes and perfume. A good time in both cases, only you're feeling a bit sick.
[![A deconstructed cigarette-format stick, showing the paper, filter, and the contents of the stick separately on a white plate.](/img/boy_vienna_11_11/boy_vienna_11_11_incense_cigarette_sticks_5.webp "I sacrificed a stick in order to take a look at the herbs inside.")](/img/boy_vienna_11_11/boy_vienna_11_11_incense_cigarette_sticks_5.webp)
While I'm not generally in favor of introducing ingredients into incense—such as paper or large amounts of wood binder—that don't somehow add to, enhance, or improve the fragrance, I recognize that the format is the key selling point here, so I don't expect it to change. What I would like to see, however, is some sort of temperature regulation in these sticks. Like putting a chunk of apple in your tobacco pouch, any number of strategies would go a long way towards reducing the harshness of these sticks: a little resin added to the mixture; using a little more pressure when loading; including a fairly oily or resinated fragrant wood as a base; or grinding ingredients more finely. I have a feeling that those used to less controlled methods of burning incense (charcoal, herb bundles, lighting Palo Santo sticks, et cetera) likely won't mind the smoky, acrid notes of plant-matter burning very quickly, but as for myself, I don't imagine I'll light one of these indoors again. I can appreciate a smoky Tibetan stick as much as anyone, but 11:11 was just a bit much for me. That said, when my partner came into the living room after I had burned a stick, they noted that the room smelled nice, so there you go.
Overall, do I regret spending $35 on eighteen Boy Vienna's 11:11 cigarette incense sticks? I don't think so, although it does smart a little that for nine dollars less I could have picked up a box of Minorien's very good [Jinko Fu-In](https://kikohincense.com/collections/minorien-incense-kikoh/products/jinko-fu-in-aloeswood-incense?variant=39598350762072) sticks. Will I be buying them again? Probably not, but I had fun trying them, and that's really all I was after.

View File

@ -0,0 +1,11 @@
---
title: "At Last, My Blog Has a Name!"
description: "New name, who dis?"
date: 2025-07-13
tags:
- Site Updates
synopsis: "New name, who dis??"
mastodon_id: "114848297332289745"
---
Since I started writing here in earnest, I've been enchanted by the idea of having a proper name for my humble blog. I didn't dare put too much thought into it until recently; the task seemed too intimidating. There's a lot to think about after all: Do you choose something dry and professional, at risk of sounding pompous or grandiose? Something pithy, at risk of sounding too cutesy? Or something funny, at risk of not being taken seriously? Well, dear readers, by combining a five dollar word, a play on words, and some perhaps lightly distasteful humor, I've somehow managed to encapsulate all three options in arriving at a name for my blog that is, perhaps unfortunately, very *me.* Introducing: *[The Stochastic Bletherist](/blog)*!

View File

@ -0,0 +1,66 @@
---
title: Setting up a Toggleable Side Panel in KDE Plasma 6
description: Creating a Raven-like side-panel in KDE Plasma 6 that can be toggled with a click using native plasma panels and Scriptinator.
synopsis: Creating a Raven-like side-panel in KDE Plasma 6 that can be toggled with a click using native plasma panels and Scriptinator.
date: 2024-03-18
tags:
- GNU/Linux
- KDE
imageURL: /img/sidePanel/sidePanel_copy.avif
imageAlt: A cropped screenshot of my plasma desktop showing a side-panel on the right side of the screen containing the clipboard history widget and the media player widget. On the bottom panel is the Scriptinator plugin, showing a tooltip the following title&#58; "Show Panel," and body text&#58; "Show the hidden right panel."
mastodon_id: "112119633092992081"
---
Since a brief tryst with [Ubuntu Budgie Edition](https://ubuntubudgie.org/), I've dearly missed its Raven side-panel, a special panel on the side of the screen that can be opened and closed with a click. As someone who *needs* a clean, minimal desktop, the workflow is just too perfect — when you have two or three widgets that you use frequently, but not frequently enough that they warrant permanent homes on a main panel, just stuff them into a disappearing side-panel that can be called with a quick key-combination or by clicking on an icon; It's a great way to keep things out of the way, but within reach, without having a permanently cluttered system tray that you might want to keep clear for things like email notifications.
[![A cropped screenshot of my plasma desktop showing a side-panel on the right side of the screen containing the clipboard history widget and the media player widget. On the bottom panel is the Scriptinator plugin, showing a tooltip the following title&#58; "Show Panel," and body text&#58; "Show the hidden right panel.](/img/sidePanel/sidePanel_copy.avif "My side panel, and the widget that launches it.")](/img/sidePanel/sidePanel_copy.avif)
There are some drawbacks; this workflow isn't well supported on KDE Plasma, so it's a bit of a faff to set up, and only a few widgets will display nicely on a wide side-panel. For instance, it would be a dream to have the KDE weather widget automatically take advantage of the horizontal space and display the information that would usually be in its dropdown, but what you get instead is a giant icon, for now at least. I use my side-panel for my clipboard history and the media player widget, both of which play nicely with a side-panel. Another niggle I have with it is that, as far as I know, there's no way to disable activation of the panel when your mouse pointer makes contact with the screen edge. This is a mild to moderate inconvenience when you're working with applications that have toolbars on the sides of the window, like design applications often do.
For me, personally, the drawbacks aren't so severe as to put me off of the workflow.
## Creating and configuring the panel
First, you'll need to create a panel. To do this, right click on an empty section of your desktop, and select "Add Panel > Empty Panel." When the panel appears, right click it and select "Enter Edit Mode." Set up your panel however you like, but you will need to set "Visibility" to "Auto Hide" and may want to give it a width of at least 400px or so.
[![](/img/sidePanel/panelSettings_copy.avif "The panel settings configuration window.")](/img/sidePanel/panelSettings_copy.avif)
## Setting up the script
Now, if you wanted to show and hide your panel with a keyboard shortcut, you can set up a focus shortcut in the panel settings window and stop here. If, like me, you want to toggle your panel by clicking on an icon somewhere, we're going to have to use a wee script, but don't worry, it's not as hard as it sounds and I'll take you through it step by step.
Before we can put our script together, we're going to need to know what the ID of our panel is. Open up KRunner with Alt+F2 or Alt+Space and run `plasma-interactiveconsole`. This will launch KDE's Desktop Shell Scripting Console. In the console, type `print(panelIds);` and click "Execute." Assuming you entered that in correctly, what you should see now in the output console beneath the text editor is a series of numbers — the ID numbers of our panels. Keep a note of these numbers.
[![The interactive console showing a series of panel IDs printed to the console.](/img/sidePanel/printIDs_copy.avif "Look at those IDs.")](/img/sidePanel/printIDs_copy.avif)
Clear the text editor and enter the following:
```javascript
let panel = panelById(401);
panel.hiding === "autohide" ? panel.hiding = "windowsgobelow" : panel.hiding = "autohide";
```
This will check if our panel is set to auto-hide; if it is, the script will set the panel to "windows go below" mode, otherwise it will set the panel to auto-hide.
Now to make use of those panel ID numbers. Which number corresponds to your new side-panel? While I can't be sure, chances are it's the last number on the list as we've just made the new panel a moment ago. So in the script above, where I have entered 401, enter the last number in your ID list and click "Execute." At this point, if the ID number is correct, your panel should appear; click "Execute" once more to hide it.
## Setting up the Scriptinator widget
Alright, we've got our script ready, so we just need one more thing in place: a button or icon that we can click on to show and hide the panel. Fortunately, we can use a widget called "Scriptinator" to provide just this. Right click on an empty area of your desktop or a panel, click "Add Widgets," and "Get New Widgets."
[![A cropped screenshot of the widgets panel with the "get new widgets" button at the top.](/img/sidePanel/getWidgets_copy.avif "Let's get that widget.")](/img/sidePanel/getWidgets_copy.avif)
From here, find and install Scriptinator. Once installed, simply drag it where you'd like it to live, either on your desktop, or on a panel. Once you've done that, right click on the widget and choose "Configure Scriptinator." Here, enter the path of the icon you'd like to use in "Custom icon full path;" I used `/usr/share/icons/breeze-dark/actions/22/sidebar-expand-right-symbolic.svg`. In "OnClick Script," enter the following:
```bash
qdbus org.kde.plasmashell /PlasmaShell evaluateScript ''
```
and between those single-quote marks, paste in the full script we put together in the Desktop Shell Scripting Console, like this:
```bash
qdbus org.kde.plasmashell /PlasmaShell evaluateScript 'let panel = panelById(401);
panel.hiding === "autohide" ? panel.hiding = "windowsgobelow" : panel.hiding = "autohide";'
```
[![](/img/sidePanel/Scriptinator_copy.avif "The Scriptinator configuration window.")](/img/sidePanel/Scriptinator_copy.avif)
Set up a tooltip if you like, hit apply, and test out your toggle button.
## Success!
If you've done everything correctly, you should see your side-panel appear when you click the widget and disappear when you click a second time. You may need to restart to see your icon applied to the widget; if you don't want to wait, you can drop the file path into "OnClick icon full path" in your Scriptinator configuration.

View File

@ -0,0 +1,21 @@
---
title: "Incense Review: Kheouns Blend"
description: Reviewing Kheouns Blend by The World Makes Scents.
date: 2024-06-23
tags:
- Incense
- Incense Review
synopsis: Reviewing Kheouns Blend by The World Makes Scents.
imageURL: /img/kheouns-blend-incense-sticks.webp
imageAlt: A partially opened box of incense sticks
mastodon_id: "112668846624633338"
---
There is a reason that much incense on the market makes extensive use of fragrance oils: it's simply easier. As returning readers [will know,](https://nathanupchurch.com/blog/gourmand-sandalwood-incense-a-perplexing-failure/) blending combustible incense made with plain old plants is extraordinarily difficult, even when only using two or three ingredients. [The World Makes Scents](https://theworldmakesscents.com/) is a Chicago-based incense maker that does just that. Their Kheoun's Blend incense sticks are based on a unique blend of plants introduced to the team by Kheoun, [a traditional incense maker based in Cambodia](https://blog.rauchfahne.de/en/2023/07/18/the-world-makes-scents-en/).
[![A partially opened box of incense sticks labelled "Keoun's Blend"](/img/kheouns-blend-incense-sticks.webp "Kheon's Blend incense sticks.")](/img/kheouns-blend-incense-sticks.webp)
The twelve sticks in my order came extremely well packaged, in a sturdy paper-over-board box with with a layer of batting both on top and beneath the sticks to prevent breakage in the post. The back of the box describes the product within as "Incense as it was made for thousands of years before industrialization and greed." I'm all for it. The hand-extruded, coreless sticks are light brown in color, roughly 185mm long, very thick at around 3.5mm, and just a little wiggly. There is a sweet, baking-spice fragrance on the unlit sticks.
I've long felt that you can't get a proper impression of the character of a stick of incense before the first ash has fallen. Often, incense briefly smells quite harsh when initially lit. Interestingly, in that first half-second of lighting, these sticks briefly emit a rather pleasant campfire / wood smoke scent. As the stick begins to burn in earnest, however, I'm met with an almost Tibetan herbaceousness, a stevia-leaf like sweetness, notes of cinnamon, anise, and sage, with occasional wafts of something bright and camphorous.
Overall the fragrance is very pleasant. Subdued baking-spice notes sit alongside a sage-like herbaceousness atop a mellow, ever-present sweetness, which is lifted by a blink-and-you'll-miss-it camphor note. Excellent temperature modulation keeps this blend very fragrant throughout; smoke production is modest for a stick of this size, and the fragrance in the burn is very much like that of the unlit stick. This is a very interesting stick unlike anything I've burned before; absolutely worth experiencing, and a great incense to burn in the living room when you have company.

View File

@ -0,0 +1,39 @@
---
title: "Learning to Love Myrrh: Myrrh & Rose Incense"
description: "I finally figure out how to make myrrh work in a composition."
date: 2024-08-05
tags:
- Incense
- Incense Making
- Incense Builds (Recipes)
synopsis: "I finally figure out how to make myrrh work in a composition."
imageURL: /img/pexels-david-roberts-940521-8323579.webp
imageAlt: A beautiful light-pink dog rose, rosa canina.
mastodon_id: "112909867440319574"
---
Myrrh can be a challenging note. I've seen the resins collected from various members of the Commiphora genus described as everything from loamy, bitter, and mushroomy, to reminiscent of cleaning fluid or a dental clinic; whatever impression you take from the fragrance of myrrh resin, there's no denying that it's unique; there is no mistaking myrrh. While I'm rarely a fan of myrrh alone, or as the predominant note in a sparse composition, I've always felt that there is something compelling about it. Despite its overall unpleasantness, I find heated myrrh resin to produce a dark, mysterious, and somehow sexy fragrance. When balanced well, such as in *Mystic Jade* from Shoyeido's *Magnifiscents* collection, it adds a wonderful, earthy warmth to a composition that's hard to beat.
For some time I've struggled to incorporate myrrh into a stick that I can be proud of; it isn't a resin that you can just drop into a composition with the expectation that it'll work. My experiments with commiphora kua, opoponax, and wightii have all ended in disappointment… until recently.
I've long had an inkling that myrrh would pair well with rose. It's challenging to incorporate flowers into combustible incense; some say it's close to impossible to do without winding up with an incense that smells of acrid burning plant material with, if you're lucky, a touch of whatever flower you've added. Certainly, I have realized that often other methods of incorporating floral fragrances work best. Recently I have discovered, however, that if you start with very good material, and methodically try varying ratios in a series of trail-burning tests, you may wind up surprised by how close a fragrance you can achieve to the fragrance of fresh flowers while minimizing acrid notes. For instance, in my testing, I found that a combination of 30% Rosa Canina and 70% Santalum Spicatum, both very high quality powders given to me by [Dave of *The World Makes Scents*,](../visiting-chicago-incense-maker-dave-of-the-world-makes-scents/) smells absolutely wonderful.
[![A beautiful light-pink dog rose, rosa canina.](/img/pexels-david-roberts-940521-8323579.webp "Rosa Canina in bloom, by [David Roberts on Pexels](https://www.pexels.com/photo/close-up-shot-of-a-dog-rose-in-bloom-8323579/)")](/img/pexels-david-roberts-940521-8323579.webp)
With that knowledge, I composed a stick featuring myrrh, rose, and sandalwood. While the build isn't perfect, I'm already really enjoying the small batch of sticks that I made only a few days ago. The fragrance is gentle and powdery, with a hint of smoke, a soft rose note and that fruitiness that occurs when rose petals are heated. Benzoin lends a subtle sweetness alongside the sandalwood, while the myrrh adds it's unmistakable fragrance and a bittersweet molasses note. The whole ensemble is lifted and brought together by a smidgen of borneol camphor. The myrrh reduces the need for binders, so I've gone with a weak binder, acacia gum, which also helps to firm up and strengthen the extruded sticks once dried.
## The Build
Note that this is a test build that produces less than four grams of dough; you may want to double the amount.
|Ingredient|Grams|% of Build|
|-|-|-|
|Myrrh Resin (Commiphora Kua) |0.2|5.6%|
|Rose Petal (Rosa Canina)|1|27.9%|
|Sandalwood (Santalum Spicatum)|2|55.9%|
|Benzoin Siam|0.14|3.9%|
|Acacia Gum|0.2|5.6%|
|Borneol Camphor|0.04|1.1%|
## Thoughts
I really like this stick, but I do think that it could stand some improvement. Some spices might round out the profile a little, maybe a little clove and cinnamon. It's not the *cleanest* fragrance in the world, likely due to both the myrrh and the high ratio of flowers, but I have been finding it incredibly moreish nonetheless. I hope someone will try to make this and let me know their thoughts!

View File

@ -0,0 +1,17 @@
---
title: Let Us Waffle
description: Tools like cooked.wiki let us strip away the cruft from online recipes. Is this necessarily a good thing?
date: 2024-01-24
tags:
- Vegan Cooking
- Quick Thoughts
synopsis: Tools like cooked.wiki let us strip away the cruft from online recipes. Is this necessarily a good thing?
imageURL: /img/pexels-brigitte-tohm-378008_compressed.webp
imageAlt: An oddly rectangular waffle covered in raspberries. It actually looks quite dry and not very nice. Hopefully there's some syrup on the side!
mastodon_id: "111812478768090324"
---
So, about this [cooked.wiki](https://cooked.wiki) thing, believe me when I say I take my fair share in our collective frustration as I find myself skimming through a hugoesque tome on Brayden and Braxlynnes wiggly teeth in order to reach the ingredients for “Keighleighs Extra Easy No-Bake Ten Minute Palmiers (*So Delicious Youll Snort the Crumbs!*),” but I must admit that the endless complaining about it puts me out a bit. Heres the thing; as someone who writes for his own personal blog, who plans to someday publish a recipe or two, *the waffling is the point.*
Keighleighs recipe blog isnt a cookbook. No one is paying a subscription fee to access her recipes, nor is her little wordpress site a public amenity. If Keighleigh is anything like me, she writes for the joy of it. Our hypothetical author here may not really be setting out to write *recipes* at all. In all likelihood, she sees herself as writing prose about her life and the things she enjoys talking and thinking about, while also taking the time to record her recipes for the benefit and enjoyment of the reader who stumbles across her home on the internet. Only wanting to share what brings her joy with others, she doesnt ask much so why not just skim? Is it really such a tall order?
Now Im not naïve; there are surely authors out there inflating their wordcount for SEO purposes, hoping to eke out an extra dollar or two from a smattering of banner ads and affiliate links. I know there are accessibility concerns also. Valid reasons abound for using a tool like Cooked; I even took the time to add [structured data](https://yoast.com/what-is-structured-data/) to my website to help others use my work in interesting and helpful ways. Theres just something downright bleak, however, about seeing the meat of my prose shelled wholesale by a piece of proprietary software, stripped down to mere data, devoid of all context and humanity. While Im not suggesting that no one should use tools like Cooked; I am asking that they maybe consider the author first. Besides that, instant gratification can be rather ungratifying isnt fiddling with the shell half the fun of eating a pistachio?

View File

@ -0,0 +1,75 @@
---
title: "Making Incense: A Cursory Guide"
description: A quick how-to on making Japanese style incense.
date: 2024-12-16
tags:
- Incense
- Incense Making
synopsis: A quick how-to on making Japanese style incense.
imageURL: /img/siftinsagesquare.webp
imageAlt: A sieve containing fluffy ground green sage beside a small pile of fine green powder.
mastodon_id: "113666537272260557"
---
While I like to post incense builds, I haven't yet posted on exactly how to go about turning raw ingredients into Japanese style incense sticks. Here's a 1,000 mile overview of the process to accompany a video I recently uploaded to my new PeerTube instance on that very topic. For more info, you can check out [IncenseDragon](https://www.youtube.com/c/IncenseDragon) on YouTube, read this [very useful article](https://blog.rauchfahne.de/en/2023/02/19/making-your-own-incense-sticks-basic-knowledge-and-useful-information/) by Irene of Rauchfahne.de, peruse [incensemaking.com](https://incensemaking.com), and look through some [posts flaired with "incense making"](https://www.reddit.com/r/Incense/?f=flair_name%3A%22Incense%20Making%22) on the [incense subreddit](https://reddit.com/r/incense). Making incense is a difficult, involved process, and this is only a shallow overview; I highly recommend looking through these resources for more in-depth information.
<figure><div style="position: relative; padding-top: 56.25%;"><iframe title="Japanese Style Incense Making Process" width="100%" height="100%" src="https://makertube.net/videos/embed/8864549d-204b-4f48-884e-ca912cf4235c" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups allow-forms" style="position: absolute; inset: 0px;"></iframe></div><figcaption>More or less the full process of making incense. It didn't go perfectly, but I think it's important to show that too. This is also the first time I've attempted to make a video like this; making incense is hard as is, let alone while trying to film the process!</figcaption></figure>
## What you'll need: the bare minimum
1. A scale
2. A mortar and pestle
3. A 140 mesh sieve
4. An extruder
5. A drying screen
6. A respirator
### A scale
If you can, get something quite fine, like a milligram scale. This will help you make very small test batches before you commit to a build.
### A mortar and pestle
You can't get all your ingredients pre-powdered, so you're going to need something to crush resins and grind herbs. It's a labor intensive method, but it produces very little heat - perfect for delicate aromatics. At some point, you'll likely want to expand your grinding capabilities, especially if you want to grind your own woods, but that's a topic for another time.
### A 140 mesh sieve
100 microns seems to be the magic number for incense powders; ingredients reduced to this size perform better in terms of fragrance, and ease of extrusion. Your sticks will burn more slowly, and you'll be able to use less binder in the dough. Sieve carefully, allowing only the finest particles to pass through.
### An extruder
I use [one of these (not an affiliate link)](https://www.aliexpress.us/item/3256804509917099.html). There are many options available, but try to find an extruder that gradually comes to a point rather than one that takes interchangeable plates - they'll produce rough sticks. Also avoid anything made of plastic; I promise you it won't be strong enough.
### A drying screen
Again, there are many options, some of which you may have already laying around. I use [one of these (also not an affiliate link)](https://www.aliexpress.us/item/3256806230786054.html).
### A respirator
I almost forgot to mention this, but [as Irene points out](https://blog.rauchfahne.de/en/2023/02/19/making-your-own-incense-sticks-basic-knowledge-and-useful-information/) this is an important piece. Inhaling fine powders of any kind is very very bad for you. Don't mess about with this one: use a proper respirator, or at least a well-fitted n95 mask.
## Coming up with a build
If you don't have a build / recipe to go by, it can be a challenge to work out what ingredients to use and in what proportions. While you can find builds in many places, eventually you're going to have to sit down and do some testing. Fundamentally, incense is comprised of three key components: base, binder, and aromatics. Some ingredients can occupy more than one of these categories. It's difficult to give even rough ratios for these components, because they will differ wildly with the specific ingredients used. What I recommend is combining ingredients in different ratios and burning them as a trail on a bed of ash, little by little. For instance, try burning a trail of 70% sandalwood and 30% frankincense. How does it burn; does it stay lit? Which fragrance is more prominent? Is it aromatic, or mostly smoky? How does this build change when 10% of the sandalwood is exchanged for lavender, or patchouli? Once you've got a fragrance you're happy with, incorporate some binder and try to burn again.
I could write extensively on this piece alone, but for now, here are some general rules to get you started:
* Herbs and flowers quickly become acrid unless used in low percentages. In [my Silver Tip build](../silvertip/), for example, I can only get away with 10% osmanthus flowers before my build begins to smell bad.
* Oily woods such as mid to high quality sandalwood, palo santo, and agarwood can be used at high percentages without smelling too smoky.
* Resins are good not only fragrant, but some can be used for binding and temperature regulation. Too much will prevent your sticks from burning, so work your way up slowly with resins.
* Less is more. It's always tempting to cram as much of an aromatic material into a stick as you can. Instead, try to see how little you can get away with for a more refined profile.
* Gum binders such as guar gum, xanthan gum, and tragacanth can be used at very low percentages — I've seen as low as 3%. Wood binders such as litsea glutinosa can require much larger percentages. After you've successfully incorporated a binder into the sample you used for a trail-burn test, try adding a drop or two of water and rolling a small stick by hand to see how the dough performs.
## Grinding
Possibly the most difficult aspect of incense making, the key to grinding quality powders is to keep things cool. Use electric grinders in short bursts, allowing ample time to cool, or use methods that generate less heat. Not only does heat release aromatics that you want to retain, resins get sticky. If using a mortar and pestle, it can help to freeze resins along with your mortar and pestle to keep from gumming up the works. It may be easiest to buy pre-powdered woods at first; while resins and herbs aren't especially difficult to powder at home, grinding wood is another beast altogether.
## Sieving
Sieve slowly and gently, being careful that only the finest particles pass through the screen. The best advice I can give here is to try to enjoy the time you spend sieving as best you can, because you're going to be spending a lot of time this way.
## Forming a dough
First thoroughly blend together your dry powdered ingredients, then add water with great trepidation while stirring until a dough begins to come together. As soon as you are able, knead this dough with your hands, adding water as necessary to form a smooth dough that doesn't crack when rolled into a ball. Too much water will result in a difficult extrusion and more warping during drying; too little will result in an even more difficult extrusion. Aim for the consistency of clay.
## Extrusion
Load the dough into your extruder, being very careful to avoid introducing any air bubbles. Carefully extrude the incense either onto a board, or directly onto your drying screen.
## Straightening and drying
Trim your sticks into even lengths while wet, and gently roll them with either a board, or your fingers, until they are straight. Carefully lay them side by side on your drying screen, and place a board against the length of the sticks to prevent too much horizontal warping as they dry. Cover the sticks with another board to prevent vertical warping, and allow the sticks to dry slowly over the course of a day or two.
## Curing
Although your incense may appear dry, it can take some time for much of the moisture to work its way out. Ingredients also benefit from time for the aromatics to settle and meld together into a cohesive composition. Give your sticks a couple of weeks before you judge them too harshly; you may notice changes in fragrance for up to a year.
## Conclusion
This is how I make my sticks, which I extrude to ~2mm and about 10" long to be broken into 5" lengths after drying. Hopefully, any builds I post here ought to work when extruded to this size in the way I have described; all sorts of factors affect incense fragrance and its ability to burn, so I can't make any guarantees as to how your incense will turn out if you follow one of my builds for a different extrusion diameter.
Incense making is a dying art even in cultures with strong incense traditions; it's a laborious exercise that requires extensive trial and error, but the results can be beautiful in ways that no other art-form can emulate. Unfortunately, incense makers tend to be opaque with their practices, and information is scarce in the English speaking world, so it is my hope that this guide can be a useful launching point for someone wishing to start down the fragrant path.

View File

@ -0,0 +1,173 @@
---
title: "Building a Quiz System With Eleventy"
description: "Remember when internet quizzes were a thing? I wanted to bring them to my website."
date: 2025-02-04
tags:
- Site Updates
- Eleventy
synopsis: "Remember when internet quizzes were a thing? I wanted to bring them to my website."
imageURL: ""
imageAlt: ""
mastodon_id: "113948404881440370"
---
You might seen my [recent toot](https://lounge.town/@nathanu/113936929893588739) about the [fancy new "How Much of a Linux Nerd are You?" quiz](/quizzes/how-much-of-a-linux-nerd-are-you/) on my website. Some time ago, I realized that I missed taking fun internet quizzes and decided to implement a quiz system on my own site that would allow me to easily make fun quizzes to share. Here's how I built it with [Eleventy](https://www.11ty.dev/).
## The plan
First, I had to decide what sort of quizzes I wanted to be able to make. Some quizzes are designed to score the quiz-taker in order to place them into a category at the end, like those fun Buzzfeed quizzes that used to be so popular. Other quizzes are designed to test the quiz-takers knowledge of a subject, with each question having a definite right answer. I wanted to be able to do both, and I wanted my quizzes to be fairly flexible.
I decided to arrange things so that the quiz-author can enter any number of questions, answers, and consequences. While any number of answers can be entered for a given question, only one answer can be selected at a time, and every question must be answered. Each answer is assigned a number of points by the quiz author: positive, negative, or zero, and consequences each have a certain points threshold after which they are eligible to appear.
A consequence is a result that appears in a modal when the quiz-taker clicks the "submit" button at the end. It shows text defined by the quiz author, an image if the author chooses to include one, and it contains a "Score Details" dropdown that shows the number of points scored on each question.
I decided that I didn't want to use a global data file, not only because it isn't terribly ergonomic, but also because it's much simpler to take advantage of Eleventy's tag/collection system when possible, and frankly, I hoped to avoid some of the faffing about I had to do when [implementing image galleries](/blog/galleries/).
## Setting up the content directory
As I was going to use markdown files to build my quizzes, I needed to set up a content directory, `/content/quizzes/`, and set some defaults in `/content/quizzes/quizzes.11tydata.js` to make sure that everything I put inside of it was automatically tagged as a quiz, and would use the correct layout.
```javascript
export default {
tags: ["quiz"],
layout: "layouts/quizzes.njk",
};
```
By tagging these files as quizzes, a new [collection](https://www.11ty.dev/docs/collections/) containing all of my quizzes will be created, and I can add this collection to the `filterTagList` filter in my config file that allows me to easily omit everything that isn't a blog post from post-lists on my site, but that's out of scope for this article.
## Quiz Structure
YAML (or in fact any markup or programming language that respects whitespace) is no fun, but at least I won't wind up with a gargantuan JavaScript data file like I have [for my galleries](https://upchur.ch/gitea/n_u/nathanupchurch.com/src/branch/main/_data/galleries.js). Here's what `/content/quizzes/my-quiz.md` might look like:
``` yaml
---
title: ""
description: ""
date: 2025-02-04
imageURL: ""
imageAlt: ""
consequences:
- title: ""
points: 0
spiel: ""
image: ""
imageAlt: ""
questions:
- title: ""
image: ""
imageAlt: ""
imageCaption: ""
answers:
- name: ""
points: 0
---
This is a great quiz that I'm sure you'll have fun taking.
```
This results in a nice JavaScript object we can iterate through. In the body of the markdown document, beneath the front matter, is the text that can be injected via `{% raw %}{{ content }}{% endraw %}`. You'll see in a bit that this will go at the top of the quiz, beneath the title, which is injected with my post layout. This is so that it's easy to use markdown to style this part of the content, include images, et cetera, without worrying about trying to get that working while including it in the YAML.
## The quiz layout
Alright! Now that we have the quiz structure nailed down, we can write `/includes/layouts/quizzes.njk` which will iterate through the data and spit out an HTML form for us. I'm using the loop index number as the question number, which I can also use to set the `name` attribute for each of the answer `<input>` elements related to a given question. By doing this, the browser knows that the answers beneath a question are all related and will only allow the quiz-taker to select one of them.
I'm going to add a link to our yet-to-be-written script here and set the form to call `handleQuizSubmit()` on submit (`return false` prevents the page from refreshing when the submit button is clicked). Don't ask me why I put the script there precisely; as it isn't called until the submit button is clicked, I suppose it could go just about anywhere.
The points threshold for each consequence is stored in the [dataset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset) `data-points-threshold` so that we can use these numbers in our JavaScript.
The answers are assigned an ID that looks like this: `q[questionNumber]a[answerNumber]`. Beyond using this to also populate the `for` property of their respective labels, you could use this to link to individual answers too.
```html
---
layout: layouts/post.njk
structuredData: none
---{% raw %}
{{ content | safe }}
<section class="quiz">
<form onsubmit="handleQuizSubmit(); return false">
{% for question in questions %}
{% set q = loop.index %}
<div class="questionBox">
<p class="quizQuestion">{{ q }}. {{ question.title }}</p>
{% if question.image %}
<figure>
<a href="{{ question.image }}">
<img src="{{ question.image }}" alt="{{ question.imageAlt }}">
</a>
{% if question.imageCaption %}
<figcaption>{{ question.imageCaption }}</figcaption>
{% endif %}
</figure>
{% endif %}
<div class="answersBox">
{% for answer in question.answers %}
<div class="answerBox">
<input class="answer" type="radio" value="{{ answer.points }}" id="q{{ q }}a{{ loop.index }}" name="{{ q }}" required>
<label for="q{{ q }}a{{ loop.index }}">{{ answer.name }}</label>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
<script src="/js/quiz.js"></script>
<button>Submit</button>
</form>
</section>
{% for consequence in consequences %}
<dialog class="consequence" data-points-threshold="{{ consequence.points }}">
<h2>{{ consequence.title }}</h2>
<p>{{ consequence.spiel }}</p>
{% if consequence.image %}
<img src="{{ consequence.image }}" alt="{{ consequence.imageAlt }}">
{% endif %}
<details>
<summary>Score Details</summary>
<p class="scoreDetails"></p>
</details>
<form method="dialog">
<button>Thanks</button>
</form>
</dialog>
{% endfor %}{% endraw %}
```
All of the consequences are rendered as `<dialog>` elements that we can open as a modal later with our script. And look, I know people have opinions about JavaScript, but I really didn't fancy the extra build time, bandwidth, and effort it would have taken to avoid fourty lines of simple JavaScript, and to be honest, I *like* JavaScript. I think it's useful and fun to write, so there.
## The quiz script
As far as logic goes, in `/js/quiz.js` we first want to calculate the score, and get the data to populate the `<details>` elements in our consequence modals. This is handled by `score()`, which will return an object containing the total number of points scored and an array containing the points scored on each question. When we have that, we'll go ahead and `populateDetails()` and finally use `dishOutConsequences()` to launch the freshly updated `<dialog>` as a modal via `showModal()`.
```javascript
const score = (answers) => {
let total = 0;
let scores = [];
for (let i = 0; i < answers.length; i++) {
const questionNumber = answers[i].name;
if (answers[i].checked) {
total += Number(answers[i].value);
scores.push({
questionNumber: questionNumber,
points: answers[i].value,
});
}
}
return { totalPoints: total, scores: scores };
};
const dishOutConsequences = (consequences, points) => {
for (let i = consequences.length - 1; i >= 0; i--) {
if (points >= Number(consequences[i].dataset.pointsThreshold)) {
consequences[i].showModal();
return;
}
}
};
const populateDetails = (detailsElement, scores, total) => {
detailsElement.innerHTML = `Total Score: ${total} points<br />`;
for (let i = 0; i < scores.length; i++) {
detailsElement.innerHTML += `<br />Question ${scores[i].questionNumber >= 10 ? scores[i].questionNumber : "0" + scores[i].questionNumber}: ${scores[i].points} points`;
}
};
const handleQuizSubmit = () => {
const answers = document.getElementsByClassName("answer");
const consequences = document.getElementsByClassName("consequence");
const details = document.getElementsByClassName("scoreDetails");
const totalPoints = score(answers).totalPoints;
const scoreDetails = score(answers).scores;
for (let i = 0; i < details.length; i++) {
populateDetails(details[i], scoreDetails, totalPoints);
}
dishOutConsequences(consequences, totalPoints);
};
```
And with that, our quiz ought to be operational! After this, I went ahead and listed my latest quiz on my index page, but that's beyond the scope of this article. It took me some time to get around to finishing this, but as you can see, it wasn't terribly difficult at all. I hope you enjoyed reading about how I built my quiz system. Please let me know if you decide to implement something similar!

View File

@ -0,0 +1,46 @@
---
title: "Incense Review: Maroma Sandalwood and Cedarwood"
description: "Whole Foods replaced Shoyeido with these sticks from Auroville. I cannot fathom why."
date: 2025-02-22
tags:
- Incense
- Incense Review
synopsis: "Whole Foods replaced Shoyeido with these sticks from Auroville. I cannot fathom why."
imageURL: "/img/maroma_packaging.webp"
imageAlt: "Two paper incense sleeves on my couch. One is yellow and the other is orange."
mastodon_id: "114050541028761876"
---
Some time ago I as I perused the incense display of a nearby Whole Foods, hoping to see the Shoyeido sticks that once graced the shelves, I noticed a range of Indian-style sticks, their otherwise matching packaging in a variety of colors. Listed prominently on each package was the text: "Incense of Auroville." This caught my attention. Auroville is an intentional community I've had a passing interest in since I discovered that some shampoo bars I had purchased were made there[^1]. Often, Indian-style incense makes *heavy* use of oils, which I'm [not a great fan of](/blog/what-do-we-expect-from-fragrance/). The sandalwood and cedarwood varieties, however, listed fairly harmless looking ingredients. According to the packaging, both contained a bamboo stick, wood powders, macchilus macaranth (tree bark powder), with the addition of either sandalwood, or cedarwood, pine, and juniper, respectively. With all of this in mind, I snagged a couple of sleeves.
## Humor me while I appreciate the packaging
As a former print broker and a current designer and print nerd, I first have to take a second to admire the packaging.
[![Two paper incense sleeves on my couch. One is yellow and the other is orange.](/img/maroma_packaging.webp "I know they're not terribly exciting visually, but hear me out.")](/img/maroma_packaging.webp)
Sure, it's not cutting edge design, but this packaging was produced by someone who knows what they're doing. The sleeves appear to be litho printed on colored card-stock (between 200 and 250 g/m2[^2] if I were to guess) in four opaque inks[^3], with a nice metallic silver ink on the cedarwood sleeve. The sleeves are comprised of a single die-cut and scored piece that folds over on itself and is glued together, which would explain the large peg-hole[^4] that would accommodate for potential registration issues when glued and folded. The card-stock is also embossed with a subtle texture: linen for the sandalwood sticks, and a pebbled texture for the cedarwood.
I need you to understand that *hardly anyone* designs print like this anymore. In today's world of digital presses and cheap, mass-produced CMYK printing a la [Vistaprint](https://www.vistaprint.com/), this is not a cheap job. While many outsourced print work for SMEs goes to these large budget printers who run hundreds of jobs at once as quickly and cheaply as they can on standard house stocks, for these sticks, an honest-to-god clunking metal press was set up specially for each sleeve variety. This mode of production used to be standard, but is now largely considered higher-end. While Maroma's packaging is not quite on the same level in terms of process and materials, it does remind me of the kind of print I used to produce for clients like [Reid & Taylor](https://bondwiththebest.com/home/), or [Torrance Yachts](https://torranceyachts.com/). You love to see it. Not every product needs to be printed in full-color on bright-white gloss coated card-stock like a damned cereal box!
## Sandalwood
Now, on to the actual incense. Despite the ingredients list, the fragrance on the unlit sticks leads me to suspect that some oil may have been used. If this is the case, it has been used sparingly as this is not a strongly scented stick, neither before nor after it has been lit. During and after the burn, I don't detect any of the off-notes that mark the presence of large quantities of burning oils. The mild sandalwood fragrance smells more Australian than Indian to my nose; it's on the dry side, with little to none of that butteriness you might expect from santalum album.
[![A stick burning in a blue ceramid censer from Shoyeido on my coffee table. In the background you can see a pair of glasses, a mug, and a brass tealight incense warmer on a pile of glass coasters.](/img/maroma_sandalwood.webp "Fortunately, the fragrance of this stick will not soak into your soft furnishings. I can't say the same for the next one…")](/img/maroma_sandalwood.webp)
There is a wood-smoke note that comes through just as much as the sandalwood does, rendering the fragrance not a particularly clean one, especially when compared to something like Shunkohdo's delightful Sarasōju sticks. It's hard to say whether this comes from the "wood powders" mentioned in the ingredients list, the bamboo stick, a high burn-temperature due to stick thickness or the coarse grind of the ingredients, or all of the above—not that I mind a bit of smokiness in incense—I often quite enjoy this quality in Tibetan and Cambodian style sticks, but it really isn't what I'm looking for in a sandalwood stick.
Overall, Maroma's sandalwood sticks offer a mild, sweet, and earthy wood-smoke and sandalwood fragrance that is more inoffensive than pleasant; nonetheless, the sleeve I purchased is now empty.
## Cedarwood
Despite listed ingredients, this stick is very clearly oil-based. As opposed to the sandalwood sticks, which are wrapped in paper inside their card-stock sleeve, the cedarwood sticks come wrapped in plastic, presumably so as to prevent porous wrapping-paper from wicking up any oils.
The fragrance on the stick is very strong, soapy, and turpenous—even lavender-like. The experience of smelling the unlit stick reminds me a bit of using those pungent [inhalers for nasal congestion](https://www.amazon.com/Benzedrex-61023-Nasal-Decongestant-Inhaler/dp/B000X76K04); it's not exactly a pleasant experience, but you somehow want to keep doing it anyway. The fragrance upon lighting is bright, acidic, and juniper-forward. As the scent builds in the room, the cologne-like fragrance becomes increasingly sharp; after only a few minutes of burn time in my reasonably large office with a tall cathedral ceiling, it has utterly saturated the room and now evokes an under-ripe granny-smith apple. There is a moderately strong 'burning oil' off-note, as well as a spicy wood-smoke, similar to the that in their sandalwood stick. I am sure that the fragrance would be pleasant absent those off notes and its eye-watering strength, but as it is, it smells more like someone's lit a cigarette in the supermarket cleaning-chemical aisle.
## Conclusion and further reading
While I didn't mind having a sandalwood stick from Maroma burning, the cedarwood variety could not be further from the style of incense that I typically enjoy. [Like Irene of Rauchfahne](https://blog.rauchfahne.de/en/2024/11/23/pema-of-tibet-faircense-sandelholz-en/), my recommendation would be that those wanting a plain sandalwood fragrance look to Japanese style sticks, and unless you have a cathedral to fill with fragrance, I'd avoid the cedarwood too (and even then I'd prefer a thurible of frankincense).
If you'd like to read more, [Irene](https://blog.rauchfahne.de/en/category/reviews-en/reviews-sorted-by-brand/auroville-mereville-trust/), [Mike (?) of Olfactory Review Service](https://olfactoryrescueservice.wordpress.com/2009/12/18/sampler-notes-maroma-scented-mountain/), and [Steve of Incense in the Wind](https://incenseinthewind.blogspot.com/search?q=auroville) have written about a number of sticks that also appear to have been made in Auroville.
[^1]: My impression of the place, from the couple of videos I've watched about it, is that it's another landing site for wealthy, predominantly white, people who have a vague sense that something isn't quite right with western society / capitalism, but rather than confront this idea intellectually, investigate any sort of political theory, and organize / engage in mutual-aid, they choose to settle like kombucha sediment into some nebulous, ill-defined form of spirituality involving psychedelics and loose-fitting trousers. I could be wrong though.
[^2]: See [grammage](https://www.neenahpaper.com/resources/paper-101/glossary-of-terms#G) on Neenah Paper's online glossary.
[^3]: The two on the front, plus black and white ink on the back.
[^4]: Get your mind out of the gutter!

View File

@ -0,0 +1,17 @@
---
title: "A New Audio Web Component; Ballin"
description: "I've gone and built a not-so-fancy audio component for my blog."
date: 2024-10-23
tags:
- Music
- Site Updates
synopsis: "I've gone and built a not-so-fancy audio component for my blog."
imageURL: /audio/covers/ballin.webp
imageAlt: An uncapped fountain pen on top of a pretty, gold-foiled pad of paper beside some envelopes with stamps featuring coffee drinks on them.
mastodon_id: "113360498256457079"
---
Fresh from [my text editor](https://kate-editor.org/) comes a neat little web component that packages the native HTML `<audio>` tag inside a `<figure>` with a song name, title, and a graphic — an album cover perhaps. Here's what it looks like, featuring a very catchy drum and bass tune, "Ballin'," by Vibe Chemistry:
{% audio "Ballin", "Vibe Chemistry", "/audio/ballin.mp3", "/audio/covers/ballin.webp" %}
It's pretty basic for now; it doesn't even truncate an over-long title, but it'll do the job for the moment. My hope is to use this to play short song snippets so that I can talk about and review them. I think this falls pretty squarely under "fair use" in the United States, and there's no admin for litigious record companies to complain to but myself anyway; coincidentally, direct all copyright complaints to [me](/me/) to have any decent snippets of your IP replaced with samples of significantly lower quality.

View File

@ -0,0 +1,29 @@
---
title: Making Two New High Contrast Themes for KMines
description: My first KDE contribution! Two new high-contrast KMines themes that will arrive with Plasma 6.
date: 2024-01-20
tags:
- KDE
- FOSS/FLOSS
synopsis: My first KDE contribution! Two new high-contrast KMines themes that will arrive with Plasma 6.
imageURL: /img/kmines_dark.webp
imageAlt: A screenshot of the KMines game window showing a new dark theme.
mastodon_id: "111794936518292495"
---
## Why KMines?
Minesweeper is a tragically underrated puzzle game. While I recall examining the mysterious array of gray squares as a child, it wasn't until adulthood that I took the time to learn the rules of the game. Despite my late start, however, I still count minesweeper as a classic. These days, good minesweeper clones are hard to come by. I settled on GNOME's [Mines](https://wiki.gnome.org/Apps/Mines) for a while, but as the look of GTK applications on my QT-based [KDE Plasma Desktop](https://kde.org/plasma-desktop/) sets my teeth on edge, I ditched it for [KMines](https://apps.kde.org/kmines/) in short order. While I enjoyed the game, I found the themes shipped with KMines a bit dated, so I thought I'd make my own.
[![A screenshot of the KMines game window showing a new dark theme.](/img/kmines_dark.webp "The Clean Blue Dark KMines theme")](/img/kmines_dark.webp)
## The Drama
I didn't quite know what I was getting into when I started working on my themes. I had expected there'd be a simple way to add themes through the KMines settings menu, or by dropping an SVG somewhere in your file-system. If only it were so simple. Adding a theme to KMines requires setting up a full-on KDE development environment, re-compiling KMines from source each time you want to test it, and then, of course, submitting a merge request to the git repository. Thanks to the help of some very patient souls in various KDE Matrix channels, I was able to work through all of this, but I found the process so tricky that I submited a second merge request, this time to the repository for [develop.kde.org](develop.kde.org), for [a page documenting the process](https://develop.kde.org/docs/apps/kmines/theme/). Now I realise that some developers out there are going to read through this and wonder if I was dropped on my head as an infant, but in my defense, when it comes to software development, I'm a humble designer and Jamstack web developer. This is all very new to me, and I was expecting a much more streamlined process for what I saw as simple visual tweaks.
[![A screenshot of the KMines game window showing a new light theme.](/img/kmines_light.webp "The Clean Blue Light KMines theme")](/img/kmines_light.webp)
## Why High Contrast
When submitting my initial design, a KDE contributor who had been helping me via Matrix pointed out that they found the theme difficult to parse visually as the contrast was quite low. I hadn't considered contrast ratios here, my thinking being that I didn't need to; I was just making one theme among many, after all, and users could choose any theme that worked best for them. After some consideration, however, it dawned on me that my theme would likely be the only modern-looking theme in the release, so it would be ideal if it were as accessible as possible. With this in mind, thanks to the feedback of one helpful individual, instead of one pretty but low contrast theme, I decided to make two modern high contrast themes, one light and one dark, targeting the WCAG AAA standard for contrast.
## Coming in Plasma 6!
With thanks to those KDE contributors who helped make it happen, the merge request containing these two themes scraped by the skin of its teeth past the closing door of a feature-freeze and will be available with Plasma 6 this February!

View File

@ -0,0 +1,32 @@
---
title: Obligatory Site Updates Post
description: All the new stuff I've done on this website lately.
date: 2024-09-29
tags:
- Site Updates
synopsis: All the new stuff I've done on this website lately.
mastodon_id: "113222650648457852"
---
Here are a few new (and not-so-new, but good to know) features I've built for my humble website:
## A Sitemap for Humans
I now have a (human readable) [sitemap](/sitemap), linked in the footer of each page, for easier discovery of the pages that aren't listed in the menu at the top, such as [colophon](/about/colophon), and [privacy](/about/privacy) pages, which are now separate from the [about page](/about).
I haven't automated this yet, mainly because I'm not sure how to best go about it; if any [Eleventy](https://www.11ty.dev/) enthusiasts out there have any suggestions, please let me know by commenting below using Mastodon!
## New Buttons
Some pages now have buttons beneath their spiel that link to relevant pages that a reader may find useful. For instance, [colophon](/about/colophon), and [privacy](/about/privacy), and [contact](/me) pages, are linked from the [about page](/about); [/blog](/blog) now links to [tags](/tags), and…
## My Blogroll
If you've been on the internet for a while (and I mean a *while*), you may remember the humble [blogroll](/blogroll): a list of blogs followed by the author of the blog you're reading, provided both as a benefit to readers and to help share traffic with other people who write interesting stuff.
As I am close to entirely removed from corporate social media, I get my news predominantly from my [newsreader](/about-feeds), which I very much enjoy going through each morning, often with a warm cup of tea. My [blogroll](/blogroll) contains most of the feeds I subscribe to, and it even provides a [convenient and very neatly formatted .opml file](/blogroll/nathanUpchurchBlogroll.opml), which you can (in theory) use to subscribe to my entire blogroll at once by importing it into your feed reader. (I very much hope it works as I haven't actually tested it, but do let me know if you try it.)
The [blogroll](/blogroll) links to both the main website and the feed for every entry, and contains a short description for each. Please bear in mind that I have been adding these as I discover them, so if it turns out I've listed the blog of someone who says mean things to kittens or something, please tell me so that I can remove their entry.
The [blogroll](/blogroll) and [.opml](/blogroll/nathanUpchurchBlogroll.opml) *are* automated, because there are an awful lot of feeds there and I have no interest in writing all that markup myself. If you'd like to know how that's done, you can [check out the repo](https://upchur.ch/gitea/n_u/nathanupchurch.com).
## A Feed for Everyone
I write about all sorts of things, and I fully recognize that people who come here for posts such as [*The Secrets of Scrumptious Seitan*](/blog/the-secrets-of-scrumptious-seitan/) may not be especially interested in posts like [*How to Transfer Files Securely with the “scp” Command*](/blog/scp-command/), so I configured individual feeds for each tag.
What this means is if you go to the [blog](/blog) page, click on "Topics" to reach the [tags](/tags) page, and click on a tag, you'll find an RSS icon next to the title linked to a feed that only contains posts marked with that tag. Convenient, right?

16
content/blog/offline.md Normal file
View File

@ -0,0 +1,16 @@
---
title: Offline
description: A conversation with a colleague caused me to consider the consequences of online-only tooling.
date: 2023-10-20
tags:
- Quick Thoughts
synopsis: A conversation with a colleague caused me to consider the consequences of online-only tooling.
imageURL: /img/kenny-eliason-uq5RMAZdZG4-unsplash.webp
imageAlt: A server rack in the dark with colorful cables draped between the ports of servers and switches.
mastodon_id: "111268603361637013"
---
As part of a project investigating a potential new piece of software, I've been speaking with colleagues and contractors to determine which features they rely on to do their day-to-day tasks, as well as discover any wish-list items for a new platform. In one of these discussions with a colleague, we had covered her relatively simple use case, and moved on to discuss potential features that might be useful. At this juncture, she mentioned, somewhat apologetically, that should a particular workflow be translated to a new platform, it was important to be able to access data and documents offline.
I've long been irritated by the propensity of modern proprietary software to lock in its users with monthly subscriptions and online-only access, allowing them to shut off the supply, as it were, at a moment's notice should a billing cycle fail to complete to their satisfaction, or should they be momentarily unable to subject their user to data collection or surveillance. I'm also no fan of slow, web-based software devouring gigabyte after gigabyte of memory, while requiring at least two machines to operate — a client, and a server. Still, I was struck by my colleague's comment; it seems rare these days that your average computer user has any expectation left that *anything* ought to work without access to the internet. It's a travesty, really.
Compared to the experience of opening Adobe Illustrator or even Outlook on the computer issued by my day-job, the results of switching my personal machines and the workflows for my small business to exclusively FLOSS tooling has felt liberating — no waiting at splash-screens, advertising baked into the OS, or fans screaming from the combined load of endless electron apps competing for their share of system resources; best of all, from spreadsheets, to my IDE, to design files, in order to get work done, not a damned thing requires me to be forever online.

20
content/blog/patience.md Normal file
View File

@ -0,0 +1,20 @@
---
title: Patience
description: Learning about patience through an incense-making miscalculation.
date: 2024-01-10
tags:
- Quick Thoughts
- Incense
- Incense Making
synopsis: Learning about patience through an incense-making miscalculation.
imageURL: /img/dragons_blood_incense_copy.avif
imageAlt: A small piece of a coreless, Japanese-style incense stick burning in a black cast-iron burner.
mastodon_id: "111732713202024407"
---
Some time ago, maybe a year or so, I extruded a batch of incense sticks from some ingredients I thought might go well together: sandalwood, cinnamon, dragon's blood resin, a touch of Hojari frankincense for acidity, and some tonka bean for sweetness, if I recall correctly. After leaving the sticks to dry overnight, I was disappointed to see that they didn't stay lit; the stick would shrink behind the ember, and it would fizzle out in short order. Even worse, the little scent I was able to detect during the short burn was terrible: acrid and smoky. Dejected, I put the sticks away, returning to attempt to burn a small fragment every few days or so before I lost interest entirely.
A few months later, the tube of crooked red incense sticks caught my eye, and I once again attempted to burn a stick. To my surprise, it stayed lit throughout the entire burn. The fragrance had transformed also, from leafy-campfire to a simple, warm, slightly sweet, and medicinal fragrance. While this was enough of an improvement to encourage me to light one every now and then, I remained disappointed that the fragrance was so far from what I'd hoped to achieve. After half-heartedly burning each stick in the little plastic tube that housed them over a period of weeks, the tube disappeared into a basket on the shelf beneath my coffee table amidst a mess of bundled cables and game-controllers, never to be seen again until just a few days ago.
[![A small piece of a coreless, Japanese-style incense stick burning in a black cast-iron burner.](/img/dragons_blood_incense_copy.avif "The last fragment.")](/img/dragons_blood_incense_copy.avif)
While rustling around in search of a controller, I discovered the thin plastic tube, noticing two small fragments of incense sliding about as I lifted the tube from the basket. As I lit the first fragment this morning, I was met with a wonderfully clear impression of dragon's blood, uplifted by the bright citrus of Hojari frankincense, on a sweet, warm, woody base; my incense had turned out well after all. Unfortunately, the recipe, written on the tube in dry-erase marker, had long worn off; thinking the batch was a failure, I hadn't recorded it anywhere else. Burning those last two fragments today was bittersweet; all I had needed to do was wait. I'm frustrated about a number of things here, but there is something oddly gratifying about the situation. By failing to record the recipe, I got to experience something rare and unique today. In those peaceful, fragrant moments, I experienced something lovely for the first and last time — and I learned a thing or two about patience.

View File

@ -0,0 +1,18 @@
---
title: "On the Recent Controversy Surrounding a Certain Perfumery. "
description: "The difference between critique and denigration."
date: 2025-07-13
tags:
- Quick Thoughts
- Incense
synopsis: "The difference between critique and denigration."
---
Someone recently shared with me transcripts and audio recordings that have been going around of comments that are alleged to have been made by the owner of a well-regarded perfumery. This owner also recently published a video on the matter. I am not going to mention names, but I am sure many in the fragrance and incense community are already aware of the situation. I'm seeing a lot of anger online, as well as a number of people coming to the owners' defense. Having seen what I have, here are my thoughts.
First of all, I'm an anti-theist. I don't believe that *any* religion is inherently deserving of respect, let alone beyond critique or reproach. As this situation involves religion, I was expecting to see yet another case of hypersensitive believers becoming upset at a simple criticism. But there is a difference between criticism and denigration, and while ideas may not be owed respect simply because they exist, I believe that people are. What I saw and heard was not critique. It was outright insult and denigration in the most inflammatory terms possible.
There is a key difference between innocent commentary on a particular worldview (even if contentious), and outright insulting an entire group of people, their beliefs, their cultures, and their countries of origin. The language and talking points I saw, in particular the parroting of right-wing anti-immigrant rhetoric aimed at Muslims, struck me not as critique, but racism. Further, to harbor the beliefs espoused in these recordings and transcripts regarding a demographic while also directly marketing products to them seems especially contemptible.
In the video addressing the situation, the individual concerned pointed out that these statements were taken out of context. It is difficult to imagine how context could possibly excuse the statements I read and heard, but they were indeed presented without context. Regardless, rather than make a genuine apology which includes an acknowledgement of the harm caused, they opined on how unfortunate it was that their remarks were made public, and chose to shut down comments when people began to share some of the remarks that are alleged to have been made.
We all make mistakes. Sometimes people make remarks in anger that they don't mean, or we phrase our arguments in ways that are hurtful and unproductive. In my mind, there's still room for that to be the case here. But the first step towards growth and forgiveness is a sincere apology: naming your mistake openly, acknowledging the harm it caused, and taking steps to rectify that harm. While I am not in the group harmed by this situation, the rhetoric purported to have been espoused here does harm individuals who I respect and care for. Thus, while it's not my place to offer forgiveness, I will not be purchasing anything from this individual until such time as an earnest apology has been offered, and steps have been taken to rectify the harm caused. If I do not see this effort, I must believe that this individual stands by the statements they are alleged to have made, and as we have come to learn, [funding people funds their beliefs](https://www.advocate.com/news/jk-rowling-anti-trans-organization).

26
content/blog/poison.md Normal file
View File

@ -0,0 +1,26 @@
---
title: "Poison"
description: "Reflecting on eating, and cooking, habits in light of Pete Wells' stepping down from his role as Times restaurant critic."
date: 2024-07-16
tags:
- Quick Thoughts
- Restaurants
- Vegan Cooking
synopsis: Reflecting on eating, and cooking, habits in light of Pete Wells' stepping down from his role as Times restaurant critic."
imageURL: /img/pexels-davideibiza-1771809.webp
imageAlt: Amber glass bottles with poison warnings.
mastodon_id: "112798801312124662"
---
I recently happened across the article in which Pete Wells [announces that he will be stepping down](https://www.nytimes.com/2024/07/16/dining/pete-wells-steps-down-food-critic.html?unlocked_article_code=1.7k0.R2zu.sGv5x7hNrfba) from his role as Times' restaurant critic. Health stood tall among the reasons behind the decision:
> My scores were bad across the board; my cholesterol, blood sugar and hypertension were worse than Id expected even in my doomiest moments. The terms pre-diabetes, fatty liver disease and metabolic syndrome were thrown around.
I've been having a similar reckoning. In 2013 I turned vegan. At the time, this meant that you had better either learn to cook or learn to love whatever meager offerings you were lucky enough to find in the miniscule corner of your local grocery store reserved for you and the other crusties: gluten deniers; allergy sufferers; and so on. Rather than endure the pasty, sour blocks of potato starch that then passed for 'vegan cheese', I started to develop my cooking skills in earnest, and not just at home; I would work in kitchens, never as a cook, but as a cocktail bartender and later a barista, both at places upscale enough to warrant cocktail or coffee stations in the kitchen. I learned a lot from those places, especially in the cocktail bar where the chef and I practically stepped on each others toes. From the talented people in that kitchen, I learned what it was to deglaze a pan, how to balance salt, fat, and acid in a dish, and that a dish is over-seasoned when you can *feel* the salt on your tongue. Through these experiences, and through consistent practice at home, I became a very competent home cook.
Using what I've learned in kitchens and from my own practice and research, I can make a Beyond Meat / Impossible style ground beef analogue at home. I can make a competent béchamel sauce with home-made cultured vegan butter, throw together a romesco, red sauce, or salsa verde at a moment's notice, and whip up fresh falafel, tamales, mushroom stroganoff, a Thai green curry, or South Indian sambar on a weeknight without so much as looking at a recipe. All of it poison, I increasingly realize.
Restaurants are places where the preparation of food, necessary to sustain life, meets with a profit motive. In order to retain custom, restaurant dishes are designed with aspirations of meeting the zenith of human tastes, forged thousands of years ago when scraping together sufficient calories of plant and animal matter to see one through the day was no mean feat. If you are among the lucky sliver of the human population that can participate in today's world of plenty, however, restaurant food doesn't only fill those key nutritional silos that drive the most intense of cravings; it utterly overwhelms them, and the consequences from overindulging can be dire.
Learning to cook this way has done me a tremendous disservice. The talented people who I've learned from over the years have inculcated into me, as gospel truth, techniques to create food that delights the palate and utterly destroys the body.
Since giving up smoking, I've learned that the craving never really leaves you entirely. As I glance down at my beautiful little marble pinch-bowl piled high with large white crystals of kosher salt, I wonder whether this craving will never truly leave me also?

View File

@ -0,0 +1,27 @@
---
title: "Rammstein Incense Cones: A Review"
description: "It's only natural that the pyrotechnics obsessed neue deutsche härte act would release a line of incense cones. Today I'm taking a look."
date: 2025-02-02
tags:
- Incense
- Incense Review
synopsis: "It's only natural that the pyrotechnics obsessed neue deutsche härte act would release a line of incense cones. Today I'm taking a look."
imageURL: /img/rammsteinShow_copy.webp
imageAlt: A shot from a Rammstein stadium tour showing the stage and great plumes of smoke from the pyrotechnics.
mastodon_id: "113936913424530239"
---
The German neue deutsche härte group Rammstein is known for many things. From their [controversial lyrics (NSFW)](https://www.reuters.com/article/lifestyle/rammstein-album-banned-from-display-in-germany-idUSTRE5A90ZK/) and [legally dubious stage antics (NSFW)](https://www.revolvermag.com/music/see-rammsteins-infamous-1998-family-values-show-landed-members-jail/), to their [over the top live performances](https://metalinjection.net/news/rammsteins-pyro-guy-discusses-the-insanity-of-his-job-how-much-fuel-the-band-uses), one thing the group is certainly *not* known for is conventional merchandise.
Far from the usual assortment of posters and t-shirts, the band's merch has ranged from [medical supplies](https://www.rammsteinshop.us/en/catalog/wound-plaster-rammplast.html) to [kitchen tools](https://www.rammsteinshop.us/en/catalog/cookie-shape-zerdrucken.html), [furniture](https://shop.rammstein.de/en/catalog/kreuztisch-oak.html), [torches](https://shop.rammstein.de/en/catalog/fire-torch-funkenstoss.html), and [*very* special editions of their albums (NSFW)](https://www.rammstein.de/en/news/rammstein-deluxe-2/). Despite this, I was inexplicably surprised to discover that the group had released official, Rammstein branded incense cones for sale on the band's online shop.
At $5.00 for a box of 24, I didn't have high expectations. The picture on [the website](https://www.rammsteinshop.us/en/catalog/incense-candles-rammstein.html) showed a handful of crudely formed black cones, the color likely due to a high charcoal content, which often indicates that the fragrance is constructed from oils rather than whole plant ingredients. Realistically, I wouldn't expect anything else at this price point. The website lists cedar, sandalwood, juniper wood, rosemary, juniper berries, myrrh, frankincense, and benzoin as components of the perfume.
The cones are manufactured by [KNOX](https://www.knox.de/), a large German manufacturer of incense cones and those delightful little wooden [incense "smokers"](https://www.youtube.com/watch?v=v0t-mlg2SoA) that I'm told are popular around the holidays in Germany. Steve of the [Incense in The Wind](https://incenseinthewind.blogspot.com/) blog recently wrote a number of reviews for a variety of KNOX cones; I must admit that after reading them I was steeling myself for the arrival of my Rammstein *Räucherkerzen*.
[![A cone burning in a cast iron burner beside the box of cones.](/img/rammstein_incense_cones.webp "They do look pretty metal.")](/img/rammstein_incense_cones.webp)
When the two small packages of cones arrived, they were identical in appearance to the images on the website. Despite being inside of a mailing box, a paper bag, a cardboard carton, and finally sealed inside of a small plastic bag, I could smell the cones before I even opened the outer box. The fragrance was woody; it was juniper-forward with a sharp, turpenous edge, all tied together with a *big* hit of sweet, creamy benzoin. I didn't detect much of the other resins mentioned, but that may be because I'm more used to the actual resin rather than extracts and imitations. I am not usually fond of highly concentrated scents, but I must admit I enjoyed this, even though even the outer packaging of the cones seems to contaminate everything it touches with fragrance—I'll often catch a whiff of these cones in their packaging while just walking around my apartment.
Upon lighting, I'm briefly met with the scent of burning paper and those off-notes typical of charcoal + oil incense, which is not exactly pleasant, but it does make me nostalgic for some of the cheap incense I used to burn as a teenager. Most of the fragrance that was present on the unlit cone has disappeared, leaving mellow cedar and sweet benzoin notes. As [Steve found in his review of KNOX' vanilla cones](https://incenseinthewind.blogspot.com/2025/01/knox-vanille-raucherkerzen-vanilla.html), these also burn hot and fast, with a large ember characteristic of a high charcoal content. Cones predominantly based on wood tend to have an ember that travels down the cone, but here the ember seems to just increase in size until it envelopes the entire cone at once beneath a thin layer of ash. The cones don't put out much smoke. The mild, sweet fragrance in the burn does linger in the room for some time, but it is so diminished from the powerful scent of the unlit cones that I'm not terribly worried about it soaking into the carpet, which is often a concern with cheaper, oil-based incense.
I didn't at all expect to say this, but I enjoy these cones. They are not an example of a high-quality incense, but I enjoy the fragrance despite it all. I suppose the beauty of cones that use highly concentrated fragrances is that they don't last long; I don't know whether I could tolerate an eleven-inch bamboo-cored stick of this, but I can absolutely enjoy a little cone. In addition, despite the off-notes that charcoal introduces, I wonder if it doesn't overcome one of the key challenges of the format: when making traditional incense cones with actual plants, the temperature increases as the ember grows, so by the time you get to the base, the scent can be quite coarse indeed. With these charcoal cones, it seems as though they start *hot* and stay that way, eliminating the challenge of dealing with a dramatic temperature increase over the course of the burn. Yea, somehow, I like these.

View File

@ -1,7 +1,7 @@
--- ---
title: How to Transfer Files Securely with the “scp” Command title: How to Transfer Files Securely with the “scp” Command
description: How to transfer files to and from a remote Server with the scp / secure copy command description: How to transfer files to and from a remote Server with the scp / secure copy command.
synopsis: How to transfer files to and from a remote Server with the scp / secure copy command synopsis: How to transfer files to and from a remote Server with the scp / secure copy command.
date: 2023-06-12 date: 2023-06-12
tags: tags:
- GNU/Linux - GNU/Linux

View File

@ -0,0 +1,42 @@
---
title: "Scribus 1.7.0: From Strength to Strength"
description: "Scribus has always been about substance. With 1.7.0 style, usability, and designer-focused features take the front seat."
date: 2025-02-13
tags:
- FOSS/FLOSS
- Libre Graphics
- Underrated Apps
synopsis: "Scribus has always been about substance. With 1.7.0 style, usability, and designer-focused features take the front seat."
imageURL: /img/scribus_splash.webp
imageAlt: "The new Scribus splash screen featuring a fountain pen drawing a stream with koi fish. The splash screen is surrounded by printer marks."
mastodon_id: "114000796038604843"
---
Looking around the internet, you could be forgiven for thinking that Scribus is dead. These days, FLOSS[^1] developers debate the merits of merge requests in public chat rooms, track bugs through GitHub issues, and announce releases through widely-circulated blog posts or sleek landing pages. In contrast, the Scribus developers work seemingly cloistered far away from popular modern conveniences like Matrix and, erm, *git*. Despite their hermetic reputation, however, it is quite possible to glean what's going on in the Scribus project. The SVN repository [is mirrored on GitHub](https://github.com/scribusproject/scribus), the [bug tracker](https://bugs.scribus.net/changelog_page.php) shows clear signs of activity, and the official website reveals a fairly [steady pace of development](https://www.scribus.net/news/). Hell, LibreArts reported on the release of 1.7.0 [just last week](https://librearts.org/2025/02/week-recap-2-feb-2025/#scribus-170).
To be fair, most casual users of the FLOSS desktop-publishing mainstay aren't sniffing around the bug tracker, and for the past few years it sure didn't seem as though much had changed judging by the clunky, dated interface and pixelated icons you'd be met with upon launch. This is likely what has driven many a would-be user to pen an expletive-ridden Reddit thread instead of diving in and gaining enough experience with the program to know what die-hard Scribus fans have known for years: that Scribus is a blisteringly competent piece of software.
## The trouble(?) with Scribus
The major pain point of Scribus is, ironically, one of its key strengths. Designers used to working in InDesign and the ilk are used to being able to throw together a document on the fly, using their desktop publishing program as more of a freeform creative tool than a tool to denote and apply structure. This is not how Scribus works best. Simple things like choosing a color on the fly aren't possible in Scribus; rather than flicking your mouse over to a color-wheel, in Scribus, you'll go to Edit > Colors and Fills, where you'll select and add a color to your document's color list. Only then can you apply that color to a fill or stroke. Working without paragraph or character styles applied to type can be done, but it's sub-ideal; you'll set up some styles to stop the pain long before your work is done. When working with Scribus, you need to come in with a plan. Designers who regularly churn out pretty but poorly prepared files (and let's admit it, that's most of us[^2]) are in for a bit of a hard time. But if you stick it out, when you realize that you're simply going to *have to* set up your files methodically and properly, Scribus begins to feel like a weapon.
## Enter 1.7.0
Despite what the denizens of Reddit have to say, Scribus has been suitable for professional work for *years* now, and naysayers have had even less to complain about since Adobe announced that Pantone colors would, like Scribus, [no longer come baked into their software](https://www.theverge.com/2022/11/1/23434305/adobe-pantone-subscription-announcement-photoshop-illustrator). With the release of 1.7.0, Scribus finally looks and feels like the mature, feature-rich, professional tool that it has been for some time.
[![](/img/scribus_color_dialog.webp "The new color dialog.")](/img/scribus_color_dialog.webp)
The user-interface has been completely overhauled, with new icons, a proper window docking system, and more intuitive controls throughout the program. [Customizable optical margins](https://bugs.scribus.net/view.php?id=10539) have been introduced, allowing for [hanging punctuation](https://en.wikipedia.org/wiki/Hanging_punctuation). A unique new feature that I'm quite excited about is the white space review mode that allows you to check for typographic rivers while avoiding the risk of displacing your contacts through repeated squinting. [The full release notes](https://www.scribus.net/scribus-1-7-0-released/) detail what truly feels like a milestone release.
[![A Scribus document with all text covered in black bars, exposing the white space between the words.](/img/scribus_white_space_preview.webp "White space preview in action.")](/img/scribus_white_space_preview.webp)
By highlighting these user-facing improvements in Scribus 1.7.0, I don't mean to diminish the tremendous work that has been done behind the scenes, not least the years of work getting Scribus ready to move to QT6. That work is important, but what excites me so much about this latest release is the change in direction it could represent for the project: these features are not the sort that would be imagined by developers and built for their personal convenience, these features clearly represent the needs of *designers*.
[![The new Scribus splash screen featuring a fountain pen drawing a stream with koi fish. The splash screen is surrounded by printer marks.](/img/scribus_splash.webp "Look at that fancy splash screen!.")](/img/scribus_splash.webp)
Counterintuitively, this isn't a natural consequence of building software that might be used by design professionals. Take Inkscape, for example. There will be those in the project who see their work solely as creating a tool that implements the SVG specification; this is a fundamentally different point of view from that held by someone like [Martin Owens](https://www.youtube.com/@doctormo) who sees it as his job to create features that make Inkscape users happier, more productive, and to make Inkscape a tool that better suits their needs. This is where you get features like the shape builder tool, and upcoming CMYK support, both very much unnecessary if your goal for the project is a technical one, but critical tools for users who want to use the program in a professional setting where time is at a premium and output may be going to print.
Inkscape's [duplicate transform](https://www.youtube.com/shorts/qsyrBrg4DT8) and Scribus' white space preview features are prime examples of the unique, needs-focused capabilities that emerge when users, designers, and developers come together on equal terms in FLOSS projects; magic happens. So let's hope this trend continues. Scribus is *the* FLOSS option for professional desktop publishing, a cornerstone of the libre-arts landscape. Combined with Scribus' wide feature-set and dedication to solid, dependable PDF output, it's easy to see why I've long been an outspoken fan of the project, even back when it was ugly 😉.
## A bright FLOSS future
It's a good time to be a [GNU/Linux](/quizzes/how-much-of-a-linux-nerd-are-you/) user. With the amazing work being done by [KDE](https://kde.org), and Linux gaming hitting the mainstream, a killer release like 1.7.0 from a FLOSS project that has (somewhat unfairly) garnered a reputation for being stodgy and slow-moving, if not (utterly unfairly) outright abandonware, feels like icing on the cake. Alongside the major advancements made by the [Inkscape](https://inkscape.org) and [Krita](https://krita.org/en/) teams, it's a beacon of hope to the small number of intrepid designers and artists who rely on FLOSS to do their work—our options are few, but they are mighty.
[^1]: Free / Libre Open Source Software
[^2]: As a working-file neat-freak, I was uniquely positioned to switch to Scribus.

43
content/blog/silvertip.md Normal file
View File

@ -0,0 +1,43 @@
---
title: "Silver Tip: an Incense Build Featuring Osmanthus and Mastic"
description: "I make a fresh, sweet, and green incense build reminiscent of the flavor of white tea"
date: 2024-09-20
tags:
- Incense
- Incense Making
- Incense Builds (Recipes)
synopsis: "I make a fresh, sweet, and green incense build reminiscent of the flavor of white tea."
imageURL: /img/testAsh.webp
imageAlt: "A small tin labelled 'test ash' beside a small glass jar containing matches."
mastodon_id: "113173725532729481"
---
If my memory serves me, some time ago I tried a stick from [Yi-Xin](https://craft-incense.com/) that contained osmanthus flowers and mastic gum. I recall enjoying the combination, so when I found a bag of dried osmanthus on sale while [doing some online grocery shopping](https://www.sayweee.com), I set out to make something using these ingredients.
Having read that osmanthus, like lavender, was one of those few flowers that could be used successfully in incense, I was brimming with confidence as I ground them finely and made an attempt at a batch of sticks containing 19% of the powder. The result was ghastly. At this percentage, alongside that characteristic beautiful fruity fragrance was a proportionate helping of the acrid scent of burning plant matter. Following this failure, I put aside my hubris, opened my tin of 'test ash'[^1] and began testing incense powders comprised of differing ratios of osmanthus and base-wood in a series of trail-burning tests, eventually finding that a ratio of 10% osmanthus to base wood seemed to return a reasonably good fragrance in the burn.
[![A small tin labelled "test ash" beside a small glass jar containing matches.](/img/testAsh.webp "My test ash; a very convenient way to perform a quick trail burn.")](/img/testAsh.webp)
Armed with this knowledge, I put together a build. The star aromatics sit atop a woody base of sandalwood and juniper sweetened by a touch of benzoin; the composition is slightly lifted with a minuscule amount of camphor, bound with guar gum and a little acacia gum. While also acting as a weak binder, the acacia gum is present to lower the burn temperature and strengthen the sticks.
## The Build
|Ingredient|Grams|% of Build|
|----------|------|-----------|
|Juniperus Virginiana|2.6|35.62%|
|Santalum Spicatum|2.6|35.62%|
|Osmanthus Fragrans|0.73|10%|
|Mastic Gum|0.5|6.85%|
|Acacia Gum|0.3|4.11%|
|Benzoin Siam|0.25|3.42%|
|Guar Gum|0.25|3.42%|
|Borneol Camphor|0.07|0.96%|
As with all of my incense, I extruded the dough into 2-2.5mm coreless sticks which I then dried on a mesh screen at room temperature and left to cure for a number of weeks.
## Conclusion
The sticks this build produces offer a [quiet listen](https://kikohincense.com/pages/listening-to-incense), but I find it very pleasant. Something about the combination of juniper, mastic, and osmanthus forms a fragrance that's at once green and fruity, with a bright, peachy, stone-fruit note, all atop a woody base. After a couple of months, the camphor is barely there on the stick; whether it is present in the burn is difficult to say without trying a build sans borneol.[^2]
My partner has a small wood-burning backpacking stove they like to use to make tea while camping. While I haven't yet had the pleasure, I have to imagine that making a cup of white tea on such a stove in a juniper forest would smell similar to the fragrance of this stick.
[^1]: I use the stick of a cotton swab to create a divot in the ash bed, which I carefully fill with incense powder to be tamped down, lit, and evaluated. When I'm done, I simply close the lid, shake the container, and drop it once or twice on a flat surface to smooth the ash and prepare it for the next use.
[^2]: Such a tricky ingredient, camphor. The tiniest amount can seem utterly overwhelming when blending or on a fresh stick, and as incense cures and ages, it seems as though it may or may not mellow out in the burn.

View File

@ -0,0 +1,47 @@
---
title: "Switching to GNU/Linux: Mentally"
description: The mindset shift that produces happy users of GNU/Linux and other Free/Libre and Open Source Software.
date: 2024-06-11
tags:
- Essays
- GNU/Linux
- FOSS/FLOSS
- KDE
synopsis: The mindset shift that produces happy users of GNU/Linux and other Free/Libre and Open Source Software.
imageURL: /img/pexels-ds-stories-9228363_copy.webp
imageAlt: A very cute photo by DS stories on pexels.com of a little pink brain-shaped candle on a light blue background.
mastodon_id: "112615355114722806"
---
[Stallman was right;](https://www.benzinga.com/news/24/06/39219971/edward-snowden-echoes-richard-stallmans-warnings-on-proprietary-software-after-user-says-adode-can-n) in the wake of Microsoft's announcement of its [much-maligned](https://www.wired.com/story/microsoft-recall-off-default-security-concerns/) Recall feature and widespread public backlash to the [terms and conditions](https://www.benzinga.com/top-stories/24/06/39209804/it-is-time-to-cancel-adobe-new-photoshop-terms-conditions-spark-outrage-among-professionals) for Adobe Creative Cloud products, it's clear that trust in big tech and the software it produces is rapidly eroding. Under the circumstances, it's no surprise that Free/Libre and Open Source Software (FLOSS) is seeing an uptick in interest from the public at large. So as ever more average users consider "switching to Linux," it strikes me that while there exist tomes on the technical aspects, there seems to be much less written on the shift in thinking that is part and parcel of every experienced and well-adjusted FLOSS user. So if you're making the switch or know someone who is, here's some advice to make the most of the transition.
[![A rather beautiful picture of a young Richard Stallman playing the recorder to a large pink butterfly perched on some beige computer equipment.](/img/rms.jpg "He was right. [CC BY-NC-ND 3.0](https://creativecommons.org/licenses/by-nc-nd/3.0/)")](/img/rms.jpg)
## Welcome
First of all: welcome to GNU/Linux! You've chosen the operating system [that powers](https://www.vrogue.co/post/linux-is-everywhere-infographic) bullet trains, the world's fastest supercomputers, U.S.A. air traffic control, CERN's Large Hadron Collider, and Google, Amazon, and Microsoft's cloud services, [used by](https://en.wikipedia.org/wiki/List_of_Linux_adopters) NASA, the People's Liberation Army, the Turkish government, whitehouse.gov, the U.S.A. Department of Defense, France's national police force, ministry of agriculture, and parliament, Iceland's public schools, the Dutch Police Internet Research and Investigation Network, Burlington Coat Factory, Peugeot, DreamWorks Animation, the Chicago Mercantile Exchange, the London Stock Exchange, the New York Stock Exchange, and [Stephen Fry.](https://en.wikipedia.org/wiki/List_of_Linux_adopters#Celebrities)
As you've no doubt inferred by now, GNU/Linux users span from your everyday cat-video viewer to large institutions and organizations where operating system reliability and performance mean the difference between life and death. No matter where you are on this spectrum, with a little humility, open-mindedness, and perseverance, I promise that you can find your self every bit as happily at-home with GNU/Linux as you were with whatever OS you've been using up to this point. This may mean giving up a long-trusted piece of software for something new and different, but for many new users the most hard-won battle is a change in mentality.
## You're not a power-user anymore
I've heard it said that the most "computer literate" people often find it especially arduous to adjust to GNU/Linux. I've been there; it's a frightening thing to go from the person family, friends, and neighbors call to help with problems with any device that has so much as an LED on it to feeling like that clueless relative with a dozen toolbars installed on their outdated version of Internet Explorer. The reality is that while you've gotten very good at navigating the operating system that you've been using for the past twenty years, very little of that knowledge is useful in GNU/Linux. This is something you're going to have to accept early on: no matter what distro you choose, it's going to be different to Windows or MacOS in very fundamental ways.
This means that, no matter your mastery of Windows keyboard shortcuts, or how convoluted your [AutoHotkey](https://www.autohotkey.com/) config may be, it's going to take you some time to grasp the basics. Beyond that, the bar to become a GNU/Linux power-user is much, much higher than it is on proprietary operating systems. In case you're feeling intimidated, know that this comes with some serious advantages. GNU/Linux systems come with a practically limitless potential for mastery, efficiency, and customization. In time, you'll be able to customize your GUI to your exact specifications, automate system maintenance, and knock out common tasks with a speed you wouldn't have thought possible on your old OS.
## Embrace the new
Switching to GNU/Linux is, in some ways, much more convenient than switching from, say, MacOS to Windows. Chiefly, most distros can be configured to run a wide range of software built for MacOS, Windows, or Android with minimal fuss. That said, I strongly encourage new users to explore FLOSS alternatives built on and for GNU/Linux. FLOSS projects often get a bad rap among users of proprietary operating systems because while a piece of software may run on these systems, the experience is rarely as good as it is on the system is was designed for: usually, GNU/Linux. FLOSS mainstays such as [LibreOffice,](https://www.libreoffice.org/) [Krita,](https://krita.org/en/) [Inkscape,](https://inkscape.org/) [Scribus,](https://www.scribus.net/) [Kdenlive,](https://kdenlive.org/en/) and [Ardour](https://ardour.org/) are at their best on GNU/Linux in terms of appearance, performance, and features. There are professionals of every stripe who do their work with an exclusively FLOSS toolset, from graphic design to video editing, audio production, data analytics, and more. If they can do it, so can you! Don't let the one piece of proprietary software that just won't work put you off of your new operating system when there's a whole new ecosystem of incredible software to explore.
[![A screenshot of Scribus.](/img/scribus_copy.webp "The latest development version of Scribus running on EndeavourOS. I guarantee you it doesn't look this good on Windows.")](/img/scribus_copy.webp)
New users of FLOSS projects often complain that the user interface or workflow of the tool they're trying is "unintuitive." Occasionally, these complaints hit on an area that genuinely could use some improvement, but more often, new users are simply expressing frustration that the workflow of a FLOSS project is different from what they are used to. These applications are not mere clones of their proprietary counterparts; they are projects in their own right, with unique goals, ideals, features, and workflows. Getting through a work project a little more slowly at first is not necessarily a flaw in the tool, it likely just means that you need a bit more practice. In time, you'll come to learn and appreciate killer features that go above and beyond the capabilities of software produced by even the largest tech companies.
## As a GNU/Linux user, you're part of a community
When you switch to GNU/Linux, you're not a customer any more. FLOSS projects are largely build by communities of volunteers who work on what they find interesting or important for their own reasons. There's no support line to call, no one to complain to if something breaks, and no one is losing anything by you choosing not to use their software. If you need help, or if you want to help make a FLOSS project better, you're going to have to engage with the wider community. Every project has a forum, a Matrix or IRC channel, or some other means of connecting users and developers. If you have a problem you can't solve on your own, these are the places to go to get help. Sign up and make a good faith effort to learn the rules and etiquette of the community, and chances are someone will be more than willing to help you find a solution out of sheer civic-mindedness.
There is likewise a great deal of pleasure and satisfaction to be gained by returning that kindness: by being an active participator in the communities you join, you'll help others overcome the stumbling blocks you once faced and foster connections with others who share your interests. Beyond the community alone, there is something wonderful about using software that you've helped shape; contributing well written bug reports, monetary donations, writing documentation, or testing new releases makes a direct positive impact on the tools you rely on each day. It's one thing to use FLOSS projects for reasons of ethics, privacy, or mere utility, but seeing a page of documentation you've written go live for anyone in the world to learn from, seeing a bug you reported vanish after an update, [a theme you created get added to a game,](https://nathanupchurch.com/blog/new-kmines-themes/) or experiencing your feature request given form in a release *really* draws you in. You're no longer at the mercy of some large tech company who only cares about profit; you're part of a community that cares about people, ideas, and making its software better, more efficient, more usable, and more useful for everyone.
## The FLOSS mindset
To distill what I've said above: Things are going to be different, and you may feel disempowered and frustrated for a while until you catch up again. The solution to this, beyond simple patience, is to embrace the fact that by using FLOSS projects, you become a part of the process of making them. Join the community with respect and humility, allow yourself to receive help and kindness from others, and you'll begin to once again remember how it feels to earn your skills. In time, you'll be the one offering help, you'll dance circles around any Windows power-user, and you'll be using tools that you've helped make better. Again I say: welcome. With these small shifts in your thinking, you're going to be in for a good time.

View File

@ -0,0 +1,24 @@
---
title: "The Office Tech Wizard"
description: "Knowing how to operate a PDF viewer does not a tech wizard make; what it means to be good at your job."
date: 2024-09-21
tags:
- Quick Thoughts
- Rants
synopsis: "Knowing how to operate a PDF viewer does not a tech wizard make; what it means to be good at your job."
mastodon_id: "113178005978869507"
---
I came across [this submission to *Not Always Right*](https://notalwaysright.com/pdf-pretty-darn-futile-part-2/) today, and it got me thinking about some of the attitudes towards technology I've seen over the years. There is a contingent of people in many workplaces who believe they can do a perfectly good job without investing the time in learning about the tech they use each day; after all, their work gets done, doesn't it? We've all encountered this sort; the sort of person who's so far removed from a basic understanding of the tools they use each day that they'll brand you the office tech-wizard for knowing how to use the zoom function in a PDF viewer, copy and paste with the keyboard alone, or *(gasp!)* googling how to restart the print spooler when a job gets stuck. And sure, many of these folks do manage to get things done, but a problem arises when you consider *how.*
Early career folk don't have the luxury of being bad at their tools; it's sink or swim. So when older colleagues or those later in their career don't know how to use a particular piece of software, guess who has to pick up the slack? This isn't necessarily a problem in and of itself; there's nothing wrong with not knowing something and needing a bit of assistance, but this quickly becomes a problem when people decide that they are exempt from learning because of their age, position, workload, et cetera. At this stage, one individual's job becomes a team effort; because of someone's attitude towards technology, another person who also has their own tasks and responsibilities is *doing their job with them.*
In considering what it is to be good at one's job, let's leave outcomes off the table for a minute. If someone has to rely on a team to do their job, no matter the result, can they seriously claim to be good at it? Surely knowledge and experience are moot if someone cannot actually perform their work. What sort of value does this individual provide an organization when they systematically reduce the productivity of their more capable colleagues each day? Further, in what other industry can people get away with this attitude? It's unthinkable that there might be a mechanic who refused to learn to work a hammer, a writer who refuses to sharpen a pencil, or a microbiologist who can't operate a microscope and is just 'too swamped' to learn how to prepare a slide. To me, a white-collar worker not knowing how to use the zoom function in a PDF viewer is equally ridiculous when working with PDFs is something they do on a regular basis.
So when we consider whether we are good at what we do, atop knowledge, experience, and outcomes, let's include a few new criteria:
1. Do we create or reduce work for others?
2. Do we truly understand the tools that we use every day?
3. Can we perform basic maintenance and troubleshooting on our tools?
…or do we rely on a wizard?

View File

@ -0,0 +1,31 @@
---
title: That Time I Drew My Ex
description: The tale of the time I made my best effort to draw my live-modeling ex. Also some not-very-good art.
date: 2024-08-20
tags:
- Storytime
- Quick Thoughts
synopsis: The tale of the time I made my best effort to draw my live-modeling ex. Also some not-very-good art.
imageURL: /img/doodle.webp
imageAlt: A wiggly vector ice cream cone with a wee smiling face and colorful sprinkles. The cone is holding two smaller ice cream cones in its long, wiggly arms, one of which is wrapped around its body.
mastodon_id: "112996800811207774"
---
At the start of the pandemic, I had just begun a relationship with an artist who had the occasional gig doing a bit of nude live modeling.
[![A wiggly vector ice cream cone with a wee smiling face and colorful sprinkles. The cone is holding two smaller ice cream cones in its long, wiggly arms, one of which is wrapped around its body.](/img/doodle.webp "Not my ex")](/img/doodle.webp)
When he invited me to join a session via zoom, I was apprehensive. Drawing has never been my strong suit. I can *doodle,* but I can't *draw.* But hey, I thought, I'm not completely devoid of artistic skill. I *have* been doing design work for years; while graphic design is not art, it's at least art-adjacent. Hell, when I sit down and take my time, I can produce something that's downright fridge-worthy!
[![A crude oil pastel ocean-scape featuring a sunset. Wee boats bob about on the waves and little birds fly above them.](/img/pastel.webp "I'd put that on my fridge!")](/img/pastel.webp)
Prepared to do my best, I settled down with my laptop, some pencils, and a pad of paper. What I was not prepared for, however, was how quickly the poses would change. There I was, expecting a good chunk of time to carefully render my new boyfriend in loving detail, only to have the pose end before I'd even managed an outline! And so I changed my strategy: I decided to prioritize *speed.* That didn't work either. Here are some of the results:
[![A very speedily drawn cat, with what I think is my ex behind it. It looks like a sack of potatoes.](/img/quicklydrawncat.webp "I'm fairly certain this was supposed to be his cat.")](/img/quicklydrawncat.webp)
[![This drawing, honest to god, looks like a rotisserie chicken with a perm.](/img/chicken.webp "I really don't know what happened here.")](/img/chicken.webp)
After much scribbling, I did begin to improve, eventually turning out this:
[![A half decent drawing of what is quite clearly a human sitting on the floor.](/img/notbad.webp "I stopped while I was ahead here.")](/img/notbad.webp)
I put the pencil down after that.

View File

@ -0,0 +1,92 @@
---
title: "The Skinny on Incense Stick Extruders"
description: "The good, the bad, and the ugly of manual incense stick extruders."
date: 2025-01-23
tags:
- Incense
- Incense Making
synopsis: "The good, the bad, and the ugly of manual incense stick extruders."
imageURL: /img/extruders/extr3_3x_tip_compressed.webp
imageAlt: "A close shot of an incense extruder tip with three extrusion holes."
mastodon_id: "113879431946665708"
author:
url: "/me/"
name: "Nathan Upchurch"
profilePic: "/img/CN20191025_301_Srt_SQUARE_crop.jpg"
---
::: info
Update 2025-06-24: You can buy the final extruder, replacement nozzles, and accessories from outside of China via [SuperBuy](https://www.superbuy.com/en/page/buy/?url=https%3A%2F%2Fdetail.1688.com%2Foffer%2F750437159209.html). For a side by side comparison of some of the extruders, see [this picture](/img/extruders/comparison1.webp) and [this picture](/img/extruders/comparison2.webp): the aluminum and stainless extruders are near identical in diameter, but the aluminum model is shorter.
:::
Given that hobbyist incense making hasn't exactly been all the rage since the tang dynasty, finding good incense-making equipment for small-scale home production can be a bit of a tribulation. If you make Chinese or Japanese style coreless incense, one of the first hurdles on the way to kitting out your very own mini incense workshop is choosing a manual extruder. Now that I finally feel confident that I've overcome this particular hurdle, here's what I've learned:
## Where to Find a Suitable Extruder
When searching for manual extruders, the first thing you'll likely come across is something like a [Makin's](https://www.makins-usa.com/products.jsp?prod_catg_id=7) clay extruder. This style of extruder often comes with a series of small discs designed to extrude clay noodles of different diameters. These are best avoided; other incense makers have found that extruding incense through these flat discs tends to create noodles with [a coarse texture](https://youtu.be/snvDZbxHnU8?si=ap7oiw0iC_HQJhCy&t=245) that must be rolled smooth after extrusion. Omitting this style of extruder from your search *drastically* narrows your options, but searching "incense extruder" on the website of any major online retailer that dropships or stocks a large number of products from China is likely to net you results featuring extrusion tips better suited to incense making. If you are willing to wait a bit for delivery, however, rather than paying Walmart, Amazon, or Ebay a convenience tax, you will have no trouble finding manual extruders on AliExpress directly for much less of your hard-earned coin. Carl "The Incense Dragon" Neal also sells a [Makin's style extruder](https://www.theincensedragon.com/tools/p/incense-extruder-20) that includes a series of 3D-printed extrusion tips allowing smooth incense extrusion.
## Extruders I've Tried
### The Syringe-Style Extruder
The internet is riddled with [syringe-style incense extruders](https://www.aliexpress.us/item/3256804771983263.html). Despite [Carl's warning regarding plastic extruders](https://youtu.be/snvDZbxHnU8?si=p59DxZMXcw64BHfi&t=278), I had to give one a go just to see for myself how they performed.
[![A syringe-style clear plastic incense extruder with a metal tip.](/img/extruders/extr1_compressed.webp "Just say no.")](/img/extruders/extr1_compressed.webp)
I cannot recommend this style of extruder. When making incense dough, it's important to use as little water as possible to avoid excessive warping during the drying stage. When attempting to extrude dough of the usual level of hydration through a 2mm tip, I was physically unable to coax any dough whatsoever beyond the extrusion tip, and I am not a weak man. This extruder was a complete bust.
[![A small metal extrusion tip.](/img/extruders/extr1_tip_compressed.webp "I'm sure this would be great if you could get anything through it.")](/img/extruders/extr1_tip_compressed.webp)
There are a range of metal extrusion tips readily available for these extruders, so someone must be using them for *something,* but I found them completely unsuited for my purposes.
### The Aluminum Option
Also relatively easy to find, [these aluminum extruders](https://www.aliexpress.us/item/3256807354775579.html) are well-made and effective:
[![An aluminum incense extruder, similar to the Makin's clay extruder, but with a longer tip for incense extrusion.](/img/extruders/extr2_compressed.webp "Truly a good, affordable option.")](/img/extruders/extr2_compressed.webp)
So long as you keep the o-ring on the piston lubricated and your dough doesn't have any large chunks, the extrusion tip produces a nice, smooth noodle of incense dough, and the turning action greatly reduces the hand-strength required to operate the device.
[![The tip for the aluminum incense extruder.](/img/extruders/extr2_tip_compressed.webp "Various tips are also available.")](/img/extruders/extr2_tip_compressed.webp)
There are a couple of small issues, namely that the caps on the turning rod can come unscrewed mid-batch if they aren't firmly screwed on, and the soft metal is prone to damage if you aren't careful. Despite these nitpicks, however, I have no hesitation in recommending this style of extruder to any incense maker focusing on thin coreless sticks.
### My First Stainless Steel Extruder
As I've been working on scaling up my production to a level that would allow me to sell a few orders of incense here and there, my interest was sparked in [this stainless steel extruder on AliExpress](https://www.aliexpress.us/item/3256806453629799.html):
[![A heavy-duty looking stainless steel incense extruder, with a black grip around the center tube.](/img/extruders/extr3_compressed.webp "Looks good, doesn't it? Well it isn't.")](/img/extruders/extr3_compressed.webp)
Specifically, I hoped that the optional extrusion tip with three outlets and the vise accessory would allow me to speed up the extrusion process. I also liked the idea of a heavy-duty item that would last for many years. I bought the "high order style," which comes with four extrusion tips, a grip, some o-rings and small cleaning tools, and the extruder itself. I also ordered the three-outlet extrusion tip, and the "sucker holder," AKA a vacuum-base vise.
[![The three-outlet tip.](/img/extruders/extr3_3x_tip_compressed.webp "Not as useful as you might think.")](/img/extruders/extr3_3x_tip_compressed.webp)
To start, the three-hole extrusion tip worked, but as anyone who works with [larger manual extruders](https://www.aliexpress.us/item/3256807859213019.html?utparam-url=scene%3Asearch%7Cquery_from%3A) knows, the flow rate from each hole isn't necessarily even. This is less of a problem when you're extruding, say, six to twelve sticks at once at a proper station with a waste bucket and a stack of boards to catch the extruded incense, but when you're hand-cranking three sticks at a time and one is firing out like billy-oh, another is extruding at the usual rate, and the last seems frightened of daylight, you realize that you would have been better off just using a normal single-outlet tip.
[![A single-outlet tip.](/img/extruders/extr3_tip_compressed.webp "The large tips that fit this extruder also retain rather a lot of dough that doesn't get extruded.")](/img/extruders/extr3_tip_compressed.webp)
The vise *was* useful, however; it's much more efficient to be able to keep the extruder in one place and have a free hand to catch the sticks on a board. The problem I faced with it was that in order to get the extruder to fit within the vise, I had to fasten an included aluminum ring around the main body of the extruder using two grub-screws. These grub screws cut into the grip on the tube, which eventually tore from the force applied during extrusion.
[![The vise alongside the aluminum ring that allows it to hold an extruder.](/img/extruders/vise_compressed.webp "Genuinely pretty useful, just not with the grip on the extruder it is sold alongside.")](/img/extruders/vise_compressed.webp)
The extruder itself appeared to be assembled from mostly off-the-shelf parts, and not especially good ones. The rings that held the turning-rod in place rusted immediately after I got them a little wet, the threads were crunchy and coarse, and the interior of the dough-tube was very dirty. Perhaps most strangely of all, the piston, or plunger, that actually pushed the dough down the tube was not attached to the threaded rod at all, unlike the aluminum extruder.
[![A little plunger.](/img/extruders/extr3_plunger_compressed.webp "Note the scoring on top; it didn't come like that.")](/img/extruders/extr3_plunger_compressed.webp)
The plunger is made of mostly brass parts that screw together and a rubber o-ring. It's very thick, reducing room for dough, and the soft brass is rapidly worn away by the stainless steel threaded rod as it spins loosely down the dough tube during extrusion, leaving sparkly grit to get mixed into your next batch of incense. It continued to wear even after I had filed and sanded down the raised parts on the end of the threaded rod.
As a result of all this, the plunger becomes more worn with every use, the dough tube becomes covered in grime, and the extrusion action is crunchy and rough. I was *very* disappointed in this extruder, and I cannot recommend it. The silver lining here is the vise, which will work with any of the metal extruders listed; in my opinion it's a worthwhile purchase.
### My Current Extruder
[This extruder](https://www.amazon.com/dp/B0DP3H8CCL) was an enigma. I hadn't seen it anywhere before it surfaced several pages deep into an Amazon search.
[![A stainless steel incense extruder that looks much better made than the last one.](/img/extruders/extr4_compressed.webp "Could this be the one?")](/img/extruders/extr4_compressed.webp)
I tried to find a Chinese source through a reverse image search. Tineye, Google, Bing, and Yandex turned up nothing. Only when I began to search the sales copy in the Amazon listing did I find the item for sale elsewhere ~~but I still never managed to find a single instance of this product being sold on AliExpress (if you manage to find one, [do let me know](/me/))~~.[^1]
It *looked* great: stainless steel; a knurled dough tube; various accessories included. The Amazon listing didn't show it, but when I looked at other listings I saw that the piston appeared to be attached to the threaded rod. Jackpot!
When it arrived, I noticed a few things immediately. The knurling was shallow and not especially neat, as though it had been etched twice over and the etchings didn't quite align. The tips shown weren't included; instead of five tapered tips in different sizes, I received three flat 2mm tips. That might be a deal-breaker for some, as I don't even know where you'd begin to find additional tips for this thing, but as I extrude 2mm sticks almost exclusively, I don't mind. I'm also not bothered by the ugly knurling either, because the performance of this extruder is great.
To begin with, the threaded rod isn't some industrial looking piece of hardware like the last stainless extruder; it looks more like a high-quality leadscrew you'd expect to see on a laser cutter or some other piece of CNC equipment where precise, measured movement is critical. This keeps the extrusion action exceptionally smooth. The threads on all of the other caps are also nicely machined, and the small extrusion tips have minimal space to accumulate wasted dough after a batch is extruded.
[![The tip for my current extruder.](/img/extruders/extr4_tip_compressed.webp "Perfect!")](/img/extruders/extr4_tip_compressed.webp)
Fitted into my vise, this extruder is a dream. The smoothness and consistency of the extrusion makes one-handed operation a breeze. I did add some o-rings to the turning rod to reduce noise, and while I do find myself wishing it didn't fit quite so loosely inside the cap on the leadscrew, these really are nitpicks of the best extruder I've used to date.
[^1]: I have since found what appears to be the same item on [AliExpress](https://www.aliexpress.us/item/3256807712368107.html?utparam-url=scene%3Asearch%7Cquery_from%3A), [Taobao](https://vn.world.taobao.com/item/858074002289.htm), [Wepost](https://www.wepost.com.my/shops/taobao-items/554179126072.html?sku_properties=1627207:2846750301) (which has a [very dramatic video](https://cloud.video.taobao.com/play/u/719156502/p/2/e/6/t/1/440842077674.mp4) showing the extruder in operation), and [1688.com](https://detail.1688.com/offer/750437159209.html). Accessories also appear to be available through these sources.

View File

@ -0,0 +1,49 @@
---
title: "Meine Welt: It May be Time For Till Lindemann to Retire"
description: "You always hope that your favorite musicians will retire before they do anything too embarrassing."
date: 2025-03-28
tags:
- Music
synopsis: "You always hope that your favorite musicians will retire before they do anything too embarrassing."
imageURL: /img/till.webp
imageAlt: A black and white photo of Till Lindemann looking sad.
mastodon_id: "114270477560168817"
---
::: info
Content Warning: Misogyny; Mention of sexual assault.
:::
Over his storied career, Till Lindemann has been given a lot of grace. Both he, as a lyricist, and the Neue Deutsche Härte powerhouse he fronts, have made some questionable decisions over the years. Many of these missteps might perhaps be chalked up to the era, such as the unfortunate fat-suits in Rammstein's *Keine Lust* music video. We might also see the red-face in *Amerika* as ignorance rather than malice, given it was donned by a group some 5,000 miles away from the peoples being insulted, and in 2004, no less. Likewise, as a queer Rammstein fan I always saw *Mann gegen Mann* as a statement on the ridiculousness inherent in the rabid homophobia that was common at the time. The trouble with satire, however, is that you can never be perfectly sure whose side is being satirized, and Lindemann's later work threatens to cast an unflattering light upon lyrics written decades ago.
In 2015, you didn't have to be on the bleeding edge of contemporary thought on matters of social justice to recognize that *Ladyboy* and *Fat* of Till Lindemann and Peter Tägtgren's *Skills in Pills* was, to put it mildly, problematic. Still, Rammstein has never taken itself too seriously; it didn't seem terribly incongruent or damning that Till would opt to play the clown in an ill-advised politically-incorrect shock-rock album that, let us admit, did contain the odd banger. Till's attempts at a contemporary *Leah Sublime[^1]* certainly ring hollow compared to much his lyrics for Rammstein—which, while also often juvenile and shocking, explore themes of love, lust, obsession, gender, and the body in interesting and compelling ways—but never have I felt that they betray anything more insidious than a blurry view of the boundaries of poor taste. Further, Rammstein detractors have so long 'spent spouting the tide'[^2] of satanic-panic style criticism and speculation as to the group's messaging and politics, that it was eventually forced to be quite frank on the matter. As Lewis Twilby reported in Edinburgh University's history, classics, and archaeology magazine, *[Retrospect Journal](https://retrospectjournal.com/2019/10/20/deutschland-by-rammstein-a-look-at-cultural-memory-in-germany/)*:
> in a 2011 interview with Rolling Stone Lindemann said that he is a socialist and that We used to be either punks or goths We hate Nazis!. This is highlighted by their song Links 2,3,4, which is a direct reference to the labour movement song Einheitsfrontlied.
Famously refusing to provide almost any detail whatsoever on the meaning of Rammstein's lyrics, it's hard to glean much about the mind behind them unless they are quite explicit. For this, Lindemann's *Meine Welt* was all the more shocking. The video, released hours ago, opens with a gagged Lindemann, wearing a cross and being pushed in a wheelchair by an angry mob of women wielding signs featuring slogans such as "Kill Till," "Toxic Masculinity," and "Female Revenge." A melancholy piano solo plays as the camera closes in on the women's scowling faces as they yell and chant. Particular focus is placed on those in the crowd with piercings, or shaven heads. As the beat picks up, the video transitions to AI generated slop: gory and alien-looking childbirth imagery. The first verse begins[^3]:
> Naughty, unabashed<br />
Unknown and unshaven<br />
Unteachable, clueless<br />
Insatiable, unpunished<br />
Immovable, so unspeakable<br />
Shameless and unbearable<br />
Useless, uncovered<br />
Unaesthetic, unlicked
The chorus follows:
> Somehow, someday<br />
We'll start over from scratch<br />
Somehow and somewhere<br />
Life laughing, senses happy<br />
I'll show you my world<br />
A place for lost souls<br />
When apersonfallsfrom heaven<br />
They won'tcount the stars
Knowing the history of Till's work with Rammstein, you *might* argue that this is a *Mann gegen Mann*-esque parody of the embarrassing "men's rights" crowd who seriously argue that women attempting to protect themselves from sexual assault and lift impunity from the men who commit it is a mysandrist witch-hunt, if it were not for the mewling chorus and, oh yes, the fact that Till [was himself accused of sexual misconduct a couple of years ago](https://www.bbc.com/news/entertainment-arts-66646096). Due to a lack of evidence, the investigation was dropped, and while this says nothing about whether or not Till committed the acts he was accused of, when these sorts of accusations occur, we have a unique opportunity to learn something about the individual to whom they are directed. Of course a range of emotions might be expected under the circumstances, but I think it's fair to say that releasing a music video two years later portraying oneself as a Christ-like figure while characterizing women as an angry, "unaesthetic," "unshaven," "unteachable," and "unlicked," mob is neither a decent nor reasonable response—even if allegations were false, or indeed, malicious.
This is a deeply embarrassing moment for Till Lindemann, or at least it ought to be. If we were to stretch the benefit of the doubt to encircle the earth, it would be difficult to believe that this release is parody, and it would remain in egregious taste in any case. In addition, the martyr act from these famous figures accused of god-knows-what is consistently pathetic—are we to feel sorry for these multimillionaires who suffer no legal consequences and fail to miss a single wayward drop of revenue following the release of the shocking allegations leveled toward them? While we don't tend to expect better from public figures, when they are known to espouse leftist beliefs, we certainly hope for it, and it's a tremendous disappointment every time. As lyricist for Rammstein, Till's behavior also threatens to cast aspersions on the band's entire body of work, potentially eroding the good faith that gave the writing an air of irony, exploration, and at times a sense of literary value as it straddled the line bordering outright vulgarity. A poetic exploration of sexual violence can sometimes be useful and cathartic for those affected—Rammstein fans have been known to write in to the band to say as much—but the work takes on a different tone entirely when its author is accused of sexual misconduct and uses the experience as an excuse to express outright misogyny *via music video* while playing the martyr.
The release also says something about where Till is (or rather, isn't) artistically. Rammstein songs have historically been replete with references to classic literature, German culture, and wordplay, their videos visually arresting and multifaceted in their storytelling—barring the odd *Pussy* affair, but the lyrics, message, and egregious quantities of AI slop in *Meine Welt* indicate to me that either Till is losing touch with both the zeitgeist and his eye for quality simultaneously, or that perhaps someone else had been reigning him in all along. In either case, the man is sprinting towards self-parody, and the teenager in me desperately wishes he had retired first.
[^1]: If you don't get this reference, count yourself lucky and don't investigate further.
[^2]: Forgive me.
[^3]: Lyrics via [genius.com](https://genius.com/Genius-english-translations-till-lindemann-meine-welt-english-translation-lyrics).

View File

@ -0,0 +1,37 @@
---
title: Underrated Apps - QOwnNotes
description: QOwnNotes is a terminally underrated native markdown note-taking app, despite the fact that you'll rarely see it mentioned on the internet.
synopsis: QOwnNotes is a terminally underrated native markdown note-taking app, despite the fact that you'll rarely see it mentioned on the internet.
date: 2023-08-09
tags:
- FOSS/FLOSS
- Underrated Apps
imageURL: /img/qownnotes.webp
imageAlt: A screenshot of QOwnNotes showing a note subfolder panel beside markdown editor and preview panels.
mastodon_id: "110862579682916657"
---
[![A screenshot of QOwnNotes showing a note subfolder panel beside markdown editor and preview panels.](/img/qownnotes.webp "QOwnNotes running on EndeavourOS / KDE Plasma")](/img/qownnotes.webp)
## What makes a good note taking app?
After its author decided to make future versions closed-source, I found myself searching for a replacement for the excellent [Notable](https://notable.app/). Unfortunately, while note-taking applications are a dime a dozen, they're also common ground for the [Notable](https://notable.app/) / [SimpleNote](https://simplenote.com/) style FLOSS bait-and-switch: developers release an outstanding note-taking app, only to make future versions closed-source, or make it inordinately difficult to properly and fully make use of the software without paying for a hosted service. Victim to the former, I set out to find a note-taking app that I felt could not only be trusted to operate in the spirit of FLOSS philosophy, but also met some key criteria:
1. Native Code
Note-taking apps often use Electron. Rather than running another full-fat web-browser (chromium no less) just to *type text*, I wanted something lightweight that would integrate well with the look and feel of the rest of my system.
2. Notes in an open format
There are few things worse that note apps that force you to save your notes in their weird proprietary format, or store your notes into a database somewhere that you can't see. If I'm writing text, I want my notes saved into normal text files that I can see, change, delete, and move, without relying on my note-taking app.
3. Markdown support
Given that I often work with static site generators, I have come to treasure Markdown. Beyond the minimal interface that markdown editors offer, Markdown keeps distractions low, allowing you to quickly format your notes without being bogged down in office-suite style toolbars and menus full of formatting buttons and dropdowns.
## Enter QOwnNotes
While, tragically, I rarely see this program mentioned in articles or recommended in forums, [QOwnNotes](https://www.qownnotes.org/) is the only note taking app I've managed to find that meets all of the above requirements; written in C++ and QT, it's zippy, light on resources, and integrates well with your desktop, especially if you're using KDE Plasma on GNU/Linux. Notes are stored in plain old markdown files, so you can edit them in any text editor, and markdown support is, of course, excellent. As if this weren't enough to make QOwnNotes a strong contender for a Notable replacement, the app is one of the more flexible note taking programs I've ever seen. It has a plugin system with a wealth of additions written by users, the flexible interface can be customized to suit your workflow precisely, and you can select from many built-in editor themes, or even craft your own. QOwnNotes also features integration with Nextcloud and OwnCloud. Best of all, the project is still actively developed and the developer, [Patrizio Bekerle](https://social.qownnotes.org/@patrizio), is responsive to GitHub issues (and has the patience of a saint!).
## Downsides
No solution is perfect. When setting up QOwnNotes for the first time, a page in the set-up wizard will notify you that collection of usage data is enabled by default. While the page also details how to disable data collection, this is a departure from the opt-in approach usually taken by FLOSS projects, and is sure to put a dent in more privacy-minded users' trust in the program. While highly customizable, QOwnNotes is by no means simple to configure. The settings menu is absolutely crammed with options, and default layouts tend to make use of lots of panels and icons. You can absolutely achieve a streamlined interface with QOwnNotes, but don't expect your ideal setup out of the box without some tweaking. Finally, programs like Syncthing can cause issues while editing notes, interfering with QOwnNotes' autosave and causing it to occasionally stop working entirely until the note is closed and re-opened. I can't imagine this would be an issue when using the built-in NextCloud integration, but it's something to look out for if you prefer to sync your notes with something that doesn't require a web-server.
## In summary
For me, QOwnNotes checks all the boxes. I would love to see *opt-in* telemetry, and I do wish that I could simply disable auto-save to avoid conflicts with Syncthing (Please reach out to me if you know how), but I feel that these are minor issues for a native markdown note-taking app. A real diamond in the rough, I cannot overstate how much I appreciate Patrizio's ongoing efforts on QOwnNotes.

View File

@ -0,0 +1,33 @@
---
title: Up to My Eyeballs
description: What Ive been up to instead of posting on my blog.
date: 2024-02-26
tags:
- Quick Thoughts
synopsis: What Ive been up to instead of posting on my blog.
imageURL: /img/logo_post.svg
mastodon_id: "112001639227268153"
---
If youre one of the handful of people who read my blog, you may have noticed that I hadnt posted yet in February. You see, about a month ago, I decided to implement that neat trick some people are doing that allows them to use replies to a mastodon post as comments on a web page. While I *could* have lifted [Juhis](https://hamatti.org/posts/blog-comments-via-mastodon/) implementation wholesale and been done in a half-hour, naturally, I decided to complicate things and build the feature using web components.
As if this wasnt enough, I figured that my site could use a bit of sprucing up. I began with changes to the typography; surely, I thought, this would only represent some minor changes to the CSS! Alas, I came across a link to [utopia.fyi](https://utopia.fyi/) and decided to implement fluid space and type scaling. I found this rather confusing at first as [utopia.fyi](https://utopia.fyi/) is pretty unclear about exactly how this works, but I got it working nicely in the end and I was even able to remove my media query in exchange for one small container query, which it seems [we can safely use now](https://caniuse.com/css-container-queries).
I also decided that I was sick of how crowded my font folder was, so I replaced the lot with two beautiful variable typefaces that only require one font file each for a slew of styles: [Manrope](https://www.gent.media/manrope) and [Fraunces](https://fraunces.undercase.xyz/).
To make a long story short: I rendered my website unusable by taking on too much at once. Could I have switched branches and uploaded the odd post? Surely, just like I *could* do my taxes the minute I get my W2, or I *could* get more exercise. In any case, I now have a prettier, leaner website with:
* Mastodon comments
* Fluid type
* Two variable typefaces instead of two giant font families
* Zero breakpoints
...and Im fairly chuffed. Some things I plan on doing in the future include:
* Styling for blockquotes, including optical margins
* Fixing styling for images that *arent* in a `<figure>`
* Better styling for code fences
* Implementing an image gallery
* Creating a /uses page
* Doing some of [this stuff](https://jamesg.blog/2024/02/19/personal-website-ideas/), and/or [this stuff](https://shellsharks.com/notes/2023/08/15/website-component-checklist)
* Finally getting around to making a professional site for my work accomplishments, et cetera
It feels good to have a working site once more. Im very excited about these changes and keen as mince to get posting again!

View File

@ -0,0 +1,41 @@
---
title: ADGs - Alternative Diet Guests and Foodservice
description: Breaking down the alternative-diet restaurant experience to offer some perspective and advice to foodservice professionals and proprietors.
date: 2023-10-03
tags:
- Essays
- Vegan Cooking
- Restaurants
synopsis: Breaking down the alternative-diet restaurant experience to offer some perspective and advice to foodservice professionals and proprietors.
imageURL: /img/k8-sWEpcc0Rm0U-unsplash.webp
imageAlt: An overhead view of a restaurant interior showing guests sitting at tables with white tablecloths, eating pastries.
mastodon_id: "111173763912666764"
---
I've been a vegan for close to a decade. From washing dishes, slinging cocktails, and pouring latte art, to recipe development, hiring, compliance, and multi-location operations, I've also been around the block a few times when it comes to foodservice. So when I tell you that the vast majority of foodservice establishments of any stripe are utter and complete complete nightmares for people with alternative diets, I hope you'll take me at my word.
For much of human civilization, food has represented more than mere fuel. Sharing a meal is a cornerstone of social and family life for billions of us around the globe; we gather together to discuss our day, we do business, we express love, and we wax philosophical over plates, bowls, leaves, platters, and hands holding an incredible variety of foods. In the present day, a growing class of people are becoming separated from the labor of cooking, while continuing to partake in its life-giving fruits. As a result of privilege, or a lack thereof, millions have come to rely on restaurants, bars, coffee shops, food stalls and stands to sustain themselves, and to participate in the social act of eating with others. While the resultant decline in food preparation skills is troubling, it is perhaps equally concerning that, whereas food was once created as a labor of love for those close to us, decisions made in the kitchens that feed so many leave those of us with less common needs and preferences largely excluded from many establishments, and with them, the important social role that they have come to play.
## For those with alternative diets, restaurants can be a source of stress.
For me and others like me, visiting a restaurant can be a difficult experience. From front of house staff with no idea what allergens their menu items contain, who don't understand the difference between Coeliac Disease and veganism, or who forget to include important information such as allergies or religious dietary restrictions into orders, to back of house staff who are equally uneducated on alternative dietary needs, lack the flexibility of process or inventory necessary to be accommodating, or who simply don't care and either treat accommodating guests with alternative diets as an encumbrance, or even lie outright and serve food that doesn't meet a guest's philosophical, religious, or even medical requirements, many of us have complicated feelings about going out to eat.
I once worked with a CEO who often invited the management team to dinner. We went to some of the best regarded restaurants in Chicago, but more often than not, I would wind up with a plate of french fries (dry, as the truffle aioli naturally wasn't vegan) and a glass of whiskey. Sometimes I'd be accommodated with a meal in-earnest. Once, I received an under-seasoned plate of couscous and mushy diced vegetables, and on another occasion, an over-priced bowl of black-bean soup. If there did happen to be a vegan menu item, it would rarely contain any protein, leaving me hungry after the meal. What ought to have been an enjoyable evening with colleagues became a source of anxiety; failing to attend these events may have left me on the sidelines at work, but going along left me feeling excluded and wishing that I were in my home kitchen making something worth eating.
## We're everywhere, and we probably want to eat at your restaurant.
Over the years I've heard many restaurateurs, managers, and chefs balk at the idea of creating a vegan menu item, claiming that it would be a moot exercise as they don't receive any vegan custom. The fact is, however, that in almost every instance they had absolutely no idea how many of their guests complied with any sort of alternative diet. From the smallest towns to the largest cities, ADGs are everywhere. If you have any custom at all, you likely have ADGs. Groups such as vegans, vegetarians, those who keep halal or kosher, those with allergies or Coeliac Disease, and so on each comprise large numbers of people, let alone in combination. If any reasonable number of people live or work near your establishment, there are almost certainly people who wish they could eat there, so near to where they spend so much of their time, but cannot for reasons either real or perceived.
Vegans and others with alternative diets have years of bad experiences to hone our expectations; we've each mentally composed a vast list of red flags - telltale signs that an establishment is going to be more trouble than its worth. When seeing these red flags, we are likely to anticipate either outright hostility, ranging from a bad attitude to being deliberately served foods we cannot eat, a lack of knowledge from staff resulting in difficulty ordering and a low degree of trust that our meal will be safe to eat, or to simply be told that there are no options available. In these situations, we may either simply avoid an establishment, or if dragged in by friends or colleagues, stick to what we know is safe: a black coffee, a fruit bowl, or even some fries, sans aioli, and a glass of whiskey. In all likelihood, a number of tickets for $5 coffees at your establishment might have been tickets for a starter and an entrée had an ADG seen one or two suitable menu items, or even just felt as though they had a fair chance at being accommodated.
## ADG items don't just make your menu accessible to swathes of new customers, done well, they should also excite your regulars.
Besides being reductive, the assertion that it's pointless to implement a vegan menu item because the business simply isn't there also implies that ADG items will only be saleable to ADGs. I can't count the number of times I've been told by someone that they simply cannot tolerate vegan food; each time, I'm tempted to express my condolences for my conversation partner's inability to enjoy a baguette, fresh fruit, vegetables, romesco sauce, peanut butter, french fries, Oreos, Swedish Fish candy, hummus, baba ganouj, nuts, Ritz Crackers, ketchup, good dark chocolate, bagels, pretzels, most potato chips, microwave popcorn, and dried pasta, foccaccia, olives, et cetera. While vegan food may be perceived by some as a special category of food, foreign and strange, only to be consumed by yet stranger people in acts of corporal mortification, vegan food, and indeed food suitable for most ADGs, is all around us; most of us already enjoy it every day, in one way or another.
[![A banana-nut doughnut: a doughnut on a plate covered in white icing, crushed nuts, and cinnamon.](/img/banana-nut-doughnut.webp "Some strange vegan food, originally posted on [my pixelfed account](https://pixelfed.social/p/nathanu/393147142652113079).")](/img/banana-nut-doughnut.webp)
Not only is there nothing strange about the food, there is also nothing so terribly different about the people who eat it. ADGs expect all of the joy from food that anyone else does: a balance of salt, fat, and acid, contrasting textures, mouth-watering flavors and aromas, and protein to keep us feeling full and satisfied. Any dish that meets these expectations ought to be worth ordering for *any* guest. This is a tough point for many otherwise proud chefs and proprietors to swallow; all else being equal, the fact is that most competent ADG menu items should be seeing sales in line with other items. Further, ADG menu items can make a menu accessible to multiple groups at once; a vegan item is also accessible to Catholics during Lent, in most instances those who keep halal or kosher, people with red meat, egg, or dairy allergies, vegetarians, and pescetarians.
## Making good food is just the start.
Designing and executing a competent ADG item or two is a fine start, but it's just that. Establishing trust takes time and effort; there are operational and cultural shifts that need to take place before a restaurant can be considered truly accessible to ADGs. While that work takes place over time, beginning with one or two competent menu items is a low-risk way for most independent establishments and other foodservice SMEs to expand their customer base. Bodies and beliefs are infinitely varied; likewise, people have an inexhaustible number of reasons to choose an ADG accessible food. As the role of restaurants becomes less of an occasional treat and more of a daily necessity, investing in menu development with ADG accessibility as a goal is increasingly becoming a simple matter of good business sense.

View File

@ -0,0 +1,33 @@
---
title: "Visiting Chicago Incense Maker Dave of The World Makes Scents"
description: "I had the pleasure of meeting Dave at The World Makes Scents studio in Bridgeport, Chicago."
date: 2024-08-04
tags:
- Incense
- Chicago
synopsis: "I had the pleasure of meeting Dave at The World Makes Scents studio in Bridgeport, Chicago."
imageURL: /img/pexels-harris-rigorad-478484242-25261413.webp
imageAlt: The Chicago flag.
mastodon_id: "112906515155787958"
---
Whether due to trauma inflicted by gas-station sticks laden with synthetic patchouli oil or the stigma unfairly landed upon the fragrant sticks by association with generations of teenagers seeking to obscure the olfactory remnants of their smoky intemperance, in the part of the world that I currently occupy, incense remains a niche interest — not only with respect to those who enjoy it; fewer yet ever attempt the art of incense-making. Western incense makers seem to huddle together into whatever dusty corner of the internet they can occupy, often knowing each other by handle and legal name alike, where together they scratch and scrape into one small pile whatever little crumbs of knowledge regarding this ancient craft are to be had in languages written with Latin-script alphabets. You can imagine, then, how thrilled I was to be invited by Dave of [The World Makes Scents](https://theworldmakesscents.com/) to see the studio that he shares with his wife, Raksmey.
The workshop is situated in an arts complex: part gallery, and part studio and event space. The walls are lined with pieces from the artists who let space there; as your footsteps echo across the lacquered wooden floors, you can't help but allow your attention to be arrested every few steps by some piece or another. In particular, I recall several striking pieces not far from The World Makes Scents' small studio featuring large nude figures at the fore of a shallow depth of field, a lenticular effect making the images appear to shift and change as you walk by them.
When we reached the studio a stick from a recent test batch was burning; coated with coarsely ground orange zest, it emitted an impressively clear and sweet note of orange oil. Dave told me the story of how Raksmey learned to make incense from women at a Buddhist temple near her home in Cambodia, how the two met, traveled through Vietnam together, rescued their pet dog from perilous circumstances, and disembarked from a plane in the U.S. right as the pandemic was entering the American collective consciousness. It's not my story to tell, so I'll leave it there, but the tale of how the pair came to be making such lovely incense in Chicago's Bridgeport neighborhood is nothing short of miraculous, and likely the most compelling pandemic hobby success story I've heard.
Since first sampling their incense through [the incense exchange subreddit,](https://www.reddit.com/r/IncenseExchange/) I had been impressed with how clean the fragrances were from their cones. I had chalked this up to the cones' golf-tee shape, which keeps the ember from becoming too large, and consequently, the burn temperature from becoming too high; seeing how the materials were processed, however, showed me how much more there was to the story. As if sourcing high quality fragrant materials wasn't enough of a challenge, processing them when they arrive is fraught.
Incense materials should, ideally, be reduced down to a particle size of 100 microns or less. The fastest methods of grinding introduce heat, which breaks down fragrant oils, and renders resins sticky and impossible to work with. Most small incense makers throughout history have thus resorted to processes such as stone grinding or the even more agonizingly slow filing of fragrant woods. Quietly humming in the background was Dave's solution to this conundrum: an array of ball mills, like giant rock-tumblers designed to carefully mill heat-sensitive materials such as black powder for firearms and pyrotechnics; the machines each consist of a rubber-lined drum atop a pair of motorized rollers that turns the drum continuously. The material to be ground is loaded into the machine alongside a series of stainless-steel balls that collide with material inside the spinning drum to break down everything from dried rose petals to cedar wood into a stunningly fine powder. The process takes hours, sometimes days, but at least it's hands-off. Following this, the ground plant matter is run through a series of increasingly fine sieves stacked atop a machine that shakes them so violently that it will soon be bolted to the floor of the studio. Suitably fine material will be used to produce incense; the rest will undergo the process once more.
The results of this procedure are striking; among the samples I left with was a bag of ground patchouli leaf, the texture of talcum powder, so redolent with its natural oils and aromatics that it almost smelled of fresh mint and myrrh resin. Once ground, ingredients are blended together with a small amount of binder; water is then added to form a dough. If destined to become cones, the dough is loaded into a sort of caulking-gun, which is used to extrude a long sausage which will be cut at regular intervals and shaped by hand into those signature golf-tee cones. To make sticks, the dough is packed into a large hand-cranked extrusion machine, capable of extruding some eight to ten noodles of incense at a time which are collected onto a wooden board before being straightened and transferred to a screen for drying. When the cones or sticks have dried completely, they are packaged by hand, labeled, and sent out to incense appreciators world-over.
Of course, the recipes that result in various fragrant doughs to extrude don't spring from nowhere; research and development is an area for which Dave clearly has a great interest and affinity. A whirlwind in the workshop, he produced innumerable ingredients, from wormwood to various frankincense varieties, sprinkling them atop a burning coal to give an impression of the fragrance of each as it burns. The small space housed many drawers and shelves of powders, tinctures, and oils, experiments both successful and otherwise. Vanilla was present in every form and variety as a part of the development process for an upcoming product, from simple extracts to pastes and a high end powdered variety that smelled rich, complex, and tobacco-like. Boxes of incense samples were produced from makers across the globe, from independent makers to large incense houses; all styles were represented, from Tibetan rope incense to bakhoor.
Very much in-line with the brand's emphasis on transparency, Dave's openness regarding processes and ingredients was impressive in an industry where players keep secrets close to their chests. Further, scaling up incense making into a viable business is no mean feat when you're not willing to compromise on quality. Even the famed Singapore incense maker [Kyara Zen wrote](https://www.kyarazen.com/incense-stick-making-a-walk-through/) of this difficulty:
> The truth is, Ive not been able to scale up production as everythings still very much purely hand made, from converting the raw material into powder, to the ingredient blending, to the extrusion, drying, collection etc.
Outside of large incense houses that use industrial hammer mills to break down whole aromatics, it's a painstaking endeavor to produce even small amounts of incense for personal enjoyment, let alone managing to increase output and reduce labor time such that it's viable to sell the incense you make. There is a reason quick and easy to make "hand dipped" incense is seen so often in stores despite its clear inferiority to its traditionally made, non-synthetic counterpart. What Dave and Raksmey have achieved in such a short time is nothing short of remarkable.
I'm very grateful to Dave for the invitation, for showing me the studio, offering a fascinating insight into The World Makes Scents' incense production methods, and for all of the incredible samples and goodies I left with. It's a wonderful thing to be able to meet with another incense maker and share knowledge and enthusiasm over the topic, and hopefully we'll be able to meet again soon; I'll no doubt have some samples to share myself when that time arrives!

View File

@ -0,0 +1,38 @@
---
title: "Washing Frankincense"
description: Reducing off-notes and improving resin fragrance in combustible incense by dissolving gum content.
date: 2024-12-09
tags:
- Incense
- Incense Making
synopsis: Reducing off-notes and improving resin fragrance in combustible incense by dissolving gum content.
imageURL: /img/frankincense_washed_ground_dried_ground.webp
imageAlt: A sieve containing frankincense powder.
mastodon_id: "113626197934900329"
---
Plant resins come with varying amounts of water-soluble gum content. Beyond the temperature-reducing aspect innate to resins in combustible incense, these gums can further affect how much of a given resin you can include in a build. As anyone who has burned resins on charcoal can attest, with resins high in gum content, the burning gum can introduce off-notes. Gums also serve as binders in incense sticks; while a little is helpful for producing a performant dough that extrudes well and a more rigid, break-resistant incense stick, too much can prevent combustible incense from remaining lit.
Naturally, I've been curious for some time as to how dissolving and discarding resin gums might impact the performance of a resin in combustible incense. Given all of the considerations I mentioned earlier, using resin in combustible incense is trickier than you might at first imagine, yet incense artisans like Yi-Xin manage to produce [very clean sticks](https://craft-incense.com/products/white-magic) using resins with a high gum content. Could dissolving the gum be the answer? When a fellow member of an incense chat group mentioned this type of processing, she unknowingly gave me the final push I needed to give it a go.
## The "washing" process
1. Grind your resin as finely as you are able.
2. Stir the ground resin into a large quantity of water in a container.
3. Let the resin and water sit overnight in the fridge.
4. When the solids have all settled beneath the water, pour the water off the top, while being careful not to lose the solids.
5. Spread the resin solids onto a sheet of wax paper and let dry.
## How it went
In my first attempt I utilized a paper coffee filter to separate the remaining resin from the gum-containing water; it took an eternity and resulted in a sticky mess on my kitchen floor, so I don't recommend it. That disaster is the reason why I moved to the method above wherein the water used to dissolve the gum content is poured off of the solids. This is based on a technique I used back in [my days as a cocktail bartender](https://makertube.net/w/boNV8AQcufwtaZVg9vUh1Q) to make ginger syrup[^1]. I do plan to attempt filtration again later with a lab vacuum filtration kit. After washing and drying the remaining material, I was left with a pleasantly crumbly mass adhered to the wax paper, which I gathered up into a container.
[![A closeup of a pile of crumbly looking chunks of frankincense in a small plastic deli container.](/img/frankincense_washed_dried.webp "Very satisfying to crumble between your fingers.")](/img/frankincense_washed_dried.webp)
Once dried, re-grinding the resin was incredibly quick and easy. I passed the ground material through a 140 mesh sieve and was met with a very fine, fragrant, and free-flowing white powder:
<figure><div style="position: relative; padding-top: 56.25%;"><iframe title="Washed Hojari Frankincense" width="100%" height="100%" src="https://makertube.net/videos/embed/e387a29a-dc61-4e3a-80a5-ccb1c1b3fda0" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups allow-forms" style="position: absolute; inset: 0px;"></iframe></div><figcaption>Hojari frankincense resin after being ground, washed, dried, ground once more, and sieved through a 140 mesh screen. The tiny spoon is for making Chinese incense seals.</figcaption></figure>
I tested the processed frankincense against an unprocessed powder in a trail-burning test at 30% resin to 70% sandalwood. While I was hardly scientific about it, my impression was that the processed frankincense was significantly improved in fragrance quantity and quality when burning compared to the unprocessed powder.
Needless to say, I'm pretty happy with the result. I'm very keen to give this a go with some of the myrrhs I've collected, and I am excited to have a greater degree of control as to just how much gum is used in a build. Following this experiment, I processed all of the Hojari frankincense I had in preparation for a bright frankincense-forward build that I'll share soon.
[^1]: First we peeled fresh ginger with a spoon to preclude any bitterness that might be introduced by the papery skin, then we would juice the ginger, let the starches settle in the fridge overnight and pour the clarified juice off of the top the following day, after which we'd combine the juice 1:1 by volume with water; et voilà, we have ginger syrup.

View File

@ -0,0 +1,36 @@
---
title: "What Do We Expect from Fragrance? Natural Incense in an Unnatural World"
description: How our expectations influence the way we experience fragrance and where natural incense fits in.
date: 2024-12-18
tags:
- Essays
- Incense
- Incense Making
synopsis: How our expectations influence the way we experience fragrance and where natural incense fits in.
imageURL: /img/incense_seal.webp
imageAlt: A burning incense seal in a flat brass censer.
mastodon_id: "113677779325283607"
---
Smoke was the first breath of early civilization, its rising plumes a synonym for human presence. This byproduct of life-sustaining flame has been constant companion to our evolution as a species, changing not only human lives, but [human bodies](https://www.psu.edu/news/research/story/where-theres-smoke-and-mutation-there-may-be-evolutionary-edge-humans). As the ubiquity of smoke rendered transparent to our ancestors' noses the once harsh notes of burning plant matter, there must have been a sense of magic when our forebears happened to toss a well-resinated tree branch or a fragrant herb upon the coals. It is little wonder, then, that the word "perfume" [stems from the Latin "perfumare,"](https://www.etymonline.com/word/perfume) translating to "through smoke."
## A rose by any other… chemical composition?
In these ancient times, the mention of a rose might have brought two fragrances to mind: that of a freshly blossomed rose in the bush, and that of the petals on the coals of a fire or burned in a censer. Later, enthusiasts of nerikoh or other forms of non-combustible incense would also become familiar with the fruity, acidic notes of gently heated rose petals. The situation is much changed today; for most people, the idea of the fragrance of rose is in no way related to incense-making traditions. Beautiful but aromatically impotent roses stuffed into plastic grocery store bins year-round aren't much help either. Today, synthesized ingredients like rose oxide, citronellol, or geraniol inform the average person's perception of how a rose smells; for those with expensive tastes, this perception may also be derived from a "natural" concentrate such as rose essential oil, wherein vast quantities of flowers are shoveled into a device and divested of volatile aromatic compounds via an industrial steam distillation process, which can result in [tiny yields, such as, for example: one part oil for every 3,000 parts roses](https://en.wikipedia.org/wiki/Rose_oil#adulteration).[^1]
In the incense making world, the siren song of these convenient ingredients is ever-present, with some even claiming that it's outright impossible to express the delicate fragrance of flower blossoms in combustible incense without them. While it is true that some fragrances cannot be expressed at all in this way, I do not believe that rose is among them, especially if we are willing to adjust our expectations and consider *what it means* to smell a rose. While there are many who would assert that the true fragrance of a material is to be found in its concentrated derivatives, given that a perfume might contain the strength of hundreds of roses while containing only a fraction of the many compounds that comprise the fragrance of a living rose, can it really be said that it effectively emulates what it is to smell a rose?
## Too much of a… thing
There have been many articles written on the field of "scent marketing," or "[sensory branding](https://en.wikipedia.org/wiki/Sensory_branding#Smell)," in which marketers manipulate the emotions of their customers through fragrance, with aim to bolster sales or steer brand perception through a medium that speaks to humankind on a most intimate and primal level. From perfumed love letters, to the occasional baker realizing that keeping something in the oven at all times certainly doesn't *hurt* sales, this is not a new phenomenon. What is new, however, is the ease with which shallow replicas of even the worlds scarcest aromatics can be whipped up with alacrity by a worker in a lab coat, and fragrance imbued into any material, any space, and any setting with little more than a few pumps of a spray bottle. This influences not only the way we think of aromatic ingredients and how their scents become known to us, but how we perceive fragrance itself: where once the acrid notes of burning wood were rendered transparent, now it is bright floral terpenes evocative of sunny spring mornings and bumblebees that fade into the periphery of our qualia; the fragrance of fresh citrus peel comes to evoke fluorescent lights and shiny tiled floors, that of vanilla becomes, well, *vanilla.*
Fragrance chemistry, the ability to synthesize compounds that speak directly to human emotion, must be among the most powerful of the cheat codes made available to us through the [Game Genie](https://en.wikipedia.org/wiki/Game_Genie#NES) of industrialization. While at first glance it seems too good to be true, you soon realize that the excitement of receiving a [P-Wing](https://www.mariowiki.com/P-Wing) is lost when you can simply spam the A-button to fly past a level; it's just not special any more—further, it loses its utility. Today there is no escape from fragrance. Your average American leaves the house with minty teeth, hair styled with wax scented with a synthetic approximation of eucalyptus and lime peel, wearing clothing washed with a "fresh laundry" fragranced detergent and dried with a lemon fabric softener; after bathing with sandalwood soap, they apply "sea salt and cedar" deodorant and a cologne featuring dozens of compounds, including a handful intending to approximate agarwood and bergamot (what the cologne adds here I struggle to imagine). In this veritable cacophony, most people fail to notice much of anything at all unless it's utterly redolent, and those who do are often those with sensory issues for whom fragrance is, more often than not, a special form of torture, inescapable so long as they wish to occupy a public space.
## Expecting redolence
In the noisily fragrant environment in which most of us live, it is interesting to consider those notes that do cause us to take notice: the humming of a cherry lip balm; the undulating tenor of a fresh bar of hand-soap; the [death metal pig-squealing](https://youtu.be/hCFBrQWYe3o?si=TWc0qzSkxNp_aOaw&t=50) of a Glade PlugIn®. In each case, our attention is arrested—violently seized and detained as hundreds of volatile organic compounds fight for access to our olfactory receptors like so many tired workers scrambling for a square foot of floor-space on the train during rush hour, only this time they compete in teams. Like music, fragrance has been demoted from something precious and closely associated with those things that we considered to be sacred—reduced to a dollar-store simulacrum stuffed into a mascot costume and made to flip a sign beside countless products that would otherwise fail to vacate store shelves on the merit of their performance alone. Certainly, some would point to the cheap ubiquity of fragrance as a sign that access has improved; after all, did the average medieval tradesman have a passing familiarity with the fragrance of sandalwood? I would rebut: do we?
In such a world, the fragrance of natural incense, incense free of unnaturally synthesized or concentrated aromatics, can be to our environment as the tune of a songbird is to the roar of passing traffic. In our homes, we can largely retreat from the soundtrack of daily life and create quiet, as far as noise is concerned. Creating quiet from fragrance, however, requires a greater degree of effort. Irrespective of our environment, much of the difficulty newcomers face in "listening to" natural incense stems from their expectations, warped by the ceaseless atonal chorus of fragrance around them. Chiefly, the hurdle that must be overcome is the idea of fragrance as a background element—a sort of olfactory elevator music; incense is, and deserves to be seen as, an activity in and of itself. When we adopt this mindset and listen with intention, it is remarkable what we are able to parse in even quite unsuited environments. Incense doesn't have to compete with the pumpkin-spice wax-melts of the world; these things serve different purposes.
## Fortissimo
Adding to their similarities, fragrance and music share a common loss: that of dynamics. The modulation of volume was historically an important piece of the emotional pull that music can have on its listeners; modern production largely omits this technique, barring a grand pause or two, in favor of a [loudness war](https://en.wikipedia.org/wiki/Loudness_war). As in classical music, classical fragrance employs this tool, creating one of the great points of pleasure of the incense format. Natural incense moves and changes, undulating in fragrance and strength, floating on the minute air currents of the room. Here, subtlety is as much an asset as is strength. I'm always disappointed to light a stick only to find that it spews a steady stream of oil-based fragrance into my living space, whether or not synthetics are involved. To be clear, I'm not inherently against the use of concentrates in incense, or even synthetics, which are often chemically identical to compounds found in natural materials. That said; for those seeking a sharp, cologne-like fragrance with unnatural clarity and strength, I believe incense is a poor choice.
While natural incense can indeed have plenty of fragrance, as an incense maker, I leave reaching for that 'beaten with a pillowcase of cinnamon sticks' projection to makers of scented candles and exfoliating bath soaps. If I intended to add to the cacophony, I'd reach for simpler means: a reed diffuser perhaps. Instead, what I aim to do is create an opportunity for respite, to create something beautiful that asks for attention rather than steals it. This approach respects the material realities of the ingredients that comprise incense, as well as the format itself. When one takes this approach, it's not long before one reaches the realization that rose petals carefully expressed in the smoke of a burning stick of incense do indeed smell of rose. So too do petals warming on a heater. So does rose oil, as well as burying your face in a fragrant blossom.
[^1]: To put this in more comprehensible terms, taking this ratio as gospel: if a quantity of rose petals equivalent to the weight of the average man living in the U.S.A. were to be distilled, the resulting essential oil would amount to *30 grams* of extremely concentrated oil.

View File

@ -0,0 +1,39 @@
---
title: "What Ive Been Doing with Incense Lately"
description: "New sticks, faster build development, percolating, and something coming soon?"
date: 2025-07-12
tags:
- Incense
- Incense Making
synopsis: "New sticks, faster build development, percolating, and something coming soon?"
imageURL: /img/what_ive_been_doing_with_incense_lately/dropper.webp
imageAlt: "A brass incense powder dropper with a bamboo lid and a tapered nozzle beside a brass hammer, a spoon, and a tray filled with white ash and several burned trails. All of this is on top of my messy work table."
mastodon_id: "114848206538212433"
---
It's been a while since I've written about incense making; to be honest, things have slowed down a little. It's been pretty hot in Chicago lately—I find that my sense of smell is dulled as the temperature and humidity rises. Unfortunately my apartment is very poorly insulated, so I've been burning, testing, and experimenting less as a result. The heat hasn't put me off entirely though; here's what I've been up to.
## Speeding up the creative process
I've picked up a device[^1] designed to help you make Chinese incense seals, whereby a design, or seal, of incense powder is burned atop a layer of ash. The kit I ordered came with a bag of ash, a ceramic tray, a brass dropper, and a small brass hammer with a detachable plastic tip.
[![A brass incense powder dropper with a bamboo lid and a tapered nozzle beside a brass hammer, a spoon, and a tray filled with white ash and several burned trails. All of this is on top of my messy work table.](/img/what_ive_been_doing_with_incense_lately/dropper.webp "You whack the thing with that wee hammer to make incense powder come out.")](/img/what_ive_been_doing_with_incense_lately/dropper.webp)
I didn't buy this for casual incense burning, but to speed up the process of creating an incense build, or blend. Rather than painstakingly making an impression in a bed of ash and filling it with incense powder using a tiny spoon, I have taken to using the dropper to quickly lay a trail of incense powder down for rapid iteration.
## Beau Soir
With six one-gram iterations using this technique, I managed to develop a new build for a stick I'm calling "Beau Soir," after the [utterly beautiful melody](https://www.youtube.com/watch?v=xKCcFxBP2o0&list=RDxKCcFxBP2o0). The fragrance is designed to evoke a walk through a garden on a cool evening: moist soil; cool air; greenery; gentle floral notes. In addition to being the first build I've developed with my swish new dropper (an excellent experience), I am using some new and exciting ingredients: namely musk root, plus a type of rhubarb. This is also another effort on my part to incorporate *actual flowers* into incense. This is a difficult task without introducing a bundle of off-notes, and as a result, it's something not many Japanese-style incense makers do. I have Dave of [The World Makes Scents](https://theworldmakesscents.com/) to thank for this. He put in the work of figuring out a particular species of rose that actually works well in incense, then processing it into an extremely high quality powder using a ball mill so that none of the fragrance is lost to heat. This powder doesn't confer a rose-oil or rose-water-like strength, but it does add a subtle, hard to describe (almost fluffy? marshmallowy?) floral note that adds something special to a build. I'm fairly pleased with Beau Soir, with a couple of positive reviews in already. But at this point, I'm just about burned out on smelling the stuff, so I'm going to send out some samples soon to gather some more opinions before I do anything more with it.
## Percolating
It is a fact, though, that some ingredients simply do not play nicely in the burn, at least less some obscure Chinese processing techniques that I am not privy to. For instance, I recently ordered a bag of chamomile to try; a trail of ten percent chamomile to ninety percent sandalwood was already acrid, with only a subtle chamomile note. What is a humble incense maker to do? Well, I've had some success with tinctures; soaking six grams of Juniperus virginiana in a fluid ounce of lavender tincture and letting the liquid evaporate results in a *very* fragrant wood powder with a clear lavender note even a year later. Tinctures are expensive to buy though, and they take forever to make, so I've decided to give percolation a try. Instead of macerating a material for months like a traditional tincture, you can make a percolated extract in around 24 hours. They are meant to be much stronger too.
[![A close-up shot of the bottom part of my new dropping funnel suspended on a lab stand. It is full of sediment with a visible layer of liquid. The device tapers down to a thin tube, the drip speed controlled by a plastic stopcock.](/img/what_ive_been_doing_with_incense_lately/percolator.webp "It's like making a coffee. Very slowly.")](/img/what_ive_been_doing_with_incense_lately/percolator.webp)
The procedure begins by hydrating your material in whatever menstruum you've chosen (190 proof Everclear for me), adding just enough so that the texture becomes like wet sand, and letting it absorb for an hour. Then you load it into a device called a "dropping funnel," which is functionally an upside down bottle with the bottom cut off. After gently packing the material evenly, you carefully pour in the rest of your menstruum and let it reach the bottom of the funnel before sealing off the stopcock and letting the mixture macerate for 24 hours. When this step is complete, you allow the liquid to drain into a container, only opening the stopcock enough for a single drop to fall every one to three seconds.
My first clumsy attempt with 200g menstruum and 100g chamomile netted me ~100ml of potent chamomile extract, which I was pretty pleased about, so I've got some rose root in the drop funnel as we speak—another ingredient that doesn't smell especially nice when you set it on fire.
## Drop soon?
Some time ago, I had an offer to sell some of my incense in a friend's webstore, a very kind offer that I'd like to take advantage of, but I just haven't been set up for it. Well, I've been working on that. I've now got a {{ "DBA" | abbr("Doing Business As: an officially registered name for a person or a business other than their full legal name or business name.") | safe }}[^2], and I'm working on the branding to match. I know this all sounds very official, but my intention is only to do a drop every now and then rather than making a real enterprise out of incense making[^3], something that is simply out of reach at the moment. While I intend to keep things small, I still want to set things up to the best of my ability. That said, don't get too excited; it'll likely be a while yet!
[^1]: I managed to dig up the link to buy the thing too: [here's where to go if you want one](https://www.aliexpress.us/item/3256806931365339.html). It looks like you have to purchase the hammer and tray separately. Kin Objects [also sells one](https://kinobjects.com/products/incense-powder-dropper-kit?variant=41578587193367).
[^2]: And no, I'm not saying what it is yet!
[^3]: Honestly, I don't know whether I'd want to; I want to be sure that something I do for joy and artistic expression doesn't become a source of stress.

View File

@ -0,0 +1,22 @@
---
title: "Incense Review: Pikake Jasmine from Yi-Xin Craft Incense"
description: "Florals are a notoriously difficult incense category. Today I'm taking a look at Yi-Xin Craft Incense's Pikake Jasmine sticks."
date: 2025-04-08
tags:
- Incense
- Incense Review
synopsis: "Florals are a notoriously difficult incense category. Today I'm taking a look at Yi-Xin Craft Incense's Pikake Jasmine sticks."
mastodon_id: "114303689771167166"
---
In June of 2024, I purchased Pikake Jasmine of Yi-Xin Craft Incense's floral *Faces in Bloom* collection. I was immediately impressed with it, but I was suspicious about how the Jasmine fragrance was achieved, and so wanted to see if the fragrance diminished over time before penning a review. I am happy to report that, close to a year later, Yi-Xin's Pikake Jasmine remains as impressive as ever.
The packaging describes these sticks as follows: "Our custom processed 'Stanford' Cedar material blended with sustainable sandalwoods and Pikake jasmine flowers." True to its name, there is a pronounced jasmine note on the unlit stick. Interestingly, actual jasmine flowers (at least the varieties that I am familiar with) are very finicky and do not work well in combustible incense.[^1] When jasmine buds are processed in India, they have to be picked at precisely the right time, and the essential oil must be distilled within hours before the buds lose their fragrance entirely. All of this in addition to the fact that fragrance of jasmine is prominent on the unlit stick[^2] makes me wonder whether an absolute or essential oil was used, or some other process such as [resin enfleurage](https://mermadearts.com/i/enfleurage-an-esoteric-and-ancient-art) (brought to my attention by Sara of [Incense Apprentice](https://incenseapprentice.substack.com/)). Of course, it might be that Pikake Jasmine is simply a varietal that works well when combusted. Who knows? Ken is infamously secretive with his processes, so we may never find out.
In the burn, the stick opens up with a beautiful sandalwood note: creamy, and slightly sweet. The cedar is quiet but present, accentuating the jasmine with light turpenous notes. This incense is less jasmine-forward than you might be led to believe from smelling the unlit stick, where the flower is prominent. When lit, the fragrance is more of a well-rounded composition, where each element is enhanced by the others. The gentle sweetness of sandalwood forms a fine base for the sharper cedar and jasmine notes, all coming together in a composition that is warm, woody, and markedly floral, while neither 'cooking' the jasmine nor beating you over the head with it. It's very pleasant.
Typical of Ken's work, this stick is also very clean, with no notable binder notes, smokiness, or acrid off-notes, even when you are sitting very close to the lit stick. Incense makers of any ilk will know how difficult this can be to achieve. I also appreciate the balance here; the fragrance doesn't even approach that sharp, cloying place that less expertly prepared floral incense tends to go. Building up in the room, the impression is predominantly that of a slightly cooler, floral sandalwood. While some sticks tend to undulate between notes, staving off olfactory fatigue, these are quite consistent and so greatly benefit from decent air circulation in the room; in fact, I rather prefer to have them burning in a room that I'm going in and out of frequently during what is quite a short but very enjoyable burn time.
Overall, Yi-Xin's Pikake Jasmine is an excellent entry into the notoriously difficult floral category of incense. As is often the case with Ken's work, this incense could serve as a reference for incense makers exploring what floral incense can be, and for those who simply enjoy burning incense, it's about as good of a floral expression as you can get in combustible incense, built on top of high-quality aromatic woods. Simple, approachable, and well-executed, I'd be happy to recommend this incense to anyone. My only regret is that I've run out.
[^1]: The last trail-burn test I performed with jasmine flowers smelled more like Marmite than jasmine!
[^2]: Many non-extract incense ingredients such as actual powdered woods, flowers, and resins don't have much fragrance until the stick is lit. It's not uncommon for natural, whole-plant based incense to have close to no fragrance at all before lighting, especially after it has aged.

View File

@ -0,0 +1,22 @@
---
permalink: /blogroll/nathanUpchurchBlogroll.opml
---
<?xml version="1.0" encoding="UTF-8"?>
<opml version="2.0">
<head>
<title>nathanUpchurchBlogroll.opml</title>
<ownerName>Nathan Upchurch</ownerName>
</head>
<body>{% for category in blogroll.categories %}
<outline text="{{ category.name }}">{% for blog in category.blogs %}
<outline
text="{{ blog.title }}"
description="{{ blog.description }}"
htmlUrl="{{ blog.url }}"
title="{{ blog.title }}"
type="rss"
version="RSS2"
xmlUrl="{{ blog.feedUrl }}"/>{% endfor %}
</outline>{% endfor %}
</body>
</opml>

View File

@ -0,0 +1,36 @@
---
layout: layouts/base.njk
title: Nathan Upchurch | Blogroll
structuredData: none
---
<h1>Blogroll</h1>
<p class="nodropcap">Here are some blogs and independent news outlets I like to read. You can click the RSS icon next to each to subscribe using <a href="../about-feeds/">your newsreader</a>, or import all of them at once by downloading and importing this convenient <a href="./nathanUpchurchBlogroll.opml" download>.opml file</a>.</p>
<p class="page-block">
<em>Skip to category:
{% for category in blogroll.categories %}
<a href="#{{ category.name | slugify }}">{{ category.name }}</a>{% if loop.last %}.{% else %},{% endif %}
{% endfor %}
</em></p>
{% for category in blogroll.categories %}
<section class="blogroll">
<h2 id="{{ category.name | slugify }}">{{ category.name }}:<a class="header-anchor" href="#{{ category.name | slugify }}">#</a></h2>
{% for blog in category.blogs %}
<div class="blogroll-category-group">
<a href="{{ blog.url }}"><h3>{{ blog.title }}</h3></a>
<a href="{{ blog.feedUrl }}">
<svg class="tag-feed-icon small" viewBox="0 0 155 155" width="153.349" height="152.909" version="1.0" xmlns="http://www.w3.org/2000/svg">
<title>RSS feed for {{ blog.url }}</title>
<g transform="translate(-427.323 -373.814)">
<ellipse style="opacity: 1; fill-opacity: 1; fill-rule: nonzero" transform="matrix(.86996 0 0 .86996 135.156 330.529)" cx="360.357" cy="200.643" rx="24.643" ry="23.929"></ellipse>
<path style="fill-opacity: 1; fill-rule: evenodd" d="m427.835 455.057-.073-30.273c64.706 3.375 100.619 49.673 101.5 101.94h-30.318c-.503-45.942-31.74-69.996-71.11-71.667z"></path>
<path style="fill-opacity: 1; fill-rule: evenodd" d="m428.201 404.571-.878-30.757C526.75 378.43 580 450.582 580.67 526.724l-31.197-.44c1.365-48.704-34.665-120.267-121.273-121.713Z"></path>
</g>
</svg>
</a>
<p>{{ blog.description | safe }}</p>
</div>
{% endfor %}
</section>
{% endfor %}

95
content/changelog.md Normal file
View File

@ -0,0 +1,95 @@
---
layout: layouts/base.njk
title: Nathan Upchurch | Changelog
structuredData: none
---
# Changelog
* 2025-08-14
* Implemented a [guestbook](/guestbook/).
* 2025-07-29
* Added [The 74](https://www.the74million.org/) to the [blogroll](/blogroll).
* 2025-07-14
* Added [Assigned](https://www.assignedmedia.org), [Prism](https://prismreports.org), [Rest of World](https://restofworld.org), and [The Appeal](https://theappeal.org/) to the [blogroll](/blogroll).
* Updated the [blogroll](/blogroll), adding a "skip to category" section, and adding direct links to all section headers.
* Removed "id" attribute from categories in [blogroll](/blogroll) [OPML](/blogroll/nathanUpchurchBlogroll.opml).
* Updated [/wish](/wish).
* 2025-07-13
* Renamed the [blog](/blog), updated [/about](/about), and added [Bardo Burner](https://bardoburner.com/) to the [blogroll](/blogroll).
* 2025-07-10
* Added [Toxel](https://www.toxel.com/) to the [blogroll](/blogroll).
* 2025-07-02
* Added [A Tea Addict's Journal](https://marshaln.com), [Bear Blog Discover](https://bearblog.dev/discover/), [Essence of Tea Blog](https://essenceoftea.com/blogs/blog), [Tea DB](https://teadb.org/), and [white2tea](https://white2tea.com/blogs/blog) to the [blogroll](/blogroll).
* 2025-06-26
* Added [Justine the Incenseur](https://justinetheincenseur.substack.com) to the [blogroll](/blogroll).
* 2025-06-24
* Implemented info boxes.
* 2025-06-09
* Added [Freethought Blogs](https://freethoughtblogs.com/) and [Cwyn's Death by Tea](https://deathbytea.blogspot.com/) to the [blogroll](/blogroll).
* 2025-06-06
* Implement [/now-burning](/now-burning/) and [/once-burned](/once-burned/).
* 2025-04-19
* Improve post list image sizing on mobile.
* 2025-04-08
* Updated the [index page](/) with a new "navigator" feature, and removed the post lists for a cleaner look.
* On the individual [tag](/tags/) pages: got rid of the big RSS logo, tweaked the text a little, added a "subscribe" button, and moved the buttons above the post list.
* Updated the [colophon](/about/colophon/).
* 2025-04-03
* Added [Graphic Rage with Aubrey Hirsch](https://aubreyhirsch.substack.com/) and [Usermag](https://www.usermag.co/) to the [blogroll](/blogroll).
* 2025-03-28
* Updated header on [/tags/](/tags/).
* 2025-03-27
* Added [Adam Silver](https://adamsilver.io/) to the [blogroll](/blogroll).
* 2025-03-20
* Added a bunch of design blogs to the [blogroll](/blogroll).
* 2025-03-12
* Removed [Kevin Drum's blog](https://jabberwocking.com/) from the [blogroll](/blogroll) in light of [his passing](https://jabberwocking.com/health-update-100/) on the seventh of March, 2025. Rest in peace, Kevin.
* 2025-03-11
* Updated [/wish](/wish).
* 2025-02-21
* Updated [/wish](/wish) again as my mum bought me some incense sticks for my birthday.
* 2025-02-20
* Updated [/wish](/wish).
* 2025-02-17
* Added [Incense Apprentice](https://incenseapprentice.substack.com) to the [blogroll](/blogroll).
* 2025-02-11
* Add [Signal](https://signal.me/#eu/j-om4cfsGXtfKo0UX28EQfEL_Gd1KpJr8nQpI9Smhdsb-r98eT5F6obQ1BcYZCcW) to [/me](/me).
* Remove [Loops](https://loops.video/) from [/me](/me).
* 2025-02-06
* Add [Friendica profile](https://friendica.world/profile/nathan) to [/me](/me).
* Deprecate cowsay of the day.
* 2025-02-04
* Re-implement support for Open Graph and Twitter Card metadata because [I'm an idiot](https://github.com/mastodon/mastodon/issues/33812#issuecomment-2635441141) and didn't realize that you can't use the `<meta>` tag for images and there appears to be no officially supported way to do this except for appropriating the mechanism reserved for app icons and favicons.
* 2025-02-02
* Implement [quiz features](/quizzes/) and add [first quiz](/quizzes/how-much-of-a-linux-nerd-are-you/).
* 2025-02-01
* Remove support for Open Graph and Twitter Card metadata because A. bloat, and B. screw Musk and Zuck.
* Add "image" meta tag for all pages, using either the image specified for the page / post, or my smiling face as a default.
* Fix issue with metadata output on gallery image pages.
* Stopped bundling CSS and injecting it into pages as I was sick of 1,000 lines of CSS on *every single page* (My build times are now a third of what they were).
* 2025-01-31
* Update the copyright notice in the footer.
* 2025-1-29
* Add [The Contrarian](https://contrarian.substack.com/) to the [blogroll](/blogroll).
* 2025-1-24
* Add buttons / update [/now/](/now/).
* 2025-1-23 - Simplify, simplify, simplify
* Styling updates to text, figures, and post lists
* Removed Mastodon comment embedding in favor of a simple button.
* Removed "Read Next / Read Previous" cards beneath articles.
* Prettier date formatting throughout.
* 2025-1-13
* Added [Popular Information](https://popular.info/) to the [blogroll](/blogroll).
* 2024-12-16
* Update PeerTube instance on [/me](/me).
* 2024-12-15
* Added a link to site stats on the [privacy](/about/privacy) page.
* Added [Uncloseted Media](https://www.unclosetedmedia.com/) to the [blogroll](/blogroll).
* 2024-12-14
* Implemented [/wish](/ai) a la [taylor.town/wish-manifesto](https://taylor.town/wish-manifesto).
* Added [Dom Corriveau](https://blog.ctms.me/) to the [blogroll](/blogroll).
* 2024-12-11
* Removed [Inverse](https://www.inverse.com/) from the [blogroll](/blogroll) due to excessive and annoying Amazon affiliate link articles.
* Added [Aftermath](https://aftermath.site/) to the [blogroll](/blogroll).
* Implemented [/changelog](/changelog) 🎉.
* Implemented [/ai](/ai) a la [slashai.page](https://slashai.page/).

7
content/error/403.md Normal file
View File

@ -0,0 +1,7 @@
---
layout: layouts/403.njk
permalink: error/403.html
title: Nathan Upchurch | 403
structuredData: none
eleventyExcludeFromCollections: true
---

7
content/error/404.md Normal file
View File

@ -0,0 +1,7 @@
---
layout: layouts/404.njk
permalink: error/404.html
title: Nathan Upchurch | 404
structuredData: none
eleventyExcludeFromCollections: true
---

View File

@ -0,0 +1,3 @@
export default {
layout: "layouts/post.njk",
};

View File

@ -1,3 +1,3 @@
module.exports = { export default {
eleventyExcludeFromCollections: true eleventyExcludeFromCollections: true
} }

View File

@ -17,16 +17,17 @@ permalink: /feed/feed.xml
</author> </author>
{%- for post in collections.posts | reverse %} {%- for post in collections.posts | reverse %}
{% set absolutePostUrl %}{{ post.url | htmlBaseUrl(metadata.url) }}{% endset %} {% set absolutePostUrl %}{{ post.url | htmlBaseUrl(metadata.url) }}{% endset %}
{% if post.image-url %}{% set imageURL %}{{ post.image-url | htmlBaseUrl(metadata.url) }}{% endset %}{% endif %} {% if post.data.imageURL %}{% set imageURL %}{{ post.data.imageURL | htmlBaseUrl(metadata.url) }}{% endset %}{% endif %}
{% set defaultImageURL %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endset %} {% set defaultImageURL %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endset %}
<entry> <entry>
<title>{{ post.data.title }}</title> <title>{{ post.data.title }}</title>
<description>{{ post.data.description | truncate(150) }}</description>
<link href="{{ absolutePostUrl }}"/> <link href="{{ absolutePostUrl }}"/>
<updated>{{ post.date | dateToRfc3339 }}</updated> <updated>{{ post.date | dateToRfc3339 }}</updated>
<id>{{ absolutePostUrl }}</id> <id>{{ absolutePostUrl }}</id>
<image> <image>
<url>{% if post.image-url %}{{ imageURL }}{% else %}{{ defaultImageURL }}{% endif %}</url> <url>{% if post.data.imageURL %}{{ imageURL }}{% else %}{{ defaultImageURL }}{% endif %}</url>
<title>{% if post.image-alt %}{{ post.image-alt }}{% else %}{{ metadata.defaultPostImageAlt }}{% endif %}</title> <title>{% if post.data.imageAlt %}{{ post.data.imageAlt }}{% else %}{{ metadata.defaultPostImageAlt }}{% endif %}</title>
<link href="{{ absolutePostUrl }}"/> <link href="{{ absolutePostUrl }}"/>
</image> </image>
<content type="html">{{ post.templateContent | transformWithHtmlBase(absolutePostUrl, post.url) }}</content> <content type="html">{{ post.templateContent | transformWithHtmlBase(absolutePostUrl, post.url) }}</content>

52
content/feeds.njk Normal file
View File

@ -0,0 +1,52 @@
---
pagination:
data: collections
size: 1
alias: tag
filter:
- all
- post
- posts
- tagList
- gallery
- galleryImages
- nowBurning
addAllPagesToCollections: true
eleventyComputed:
title: “{{ tag }}”
permalink: "/feeds/{{ tag | slugify }}.xml"
---
<?xml version="1.0" encoding="utf-8"?>{% set postslist = collections[ tag ] %}
<?xml-stylesheet href="../xsl/basic.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="{{ metadata.language }}">
<title>{{ title }} from {{ metadata.title }}</title>
<subtitle>{{ tag }}: {{ metadata.description }}</subtitle>
<link href="{{ metadata.url }}feeds/{{ tag | slugify }}.xml" rel="self"/>
<link href="{{ metadata.url | addPathPrefixToFullUrl }}"/>
<updated>{{ postslist | getNewestCollectionItemDate | dateToRfc3339 }}</updated>
<id>{{ metadata.url }}</id>
<author>
<name>{{ metadata.author.name }}</name>
<email>{{ metadata.author.email }}</email>
</author>
{%- for post in postslist | reverse %}
{% if post.url %}
{% set absolutePostUrl %}{{ post.url | htmlBaseUrl(metadata.url) }}{% endset %}
{% if post.data.imageURL %}{% set imageURL %}{{ post.data.imageURL | htmlBaseUrl(metadata.url) }}{% endset %}{% endif %}
{% set defaultImageURL %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endset %}
<entry>
<title>{{ post.data.title }}</title>
<description>{{ post.data.description | truncate(150) }}</description>
<link href="{{ absolutePostUrl }}"/>
<updated>{{ post.date | dateToRfc3339 }}</updated>
<id>{{ absolutePostUrl }}</id>
<image>
<url>{% if post.data.imageURL %}{{ imageURL }}{% else %}{{ defaultImageURL }}{% endif %}</url>
<title>{% if post.data.imageAlt %}{{ post.data.imageAlt }}{% else %}{{ metadata.defaultPostImageAlt }}{% endif %}</title>
<link href="{{ absolutePostUrl }}"/>
</image>
<content type="html">{{ post.templateContent | transformWithHtmlBase(absolutePostUrl, post.url) }}</content>
</entry>
{% endif %}
{%- endfor %}
</feed>

24
content/galleries.njk Normal file
View File

@ -0,0 +1,24 @@
---
pagination:
data: galleries
size: 1
alias: gallery
layout: layouts/base.njk
tags: gallery
structuredData: none
eleventyComputed:
title: "{{ gallery.title }}"
permalink: "/gallery/{{ gallery.title | slugify }}/"
description: "{{ gallery.description }}"
---
<h1>{{ gallery.title }}</h1>
<p class="page-block nodropcap">{{ gallery.description }}</p>
<section class="gallery-images">
{% for picture in gallery.pictures %}
<a href="/gallery/{{ gallery.title | slugify }}/{{ picture.filename | slugify }}/">
<wc-card class="gallery-image-container">
<img alt="{{ gallery.thumbAltText }}" class="gallery-image" src="{{ gallery.url }}{{ picture.filename }}">
</wc-card>
</a>
{% endfor %}
</section>

View File

@ -0,0 +1,8 @@
---
layout: layouts/base.njk
---
<h1>My image galleries.</h1>
<p class="page-block nodropcap">
Photography trips, memes, and other pictures I thought would be worth sharing.
</p>
{% include "gallerieslist.njk" %}

41
content/galleryImage.njk Normal file
View File

@ -0,0 +1,41 @@
---
pagination:
data: collections.galleryImages
size: 1
alias: picture
layout: layouts/base.njk
structuredData: none
eleventyComputed:
imageURL: "{{ picture.baseUrl }}/{{ picture.filename }}"
title: "Image: {{ picture.title }}"
permalink: "/gallery/{{ picture.containingGallery | slugify }}/{{ picture.filename | slugify }}/"
description: "{{ picture.title }} from gallery: {{ picture.containingGallery}}"
---
<article>
<h1>{{ picture.title }}</h1>
<div class="buttonContainer galleryButtons">
{% if picture.previousImage %}
<a href="../{{ picture.previousImage | slugify }}">
<button type="button">Previous</button>
</a>
{% endif %}
<a href="/gallery/{{ picture.containingGallery | slugify }}/">
<button type="button">Gallery</button>
</a>
{% if picture.nextImage %}
<a href="../{{ picture.nextImage | slugify }}">
<button type="button">Next</button>
</a>
{% endif %}
</div>
<figure>
<a href="{{ picture.baseUrl }}/{{ picture.filename }}">
<img src="{{ picture.baseUrl }}/{{ picture.filename }}" alt="{{ picture.altText }}">
</a>
{% if picture.caption %}
<figcaption>
{{ picture.caption }}
</figcaption>
{% endif %}
</figure>
</article>

55
content/guestbook.njk Normal file
View File

@ -0,0 +1,55 @@
---
layout: layouts/base.njk
title: Nathan Upchurch | Guestbook
structuredData: none
---
<h1>Sign My Guestbook</h1>
<!-- Guestbook Script -->
<script async src="https://guestbooks.meadow.cafe/resources/js/embed_script/835/script.js"></script>
<!-- Guestbook Form -->
<div id="guestbooks___guestbook-form-container">
<form id="guestbooks___guestbook-form"
action="https://guestbooks.meadow.cafe/guestbook/835/submit"
method="post">
<label for="name">Your name:</label>
<div class="guestbooks___input-container">
<input type="text"
id="name"
name="name"
required>
</div>
<label for="website">Your website (optional):</label>
<div class="guestbooks___input-container">
<input type="url"
id="website"
name="website">
</div>
<div id="guestbooks___challenge-answer-container"></div>
<label for="text">Your message:</label>
<div class="guestbooks___input-container">
<textarea id="text"
name="text"
rows="4"
style="width: 100%; box-sizing: border-box; resize: vertical;"
required></textarea>
</div>
<button type="submit">Sign Guestbook</button>
<div id="guestbooks___error-message"></div>
</form>
</div>
<!-- Attribution (optional but appreciated!) -->
<div id="guestbooks___guestbook-made-with" style="text-align: right; margin-top: 10px;">
<small>Powered by <a href="https://guestbooks.meadow.cafe" target="_blank">Guestbooks</a></small>
</div>
<!-- Messages Section -->
<hr/>
<h2 id="guestbooks___guestbook-messages-header">Messages</h2>
<div id="guestbooks___guestbook-messages-container"></div>

View File

@ -3,24 +3,5 @@ layout: layouts/home.njk
eleventyNavigation: eleventyNavigation:
key: Home key: Home
order: 1 order: 1
numberOfLatestPostsToShow: 10
--- ---
{% set postsCount = collections.posts | length %} {% include "navigator.njk" %}
{% set latestPostsCount = postsCount | min(numberOfLatestPostsToShow) %}
{% set postslist = collections.posts | head(-1 * numberOfLatestPostsToShow) %}
{% set postslistCounter = postsCount %}
{% include "postslist.njk" %}
{% set morePosts = postsCount - numberOfLatestPostsToShow %}
{% if morePosts > 0 %}
<p>See {{ morePosts }} more post{% if morePosts != 1 %}s{% endif %} in <a href="/blog/">the blog</a>.</p>
{% endif %}
{# List every content page in the project #}
{#
<ul>
{%- for entry in collections.all %}
<li><a href="{{ entry.url }}"><code>{{ entry.url }}</code></a></li>
{%- endfor %}
</ul>
#}

View File

@ -1,4 +1,7 @@
--- ---
title: Nathan Upchurch title: Nathan Upchurch
layout: layouts/links.njk layout: layouts/links.njk
eleventyNavigation:
key: Contact
order: 3
--- ---

23
content/now-burning.njk Normal file
View File

@ -0,0 +1,23 @@
---
layout: layouts/base.njk
title: "Nathan Upchurch | Now Burning: What incense I'm burning at the moment."
structuredData: none
postlistHeaderText: "What I've been burning:"
---
{% set burning = collections.nowBurning | last %}
<h1>Now Burning:</h1>
<article class="post microblog-post">
<img class="microblog-icon" src="/img/censer.svg">
<div class="microblog-status">
<h2 class="">{{ burning.data.title }}{% if burning.data.manufacturer %}, {{ burning.data.manufacturer }}{% endif %}, {{ burning.date | niceDate }}, {{ burning.data.time }}</h2>
{% if burning.content %}
<div class="microblog-comment">
{{ burning.content | safe }}
</div>
{% endif %}
</div>
</article>
<a href="/once-burned/">
<button type="button">Previous Entries »</button>
</a>

View File

@ -0,0 +1,7 @@
---
title: "Moss Garden (Nokiba)"
manufacturer: "Shoyeido"
date: 2025-06-06 19:12:00
time: 7:12 PM
---
Love this stick. Absolute classic.

View File

@ -0,0 +1,7 @@
---
title: A chunk of Palo Santo that I lit on fire
manufacturer:
date: 2025-06-08 22:40:00
time: 10:40 PM
---

Some files were not shown because too many files have changed in this diff Show More