Compare commits
49 Commits
859272b2a5
...
responsive
Author | SHA1 | Date | |
---|---|---|---|
0b9b30f6c2 | |||
e4f4a0ba26 | |||
db56e011eb | |||
54bd9ad9ec | |||
3d672ce033 | |||
2c93d9199e | |||
621ad15006 | |||
345a62ea47 | |||
cdb82fe827 | |||
7f80d0615c | |||
2913703074 | |||
777d33a4bb | |||
0cdf1e297b | |||
b09aa47d06 | |||
7b00d49d43 | |||
62f6268651 | |||
0387793868 | |||
ed1acf8cc8 | |||
bd04a9be19 | |||
77067c7e01 | |||
ccdaea6d80 | |||
836463ad92 | |||
54ec74c6ed | |||
e55fa73d92 | |||
4569060d41 | |||
a7c7d31552 | |||
0536a3aeb7 | |||
a0dc421189 | |||
cf18f89e10 | |||
6379ce0041 | |||
07f3be8083 | |||
3de856f413 | |||
59484d8363 | |||
a6bd281946 | |||
049ba826dc | |||
b1b57c7b6a | |||
bfb31ba036 | |||
e0e09bcea1 | |||
8100e05cc3 | |||
0aee314908 | |||
779cce9f9d | |||
12baf5df2e | |||
dfa3989409 | |||
e3061b9f5b | |||
7582ac5218 | |||
2039c3d886 | |||
08021fa945 | |||
948fab0bb9 | |||
a6f3143466 |
42
README.md
@ -1,17 +1,37 @@
|
|||||||
# nathanupchurch.com
|
# My 11ty Blog
|
||||||
My blog, based on the very helpful eleventy-base-blog v8.
|
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).
|
||||||
|
|
||||||

|
## 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
|
||||||
|
|
||||||
## Documentation
|
### Fediverse Integration
|
||||||
|
* Mastodon [toot embedding](https://upchur.ch/gitea/n_u/nathanupchurch.com/wiki/Home#embed-a-toot-from-mastodon-using-the-toot-shortcode)
|
||||||
|
* [Commenting](https://upchur.ch/gitea/n_u/nathanupchurch.com/wiki/Home#adding-comments-via-mastodon) via Mastodon
|
||||||
|
|
||||||
### Metadata
|
### Indieweb
|
||||||
Site metadata such as author info, title, etc. lives in _data/metadata.js. Links on the /me page, and default post images are also configured here.
|
* [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"
|
||||||
|
|
||||||
### How to add a cowsay to a post with the custom nunjucks filter
|
### Technical
|
||||||
You can use the `cowsay` filter to output a captioned `<figure>` containing a copy of an output from the cowsay program. Instead of using the usual three backticks, this method is accessible to visually impaired users thanks to the automatic captioning. Here's how to do it:
|
* Reusable web components:
|
||||||
|
* Card
|
||||||
|
* Mastodon comment
|
||||||
|
* Profile picture
|
||||||
|
* Embedded toot
|
||||||
|
|
||||||
1. Add a copy of the cowsay output you'd like to display to _data/cowList.js. Be sure and escape any backslashes.
|
### Quality of Life
|
||||||
2. Use the filter like this: `{{ cowList.name | cowsay | safe }}`.
|
* 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
|
||||||
|
|
||||||
The `safe` filter is necessary so that Eleventy doesn't sanitize our HTML.
|
### Weird and Wonderful
|
||||||
|
* [Accessible cowsay output embedding](https://upchur.ch/gitea/n_u/nathanupchurch.com/wiki#add-a-cowsay-to-a-post)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module.exports = {
|
export default {
|
||||||
onScience: `
|
onScience: `
|
||||||
_________________________________________
|
_________________________________________
|
||||||
( Once, when the secrets of science were )
|
( Once, when the secrets of science were )
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module.exports = {
|
export default {
|
||||||
title: "Nathan Upchurch",
|
title: "Nathan Upchurch",
|
||||||
logo: "/img/logo.svg",
|
logo: "/img/logo.svg",
|
||||||
url: "https://nathanupchurch.com/",
|
url: "https://nathanupchurch.com/",
|
||||||
@ -8,14 +8,14 @@ module.exports = {
|
|||||||
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"
|
||||||
},
|
},
|
||||||
copyrightNotice: "© Nathan Upchurch 2022 - 2024",
|
copyrightNotice: "© Nathan Upchurch 2022 - 2024",
|
||||||
defaultPostImageURL: "/img/vasilina-sirotina-1NMPvajSt9Q-unsplash_copy.avif",
|
defaultPostImageURL: "/img/vasilina-sirotina-1NMPvajSt9Q-unsplash_copy.avif",
|
||||||
defaultPostImageAlt: "The default post image: a close picture of the dark green leaves of a plant.",
|
defaultPostImageAlt: "The default post image: a close picture of the dark green leaves of a plant.",
|
||||||
mastodonHost: "lounge.town",
|
mastodonHost: "lounge.town",
|
||||||
mastodonUser: "nathanu",
|
mastodonUser: "nathanu",
|
||||||
postlistHeaderText: "Latest Posts",
|
postlistHeaderText: "Latest posts from the blog:",
|
||||||
socialLinks: [
|
socialLinks: [
|
||||||
{
|
{
|
||||||
title: "My Blog",
|
title: "My Blog",
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
<a href="#skip" class="visually-hidden">Skip to main content</a>
|
<a href="#skip" class="visually-hidden">Skip to main content</a>
|
||||||
<header>
|
<header>
|
||||||
<a href="/" class="home-link"><img class="logo" src="{{ metadata.logo }}" alt="{{ metadata.title }}"></a>
|
<a
|
||||||
|
href="/"
|
||||||
|
class="home-link">
|
||||||
|
<img
|
||||||
|
class="logo"
|
||||||
|
src="{{ metadata.logo }}"
|
||||||
|
alt="{{ metadata.title }}">
|
||||||
|
</a>
|
||||||
{% if not hideNav %}{% include "nav.njk" %}{% endif %}
|
{% if not hideNav %}{% include "nav.njk" %}{% endif %}
|
||||||
</header>
|
</header>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
layout: layouts/base.njk
|
layout: layouts/base.njk
|
||||||
showPostListHeader: yep
|
showPostListHeader: yep
|
||||||
---
|
---
|
||||||
<h1>Welcome to Nathan’s Website and Blog.</h1>
|
<h1>Hi there, friend.</h1>
|
||||||
<p class="nodropcap page-block">Hi there, I'm Nathan Upchurch. 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. Learn more <a href="about">about me</a>, see <a href="now">what I've been up to lately</a>, or have a look at my latest posts below.</p>
|
<p class="nodropcap page-block">My name is Nathan Upchurch. Welcome to my personal website and blog, where I write about <a href="./tags/incense/">incense,</a> <a href="./tags/foss-floss/">free and open source software,</a> design, <a href="./tags/vegan-cooking/">vegan cooking,</a> music, and all sorts of <a href="/tags">other topics</a> that I find interesting. Learn more <a href="about">about me,</a> see <a href="now">what I’ve been up to lately,</a> or have a look at my latest blog posts below.</p>
|
||||||
|
|
||||||
{{ content | safe }}
|
{{ content | safe }}
|
||||||
|
@ -5,29 +5,42 @@ layout: layouts/base.njk
|
|||||||
{%- css %}{% include "public/css/code.css" %}{% endcss %}
|
{%- css %}{% include "public/css/code.css" %}{% endcss %}
|
||||||
<article class="post">
|
<article class="post">
|
||||||
<h1>{{ title }}</h1>
|
<h1>{{ title }}</h1>
|
||||||
|
{% if not hideMetadata %}
|
||||||
<div class="post-metadata">
|
<div class="post-metadata">
|
||||||
{% if author %}
|
{% if author %}
|
||||||
|
{% if author.profilePic %}
|
||||||
{% if author.url %}<a href="{{ author.url }}">{% endif %}
|
<img class="profilePic" src="{{ author.profilePic }}">
|
||||||
<p>{% if author.name %}{{ author.name }}, {% endif %}{% if author.url %}</a>{% endif %}<time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time></p>
|
{% endif %}
|
||||||
|
<div class="post-metadata-copy">
|
||||||
|
<p>{% if author.url %}<a href="{{ author.url }}">{% endif %}
|
||||||
|
{% if author.name %}{{ author.name }}, {% endif %}{% if author.url %}</a>{% endif %}<time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time></p>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
{% if metadata.author.profilePic %}
|
||||||
{% if metadata.author.url %}<a href="{{ metadata.author.url }}">{% endif %}
|
<img class="profilePic" src="{{ metadata.author.profilePic }}">
|
||||||
<p>{% if metadata.author.name %}{{ metadata.author.name }}, {% endif %}{% if metadata.author.url %}</a>{% endif %}<time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time></p>
|
{% endif %}
|
||||||
|
<div class="post-metadata-copy">
|
||||||
|
<p>{% if metadata.author.url %}<a href="{{ metadata.author.url }}">{% endif %}
|
||||||
|
{% if metadata.author.name %}{{ metadata.author.name }}, {% endif %}{% if metadata.author.url %}</a>{% endif %}<time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time></p>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
<ul>
|
<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>
|
||||||
{%- endfor %}
|
<a
|
||||||
</ul>
|
href="{{ tagUrl }}"
|
||||||
|
class="post-tag">
|
||||||
|
{{ tag }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{%- endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
{{ content | safe }}
|
{{ content | safe }}
|
||||||
</article>
|
</article>
|
||||||
{% include "mastodonComments.njk" %}
|
{% include "mastodonComments.njk" %}
|
||||||
|
@ -8,43 +8,27 @@
|
|||||||
<div class="continue-discussion">
|
<div class="continue-discussion">
|
||||||
<a class="link-button" href="https://{{ metadata.mastodonHost }}/@{{ metadata.mastodonUser }}/{{ mastodon_id }}">
|
<a class="link-button" href="https://{{ metadata.mastodonHost }}/@{{ metadata.mastodonUser }}/{{ mastodon_id }}">
|
||||||
<button type="button">
|
<button type="button">
|
||||||
Comment by replying to this post on Mastodon »
|
Reply on Mastodon to comment »
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<template id="comment-template">
|
<template id="comment-template">
|
||||||
<wc-comment
|
<wc-card>
|
||||||
author_name=""
|
<wc-comment
|
||||||
author_url=""
|
author_name=""
|
||||||
avatar_url=""
|
author_url=""
|
||||||
comment_content=""
|
avatar_url=""
|
||||||
publish_date=""
|
comment_content=""
|
||||||
sharp_corner="">
|
publish_date=""
|
||||||
</wc-comment>
|
sharp_corner="">
|
||||||
|
</wc-comment>
|
||||||
|
</wc-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script type="module">
|
||||||
const monthMap = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
import {dateSuffixAdder, monthMap, timeFormatter} from "../../js/modules/mastodonDateTools.js";
|
||||||
|
|
||||||
const dateSuffixAdder = (date) => {
|
|
||||||
if (date > 9 && date < 20) {
|
|
||||||
return "th";
|
|
||||||
} else {
|
|
||||||
let dateString = date < 10 ? "0" + date : "" + date;
|
|
||||||
if (dateString[1] < 4 && dateString[1] > 0) {
|
|
||||||
return dateString[1] == 1 ? "st" :
|
|
||||||
dateString[1] == 2 ? "nd" :
|
|
||||||
dateString[1] == 3 ? "rd" : null;
|
|
||||||
} else {
|
|
||||||
return "th"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const timeFormatter = (hours, minutes) => {
|
|
||||||
return `${hours < 12 ? hours : hours - 12}:${minutes < 10 ? "0" : ""}${minutes} ${hours < 12 ? "AM" : "PM"}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const renderComment = (comment, target, parentIdm) => {
|
const renderComment = (comment, target, parentIdm) => {
|
||||||
const node = document
|
const node = document
|
||||||
@ -56,8 +40,7 @@ const renderComment = (comment, target, parentIdm) => {
|
|||||||
const dateTime = `${dateObj.getDate()}${dateSuffixAdder(dateObj.getDate())} of ${monthMap[dateObj.getMonth()]}, ${dateObj.getFullYear()}, at ${timeFormatter(dateObj.getHours(), dateObj.getMinutes())}`;
|
const dateTime = `${dateObj.getDate()}${dateSuffixAdder(dateObj.getDate())} of ${monthMap[dateObj.getMonth()]}, ${dateObj.getFullYear()}, at ${timeFormatter(dateObj.getHours(), dateObj.getMinutes())}`;
|
||||||
|
|
||||||
node.querySelector("wc-comment").setAttribute("author_name", comment.account.display_name);
|
node.querySelector("wc-comment").setAttribute("author_name", comment.account.display_name);
|
||||||
node.querySelector("wc-comment").setAttribute("author_url",
|
node.querySelector("wc-comment").setAttribute("author_url", comment.url.replace(/\/[0-9]+/, ""));
|
||||||
`${comment.account.acct == "{{ metadata.mastodonUser }}" ? "https://{{ metadata.mastodonHost }}/@{{ metadata.mastodonUser }}" : comment.account.acct}`);
|
|
||||||
node.querySelector("wc-comment").setAttribute("avatar_url", comment.account.avatar_static);
|
node.querySelector("wc-comment").setAttribute("avatar_url", comment.account.avatar_static);
|
||||||
node.querySelector("wc-comment").setAttribute("comment_content", comment.content);
|
node.querySelector("wc-comment").setAttribute("comment_content", comment.content);
|
||||||
node.querySelector("wc-comment").setAttribute("publish_date", dateTime);
|
node.querySelector("wc-comment").setAttribute("publish_date", dateTime);
|
||||||
|
@ -1,51 +1,62 @@
|
|||||||
{%- if collections.posts %}
|
{% if collections.posts %}
|
||||||
{%- set previousPost = collections.posts | getPreviousCollectionItem %}
|
{% set previousPost = collections.posts | getPreviousCollectionItem %}
|
||||||
{%- set nextPost = collections.posts | getNextCollectionItem %}
|
{% set nextPost = collections.posts | getNextCollectionItem %}
|
||||||
{%- if nextPost or previousPost %}
|
{% if nextPost or previousPost %}
|
||||||
<section class="links-nextprev">
|
<section class="links-nextprev">
|
||||||
<h2>Read Next</h2>
|
<h2>Read Next</h2>
|
||||||
<div class="postlist-item-container">
|
<div class="postlist-item-container">
|
||||||
{%- if previousPost %}
|
{% if previousPost %}
|
||||||
<article class="postlist-item{% if post.url == url %} postlist-item-active{% endif %}">
|
<article class="postlist-item{% if post.url == url %} postlist-item-active{% endif %}">
|
||||||
<a href="{{ previousPost.url }}" class="postlist-link">
|
<a href="{{ previousPost.url }}" class="postlist-link">
|
||||||
<div class="post-image-container">
|
<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 %}>
|
<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>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<div class="post-copy">
|
<div class="post-copy">
|
||||||
<a href="{{ previousPost.url }}" class="postlist-link">
|
<a href="{{ previousPost.url }}" class="postlist-link">
|
||||||
<p>Previous Article:</p>
|
<p>Previous Article:</p>
|
||||||
<h3>
|
<h3>
|
||||||
{% if previousPost.data.title %}{{ previousPost.data.title }}{% else %}<code>{{ previousPost.url }}</code>{% endif %}
|
{% if previousPost.data.title %}{{ previousPost.data.title }}{% else %}<code>{{ previousPost.url }}</code>{% endif %}
|
||||||
</h3>
|
</h3>
|
||||||
</a>
|
</a>
|
||||||
<time class="postlist-date" datetime="{{ previousPost.date | htmlDateString }}">{{ previousPost.date | readableDate("LLLL yyyy") }}</time>
|
<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 %}{{ previousPost.content | truncate(105) | safe }}{% endif %}
|
{% if previousPost.data.synopsis %}
|
||||||
</div>
|
<p>{{ previousPost.data.synopsis | truncate(105) | safe }}</p>
|
||||||
</article>
|
{% 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 %}
|
||||||
{%- 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 %}{{ nextPost.content | truncate(105) | safe }}{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
|
||||||
{%- endif %}
|
|
||||||
{%- endif %}
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
layout: layouts/base.njk
|
layout: layouts/post.njk
|
||||||
|
hideMetadata: yep
|
||||||
---
|
---
|
||||||
# How to use feeds.
|
# How to use feeds.
|
||||||
<p><!-- a <p> just to stop the dropcap from happening --></p>
|
<p><!-- a <p> just to stop the dropcap from happening --></p>
|
||||||
|
@ -6,18 +6,17 @@ eleventyNavigation:
|
|||||||
---
|
---
|
||||||
<article>
|
<article>
|
||||||
<h1>About me and this website I’ve built.</h1>
|
<h1>About me and this website I’ve built.</h1>
|
||||||
<h2>All about Nathan</h2>
|
<p>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 maker and appreciator, writer, electronics hobbyist, designer, programmer, music producer, print lover, and human with too many interests and too little time.</p>
|
||||||
<p>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 appreciator, 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, a little corner of the internet where I can talk about whatever I like without worrying about maintaining a ‘personal brand’, or constraining subject matter to those topics which might help advance my career or establish me as a ‘thought leader’. I'm here to express myself as a human and have fun writing about topics I enjoy. If you'd like to learn more about my professional accomplishments and work, I'll link my professional website here soon.</p>
|
<p>This is my personal website and blog, a little corner of the internet where I can talk about whatever I like without worrying about maintaining a ‘personal brand’, or constraining subject matter to those topics which might help advance my career or establish me as a ‘thought leader’. I’m here to express myself as a human and have fun writing about topics I enjoy. If you’d like to learn more about my professional accomplishments and work, I’ll link my professional website here soon.</p>
|
||||||
|
|
||||||
<h2>About this website</h2>
|
<h2>About this website</h2>
|
||||||
<p>This website is made with <a href="https://www.11ty.dev/">the 11ty static site generator</a>, free and open source variable typefaces <a href="https://www.gent.media/manrope">Manrope</a> and <a href="https://fraunces.undercase.xyz/">Fraunces</a>, along with plain-old HTML, CSS, and some vanilla JavaScript for the web components that I built to handle comments. I used the handy calculators on <a href="https://utopia.fyi">utopia.fyi</a> to help me implement fluid typography and spacing.
|
<p>This website is made with <a href="https://www.11ty.dev/">the 11ty static site generator</a>, free and open source variable typefaces <a href="https://fraunces.undercase.xyz/">Fraunces</a> and <a href="https://www.gent.media/manrope">Manrope</a>, along with plain-old HTML, CSS, and some vanilla JavaScript for the web components that I built to handle comments. I used the handy calculators on <a href="https://utopia.fyi">utopia.fyi</a> to help me implement fluid typography and spacing.</p>
|
||||||
|
|
||||||
I don't collect any of your personal information, full-stop. All webfonts, icons, and images are hosted locally (these things can sometimes be used to <a href="https://www.firstpost.com/world/how-google-uses-fonts-to-track-what-users-do-online-and-sell-data-to-advertisers-12496552.html">track people across the internet</a> otherwise). I use <a href="https://umami.is/">umami</a>, an open source, privacy-respecting analytics tool, to see how many people visit this website.
|
<p>I don’t collect any of your personal information, full-stop. All webfonts, icons, and images are hosted locally (these things can sometimes be used to <a href="https://www.firstpost.com/world/how-google-uses-fonts-to-track-what-users-do-online-and-sell-data-to-advertisers-12496552.html">track people across the internet</a> otherwise). I use <a href="https://umami.is/">umami</a>, an open source, privacy-respecting analytics tool, to see how many people visit this website.</p>
|
||||||
|
|
||||||
Miss when the internet was fun? Find more interesting personal blogs at <a href="https://blogroll.org">blogroll.org</a>, or <a href="https://ooh.directory/">ooh.directory</a>.</p>
|
<p>Miss when the internet was fun? Find more interesting personal blogs at <a href="https://blogroll.org">blogroll.org</a>, <a href="https://ooh.directory/">ooh.directory</a>, or surf through the webrings at the bottom of the page.</p>
|
||||||
|
|
||||||
<h2>Contact Me</h2>
|
<h2>Contact Me</h2>
|
||||||
<p>If you would like to say something nice, ask a question, or simply follow me on the fediverse, <a href="../me">here's where you can find me</a>.</p>
|
<p>If you would like to say something nice, ask a question, or simply follow me on the fediverse, <a href="../me">here’s where you can find me</a>.</p>
|
||||||
</article>
|
</article>
|
||||||
|
57
content/blog/a-breakthrough-incense-blend.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
|
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.*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[](/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.
|
||||||
|
|
||||||
|
[](/img/heart-of-lavender.webp)
|
||||||
|
|
||||||
|
Here is a comparison between *Grand Dame* and *Heart of Lavender*:
|
||||||
|
|
||||||
|
|
||||||
|
[](/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.
|
@ -1,4 +1,4 @@
|
|||||||
module.exports = {
|
export default {
|
||||||
tags: [
|
tags: [
|
||||||
"posts"
|
"posts"
|
||||||
],
|
],
|
||||||
|
41
content/blog/cedar-frankincense-incense.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
|
||||||
|
[](/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.
|
||||||
|
|
||||||
|
[](/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.
|
@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
title: A Perplexing Failure
|
||||||
|
description: Failing to make the most delicious batch of incense ever.
|
||||||
|
date: 2024-04-13
|
||||||
|
tags:
|
||||||
|
- Incense
|
||||||
|
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.
|
||||||
|
|
||||||
|
[](/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.
|
||||||
|
|
||||||
|
[](/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.
|
||||||
|
|
66
content/blog/kde-plasma-side-panel.md
Normal 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: "Show Panel," and body text: "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.
|
||||||
|
|
||||||
|
[](/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)
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
[](/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."
|
||||||
|
|
||||||
|
[](/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)
|
||||||
|
|
||||||
|
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.
|
21
content/blog/kheouns-blend.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
title: "Incense Review: Kheoun’s Blend"
|
||||||
|
description: Reviewing Kheoun’s Blend by The World Makes Scents.
|
||||||
|
date: 2024-06-23
|
||||||
|
tags:
|
||||||
|
- Incense
|
||||||
|
- Incense Review
|
||||||
|
synopsis: Reviewing Kheoun’s 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/).
|
||||||
|
|
||||||
|
[](/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.
|
@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
|
||||||
|
[")](/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!
|
@ -10,8 +10,10 @@ 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.
|
imageAlt: A small piece of a coreless, Japanese-style incense stick burning in a black cast-iron burner.
|
||||||
mastodon_id: "111732713202024407"
|
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.
|
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.
|
||||||
|
|
||||||
[](/img/dragons_blood_incense_copy.avif)
|
[](/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.
|
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.
|
||||||
|
26
content/blog/poison.md
Normal 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 I’d 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?
|
46
content/blog/switching-to-gnu-linux-mentally.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
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:
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
[")](/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.
|
||||||
|
|
||||||
|
[](/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.
|
BIN
content/blog/that-time-i-drew/1587521755455.jpg
Normal file
After Width: | Height: | Size: 277 KiB |
BIN
content/blog/that-time-i-drew/1587521817965.jpg
Normal file
After Width: | Height: | Size: 462 KiB |
BIN
content/blog/that-time-i-drew/1587521888334.jpg
Normal file
After Width: | Height: | Size: 235 KiB |
@ -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, I’ve not been able to scale up production as everything’s 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!
|
@ -1,3 +1,3 @@
|
|||||||
module.exports = {
|
export default {
|
||||||
eleventyExcludeFromCollections: true
|
eleventyExcludeFromCollections: true
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,28 @@ eleventyNavigation:
|
|||||||
key: Home
|
key: Home
|
||||||
order: 1
|
order: 1
|
||||||
numberOfLatestPostsToShow: 5
|
numberOfLatestPostsToShow: 5
|
||||||
|
numberOfNowPostsToShow: 1
|
||||||
---
|
---
|
||||||
|
<div class="now">
|
||||||
|
<h2>What I've been up to:</h2>
|
||||||
|
{% set postsCount = collections.now | length %}
|
||||||
|
{% set latestPostsCount = postsCount | min(numberOfNowPostsToShow) %}
|
||||||
|
{% set postslist = collections.now | head(-1 * numberOfNowPostsToShow) %}
|
||||||
|
{% set postslistCounter = postsCount %}
|
||||||
|
{% set showPostListHeader = false %}
|
||||||
|
{% include "postslist.njk" %}
|
||||||
|
<a class="link-button" href="/now/">
|
||||||
|
<button type="button">
|
||||||
|
See more on the “now” page
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% set postsCount = collections.posts | length %}
|
{% set postsCount = collections.posts | length %}
|
||||||
{% set latestPostsCount = postsCount | min(numberOfLatestPostsToShow) %}
|
{% set latestPostsCount = postsCount | min(numberOfLatestPostsToShow) %}
|
||||||
{% set postslist = collections.posts | head(-1 * numberOfLatestPostsToShow) %}
|
{% set postslist = collections.posts | head(-1 * numberOfLatestPostsToShow) %}
|
||||||
{% set postslistCounter = postsCount %}
|
{% set postslistCounter = postsCount %}
|
||||||
|
{% set showPostListHeader = true %}
|
||||||
{% include "postslist.njk" %}
|
{% include "postslist.njk" %}
|
||||||
|
|
||||||
{% set morePosts = postsCount - numberOfLatestPostsToShow %}
|
{% set morePosts = postsCount - numberOfLatestPostsToShow %}
|
||||||
|
@ -3,50 +3,20 @@ layout: layouts/base.njk
|
|||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: Now
|
key: Now
|
||||||
order: 4
|
order: 4
|
||||||
numberOfLatestPostsToShow: 4
|
|
||||||
---
|
---
|
||||||
{% set postsCount = collections.now | length %}
|
<article class="post">
|
||||||
{% set latestPostsCount = postsCount | min(numberOfLatestPostsToShow) %}
|
|
||||||
{% set postslist = collections.now | head(-1 * numberOfLatestPostsToShow) %}
|
|
||||||
{% set postslistCounter = postsCount %}
|
|
||||||
{% set morePosts = postsCount - numberOfLatestPostsToShow %}
|
|
||||||
<article>
|
|
||||||
<h1>Now: What’s Been Going on Lately?</h1>
|
<h1>Now: What’s Been Going on Lately?</h1>
|
||||||
{% set now = collections.now | last %}
|
{% set now = collections.now | last %}
|
||||||
<h2>{{ now.data.title }}</h2>
|
<h2>{{ now.data.title }}</h2>
|
||||||
{{ now.content | safe }}
|
{{ now.content | safe }}
|
||||||
<p class="metadata">Updated: {{ now.date | readableDate }} | <a href="https://nownownow.com/about">What is a now page?</a></p>
|
|
||||||
</article>
|
</article>
|
||||||
|
<p class="metadata">Updated: {{ now.date | readableDate }} | <a href="https://nownownow.com/about">What is a now page?</a></p>
|
||||||
|
|
||||||
|
{% set postsCount = collections.now | removeMostRecent | length %}
|
||||||
{% if postsCount > 1 %}
|
{% if postsCount > 1 %}
|
||||||
<h2>Previous Entries:</h2>
|
<h2>Previous Entries:</h2>
|
||||||
<section class="postlist">
|
{% set postslist = collections.now | removeMostRecent %}
|
||||||
<div class="postlist-item-container">
|
{% set showPostListHeader = false %}
|
||||||
{% for post in postslist | reverse %}
|
{% include "postslist.njk" %}
|
||||||
{% if post.data.title != now.data.title %}
|
|
||||||
<article class="postlist-item{% if post.url == url %} postlist-item-active{% endif %}">
|
|
||||||
<a href="{{ post.url }}" class="postlist-link">
|
|
||||||
<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 %}>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<div class="post-copy">
|
|
||||||
<a href="{{ post.url }}" class="postlist-link">
|
|
||||||
<h3>
|
|
||||||
{% if post.data.title %}{{ post.data.title }}{% else %}<code>{{ post.url }}</code>{% endif %}
|
|
||||||
</h3>
|
|
||||||
</a>
|
|
||||||
<time class="postlist-date" datetime="{{ post.date | htmlDateString }}">{{ post.date | readableDate("LLLL yyyy") }}</time>
|
|
||||||
{% if post.data.synopsis %}<p>{{ post.data.synopsis | truncate(150) | safe }}</p>{% else %}{{ post.content | truncate(150) | safe }}{% endif %}
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% if morePosts > 0 %}
|
|
||||||
<a href="/tags/now"><p>See {{ morePosts }} more post{% if morePosts != 1 %}s{% endif %}</a>.</p>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module.exports = {
|
export default {
|
||||||
tags: [
|
tags: [
|
||||||
"now"
|
"now"
|
||||||
],
|
],
|
||||||
|
15
content/now/now_2024-04-13.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
title: Touching Grass
|
||||||
|
description: What I've been up to lately — fresh air, more incense making, and doing more KDE stuff.
|
||||||
|
synopsis: I go outside, make more incense, contribute to KDE, and eat brownies.
|
||||||
|
date: 2024-04-13
|
||||||
|
imageURL: /img/justin-veenema-gf03H-I7C9Y-unsplash_copy.webp
|
||||||
|
imageAlt: A blue neon sign that reads "Time is precious."
|
||||||
|
---
|
||||||
|
For some reason, I just seem to be itching to get outside lately. Perhaps I'm coming out of some sort of hibernation — after all, spring has sprung, the ornamental pear trees are [somewhat unfortunately](https://www.vice.com/en/article/7x4zza/heres-why-the-trees-on-your-street-smell-like-semen) in full bloom, turtles are basking in the sunshine on riverside logs, and I just don't feel right if I haven't fed a duck some frozen peas in a few days. I've been making heavy use of my under-desk treadmill too; walking a few miles while checking my feeds and answering emails is a surprisingly nice thing to do in the morning after breakfast.
|
||||||
|
|
||||||
|
But lest my doctor fall and injure himself from shock, I've also been engaging in plenty of activities that *don't* involve sunshine, exercise, and fresh air. Just this morning I broke a freshly-dried batch of incense down into five inch pieces. This time I modified a previously successful build to feature rose and myrrh. While there are many varieties of myrrh, the variety I used predominantly (Commiphora Kua) is pungent, bitter, perfumey, and dignified. I wish I could describe it better, but it's quite a difficult fragrance to relate to much else. It really sings in a blend, and I thought it would play nicely with the classic combination of rose and agarwood. The sticks extruded extremely well, and they burn nicely after one night of drying. I'm going to come back to them in two weeks to see how the fragrance has turned out after they've had time to cure and settle.
|
||||||
|
|
||||||
|
I've started to muck-in a bit more with KDE which, if you don't know, is an international community that creates free and open source software. Since [my first contribution](../../blog/new-kmines-themes/) (barring bug reports) several months ago, I've been more active on the KDE forum, participating in the visual design group on Matrix and joining in conversations on KDE's GitLab when design issues arise. I may not know C++, but I have been designing things professionally for over a decade; as a huge fan of KDE and a daily user of their Plasma desktop and many KDE applications, I'm delighted to be helping. I'd also like to point out that KDE is doing some really exciting work; KDE is recommending their [Kirigami framework](https://develop.kde.org/frameworks/kirigami/) for all new KDE applications. Kirigami is a *convergent* UI framework, a framework that allows developers to easily create "beautiful apps that run on computers, phones, TVs and everything in between." KDE also has teams working on [Plasma Bigscreen,](https://plasma-bigscreen.org/) a version of the Plasma desktop for TVs, and [Plasma Mobile,](https://plasma-mobile.org/) for smartphones. *Who else* is doing this? Not only does KDE provide desktop environments for TVs, personal computers, and phones — they've created a framework that allows developers to create applications that work on all of these platforms, without making separate versions. The very same application that works on your desktop can run on your phone. How exciting!
|
||||||
|
|
||||||
|
To complete this update, my partner has recently gotten back into baking brownies, so over the past few weeks I've exercised the solemn duty of ensuring that not the least morsel of the several batches they've baked goes to waste, whether they're hazelnut and chocolate chip, walnut, or cookie butter. It's a hard life, this one. Perhaps this might go some way towards an explanation as to where all of my extra energy has come from of late.
|
@ -6,7 +6,7 @@ date: 2024-02-26
|
|||||||
imageURL: /img/pexels-pixabay-277458_copy.webp
|
imageURL: /img/pexels-pixabay-277458_copy.webp
|
||||||
imageAlt: A series of clocks on tall black poles in a clearing in front of some trees.
|
imageAlt: A series of clocks on tall black poles in a clearing in front of some trees.
|
||||||
---
|
---
|
||||||
I spent about a month working on my blog, while [not blogging on the thing](../blog/up-to-my-eyeballs/), but I’m very pleased about the new changes. The biggest new feature as a result of the work is the ability to comment on my posts via Mastodon!
|
I spent about a month working on my blog, while [not blogging on the thing](https://nathanupchurch.com/blog/up-to-my-eyeballs/), but I’m very pleased about the new changes. The biggest new feature as a result of the work is the ability to comment on my posts via Mastodon!
|
||||||
|
|
||||||
After a failed batch, I went back to basics and made some plain Palo Santo incense that turned out very, very well. I expect I’ll write a post about it soon. I also caved and got three varieties from [Yi-Xin Craft Incense](https://craft-incense.com/pages/about-the-artist)’s February collection. Not only is his stuff consistently gorgeous, it’s also great reference incense for those masochists who like to make their own. If you want to know what a *good* stick can be, you can’t go wrong with one of Ken’s.
|
After a failed batch, I went back to basics and made some plain Palo Santo incense that turned out very, very well. I expect I’ll write a post about it soon. I also caved and got three varieties from [Yi-Xin Craft Incense](https://craft-incense.com/pages/about-the-artist)’s February collection. Not only is his stuff consistently gorgeous, it’s also great reference incense for those masochists who like to make their own. If you want to know what a *good* stick can be, you can’t go wrong with one of Ken’s.
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ permalink: "/tags/{{ tag | slugify }}/"
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="page-block nodropcap">Here's everything I've posted with the tag “{{ tag }}:”</p>
|
<p class="page-block nodropcap">Here’s everything I’ve posted with the tag “{{ tag }}:”</p>
|
||||||
|
|
||||||
{% set postslist = collections[ tag ] %}
|
{% set postslist = collections[ tag ] %}
|
||||||
{% include "postslist.njk" %}
|
{% include "postslist.njk" %}
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
const { DateTime } = require("luxon");
|
import { DateTime } from "luxon";
|
||||||
const markdownIt = require("markdown-it");
|
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
|
||||||
const markdownItFootnote = require("markdown-it-footnote");
|
import markdownIt from "markdown-it";
|
||||||
const markdownItAnchor = require("markdown-it-anchor");
|
import markdownItFootnote from "markdown-it-footnote";
|
||||||
const mdfigcaption = require('markdown-it-image-figures');
|
import markdownItAnchor from "markdown-it-anchor";
|
||||||
const pluginRss = require("@11ty/eleventy-plugin-rss");
|
import mdfigcaption from 'markdown-it-image-figures';
|
||||||
const pluginSyntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
|
import pluginRss from "@11ty/eleventy-plugin-rss";
|
||||||
const pluginBundle = require("@11ty/eleventy-plugin-bundle");
|
import pluginSyntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
|
||||||
const pluginNavigation = require("@11ty/eleventy-navigation");
|
import pluginBundle from "@11ty/eleventy-plugin-bundle";
|
||||||
const { EleventyHtmlBasePlugin } = require("@11ty/eleventy");
|
import pluginNavigation from "@11ty/eleventy-navigation";
|
||||||
|
import prettier from "prettier";
|
||||||
|
import { EleventyHtmlBasePlugin } from "@11ty/eleventy";
|
||||||
|
import {dateSuffixAdder, monthMap, timeFormatter} from "./public/js/modules/mastodonDateTools.js";
|
||||||
|
|
||||||
const figoptions = {
|
const figoptions = {
|
||||||
figcaption: true
|
figcaption: true
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = function(eleventyConfig) {
|
export default async function(eleventyConfig) {
|
||||||
|
|
||||||
// Helper Functions
|
// Helper Functions
|
||||||
const multiReplace = (text, replacementTable) => {
|
const multiReplace = (text, replacementTable) => {
|
||||||
@ -22,9 +25,29 @@ module.exports = function(eleventyConfig) {
|
|||||||
return newText;
|
return newText;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Transforms
|
||||||
|
eleventyConfig.addTransform("prettier", function (content, outputPath) {
|
||||||
|
if (outputPath && outputPath.endsWith(".html")) {
|
||||||
|
return prettier.format(content, {parser: "html", bracketSameLine: true, vueIndentScriptAndStyle: true, singleAttributePerLine: true, htmlWhitespaceSensitivity: "ignore"});
|
||||||
|
} else {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
eleventyConfig.addWatchTarget("content/**/*.{svg,webp,png,jpeg}");
|
eleventyConfig.addWatchTarget("content/**/*.{svg,webp,png,jpeg}");
|
||||||
|
|
||||||
// Official plugins
|
// Official plugins
|
||||||
|
/*
|
||||||
|
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
|
||||||
|
extensions: "html",
|
||||||
|
formats: ["webp"],
|
||||||
|
widths: [270,540,810,1080],
|
||||||
|
defaultAttributes: {
|
||||||
|
loading: "lazy",
|
||||||
|
decoding: "async",
|
||||||
|
},
|
||||||
|
urlPath: "/img/",
|
||||||
|
});*/
|
||||||
eleventyConfig.addPlugin(pluginRss);
|
eleventyConfig.addPlugin(pluginRss);
|
||||||
eleventyConfig.addPlugin(pluginSyntaxHighlight, {
|
eleventyConfig.addPlugin(pluginSyntaxHighlight, {
|
||||||
preAttributes: { tabindex: 0 }
|
preAttributes: { tabindex: 0 }
|
||||||
@ -44,7 +67,13 @@ module.exports = function(eleventyConfig) {
|
|||||||
return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat('yyyy-LL-dd');
|
return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat('yyyy-LL-dd');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
eleventyConfig.addFilter("removeMostRecent", arr => {
|
||||||
|
return arr.slice(0, arr.length-1);
|
||||||
|
});
|
||||||
|
|
||||||
// Shortcodes
|
// Shortcodes
|
||||||
|
|
||||||
|
// Cowsay
|
||||||
eleventyConfig.addNunjucksFilter("cowsay", cowText => {
|
eleventyConfig.addNunjucksFilter("cowsay", cowText => {
|
||||||
const cowCaptionReplacementTable = [
|
const cowCaptionReplacementTable = [
|
||||||
[`
|
[`
|
||||||
@ -74,12 +103,39 @@ module.exports = function(eleventyConfig) {
|
|||||||
`;
|
`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Embed a toot
|
||||||
|
eleventyConfig.addAsyncShortcode("toot", async function(instance, ID) {
|
||||||
|
const tootData = await fetch(
|
||||||
|
`https://${instance}/api/v1/statuses/${ID}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const toot = await tootData.json();
|
||||||
|
|
||||||
|
const dateObj = new Date(toot.created_at);
|
||||||
|
|
||||||
|
const dateTime = `${dateObj.getDate()}${dateSuffixAdder(dateObj.getDate())} of ${monthMap[dateObj.getMonth()]}, ${dateObj.getFullYear()}, at ${timeFormatter(dateObj.getHours(), dateObj.getMinutes())}`;
|
||||||
|
|
||||||
|
return `
|
||||||
|
<wc-toot
|
||||||
|
author_name="${toot.account.display_name}"
|
||||||
|
author_url="${toot.url.replace(/\/[0-9]+/, "")}"
|
||||||
|
author_username="${toot.account.username}"
|
||||||
|
avatar_url="${toot.account.avatar_static}"
|
||||||
|
toot_content="${toot.content}"
|
||||||
|
toot_url="${toot.url}"
|
||||||
|
publish_date="${dateTime}"
|
||||||
|
sharp_corner="">
|
||||||
|
</wc-toot>
|
||||||
|
`
|
||||||
|
});
|
||||||
|
|
||||||
// Passthrough
|
// Passthrough
|
||||||
eleventyConfig.addPassthroughCopy({ 'public/xsl/*': "/xsl/" });
|
eleventyConfig.addPassthroughCopy({ 'public/xsl/*': "/xsl/" });
|
||||||
eleventyConfig.addPassthroughCopy({ 'public/img/*': "/img/" });
|
eleventyConfig.addPassthroughCopy({ 'public/img/*': "/img/" });
|
||||||
eleventyConfig.addPassthroughCopy({ 'public/robots.txt': "/" });
|
eleventyConfig.addPassthroughCopy({ 'public/robots.txt': "/" });
|
||||||
eleventyConfig.addPassthroughCopy({ 'public/js/*': "/js/" });
|
eleventyConfig.addPassthroughCopy({ 'public/js/*': "/js/" });
|
||||||
eleventyConfig.addPassthroughCopy({ 'public/js/webComponents/*': "/js/webComponents" });
|
eleventyConfig.addPassthroughCopy({ 'public/js/webComponents/*': "/js/webComponents" });
|
||||||
|
eleventyConfig.addPassthroughCopy({ 'public/js/modules/*': "/js/modules" });
|
||||||
// Copying so that basic.xsl can use it
|
// Copying so that basic.xsl can use it
|
||||||
eleventyConfig.addPassthroughCopy({ 'public/css/index.css': "/css/index.css" });
|
eleventyConfig.addPassthroughCopy({ 'public/css/index.css': "/css/index.css" });
|
||||||
eleventyConfig.addPassthroughCopy({ 'public/css/webfonts/*': "/css/webfonts/" });
|
eleventyConfig.addPassthroughCopy({ 'public/css/webfonts/*': "/css/webfonts/" });
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "nathanupchurch.com",
|
"name": "nathanupchurch.com",
|
||||||
"version": "8.0.0",
|
"version": "8.0.0",
|
||||||
"description": "The personal website and blog of Nathan Upchurch",
|
"description": "The personal website and blog of Nathan Upchurch",
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npx @11ty/eleventy",
|
"build": "npx @11ty/eleventy",
|
||||||
"build-ghpages": "npx @11ty/eleventy --pathprefix=/eleventy-base-blog/",
|
"build-ghpages": "npx @11ty/eleventy --pathprefix=/eleventy-base-blog/",
|
||||||
@ -28,8 +29,8 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://upchur.ch/gitea/n_u/nathanupchurch.com",
|
"homepage": "https://upchur.ch/gitea/n_u/nathanupchurch.com",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@11ty/eleventy": "^2.0.1",
|
"@11ty/eleventy": "3.0.0-alpha.13",
|
||||||
"@11ty/eleventy-img": "^3.1.0",
|
"@11ty/eleventy-img": "5.0.0-beta.10",
|
||||||
"@11ty/eleventy-navigation": "^0.3.5",
|
"@11ty/eleventy-navigation": "^0.3.5",
|
||||||
"@11ty/eleventy-plugin-bundle": "^1.0.4",
|
"@11ty/eleventy-plugin-bundle": "^1.0.4",
|
||||||
"@11ty/eleventy-plugin-rss": "^1.2.0",
|
"@11ty/eleventy-plugin-rss": "^1.2.0",
|
||||||
@ -41,6 +42,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"markdown-it-footnote": "^3.0.3",
|
"markdown-it-footnote": "^3.0.3",
|
||||||
"markdown-it-image-figures": "^2.1.1"
|
"markdown-it-image-figures": "^2.1.1",
|
||||||
|
"prettier": "^3.2.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
89
public/ai.txt
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
# Spawning AI
|
||||||
|
# Prevent datasets from using the following file types
|
||||||
|
|
||||||
|
User-Agent: *
|
||||||
|
Disallow: *.txt
|
||||||
|
Disallow: *.pdf
|
||||||
|
Disallow: *.doc
|
||||||
|
Disallow: *.docx
|
||||||
|
Disallow: *.odt
|
||||||
|
Disallow: *.rtf
|
||||||
|
Disallow: *.tex
|
||||||
|
Disallow: *.wks
|
||||||
|
Disallow: *.wpd
|
||||||
|
Disallow: *.wps
|
||||||
|
Disallow: *.html
|
||||||
|
Disallow: *.bmp
|
||||||
|
Disallow: *.gif
|
||||||
|
Disallow: *.ico
|
||||||
|
Disallow: *.jpeg
|
||||||
|
Disallow: *.jpg
|
||||||
|
Disallow: *.png
|
||||||
|
Disallow: *.svg
|
||||||
|
Disallow: *.avif
|
||||||
|
Disallow: *.tif
|
||||||
|
Disallow: *.tiff
|
||||||
|
Disallow: *.webp
|
||||||
|
Disallow: *.aac
|
||||||
|
Disallow: *.aiff
|
||||||
|
Disallow: *.amr
|
||||||
|
Disallow: *.flac
|
||||||
|
Disallow: *.m4a
|
||||||
|
Disallow: *.mp3
|
||||||
|
Disallow: *.oga
|
||||||
|
Disallow: *.opus
|
||||||
|
Disallow: *.wav
|
||||||
|
Disallow: *.wma
|
||||||
|
Disallow: *.mp4
|
||||||
|
Disallow: *.webm
|
||||||
|
Disallow: *.ogg
|
||||||
|
Disallow: *.avi
|
||||||
|
Disallow: *.mov
|
||||||
|
Disallow: *.wmv
|
||||||
|
Disallow: *.flv
|
||||||
|
Disallow: *.mkv
|
||||||
|
Disallow: *.py
|
||||||
|
Disallow: *.js
|
||||||
|
Disallow: *.java
|
||||||
|
Disallow: *.c
|
||||||
|
Disallow: *.cpp
|
||||||
|
Disallow: *.cs
|
||||||
|
Disallow: *.h
|
||||||
|
Disallow: *.css
|
||||||
|
Disallow: *.php
|
||||||
|
Disallow: *.swift
|
||||||
|
Disallow: *.go
|
||||||
|
Disallow: *.rb
|
||||||
|
Disallow: *.pl
|
||||||
|
Disallow: *.sh
|
||||||
|
Disallow: *.sql
|
||||||
|
Disallow: /
|
||||||
|
Disallow: *
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@( @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% @@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@
|
||||||
|
# @@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@( @@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@ %@@@@@/@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@ %@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@, @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@( %@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@
|
||||||
|
# @@@@@@@@@@@/@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@
|
||||||
|
# @@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@, @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@ *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@ %@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@ %@@@@& @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@ .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ spawning.ai
|
@ -1,10 +1,9 @@
|
|||||||
code[class*="language-"],
|
code[class*="language-"], pre[class*="language-"] {
|
||||||
pre[class*="language-"] {
|
|
||||||
color: #f8f8f2;
|
color: #f8f8f2;
|
||||||
background: none;
|
background: none;
|
||||||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
||||||
font-family: var(--font-family-monospace);
|
font-family: var(--font-family-monospace);
|
||||||
font-size: var(--font-n);
|
font-size: var(--step--1);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
word-spacing: normal;
|
word-spacing: normal;
|
||||||
@ -24,7 +23,7 @@ pre[class*="language-"] {
|
|||||||
|
|
||||||
/* Code blocks */
|
/* Code blocks */
|
||||||
pre[class*="language-"] {
|
pre[class*="language-"] {
|
||||||
padding: var(--single-gap);
|
padding: var(--space-2xs);
|
||||||
margin: .5em 0;
|
margin: .5em 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
border-radius: 0.3em;
|
border-radius: 0.3em;
|
||||||
@ -121,7 +120,7 @@ pre[class*="language-diff-"] {
|
|||||||
padding-left: var(--eleventy-code-padding);
|
padding-left: var(--eleventy-code-padding);
|
||||||
padding-right: var(--eleventy-code-padding);
|
padding-right: var(--eleventy-code-padding);
|
||||||
font-family: var(--font-family-monospace);
|
font-family: var(--font-family-monospace);
|
||||||
font-size: 1em;
|
font-size: var(--step--1);
|
||||||
}
|
}
|
||||||
.token.deleted {
|
.token.deleted {
|
||||||
background-color: hsl(0, 51%, 37%);
|
background-color: hsl(0, 51%, 37%);
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
--font-variation-default: "opsz" 18, "wght" 310, "SOFT" 40, "WONK" 0;
|
--font-variation-default: "opsz" 18, "wght" 310, "SOFT" 40, "WONK" 0;
|
||||||
--font-variation-ui: "wght" 500;
|
--font-variation-ui: "wght" 500;
|
||||||
--font-family-monospace: Consolas, Menlo, Monaco, Andale Mono WT, Andale Mono, Lucida Console, Lucida Sans Typewriter, DejaVu Sans Mono, Bitstream Vera Sans Mono, Liberation Mono, Nimbus Mono L, Courier New, Courier, monospace;
|
--font-family-monospace: Consolas, Menlo, Monaco, Andale Mono WT, Andale Mono, Lucida Console, Lucida Sans Typewriter, DejaVu Sans Mono, Bitstream Vera Sans Mono, Liberation Mono, Nimbus Mono L, Courier New, Courier, monospace;
|
||||||
|
--meta-font-family: "Fraunces", serif;
|
||||||
--meta-font-size: var(--step--1);
|
--meta-font-size: var(--step--1);
|
||||||
--meta-font-style: italic;
|
--meta-font-style: normal;
|
||||||
--meta-font-variation-settings: "opsz" 12, "wght" 310, "SOFT" 40, "WONK" 0;
|
--ui-letter-spacing: calc(var(--space-3xs) * 0.5);
|
||||||
--ui-letter-spacing: var(--space-3xs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -57,45 +57,45 @@
|
|||||||
--text-color-tag: var(--contrast-color);
|
--text-color-tag: var(--contrast-color);
|
||||||
|
|
||||||
/* Font Size Scaling Tokens - https://utopia.fyi/ */
|
/* Font Size Scaling Tokens - https://utopia.fyi/ */
|
||||||
--step--2: clamp(0.7813rem, 0.7747rem + 0.0326vi, 0.8rem);
|
--step--2: clamp(0.8681rem, 0.8163rem + 0.259vw, 0.96rem);
|
||||||
--step--1: clamp(0.9375rem, 0.9158rem + 0.1087vi, 1rem);
|
--step--1: clamp(1.0417rem, 0.9525rem + 0.446vw, 1.2rem);
|
||||||
--step-0: clamp(1.125rem, 1.0815rem + 0.2174vi, 1.25rem);
|
--step-0: clamp(1.25rem, 1.1092rem + 0.7042vw, 1.5rem);
|
||||||
--step-1: clamp(1.35rem, 1.2761rem + 0.3696vi, 1.5625rem);
|
--step-1: clamp(1.5rem, 1.2887rem + 1.0563vw, 1.875rem);
|
||||||
--step-2: clamp(1.62rem, 1.5041rem + 0.5793vi, 1.9531rem);
|
--step-2: clamp(1.8rem, 1.4937rem + 1.5317vw, 2.3438rem);
|
||||||
--step-3: clamp(1.944rem, 1.771rem + 0.8651vi, 2.4414rem);
|
--step-3: clamp(2.16rem, 1.7264rem + 2.1681vw, 2.9297rem);
|
||||||
--step-4: clamp(2.3328rem, 2.0827rem + 1.2504vi, 3.0518rem);
|
--step-4: clamp(2.592rem, 1.9891rem + 3.0144vw, 3.6621rem);
|
||||||
--step-5: clamp(2.7994rem, 2.4462rem + 1.7658vi, 3.8147rem);
|
--step-5: clamp(3.1104rem, 2.2838rem + 4.1331vw, 4.5776rem);
|
||||||
--step-6: clamp(3.3592rem, 2.8691rem + 2.4507vi, 4.7684rem);
|
--step-6: clamp(3.7325rem, 2.6116rem + 5.6044vw, 5.722rem);
|
||||||
--step-7: clamp(4.0311rem, 3.36rem + 3.3555vi, 5.9605rem);
|
--step-7: clamp(4.479rem, 2.9727rem + 7.5312vw, 7.1526rem);
|
||||||
--step-8: clamp(4.8373rem, 3.9283rem + 4.5448vi, 7.4506rem);
|
--step-8: clamp(5.3748rem, 3.3658rem + 10.0449vw, 8.9407rem);
|
||||||
|
|
||||||
/* Space Scaling Tokens - https://utopia.fyi/ */
|
/* Space Scaling Tokens - https://utopia.fyi/ */
|
||||||
--space-3xs: clamp(0.3125rem, 0.3125rem + 0vi, 0.3125rem);
|
--space-3xs: clamp(0.3125rem, 0.2773rem + 0.1761vw, 0.375rem);
|
||||||
--space-2xs: clamp(0.5625rem, 0.5408rem + 0.1087vi, 0.625rem);
|
--space-2xs: clamp(0.625rem, 0.5546rem + 0.3521vw, 0.75rem);
|
||||||
--space-xs: clamp(0.875rem, 0.8533rem + 0.1087vi, 0.9375rem);
|
--space-xs: clamp(0.9375rem, 0.8319rem + 0.5282vw, 1.125rem);
|
||||||
--space-s: clamp(1.125rem, 1.0815rem + 0.2174vi, 1.25rem);
|
--space-s: clamp(1.25rem, 1.1092rem + 0.7042vw, 1.5rem);
|
||||||
--space-m: clamp(1.6875rem, 1.6223rem + 0.3261vi, 1.875rem);
|
--space-m: clamp(1.875rem, 1.6637rem + 1.0563vw, 2.25rem);
|
||||||
--space-l: clamp(2.25rem, 2.163rem + 0.4348vi, 2.5rem);
|
--space-l: clamp(2.5rem, 2.2183rem + 1.4085vw, 3rem);
|
||||||
--space-xl: clamp(3.375rem, 3.2446rem + 0.6522vi, 3.75rem);
|
--space-xl: clamp(3.75rem, 3.3275rem + 2.1127vw, 4.5rem);
|
||||||
--space-2xl: clamp(4.5rem, 4.3261rem + 0.8696vi, 5rem);
|
--space-2xl: clamp(5rem, 4.4366rem + 2.8169vw, 6rem);
|
||||||
--space-3xl: clamp(6.75rem, 6.4891rem + 1.3043vi, 7.5rem);
|
--space-3xl: clamp(7.5rem, 6.6549rem + 4.2254vw, 9rem);
|
||||||
|
|
||||||
/* One-up pairs - https://utopia.fyi/ */
|
/* One-up pairs - https://utopia.fyi/ */
|
||||||
--space-3xs-2xs: clamp(0.3125rem, 0.2038rem + 0.5435vi, 0.625rem);
|
--space-3xs-2xs: clamp(0.3125rem, 0.066rem + 1.2324vw, 0.75rem);
|
||||||
--space-2xs-xs: clamp(0.5625rem, 0.4321rem + 0.6522vi, 0.9375rem);
|
--space-2xs-xs: clamp(0.625rem, 0.3433rem + 1.4085vw, 1.125rem);
|
||||||
--space-xs-s: clamp(0.875rem, 0.7446rem + 0.6522vi, 1.25rem);
|
--space-xs-s: clamp(0.9375rem, 0.6206rem + 1.5845vw, 1.5rem);
|
||||||
--space-s-m: clamp(1.125rem, 0.8641rem + 1.3043vi, 1.875rem);
|
--space-s-m: clamp(1.25rem, 0.6866rem + 2.8169vw, 2.25rem);
|
||||||
--space-m-l: clamp(1.6875rem, 1.4049rem + 1.413vi, 2.5rem);
|
--space-m-l: clamp(1.875rem, 1.2412rem + 3.169vw, 3rem);
|
||||||
--space-l-xl: clamp(2.25rem, 1.7283rem + 2.6087vi, 3.75rem);
|
--space-l-xl: clamp(2.5rem, 1.3732rem + 5.6338vw, 4.5rem);
|
||||||
--space-xl-2xl: clamp(3.375rem, 2.8098rem + 2.8261vi, 5rem);
|
--space-xl-2xl: clamp(3.75rem, 2.4824rem + 6.338vw, 6rem);
|
||||||
--space-2xl-3xl: clamp(4.5rem, 3.4565rem + 5.2174vi, 7.5rem);
|
--space-2xl-3xl: clamp(5rem, 2.7465rem + 11.2676vw, 9rem);
|
||||||
|
|
||||||
/* Custom pairs - https://utopia.fyi/ */
|
/* Custom pairs - https://utopia.fyi/ */
|
||||||
--space-s-l: clamp(1.125rem, 0.6467rem + 2.3913vi, 2.5rem);
|
--space-s-l: clamp(1.25rem, 0.2641rem + 4.9296vw, 3rem);
|
||||||
|
|
||||||
/* Fluid Grid Tokens - https://utopia.fyi/ */
|
/* Fluid Grid Tokens - https://utopia.fyi/ */
|
||||||
--grid-max-width: 43.75rem;
|
--grid-max-width: 55.50rem;
|
||||||
--grid-gutter: var(--space-s-l, clamp(1.125rem, -0.0329rem + 5.7895vw, 2.5rem));
|
--grid-gutter: var(--space-s-s, clamp(1.25rem, 1.1092rem + 0.7042vw, 1.5rem));
|
||||||
--grid-columns: 12;
|
--grid-columns: 12;
|
||||||
|
|
||||||
/* Change <img> SVG color with filter */
|
/* Change <img> SVG color with filter */
|
||||||
@ -122,12 +122,13 @@
|
|||||||
/* Web Component Tokens */
|
/* Web Component Tokens */
|
||||||
--wc-card-background-color: var(--card-color);
|
--wc-card-background-color: var(--card-color);
|
||||||
--wc-card-border-radius: var(--border-radius);
|
--wc-card-border-radius: var(--border-radius);
|
||||||
|
--wc-card-margin: 0 0 var(--space-s) 0;
|
||||||
--wc-card-box-shadow: var(--box-shadow);
|
--wc-card-box-shadow: var(--box-shadow);
|
||||||
--wc-link-color: var(--text-color);
|
--wc-link-color: var(--text-color);
|
||||||
--wc-link-decoration-color: var(--contrast-color);
|
--wc-link-decoration-color: var(--contrast-color);
|
||||||
--wc-link-decoration-thickness: var(--link-decoration-thickness);
|
--wc-link-decoration-thickness: var(--link-decoration-thickness);
|
||||||
--wc-comment-text-margin: auto auto auto 4rem;
|
--wc-comment-text-margin: var(--space-xs) 0 0 0;
|
||||||
--wc-profile-pic-size: 3rem;
|
--wc-profile-pic-size: var(--space-l);
|
||||||
--wc-profile-pic-border-radius: 10rem;
|
--wc-profile-pic-border-radius: 10rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +170,17 @@ html {
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
blockquote p {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
blockquote:before {
|
||||||
|
content: "“";
|
||||||
|
font-size: 10rem;
|
||||||
|
margin-left: -4rem;
|
||||||
|
margin-top: -2rem;
|
||||||
|
position: fixed;
|
||||||
|
filter: opacity(.15);
|
||||||
|
}
|
||||||
body {
|
body {
|
||||||
animation: var(--slide-in-blurred-bottom);
|
animation: var(--slide-in-blurred-bottom);
|
||||||
font-size: var(--step-0);
|
font-size: var(--step-0);
|
||||||
@ -181,6 +193,17 @@ body {
|
|||||||
button, .nav-item {
|
button, .nav-item {
|
||||||
font-family: var(--font-family-ui);
|
font-family: var(--font-family-ui);
|
||||||
}
|
}
|
||||||
|
code {
|
||||||
|
background-color: var(--color-gray-20);
|
||||||
|
border-radius: 0.3em;
|
||||||
|
font-size: var(--step--1);
|
||||||
|
padding: 0 var(--space-3xs);
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
code {
|
||||||
|
background-color: var(--card-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
header, footer, main {
|
header, footer, main {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--grid-gutter);
|
gap: var(--grid-gutter);
|
||||||
@ -189,10 +212,19 @@ header, footer, main {
|
|||||||
nav {
|
nav {
|
||||||
grid-column: 2 / span 12;
|
grid-column: 2 / span 12;
|
||||||
}
|
}
|
||||||
|
.now {
|
||||||
|
display: grid;
|
||||||
|
grid-column: 1 / span 12;
|
||||||
|
padding-bottom: var(--space-xl);
|
||||||
|
}
|
||||||
section {
|
section {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-column: 1 / span 12;
|
grid-column: 1 / span 12;
|
||||||
}
|
}
|
||||||
|
::selection {
|
||||||
|
background: var(--contrast-color);
|
||||||
|
color: var(--background-color);
|
||||||
|
}
|
||||||
.page-block {
|
.page-block {
|
||||||
grid-column: 1 / span 12;
|
grid-column: 1 / span 12;
|
||||||
font-size: var(--step-1);
|
font-size: var(--step-1);
|
||||||
@ -237,18 +269,19 @@ h1, h2, h3 {
|
|||||||
h1 {
|
h1 {
|
||||||
font-family: var(--font-family-headline);
|
font-family: var(--font-family-headline);
|
||||||
font-variation-settings: "opsz" 100, "wght" 500, "SOFT" 10, "WONK" 1;
|
font-variation-settings: "opsz" 100, "wght" 500, "SOFT" 10, "WONK" 1;
|
||||||
font-size: var(--step-6);
|
font-size: var(--step-5);
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
line-height: calc(var(--step-6) * 0.25 + var(--step-6));
|
line-height: calc(var(--step-5) * 0.25 + var(--step-5));
|
||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
font-size: var(--step-3);
|
font-size: var(--step-2);
|
||||||
font-variation-settings: "opsz" 50, "wght" 300, "SOFT" 60, "WONK" 1;
|
font-variation-settings: "opsz" 50, "wght" 350, "SOFT" 20, "WONK" 1;
|
||||||
padding-bottom: var(--space-l);
|
padding-bottom: var(--space-l);
|
||||||
padding-top: var(--space-xl);
|
padding-top: var(--space-xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
font-size: var(--step-2);
|
font-size: var(--step-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
@ -277,6 +310,11 @@ p, li {
|
|||||||
font-size: var(--step-0);
|
font-size: var(--step-0);
|
||||||
line-height: calc(var(--step-0) * 0.5 + var(--step-0));
|
line-height: calc(var(--step-0) * 0.5 + var(--step-0));
|
||||||
}
|
}
|
||||||
|
th {
|
||||||
|
font-variation-settings: "opsz" 25, "wght" 500, "SOFT" 40, "WONK" 0;
|
||||||
|
padding-bottom: var(--space-2xs);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
figure {
|
figure {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: var(--space-m) 0 var(--space-m) 0;
|
padding: var(--space-m) 0 var(--space-m) 0;
|
||||||
@ -296,9 +334,8 @@ html.barebones, body.barebones {
|
|||||||
}
|
}
|
||||||
|
|
||||||
figcaption {
|
figcaption {
|
||||||
font-size: var(--meta-font-size);
|
font-size: var(--step--1);
|
||||||
font-style: var(--meta-font-style);
|
font-style: italic;
|
||||||
font-variation-settings: var(--meta-font-variation-settings);
|
|
||||||
padding-top: var(--space-s);
|
padding-top: var(--space-s);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@ -364,20 +401,29 @@ table th {
|
|||||||
.continue-discussion button {
|
.continue-discussion button {
|
||||||
margin-top: var(--space-xs);
|
margin-top: var(--space-xs);
|
||||||
}
|
}
|
||||||
wc-comment::part(author-link) {
|
wc-comment::part(author-link), wc-toot::part(author-link) {
|
||||||
font-size: var(--step-0);
|
font-size: var(--step-0);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
wc-comment::part(main) {
|
wc-comment::part(main) {
|
||||||
margin-bottom: var(--space-l);
|
padding: var(--space-m);
|
||||||
}
|
}
|
||||||
wc-comment::part(publish-date) {
|
wc-comment::part(publish-date), wc-toot::part(publish-date) {
|
||||||
|
font-family: var(--meta-font-family);
|
||||||
font-size: var(--meta-font-size);
|
font-size: var(--meta-font-size);
|
||||||
font-style: var(--meta-font-style);
|
font-style: var(--meta-font-style);
|
||||||
font-variation-settings: var(--font-variation-settings);
|
font-variation-settings: var(--font-variation-settings);
|
||||||
margin-top: -.25rem;
|
|
||||||
}
|
}
|
||||||
|
wc-toot::part(main) {
|
||||||
|
color: white;
|
||||||
|
font-family: var(--meta-font-family);
|
||||||
|
font-size: var(--step--1);
|
||||||
|
}
|
||||||
|
wc-toot::part(author), wc-toot::part(author-link){
|
||||||
|
color: white;
|
||||||
|
font-style: var(--meta-font-style);
|
||||||
|
font-variation-settings: "wght" 600;
|
||||||
|
}
|
||||||
/* Code Fences */
|
/* Code Fences */
|
||||||
pre,
|
pre,
|
||||||
code {
|
code {
|
||||||
@ -497,9 +543,6 @@ nav ul {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Posts list */
|
/* Posts list */
|
||||||
.postlist h3 {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
.postlist-item-container {
|
.postlist-item-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
@ -533,7 +576,7 @@ nav ul {
|
|||||||
.postlist-date,
|
.postlist-date,
|
||||||
.postlist-item:before {
|
.postlist-item:before {
|
||||||
color: var(--color-gray-90);
|
color: var(--color-gray-90);
|
||||||
font-size: var(--step--1); /* 13px /16 */
|
font-size: var(--meta-font-size); /* 13px /16 */
|
||||||
}
|
}
|
||||||
.postlist-date {
|
.postlist-date {
|
||||||
word-spacing: -0.5px;
|
word-spacing: -0.5px;
|
||||||
@ -543,10 +586,7 @@ nav ul {
|
|||||||
padding-right: .5em;
|
padding-right: .5em;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.postlist-link h3 {
|
|
||||||
font-size: var(--step-2);
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
.postlist-link p {
|
.postlist-link p {
|
||||||
background-color: var(--color-gray-90);
|
background-color: var(--color-gray-90);
|
||||||
border-radius: 100px;
|
border-radius: 100px;
|
||||||
@ -554,7 +594,7 @@ nav ul {
|
|||||||
font-family: var(--font-family-ui);
|
font-family: var(--font-family-ui);
|
||||||
font-size: var(--step--2);
|
font-size: var(--step--2);
|
||||||
font-variation-settings: var(--font-variation-ui);
|
font-variation-settings: var(--font-variation-ui);
|
||||||
letter-spacing: var(--space-3xs);
|
letter-spacing: var(--ui-letter-spacing);
|
||||||
margin-top: calc(var(--space-3xs) * -1);
|
margin-top: calc(var(--space-3xs) * -1);
|
||||||
padding-left: var(--space-xs);
|
padding-left: var(--space-xs);
|
||||||
padding-right: var(--space-xs);
|
padding-right: var(--space-xs);
|
||||||
@ -634,15 +674,20 @@ a.post-tag:hover {
|
|||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Article / Post */
|
|
||||||
.post h2 {
|
|
||||||
font-size: var(--step-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Post Metadata */
|
/* Post Metadata */
|
||||||
.post-metadata {
|
.post-metadata {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
padding: var(--space-m) 0 var(--space-l) 0;
|
padding: var(--space-m) 0 var(--space-l) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.post-metadata-copy {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
justify-content: center;
|
||||||
|
padding-left: var(--space-s);
|
||||||
|
}
|
||||||
|
|
||||||
.post-metadata p, .post-metadata ul, .post-metadata ul li, time, .metadata {
|
.post-metadata p, .post-metadata ul, .post-metadata ul li, time, .metadata {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row wrap;
|
flex-flow: row wrap;
|
||||||
@ -659,6 +704,11 @@ a.post-tag:hover {
|
|||||||
padding-left: .15rem;
|
padding-left: .15rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.profilePic:not(.links-container > img.profilePic) {
|
||||||
|
width: var(--space-xl);
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/* Direct Links / Markdown Headers */
|
/* Direct Links / Markdown Headers */
|
||||||
a.header-anchor {
|
a.header-anchor {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@ -687,6 +737,12 @@ article.post {
|
|||||||
container: article / inline-size;
|
container: article / inline-size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Adds fleuron to article end */
|
||||||
|
article.post > p:not(blockquote > p):last-child:after {
|
||||||
|
content: "\2766";
|
||||||
|
display: inline;
|
||||||
|
font-size: var(--step-1);
|
||||||
|
}
|
||||||
/* Utilities */
|
/* Utilities */
|
||||||
.grid-container {
|
.grid-container {
|
||||||
max-width: var(--grid-max-width);
|
max-width: var(--grid-max-width);
|
||||||
|
BIN
public/img/CN20191025_301_Srt_SQUARE_crop.jpg
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
public/img/_DSC0014_copy.avif
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
public/img/_DSC0079_copy.avif
Normal file
After Width: | Height: | Size: 447 KiB |
BIN
public/img/cedar_frank.webp
Normal file
After Width: | Height: | Size: 154 KiB |
BIN
public/img/heart-of-lavender.webp
Normal file
After Width: | Height: | Size: 231 KiB |
BIN
public/img/incense-stick-comparison.webp
Normal file
After Width: | Height: | Size: 283 KiB |
BIN
public/img/incense_seal.webp
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
public/img/justin-veenema-gf03H-I7C9Y-unsplash_copy.webp
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
public/img/kheouns-blend-incense-sticks.webp
Normal file
After Width: | Height: | Size: 275 KiB |
BIN
public/img/pexels-david-roberts-940521-8323579.webp
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
public/img/pexels-davideibiza-1771809.webp
Normal file
After Width: | Height: | Size: 160 KiB |
BIN
public/img/pexels-harris-rigorad-478484242-25261413.webp
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
public/img/pexels-pixabay-277458_copy.webp
Normal file
After Width: | Height: | Size: 163 KiB |
BIN
public/img/sending-incense-samples.webp
Normal file
After Width: | Height: | Size: 68 KiB |
@ -1,3 +1,4 @@
|
|||||||
import './webComponents/card.js';
|
import './webComponents/card.js';
|
||||||
import './webComponents/profilePic.js';
|
import './webComponents/profilePic.js';
|
||||||
import './webComponents/comment.js';
|
import './webComponents/comment.js';
|
||||||
|
import './webComponents/toot.js';
|
||||||
|
22
public/js/modules/mastodonDateTools.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
const dateSuffixAdder = (date) => {
|
||||||
|
if (date > 9 && date < 20) {
|
||||||
|
return "th";
|
||||||
|
} else {
|
||||||
|
let dateString = date < 10 ? "0" + date : "" + date;
|
||||||
|
if (dateString[1] < 4 && dateString[1] > 0) {
|
||||||
|
return dateString[1] == 1 ? "st" :
|
||||||
|
dateString[1] == 2 ? "nd" :
|
||||||
|
dateString[1] == 3 ? "rd" : null;
|
||||||
|
} else {
|
||||||
|
return "th"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const monthMap = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
||||||
|
|
||||||
|
const timeFormatter = (hours, minutes) => {
|
||||||
|
return `${hours < 12 ? hours : hours - 12}:${minutes < 10 ? "0" : ""}${minutes} ${hours < 12 ? "AM" : "PM"}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export {dateSuffixAdder, monthMap, timeFormatter};
|
@ -10,7 +10,7 @@ template.innerHTML = `
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row nowrap;
|
flex-flow: row nowrap;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
margin-bottom: 1em;
|
margin: var(--wc-card-margin);
|
||||||
padding: var(--single-gap) 1.1rem var(--single-gap) 1.1rem;
|
padding: var(--single-gap) 1.1rem var(--single-gap) 1.1rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@ const template = document.createElement('template');
|
|||||||
template.innerHTML = `
|
template.innerHTML = `
|
||||||
<style>
|
<style>
|
||||||
#profilePic {
|
#profilePic {
|
||||||
border-radius: var(--wc-profile-pic-border-radius);
|
border-radius: var(--wc-profile-pic-border-radius);
|
||||||
width: var(--wc-profile-pic-size);
|
width: var(--wc-profile-pic-size);
|
||||||
height: var(--wc-profile-pic-size);
|
height: var(--wc-profile-pic-size);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
136
public/js/webComponents/toot.js
Normal file
@ -1,23 +1,102 @@
|
|||||||
User-agent: CCBot
|
user-agent: AdsBot-Google
|
||||||
Disallow: /
|
Disallow: /
|
||||||
|
|
||||||
User-agent: ChatGPT-User
|
|
||||||
|
User-agent: Amazonbot
|
||||||
Disallow: /
|
Disallow: /
|
||||||
|
|
||||||
User-agent: GPTBot
|
|
||||||
Disallow: /
|
|
||||||
|
|
||||||
User-agent: Google-Extended
|
|
||||||
Disallow: /
|
|
||||||
|
|
||||||
User-agent: anthropic-ai
|
User-agent: anthropic-ai
|
||||||
Disallow: /
|
Disallow: /
|
||||||
|
|
||||||
User-agent: Omgilibot
|
|
||||||
|
User-agent: Applebot
|
||||||
Disallow: /
|
Disallow: /
|
||||||
|
|
||||||
User-agent: Omgili
|
|
||||||
|
User-agent: AwarioRssBot
|
||||||
Disallow: /
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: AwarioSmartBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: Bytespider
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: CCBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: ChatGPT-User
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: ClaudeBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: Claude-Web
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: cohere-ai
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: DataForSeoBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: Diffbot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
User-agent: FacebookBot
|
User-agent: FacebookBot
|
||||||
Disallow: /
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: Google-Extended
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: GoogleOther
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: GPTBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: ImagesiftBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: magpie-crawler
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: omgili
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: omgilibot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: peer39_crawler
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: peer39_crawler/1.0
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: PerplexityBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
User-agent: YouBot
|
||||||
|
Disallow: /
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<h1>RSS Feed Preview</h1>
|
<h1>RSS Feed Preview</h1>
|
||||||
<p class="nodropcap page-block">This is an RSS feed. Subscribe by copying the URL from the address bar into your newsreader. Don't have a newsreader? <a href="../about-feeds/">Learn more and get started</a>. It’s free. Below is a preview of what you'll see in your newsreader when you subscribe. Done here? <a href="../">Go back to nathanupchurch.com</a></p>
|
<p class="nodropcap page-block">This is an RSS feed. Subscribe by copying the URL from the address bar into your newsreader. Don’t have a newsreader? <a href="../about-feeds/">Learn more and get started</a>. It’s free. Below is a preview of what you’ll see in your newsreader when you subscribe. Done here? <a href="../">Go back to nathanupchurch.com</a></p>
|
||||||
<h2>Latest posts</h2>
|
<h2>Latest posts</h2>
|
||||||
<section class="postlist">
|
<section class="postlist">
|
||||||
<div class="postlist-item-container">
|
<div class="postlist-item-container">
|
||||||
|