Compare commits

...

5 Commits

14 changed files with 277 additions and 47 deletions

View File

@ -8,10 +8,62 @@ My blog, based on the very helpful eleventy-base-blog v8.
### Metadata
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.
### How to add a cowsay to a post with the custom nunjucks filter
#### /me
Links at /me are configured in `metadata.js` like so:
``` javascript
socialLinks: [
{
title: "My Blog",
linkURL: "https://nathanupchurch.com",
linkDisplay: "My Blog",
iconURL: "/img/logo.svg"
}
]
```
Any links added here will render on the /me page.
#### Webrings
Webrings configured in `metadata.js` will display in the footer of most pages beneath the copyright notice:
``` javascript
webrings: [
{
name: "Fediring",
ringURL: "https://fediring.net/",
previousURL: "https://fediring.net/previous?host=nathanupchurch.com",
nextURL: "https://fediring.net/next?host=nathanupchurch.com"
}
]
```
Any links added here will render on the /me page.
### Add a cowsay to a post
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:
1. Add a copy of the cowsay output you'd like to display to _data/cowList.js. Be sure and escape any backslashes.
2. Use the filter like this: `{{ cowList.name | cowsay | safe }}`.
The `safe` filter is necessary so that Eleventy doesn't sanitize our HTML.
### Embed a toot in a post
Embed a toot from Mastodon using the `toot` shortcode:
```
{% toot "instance", "tootID" %}
```
For example:
```
{% toot "lounge.town", "112672230453089386" %}
```
Embedded toots are live, so if the toot or instance is not reachable, the toot will not be shown on the page. I haven't built any error handling for this yet.
### Adding comments via Mastodon
Simply add a toot ID to a post's frontmatter using the `mastodon_id` key in order to enable commenting via Mastodon:
```
mastodon_id: "111688829907363670"
```
The toot at the given ID will be embedded in a comment section at the bottom of the post; users can reply to the post on Mastodon and their replies will automatically be embedded on the post.
Like embedding a toot, comments are live and rely on the instance and toots / comments to be reachable on the remote server.
I also have not added any error handling for this, nor have I added any sort of moderation at this point.

View File

@ -1,4 +1,4 @@
module.exports = {
export default {
onScience: `
_________________________________________
( Once, when the secrets of science were )

View File

@ -1,4 +1,4 @@
module.exports = {
export default {
title: "Nathan Upchurch",
logo: "/img/logo.svg",
url: "https://nathanupchurch.com/",

View File

@ -25,27 +25,8 @@
</wc-comment>
</template>
<script>
const monthMap = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
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"}`
}
<script type="module">
import {dateSuffixAdder, monthMap, timeFormatter} from "../../js/modules/mastodonDateTools.js";
const renderComment = (comment, target, parentIdm) => {
const node = document

View File

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

View File

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

View File

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

View File

@ -1,20 +1,21 @@
const { DateTime } = require("luxon");
const markdownIt = require("markdown-it");
const markdownItFootnote = require("markdown-it-footnote");
const markdownItAnchor = require("markdown-it-anchor");
const mdfigcaption = require('markdown-it-image-figures');
const pluginRss = require("@11ty/eleventy-plugin-rss");
const pluginSyntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
const pluginBundle = require("@11ty/eleventy-plugin-bundle");
const pluginNavigation = require("@11ty/eleventy-navigation");
const prettier = require("prettier");
const { EleventyHtmlBasePlugin } = require("@11ty/eleventy");
import { DateTime } from "luxon";
import markdownIt from "markdown-it";
import markdownItFootnote from "markdown-it-footnote";
import markdownItAnchor from "markdown-it-anchor";
import mdfigcaption from 'markdown-it-image-figures';
import pluginRss from "@11ty/eleventy-plugin-rss";
import pluginSyntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
import pluginBundle from "@11ty/eleventy-plugin-bundle";
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 = {
figcaption: true
};
module.exports = eleventyConfig => {
export default async function(eleventyConfig) {
// Helper Functions
const multiReplace = (text, replacementTable) => {
@ -88,12 +89,38 @@ module.exports = eleventyConfig => {
`;
});
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
eleventyConfig.addPassthroughCopy({ 'public/xsl/*': "/xsl/" });
eleventyConfig.addPassthroughCopy({ 'public/img/*': "/img/" });
eleventyConfig.addPassthroughCopy({ 'public/robots.txt': "/" });
eleventyConfig.addPassthroughCopy({ 'public/js/*': "/js/" });
eleventyConfig.addPassthroughCopy({ 'public/js/webComponents/*': "/js/webComponents" });
eleventyConfig.addPassthroughCopy({ 'public/js/modules/*': "/js/modules" });
// Copying so that basic.xsl can use it
eleventyConfig.addPassthroughCopy({ 'public/css/index.css': "/css/index.css" });
eleventyConfig.addPassthroughCopy({ 'public/css/webfonts/*': "/css/webfonts/" });

View File

@ -2,6 +2,7 @@
"name": "nathanupchurch.com",
"version": "8.0.0",
"description": "The personal website and blog of Nathan Upchurch",
"type": "module",
"scripts": {
"build": "npx @11ty/eleventy",
"build-ghpages": "npx @11ty/eleventy --pathprefix=/eleventy-base-blog/",
@ -28,7 +29,7 @@
},
"homepage": "https://upchur.ch/gitea/n_u/nathanupchurch.com",
"devDependencies": {
"@11ty/eleventy": "^2.0.1",
"@11ty/eleventy": "3.0.0-alpha.13",
"@11ty/eleventy-img": "^3.1.0",
"@11ty/eleventy-navigation": "^0.3.5",
"@11ty/eleventy-plugin-bundle": "^1.0.4",

View File

@ -18,9 +18,10 @@
--font-variation-default: "opsz" 18, "wght" 310, "SOFT" 40, "WONK" 0;
--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;
--meta-font-size: var(--step--1);
--meta-font-style: italic;
--meta-font-variation-settings: "opsz" 12, "wght" 310, "SOFT" 40, "WONK" 0;
--meta-font-family: var(--font-family-ui);
--meta-font-size: var(--step--2);
--meta-font-style: normal;
--meta-font-variation-settings: var(--font-variation-ui);
--ui-letter-spacing: calc(var(--space-3xs) * 0.5);
}
@ -386,20 +387,30 @@ table th {
.continue-discussion button {
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);
text-decoration: none;
}
wc-comment::part(main) {
margin-bottom: var(--space-l);
}
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-style: var(--meta-font-style);
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 */
pre,
code {

View File

@ -1,3 +1,4 @@
import './webComponents/card.js';
import './webComponents/profilePic.js';
import './webComponents/comment.js';
import './webComponents/toot.js';

View 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};

View File

@ -10,7 +10,6 @@ template.innerHTML = `
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
margin-bottom: 1em;
padding: var(--single-gap) 1.1rem var(--single-gap) 1.1rem;
width: 100%;
}

File diff suppressed because one or more lines are too long