WIP: lotta work on partials and such

This commit is contained in:
a 2024-10-18 02:33:33 -05:00
parent 391f67f5cc
commit 3b845babe6
71 changed files with 665 additions and 466 deletions

View file

@ -6,9 +6,12 @@
@import "features/links"; @import "features/links";
@import "features/syntax-highlighting"; @import "features/syntax-highlighting";
@import "features/skip-links";
@import "components/table-of-contents"; @import "components/table-of-contents";
@import "components/site-header";
// default layout // default layout
@import "layouts/_default/list"; @import "layouts/_default/list";
@ -18,10 +21,14 @@
@import "layouts/_default/_markup/render-heading"; @import "layouts/_default/_markup/render-heading";
@import "layouts/_default/_markup/render-link"; @import "layouts/_default/_markup/render-link";
@import "layouts/partials/mf2/h-entry";
@import "layouts/partials/mf2/h-card"; @import "layouts/partials/mf2/h-card";
@import "layouts/partials/mf2/u-in-reply-to";
@import "components/admonition"; @import "components/admonition";
@import "components/quote-block"; @import "components/quote-block";
@import "components/codeblock"; @import "components/codeblock";
@import "components/series-list";
@import "components/syndication-list";
@import "features/footnotes"; @import "features/footnotes";

View file

@ -66,5 +66,5 @@ pre {
} }
/* limit img to page width */ /* limit img to page width */
img { img {
max-width: 100%; max-inline-size: 100%;
} }

View file

@ -1,19 +1,36 @@
.quote-block { .quote-block {
background: var(--ui-overlay-transparent); padding: 1em;
border-inline-start: 0.5em solid var(--ui-overlay);
box-sizing: border-box; box-sizing: border-box;
padding-inline: 1.5em; background: var(--ui-overlay-transparent);
padding-block: 1.5em; &__header {
position: relative;
border-radius: 0.5em; }
&__icon { &__attribution {
font-size: 2em; margin: 0;
position: absolute; display: inline-flex;
z-index: 1; }
inset-inline-start: -0.375em; &__card {
inset-block-start: -0.1725em; display: inline-grid;
place-items: center;
}
&__author {
display: inline-grid;
place-items: center;
a {
display: inline-flex;
align-items: center;
}
}
&__prepend {
margin-block: 0;
}
&__postpend {
display: inline-grid;
align-items: center;
white-space: pre;
} }
&__content { &__content {
blockquote {
margin: 0; margin: 0;
> *:first-child { > *:first-child {
margin-block-start: 0; margin-block-start: 0;
@ -22,12 +39,40 @@
margin-block-end: 0; margin-block-end: 0;
} }
} }
footer:before { position: relative;
// &:before {
// content: '';
// mask: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxLjE5ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMTY2NCAxNDA4Ij48cGF0aCBmaWxsPSJ3aGl0ZSIgZD0iTTc2OCA4MzJ2Mzg0cTAgODAtNTYgMTM2dC0xMzYgNTZIMTkycS04MCAwLTEzNi01NlQwIDEyMTZWNTEycTAtMTA0IDQwLjUtMTk4LjVUMTUwIDE1MFQzMTMuNSA0MC41VDUxMiAwaDY0cTI2IDAgNDUgMTl0MTkgNDV2MTI4cTAgMjYtMTkgNDV0LTQ1IDE5aC02NHEtMTA2IDAtMTgxIDc1dC03NSAxODF2MzJxMCA0MCAyOCA2OHQ2OCAyOGgyMjRxODAgMCAxMzYgNTZ0NTYgMTM2bTg5NiAwdjM4NHEwIDgwLTU2IDEzNnQtMTM2IDU2aC0zODRxLTgwIDAtMTM2LTU2dC01Ni0xMzZWNTEycTAtMTA0IDQwLjUtMTk4LjVUMTA0NiAxNTB0MTYzLjUtMTA5LjVUMTQwOCAwaDY0cTI2IDAgNDUgMTl0MTkgNDV2MTI4cTAgMjYtMTkgNDV0LTQ1IDE5aC02NHEtMTA2IDAtMTgxIDc1dC03NSAxODF2MzJxMCA0MCAyOCA2OHQ2OCAyOGgyMjRxODAgMCAxMzYgNTZ0NTYgMTM2Ii8+PC9zdmc+);
// background-color: currentColor;
// mask-repeat: no-repeat;
// position: absolute;
// inset-inline-start: -0.5em;
// inset-block-start: -0em;
// display: block;
// inline-size: 100%;
// block-size: 100%;
// pointer-events: none;
// opacity: 0.5;
// }
// &:after {
// content: '';
// background-color: currentColor;
// mask: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxLjE5ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMTY2NCAxNDA4Ij48cGF0aCBmaWxsPSJ3aGl0ZSIgZD0iTTc2OCAxOTJ2NzA0cTAgMTA0LTQwLjUgMTk4LjVUNjE4IDEyNTh0LTE2My41IDEwOS41VDI1NiAxNDA4aC02NHEtMjYgMC00NS0xOXQtMTktNDV2LTEyOHEwLTI2IDE5LTQ1dDQ1LTE5aDY0cTEwNiAwIDE4MS03NXQ3NS0xODF2LTMycTAtNDAtMjgtNjh0LTY4LTI4SDE5MnEtODAgMC0xMzYtNTZUMCA1NzZWMTkycTAtODAgNTYtMTM2VDE5MiAwaDM4NHE4MCAwIDEzNiA1NnQ1NiAxMzZtODk2IDB2NzA0cTAgMTA0LTQwLjUgMTk4LjVUMTUxNCAxMjU4dC0xNjMuNSAxMDkuNVQxMTUyIDE0MDhoLTY0cS0yNiAwLTQ1LTE5dC0xOS00NXYtMTI4cTAtMjYgMTktNDV0NDUtMTloNjRxMTA2IDAgMTgxLTc1dDc1LTE4MXYtMzJxMC00MC0yOC02OHQtNjgtMjhoLTIyNHEtODAgMC0xMzYtNTZ0LTU2LTEzNlYxOTJxMC04MCA1Ni0xMzZ0MTM2LTU2aDM4NHE4MCAwIDEzNiA1NnQ1NiAxMzYiLz48L3N2Zz4=);
// mask-repeat: no-repeat;
// position: absolute;
// display: block;
// inline-size: 100%;
// block-size: 100%;
// inset-inline-end: 0em;
// inset-block-end: 0em;
// mask-position: bottom right;
// pointer-events: none;
// opacity: 0.5;
// }
}
&__footer {
&:before {
content: ''; content: '';
} }
footer .u-url {
display: inline-block;
margin-block-start: 1em;
padding-inline: 0;
} }
} }

View file

@ -0,0 +1,25 @@
.series-hint {
font-style: italic;
.series-link {
font-style: initial;
}
}
.series-list {
list-style: none;
padding-inline-start: 1em;
.current-post {
font-weight: bold;
}
.series-post {
margin-block: 0.5em;
&__part {
margin-inline-end: 0.5em;
}
&__title {
}
&__link {
}
}
}

View file

@ -0,0 +1,12 @@
.site-header {
.container {
}
.site-masthead {
color: inherit;
text-decoration: none;
}
.site-title {
}
}

View file

@ -0,0 +1,10 @@
.syndication-hint {
margin-block-end: 0;
}
.syndication-list {
margin-block-start: 0;
&-item {
margin-block: 0;
.u-syndication {}
}
}

View file

@ -4,7 +4,7 @@ h3 {counter-reset: h4}
h4 {counter-reset: h5} h4 {counter-reset: h5}
h5 {counter-reset: h6} h5 {counter-reset: h6}
article[autonumbering] { *[autonumbering] {
h2:before { h2:before {
counter-increment: h2; counter-increment: h2;
content: counter(h2) " "; content: counter(h2) " ";

View file

@ -21,9 +21,25 @@
} }
&:after { &:after {
content: ''; content: '';
width: 100%; inline-size: 100%;
margin-inline-start: 1rem; margin-inline-start: 1rem;
border-block-end: 1px solid var(--ui-overlay); border-block-end: 1px solid var(--ui-overlay);
} }
} }
} }
#footnotes h2 {
font-size: 1rem;
font-weight: 900;
text-transform: uppercase;
position: relative;
&:after {
content: '';
position: absolute;
inset-inline-end: 0;
inset-block-start: calc(50% - 1px);
background: var(--ui-overlay);
block-size: 1px;
inline-size: calc(100% - 12ch);
}
}

View file

@ -36,8 +36,8 @@
} }
#search-form { #search-form {
width: 100%; inline-size: 100%;
max-width: 18rem; max-inline-size: 18rem;
display: grid; display: grid;
grid-template-columns: 20ch 8ch; grid-template-columns: 20ch 8ch;
gap: 1rem; gap: 1rem;
@ -51,7 +51,7 @@
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
box-sizing: border-box; box-sizing: border-box;
resize: horizontal; resize: horizontal;
width: 100%; inline-size: 100%;
grid-column: 1; grid-column: 1;
block-size: 2rem; block-size: 2rem;
line-height: 1rem; line-height: 1rem;

View file

@ -0,0 +1,50 @@
@import "../mixins/shadow.scss";
body {
position: relative;
}
.back-to-top {
position: absolute;
inset-block-end: 1em;
inset-inline-start: -12em;
transition: 0.25s all ease-in;
background: var(--ui-overlay);
color: var(--ui-overlay-text) !important;
padding: 1em;
@include shadow-high;
&:focus {
inset-inline-start: 1em;
}
}
.skip-to-items {
position: absolute;
inset-block-start: -5em;
inset-inline-start: 1em;
transition: all 0.25s ease-in;
background: var(--ui-overlay);
color: var(--ui-overlay-text) !important;
padding: 1em;
@include shadow-high;
&:focus {
inset-block-start: 1em;
}
}
.skip-syndication {
position: absolute;
inset-block-start: -5em;
inset-inline-start: 1em;
transition: 0.25s all ease-in;
background: var(--ui-overlay);
color: var(--ui-overlay-text);
padding: 1em;
@include shadow-high;
&:focus {
inset-block-start: 1em;
}
&:before {
content: "Skip syndication information";
}
}

View file

@ -16,7 +16,9 @@
display: grid; display: grid;
place-items: center; place-items: center;
align-self: start; align-self: start;
&__text { &:before {
content: "[link]";
display: inline-block;
font-size: 1rem; font-size: 1rem;
} }
} }

View file

@ -1,36 +1,8 @@
@import "../../mixins/shadow.scss";
.layout-_default-list { .layout-_default-list {
.skip-to-items {
position: absolute;
inset-block-start: -5em;
inset-inline-start: 1em;
transition: all 0.25s ease-in;
background: var(--ui-overlay);
color: var(--ui-overlay-text);
padding: 1em;
@include shadow-low;
&:focus {
inset-block-start: 1em;
}
}
.back-to-top {
position: absolute;
inset-block-end: 1em;
inset-inline-start: -15em;
transition: all 0.25s ease-in;
background: var(--ui-overlay);
color: var(--ui-overlay-text);
padding: 1em;
@include shadow-low;
&:focus {
inset-inline-start: 1em;
}
}
.list-header { .list-header {
hr {display: none;} hr {display: none;}
.container { .container {
max-width: 80ch; max-inline-size: 80ch;
margin-inline: auto; margin-inline: auto;
} }
} }
@ -68,26 +40,13 @@
} }
} }
.list-pages { .list-pages {
max-width: 80ch; max-inline-size: 80ch;
margin-inline: auto; margin-inline: auto;
.pages-list { .pages-list {
list-style: none; list-style: none;
padding-inline-start: 0; padding-inline-start: 0;
&__item { &-item {
line-height: 1.5;
margin-inline-start: 0; margin-inline-start: 0;
margin-block: 1em;
.u-url {display: inline;}
.p-name {
font-weight: bold;
font-size: 1em;
margin: 0;
display: inline;
}
.p-summary {
font-style: italic;
display: block;
}
} }
} }
} }

View file

@ -1,37 +1,8 @@
@import "../../mixins/shadow.scss";
.layout-_default-single { .layout-_default-single {
position: relative;
.skip-to-end-of-header {
position: absolute;
inset-block-start: -5em;
inset-inline-start: 1em;
transition: 0.25s all ease-in;
background: var(--ui-overlay);
color: var(--ui-overlay-text);
padding: 1em;
@include shadow-low;
&:focus {
inset-block-start: 1em;
}
}
.back-to-top {
position: absolute;
inset-block-end: 1em;
inset-inline-start: -15em;
transition: 0.25s all ease-in;
background: var(--ui-overlay);
color: var(--ui-overlay-text);
padding: 1em;
@include shadow-low;
&:focus {
inset-inline-start: 1em;
}
}
.page-header { .page-header {
hr {display: none;} hr {display: none;}
.container { .container {
max-width: 80ch; max-inline-size: 80ch;
margin-inline: auto; margin-inline: auto;
} }
} }
@ -67,8 +38,8 @@
.reply-icon { .reply-icon {
background: var(--ui-overlay); background: var(--ui-overlay);
display: inline-block; display: inline-block;
width: 1em; inline-size: 1em;
height: 1em; block-size: 1em;
padding: 0.25em; padding: 0.25em;
border-radius: 100em; border-radius: 100em;
} }
@ -79,71 +50,27 @@
.u-url {font-family: monospace;} .u-url {font-family: monospace;}
} }
.page-syndication { .page-syndication {
p {margin-block-end: 0;}
.syndication-list {
margin-block-start: 0;
&-item {
margin-block: 0;
.u-syndication {}
}
}
} }
.page-series { .page-series {
hr {display: none;} hr {display: none;}
// background: var(--ui-overlay); // background: var(--ui-overlay);
// color: var(--ui-overlay-text); // color: var(--ui-overlay-text);
.container { .container {
max-width: 80ch; max-inline-size: 80ch;
margin-inline: auto; margin-inline: auto;
} }
&__hint {
font-style: italic;
}
.series {
list-style: none;
padding-inline-start: 1em;
.current-post {
font-weight: bold;
}
.series-post {
margin-block: 0.5em;
&__part {
margin-inline-end: 0.5em;
}
&__title {
}
&__link {
}
}
}
} }
.page-content { .page-content {
width: 100%; inline-size: 100%;
max-width: 80ch; max-inline-size: 80ch;
margin-inline: auto; margin-inline: auto;
} }
.page-footer { .page-footer {
hr {display: none;} hr {display: none;}
width: 100%; inline-size: 100%;
max-width: 80ch; max-inline-size: 80ch;
margin-inline: auto; margin-inline: auto;
#footnotes h2 {
font-size: 1rem;
font-weight: 900;
text-transform: uppercase;
position: relative;
&:after {
content: '';
position: absolute;
inset-inline-end: 0;
inset-block-start: calc(50% - 1px);
background: var(--ui-overlay);
block-size: 1px;
inline-size: calc(100% - 12ch);
}
}
} }
.page[has-toc] { .page[has-toc] {
padding-block-end: 4em; padding-block-end: 4em;
@ -158,11 +85,11 @@
position: fixed; position: fixed;
z-index: 10; z-index: 10;
inset-block-end: 6em; inset-block-end: 6em;
height: max-content; block-size: max-content;
width: 80%; inline-size: 80%;
max-width: 20em; max-inline-size: 20em;
max-height: #{min}(40em, 70vh); max-block-size: #{m}in(40em, 70vh);
overflow-y: scroll; overflow-block: scroll;
inset-inline-end: 1em; inset-inline-end: 1em;
background: var(--ui-overlay); background: var(--ui-overlay);
border-radius: 1em; border-radius: 1em;
@ -181,7 +108,7 @@
background: var(--ui-overlay); background: var(--ui-overlay);
padding: 1em; padding: 1em;
border-radius: 100em; border-radius: 100em;
width: 6em; inline-size: 6em;
display: flex; display: flex;
justify-content: center; justify-content: center;
@include shadow-low; @include shadow-low;

View file

@ -1,20 +1,27 @@
.author-card { .author-card {
display: inline-flex; display: inline-flex;
align-items: center;
gap: 0.5em;
.author-card__link { .author-card__link {
text-decoration: none; text-decoration: none;
color: inherit; color: inherit;
display: contents; display: inline-flex;
align-items: center;
&:after { &:after {
display: none !important; // suppress "external links" icon display: none !important; // suppress "external links" icon
} }
} }
&__avatar { &__avatar {
width: 3em; inline-size: 3em;
block-size: 3em;
border-radius: 100em; border-radius: 100em;
display: inline-block;
margin-inline-end: 0.5em;
&:not(img) {
background: var(--ui-overlay-transparent);
}
} }
&__name { &__name {
font-weight: bold; font-weight: bold;
display: inline-flex;
align-items: center;
} }
} }

View file

@ -0,0 +1,14 @@
.feed-item {
&__title {
}
&__date {
}
&__summary {
}
&__readmore {
}
}

View file

@ -0,0 +1,22 @@
.in-reply-to-prepend {
display: grid;
place-items: start start;
grid-template-columns: auto 1fr;
&__text {
place-self: center start;
line-height: 1.5em;
}
&:before {
content: '';
display: inline-block;
background: var(--ui-overlay);
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGZpbGw9IndoaXRlIiBkPSJNMTAgOVY1bC03IDdsNyA3di00LjFjNSAwIDguNSAxLjYgMTEgNS4xYy0xLTUtNC0xMC0xMS0xMSIvPjwvc3ZnPg==);
width: 1em;
height: 1em;
padding: 0.25em;
border-radius: 100em;
background-repeat: no-repeat;
background-position: center;
margin-inline-end: 0.5em;
}
}

View file

@ -1,2 +0,0 @@
+++
+++

View file

@ -1,2 +0,0 @@
+++
+++

View file

@ -1,2 +0,0 @@
+++
+++

View file

@ -1,4 +0,0 @@
+++
title = "articles"
summary = ""
+++

View file

@ -56,4 +56,5 @@ When you put it like this, it becomes clear that if the fediverse wants to conti
And the challenge here, the issue is, that if we don't do this work at a grassroots level, then Meta will do it for us. (Can you imagine a "developer portal" for "interoperating with Threads"?) Things like the FEP process allow writing up these "micro-protocols", and then after that, the difficult task of cat-herding begins, as you need to get implementers onboard with adhering to these specifications. And of course, we're all mostly doing this in our free time and without access to the resources that larger organizations have or can gain access to. So it's going to be an uphill battle. But whichever "protocol building blocks" we can agree and align upon, let's go for it. And the challenge here, the issue is, that if we don't do this work at a grassroots level, then Meta will do it for us. (Can you imagine a "developer portal" for "interoperating with Threads"?) Things like the FEP process allow writing up these "micro-protocols", and then after that, the difficult task of cat-herding begins, as you need to get implementers onboard with adhering to these specifications. And of course, we're all mostly doing this in our free time and without access to the resources that larger organizations have or can gain access to. So it's going to be an uphill battle. But whichever "protocol building blocks" we can agree and align upon, let's go for it.
[^multi-proto-approach]: I was specifically looking at a "unified communication" project, which mapped abstract forms of communication like "messaging", "publishing", "discussing", "reading" onto existing protocols like SMTP, XMPP, ActivityPub, IRC, RSS, ATOM, HTTP. There's a risk of ending up with something like Pidgin here, but maybe that's not the worst thing. [^multi-proto-approach]: I was specifically looking at a "unified communication" project, which mapped abstract forms of communication like "messaging", "publishing", "discussing", "reading" onto existing protocols like SMTP, XMPP, ActivityPub, IRC, RSS, ATOM, HTTP. There's a risk of ending up with something like Pidgin here, but maybe that's not the worst thing.
[^protocol-layering]: And of course, other protocols and other layerings are possible. Libervia (formerly Salut a Toi) does AS2 with PubSub over XMPP, but offers an "ActivityPub gateway". You could, if you wanted to, send AS2 over an SMTP transport. [^protocol-layering]: And of course, other protocols and other layerings are possible. Libervia (formerly Salut a Toi) does AS2 with PubSub over XMPP, but offers an "ActivityPub gateway". You could, if you wanted to, send AS2 over an SMTP transport.

View file

@ -1,10 +0,0 @@
+++
title = "making better stuff is unprofitable"
summary = "there will inevitably be a point where it is unprofitable to improve a product any further."
date = 2017-12-22T06:06:00-06:00
source = "https://mastodon.social/@trwnh/99217860566004390"
+++
There will inevitably be a point where it is unprofitable to improve a product any further.
i.e., if Apple's primary goal was to make useful products, it would make choices that result in a better product even if it was slightly more expensive. But their primary goal is profit, as it is for every corporation under capitalism. Making better stuff is unprofitable.

View file

@ -1,5 +1,5 @@
+++ +++
title = "product vs profit" title = "making better stuff is unprofitable"
summary = "There will inevitably be a point where it is unprofitable to improve a product any further." summary = "There will inevitably be a point where it is unprofitable to improve a product any further."
date = 2017-12-22T06:06:00-06:00 date = 2017-12-22T06:06:00-06:00
source = "https://mastodon.social/@trwnh/99217860566004390" source = "https://mastodon.social/@trwnh/99217860566004390"

View file

@ -1,5 +1,5 @@
+++ +++
title = "voluntarism vs socialism" title = "voluntarism requires equality"
summary = "If two people are inequal, then they can never come to a voluntary agreement -- the power of one will coerce the other" summary = "If two people are inequal, then they can never come to a voluntary agreement -- the power of one will coerce the other"
date = 2018-04-06T18:19:00-05:00 date = 2018-04-06T18:19:00-05:00
source = "https://mastodon.social/@trwnh/99815047195372515" source = "https://mastodon.social/@trwnh/99815047195372515"

View file

@ -0,0 +1,4 @@
+++
title = "responses"
summary = "everything you see here is something that largely only makes sense if you read the original. WARNING: this category is unstable"
+++

View file

@ -0,0 +1,56 @@
+++
date = 2024-10-17T08:49:47-05:00
[[params.inReplyTo]]
name = "The Challenge of ActivityPub Data Portability"
url = "https://bengo.is/blogging/2024-10-03-the-challenge-of-activitypub-data-portability/"
+++
great read! you're spot on in a lot of things, but i had a few nitpicks
> **In ActivityPub, Data Portability comes largely from the Social Data Syntax, not the network protocols.**
>
> The data syntax and semantics enables, amongst other things, data portability and a good federation protocol.
>
> But various endeavors above are trying to solve data portability primarily via network protocols. I've been wondering whether that's the right layer on which to tackle this challenge? Or if some enhancement at the data syntax layer might help.
{cite="https://bengo.is/blogging/2024-10-03-the-challenge-of-activitypub-data-portability/" author="[bengo](https://bengo.is)"}
the data syntax is mostly fine, actually. the challenge for data portability is not in copying documents from one location to another; it's in being able to refer to them independently of network location, as you touch on later. **links are what define the network.** the data is already "portable", it's just that if you port the data, then you destroy the existing network of links.
> a hard choice to make for 5 years now: do you build for ActivityPub's protocol, or do you build for the Mastodon Protocol? The former is fairly well-specified, has consensus-driven governance via W3C / FEPs, but is not implemented by Mastodon. The latter has all the end-users.
{cite="https://bengo.is/blogging/2024-10-03-the-challenge-of-activitypub-data-portability/" author="[bengo](https://bengo.is)"}
i actually think the "activitypub protocol" is not "fairly well-specified". it's not that mastodon simply has all the users. it's that mastodon implements its own protocol on top of activitypub (or LDN). the only S2S protocols that activitypub actually defines are:
- delivery (LDN where the payload is an `Activity`)
- following (send a `Follow`, get back an `Accept Follow` or `Reject Follow`, you can `Undo Follow` -- but note that removing a follower is undefined!)
- liking (send a `Like`, it gets added to the `likes` collection on that object, also it gets added to your `liked` collection on your actor)
- sharing (send an `Announce`, it gets added to the `shares` collection on that object)
the other activities mostly don't have any side effects within activitypub. for example, Create has "surprisingly few side effects" in S2S AP, but in the Mastodon Protocol it actually has significant side effects, in that it persists a "status" in the remote database, and the shape of that activity has a lot of additional requirements placed on top of it. these are all things that are left undefined by AP, and i don't think it is AP's responsibility to define those things, but an additional protocol layered on top of AP should definitely do that. and this is de facto the Mastodon Protocol unless some other entity defines a different protocol (e.g. the Lemmy Protocol)
these are actually really important things to define, and the fact that they're not defined is the biggest problem with the "fediverse" as a network. if you want to interoperate with anyone, you need to basically read their documentation and probably their codebase too and possibly reverse-engineer stuff as well and discuss with other people who did the same. all behavior is formally undefined, or more appropriately implicitly defined by the codebases. it's never stated anywhere that things like deleting your actor have additional side effects like possibly deleting all your "statuses" in that remote database.
> When followed, the link to the input of the ActivityPubOutboxPostProcess would be the exact request body of the HTTP Post request sent by the client to the outbox server, and would include any DataIntegrityProof created by the client.
{cite="https://bengo.is/blogging/2024-10-03-the-challenge-of-activitypub-data-portability/" author="[bengo](https://bengo.is)"}
i don't think it makes sense to store the HTTP POST request unmodified unless you're interested in doing anything with it later e.g. validating an HTTP Signature...
> The more concerning part of what Mastodon has normalized is that the Mastodon Server generates keypairs, not the end-user that is the true entity that the social objects are attributedTo.
{cite="https://bengo.is/blogging/2024-10-03-the-challenge-of-activitypub-data-portability/" author="[bengo](https://bengo.is)"}
one thing i've toyed with is the possibility of linking an object to the Create activity that led to its creation. i was going to use `attributedTo` for this.
> servers should really let an end-user that the Actor represents bring their own verification methods, and only share the public keys with the ActivityPub Server.
{cite="https://bengo.is/blogging/2024-10-03-the-challenge-of-activitypub-data-portability/" author="[bengo](https://bengo.is)"}
the server can lie about public keys attached to the actor though. what we probably need is to instead signal which *clients* are attached to any given actor, and then allow *clients* to declare their own keys. this is because the clients are the user-agents that are acting on behalf of the user, and it is generally not the user who should be handling their own keys directly.
> There's no reason an ActivityPub server should demand to control the end-user's private keys.
{cite="https://bengo.is/blogging/2024-10-03-the-challenge-of-activitypub-data-portability/" author="[bengo](https://bengo.is)"}
one reason is that an actor needs something to prove its own identity when making network requests. the client can use the `proxyUrl` endpoint to fetch objects as the actor, and so the actor needs its own key for federated identity... or so goes the argument.
> I think a lot of people want 'Account Portability' because what they really want is Single Sign On.
{cite="https://bengo.is/blogging/2024-10-03-the-challenge-of-activitypub-data-portability/" author="[bengo](https://bengo.is)"}
disagree; SSO is nice to have but you should be able to port your identity just like you should be able to port your data.

View file

@ -1,6 +1,7 @@
+++ +++
date = 2024-09-30T17:41:00-06:00 date = 2024-09-30T17:41:00-05:00
tags = ["capitalism", "social", "capital", "mastodon", "utility", "analysis"] tags = ["capitalism", "social", "capital", "mastodon", "utility", "analysis"]
draft = true
[[params.inReplyTo]] [[params.inReplyTo]]
name = "post #36 of \"SocialWebFoundation - what do people think?\"" name = "post #36 of \"SocialWebFoundation - what do people think?\""
url = "https://socialhub.activitypub.rocks/t/socialwebfoundation-what-do-people-think/4564/36" url = "https://socialhub.activitypub.rocks/t/socialwebfoundation-what-do-people-think/4564/36"

View file

@ -0,0 +1,5 @@
+++
layout = "page"
+++
test

View file

@ -0,0 +1 @@
talking about the making of this website. this section might not exist later if i end up thinking of a better place to put stuff

View file

@ -0,0 +1,46 @@
+++
title = "URI design and slug choice"
summary = "Some guidelines on where to put content files."
updated = 2024-10-16
toc = true
+++
## Sections
### Why sections?
Web pages generally benefit from having some context associated with them. If they don't, then it's fine to stick them directly under the root of your domain name. These "top-level" pages are standalone and don't need any additional context. Common examples include:
- /about
- /contact
- /search
### Defining a section
When defining a section, it should have a clear reason to exist, and it should be defined narrowly enough that it doesn't overlap with any other section. Within each section, typically aim for zero nesting. The aim is for each section to represent a logical bucket into which I can put stuff, and then later be able to easily find that stuff.
### Currently existing sections
- /monologues = self-replies and other passing stream-of-consciousness stuff
- /theorycrafting = exploring ideas and concepts
- /essays = writings intended to convince
### Future potential sections
- /posts = a section that i can hook up to a micropub server or something, which i would use for primarily "social media" style use-cases. it's very likely that most things in here will be indieweb post type "note", but i don't actually care what the post type is, and it doesn't actually matter what the post type is. as far as i'm concerned and as far as this section is concerned, they're all posts.
- /meta = stuff about this website itself, like this document
- /unstable = stuff that might disappear at any time, kind of a dumping ground
## Slugs
### Slugs are not titles
The slug **SHOULD NOT** be thought of as linked to the title in any way. You can use the title as a suggestion for a slug, but the slug has no bearing on the title. This is because the title can change freely without affecting the slug. They are separate things.
### Slugs should start with the primary subject
The first part of the slug **SHOULD** be the primary subject of whatever the page/article/writing is about. For example, a content piece in `/monologues` with the title "specs aren't enough" may not actually be primarily about "specs". It is in fact about fedi. So the slug should be `fedi-specs-arent-enough` and not `specs-arent-enough`. Note that this can still be ambiguous because it is unclear whether the primary subject is "specs" or "fedi specs". I don't have a good solution for this ambiguity, but it is better to keep "fedi" in there, because a potential reader seeing only `specs-arent-enough` will have no way of knowing that the content is about fedi in particular.
### Slugs should match the folder name
Custom slugs **SHOULD NOT** be set. If it's good enough for your filesystem, it should be good enough for your URI, and vice-versa.

View file

@ -8,10 +8,11 @@
{{- else }} {{- else }}
{{- /* this is a quote */}} {{- /* this is a quote */}}
{{- $datapath := (split (.Attributes.card) "/") }} {{- $datapath := (split (.Attributes.card) "/") }}
{{- $author := .Page.Site.Data.people }} {{- $card := .Page.Site.Data.people }}
{{- range $datapath }} {{- range $datapath }}
{{- $author = index $author . }} {{- $card = index $card . }}
{{- end }} {{- end }}
{{- $author := .Attributes.author }}
{{- $content := .Text }} {{- $content := .Text }}
{{- $cite := .Attributes.cite }} {{- $cite := .Attributes.cite }}
{{- $title := .Attributes.title }} {{- $title := .Attributes.title }}
@ -19,6 +20,7 @@
{{- $caption := .Attributes.caption }} {{- $caption := .Attributes.caption }}
{{- $opts := dict {{- $opts := dict
"ctx" . "ctx" .
"card" $card
"author" $author "author" $author
"content" $content "content" $content
"cite" $cite "cite" $cite

View file

@ -1,6 +1,5 @@
<h{{.Level}} class="rendered-heading" id="{{.Anchor | safeURL}}">{{- /* chomp whitespace */ -}} <h{{.Level}} class="rendered-heading" id="{{.Anchor | safeURL}}">{{- /* chomp whitespace */ -}}
<span class="rendered-heading__text">{{.Text | safeHTML}}</span>{{- /* chomp whitespace */ -}} <span class="rendered-heading__text">{{.Text | safeHTML}}</span>{{- /* chomp whitespace */ -}}
<a class="rendered-heading__anchor-link" href="#{{.Anchor | safeURL}}" aria-hidden="true">{{- /* chomp whitespace */ -}} <a class="rendered-heading__anchor-link" href="#{{.Anchor | safeURL}}" aria-hidden="true">{{- /* chomp whitespace */ -}}
<span class="rendered-heading__anchor-link__text">[link]</span>{{- /* chomp whitespace */ -}}
</a>{{- /* chomp whitespace */ -}} </a>{{- /* chomp whitespace */ -}}
</h{{.Level}}> </h{{.Level}}>

View file

@ -1,5 +1,6 @@
{{ define "body" }} {{ define "body" }}
<body class="layout-_default-list"> <body class="layout-_default-list">
{{ partial "site-header.html" . }}
<main class="h-feed hfeed" id="main"> <main class="h-feed hfeed" id="main">
{{ "<!-- the main header contains list metadata -->" | safeHTML }} {{ "<!-- the main header contains list metadata -->" | safeHTML }}
<header class="list-header section"> <header class="list-header section">
@ -33,52 +34,15 @@
<section class="list-pages section" id="items"> <section class="list-pages section" id="items">
<div class="container"> <div class="container">
<ol class="pages-list"> <ol class="pages-list">
{{- range .Pages }} {{- range .RegularPagesRecursive }}
{{- if .Title }}{{/* indieweb post kind is probably article */}} <li class="pages-list-item">
<li class="pages-list__item"> {{ partial "mf2/h-entry.html" . }}
<article class="h-entry hentry">
<header style="display: contents">
<span><time class="dt-published published" datetime="{{.Date.Format "2006-01-02T15:04:05Z"}}">{{.Date.Format "2006-01-02"}}</time>: <a class="u-url url" href="{{.Permalink}}"><h2 class="p-name entry-title">{{.Title}}</h2></a></span>
{{- if isset .Params "summary" }}{{/* only use explicitly-set summaries, not auto-generated ones */ -}}
<br>
<span class="p-summary entry-summary">{{.Summary}}</span>
{{- end }}{{/* end if isset .Params "summary" */ -}}
</header>
</article>
</li> </li>
{{- else }}{{/* indieweb post kind is probably note */}}
{{- if eq .Content (truncate 1000 "..." .Content) }}{{/* if it's short enough, render the whole thing. */}}
<li class="pages-list__item">
<article class="h-entry hentry">
<header>
<p><span><time class="dt-published published" datetime="{{.Date.Format "2006-01-02T15:04:05Z"}}">{{.Date.Format "2006-01-02"}}</time>: <a href="{{.Permalink}}">untitled post</a></span></p>
</header>
<section class="e-content entry-content">
{{- .Content }} {{/* TODO: better representation? */}}
</section>
</article>
</li>
{{- else }}{{/* otherwise render a truncated summary. */}}
<li class="pages-list__item">
<article class="h-entry hentry">
<header>
<p><span><time class="dt-published published" datetime="{{.Date.Format "2006-01-02T15:04:05Z"}}">{{.Date.Format "2006-01-02"}}</time>: <a href="{{.Permalink}}">untitled post</a></span></p>
</header>
<section class="e-content entry-content">
{{- .Summary }} {{/* TODO: better representation? */}}
<p><a href="{{.Permalink}}">Read more</a></p>
</section>
</article>
</li>
{{- end }}
{{- end }}{{/* end if-title post type check */ -}}
{{- end }}{{/* end range over pages */ -}} {{- end }}{{/* end range over pages */ -}}
</ol> </ol>
</div> </div>
</section> </section>
<footer>
<a href="#main" class="back-to-top">Go back to the top</a>
</footer>
</main> </main>
{{ partial "site-footer.html" . }}
</body> </body>
{{ end }}{{/* end define-body */ -}} {{ end }}{{/* end define-body */ -}}

View file

@ -0,0 +1,7 @@
{{ define "body" }}
<body class="layout-_default-page">
<main id="main" class="page-main">
{{ .Content }}
</main>
</body>
{{ end }}

View file

@ -3,6 +3,7 @@
{{- define "body" }} {{- define "body" }}
<body class="layout-_default-single"> <body class="layout-_default-single">
{{ partial "site-header.html" . }}
<main id="main"> <main id="main">
{{ "<!-- begin article -->" | safeHTML }} {{ "<!-- begin article -->" | safeHTML }}
<article class="page h-entry hentry" {{- if .Param "autonumbering" }} autonumbering {{- end }}{{- if .Param "toc" }} has-toc {{- end }}> <article class="page h-entry hentry" {{- if .Param "autonumbering" }} autonumbering {{- end }}{{- if .Param "toc" }} has-toc {{- end }}>
@ -12,8 +13,9 @@
{{- if isset .Params "summary" }}{{/* only use explicitly-set summaries, not auto-generated ones */}} {{- if isset .Params "summary" }}{{/* only use explicitly-set summaries, not auto-generated ones */}}
{{ with .Summary | safeHTML }}<p class="page-summary p-summary entry-summary">{{.}}</p>{{ end }} {{ with .Summary | safeHTML }}<p class="page-summary p-summary entry-summary">{{.}}</p>{{ end }}
{{- end }} {{- end }}
{{- with (index .Site.Data.people "trwnh.com").a }}{{/* TODO: make author a variable instead of assuming it's always me */}} {{- with (index .Site.Data.people "trwnh.com").a }}{{/* TODO: make author a variable instead of assuming it's always me. also maybe support multiple authors */}}
<p class="page-author p-author"> <p class="page-author p-author">
<span style="display: none">Written by </span>
{{- partial "mf2/h-card.html" . }} {{- partial "mf2/h-card.html" . }}
</p> </p>
{{- end }} {{- end }}
@ -24,6 +26,7 @@ Published <time class="dt-published published" datetime="{{.Format "2006-01-02T1
{{- end }} {{- end }}
{{- with .Params.inReplyTo }} {{- with .Params.inReplyTo }}
{{- range . }} {{- range . }}
{{- if .}}
{{- $name := or .name "[link]" }} {{- $name := or .name "[link]" }}
{{- $href := "" }} {{- $href := "" }}
{{- if .pageRef }} {{- if .pageRef }}
@ -31,29 +34,20 @@ Published <time class="dt-published published" datetime="{{.Format "2006-01-02T1
{{- else }} {{- else }}
{{- $href = .url }} {{- $href = .url }}
{{- end }} {{- end }}
<p class="page-inreplyto"> {{- partial "mf2/u-in-reply-to.html" . }}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" class="reply-icon" aria-hidden="true"><path fill="currentColor" d="M19 19v-4q0-1.25-.875-2.125T16 12H6.825l3.6 3.6L9 17l-6-6l6-6l1.425 1.4l-3.6 3.6H16q2.075 0 3.538 1.463T21 15v4z"/></svg>
<span>In response to: <a class="u-in-reply-to"{{with $href}} href="{{.}}"{{end}}><span>{{$name}}</span></a></span>
</p>
{{- end }} {{- end }}
{{- end }} {{- end }}
<a href="#end-of-header" class="skip-to-end-of-header">Skip syndication information</a> {{- end }}
<a href="#end-of-header" class="skip-syndication" aria-label="Skip syndication information"></a>
{{- with .Permalink }} {{- with .Permalink }}
<p class="page-permalink">h-entry URL: <a class="u-url url" href="{{.}}">{{.}}</a></p> <p class="page-permalink" aria-hidden="true">h-entry URL: <a class="u-url url" href="{{.}}">{{.}}</a></p>
{{- end }} {{- end }}
{{- with .Params.syndication }} {{- with .Params.syndication }}
<aside class="page-syndication"> <aside class="page-syndication">
<p>This entry has been posted elsewhere:</p> {{ partial "components/syndication-list.html" . }}
<ul class="syndication-list">
{{- range . }}
<li class="syndication-list-item">
<a{{with .url}} href="{{.}}" rel="syndication" class="u-syndication"{{end}}>{{or .name .url}}</a>
</li>
{{- end }}
</ul>
</aside> </aside>
{{- end }} {{- end }}
{{/* {{ with .Params.source }} {{- /* {{ with .Params.source }}
{{ $type := (printf "%T" .) }} {{ $type := (printf "%T" .) }}
{{ if eq $type "string"}} {{ if eq $type "string"}}
{{ if (findRE "^http" .) }} {{ if (findRE "^http" .) }}
@ -65,34 +59,13 @@ Published <time class="dt-published published" datetime="{{.Format "2006-01-02T1
{{ end }} */}} {{ end }} */}}
</div> </div>
<hr /> <hr />
<a id="end-of-header"></a> <a id="end-of-header" aria-hidden="true"></a>
</header> </header>
{{- if .Params.series }} {{- if .Params.series }}
{{ "<!-- article aside: this article is part of a series -->" | safeHTML }} {{ "<!-- article aside: this article is part of a series -->" | safeHTML }}
<aside class="page-series section"> <aside class="page-series section">
<div class="container"> <div class="container">
{{- with .Site.Taxonomies.series }} {{ partial "components/series-list.html" . }}
{{- range $term, $weightedpages := . }}
<p class="page-series__hint">This post is part of a series: <a href="{{.Page.Permalink}}">{{.Page.LinkTitle}}</a></p>
<ol class="series">
{{- range $weightedpages.Pages.ByWeight.Reverse }}
<li class="series-post">
{{- if eq .File.UniqueID $.File.UniqueID -}}
{{- with .Params.series_part }}
<span class="series-post__part">Part {{.}}: </span>
{{- end }}
<span class="series-post__title current-post">{{.Title}}</span>
{{- else }}
{{- with .Params.series_part }}
<span class="series-post__part">Part {{.}}: </span>
{{- end }}
<a href="{{.Permalink}}" class="series-post__link"><span class="series-post__title">{{.Title}}</span></a>
{{- end }}
</li>
{{- end }}
</ol>
{{- end }}
{{- end }}
</div> </div>
<hr /> <hr />
</aside> </aside>
@ -123,8 +96,8 @@ Published <time class="dt-published published" datetime="{{.Format "2006-01-02T1
</div> </div>
</footer> </footer>
</article> </article>
<a href="#main" class="back-to-top">Back to top</a>
{{ "<!-- end article -->" | safeHTML }} {{ "<!-- end article -->" | safeHTML }}
</main> </main>
{{ partial "site-footer.html" . }}
</body> </body>
{{ end }} {{ end }}

View file

@ -1,34 +1,38 @@
{{- $author := .author }} {{- $author := .author }}
{{- $card := .card }}
{{- $content := .content }} {{- $content := .content }}
{{- $cite := .cite }} {{- $cite := .cite }}
{{- $title := .title }} {{- $title := .title }}
{{- $ref := .ref }} {{- $ref := .ref }}
{{- $caption := .caption }} {{- $caption := .caption }}
<article class="quote-block{{if $cite}} h-cite{{end}}{{ if $author}} h-x-quote{{end}}"> <article class="quote-block{{if $cite}} h-cite{{end}}{{ if $author}} h-x-quote{{end}}">
{{- with $author }} {{- with or $card $author }}
<header style="display: contents"> <header class="quote-block__header">
<svg class="quote-block__icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 290 290" width="1em" height="1em" fill="currentColor"><title>quote</title><path d="M22.12 145v97.65h97.65V145H70.95c0-26.92 21.9-48.82 48.82-48.82V47.35c-53.93 0-97.65 43.72-97.65 97.65zm245.76-48.82V47.35c-53.93 0-97.65 43.72-97.65 97.65v97.65h97.65V145h-48.82c-.01-26.92 21.89-48.82 48.82-48.82z"></path></svg> <p class="quote-block__attribution">
<p style="display: contents"> {{- with $card }}
<span class="p-author"> <span class="quote-block__card p-author">{{ partial "mf2/h-card.html" . }}</span>
{{- partial "mf2/h-card.html" . }} {{- else with $author }}
<span class="quote-block__author p-author h-card">
{{ . | markdownify }}
</span> </span>
<span style="display: none"> wrote:</span> {{- end -}}
<span class="quote-block__postpend"> wrote:</span>
</p> </p>
</header> </header>
{{- else }} {{- else }}
<header style="display: contents"> <header class="quote-block__header">
<svg class="quote-block__icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 290 290" width="1em" height="1em" fill="currentColor"><title>quote</title><path d="M22.12 145v97.65h97.65V145H70.95c0-26.92 21.9-48.82 48.82-48.82V47.35c-53.93 0-97.65 43.72-97.65 97.65zm245.76-48.82V47.35c-53.93 0-97.65 43.72-97.65 97.65v97.65h97.65V145h-48.82c-.01-26.92 21.89-48.82 48.82-48.82z"></path></svg> <p class="quote-block__prepend">Quote:</p>
</header> </header>
{{- end }} {{- end }}
{{- with $content }} {{- with $content }}
<section style="display: contents"> <section class="quote-block__content">
<blockquote class="quote-block__content e-content"{{ with $cite }} cite="{{.}}"{{end}}> <blockquote class="e-content"{{ with $cite }} cite="{{.}}"{{end}}>
{{. -}} {{. -}}
</blockquote> </blockquote>
</section> </section>
{{- end }} {{- end }}
{{- if (or $caption $cite) }} {{- if (or $caption $cite) }}
<footer style="display: contents"> <footer class="quote-block__footer">
<p style="display: contents"> <p style="display: contents">
{{- with $caption }} {{/* caption is manually set and overrides cite+title+ref/etc */}} {{- with $caption }} {{/* caption is manually set and overrides cite+title+ref/etc */}}
<span class="quote-block__caption">{{ . | markdownify }}</span> <span class="quote-block__caption">{{ . | markdownify }}</span>

View file

@ -0,0 +1,22 @@
{{- with .Site.Taxonomies.series }}
{{- range $term, $weightedpages := . }}
<p class="series-hint">This post is part of a series: <a href="{{.Page.Permalink}}" class="series-link">{{.Page.LinkTitle}}</a></p>
<ol class="series-list">
{{- range $weightedpages.Pages.ByWeight.Reverse }}
<li class="series-post">
{{- if eq .File.UniqueID $.File.UniqueID -}}
{{- with .Params.series_part }}
<span class="series-post__part">Part {{.}}: </span>
{{- end }}
<span class="series-post__title current-post">{{.Title}}</span>
{{- else }}
{{- with .Params.series_part }}
<span class="series-post__part">Part {{.}}: </span>
{{- end }}
<a href="{{.Permalink}}" class="series-post__link"><span class="series-post__title">{{.Title}}</span></a>
{{- end }}
</li>
{{- end }}
</ol>
{{- end }}
{{- end }}

View file

@ -0,0 +1,8 @@
<p class="syndication-hint">This entry has been posted elsewhere:</p>
<ul class="syndication-list">
{{- range . }}
<li class="syndication-list-item">
<a{{with .url}} href="{{.}}" class="u-syndication"{{end}}>{{or .name .url}}</a>
</li>
{{- end }}
</ul>

View file

@ -0,0 +1 @@
<time class="dt-published published" datetime="{{.Date.Format "2006-01-02T15:04:05-07:00"}}">{{.Date.Format "2006-01-02"}}</time>

View file

@ -1,32 +1,25 @@
{{ $name := .name }} {{- $name := .name }}
{{- $url := .url }} {{- $url := .url }}
{{- $icon := .icon }} {{- $icon := .icon }}
<span class="author-card h-card vcard"> <span class="author-card h-card vcard">
{{- if $url }} {{- if $url }}
<a class="author-card__link u-url url" href="{{$url}}"> <a class="author-card__link u-url url" href="{{$url}}">
{{- with $icon }} {{- end }}
<img class="author-card__avatar u-photo u-logo photo logo" {{- if $icon }}
src="{{.}}" <img class="author-card__avatar u-photo u-logo photo logo"
alt="" src="{{$icon}}"
width="48" alt=""
height="48" width="48"
aria-hidden="true" height="48"
/> aria-hidden="true"
{{- end }} />
{{- with $name }} {{- else }}
<span class="author-card__name p-name fn">{{.}}</span> <span class="author-card__avatar"></span>
{{- end }} {{- end }}
</a> {{- if $name }}
{{- else }} <span class="author-card__name p-name fn">{{$name}}</span>
{{- with $icon }} {{- end }}
<img class="author-card__avatar u-photo u-logo photo logo" {{- if $url }}
src="{{.}}" </a>
alt="" {{- end }}
aria-hidden="true"
/>
{{- end }}
{{- with $name }}
<span class="author-card__name p-name fn">{{.}}</span>
{{- end }}
{{- end }}
</span> </span>

View file

@ -0,0 +1,13 @@
<article class="feed-item h-entry hentry">
<h2 class="feed-item__title p-name"><a href="{{.Permalink}}" class="u-url">{{or .Title "[untitled post]"}}</a></h2>
<p style="display: contents"><span style="display: none">Published on </span><span class="feed-item__date">{{ partial "mf2/dt-published.html" . }}</span></p>
{{- range .Params.inReplyTo }}
{{- with . }}
{{ partial "mf2/u-in-reply-to.html" . }}
{{- end }}
{{- end }}
<section class="feed-item__summary e-summary">
{{.Summary}}
</section>
<p class="feed-item__readmore"><a href="{{ .Permalink }}" class="u-url">View full entry</a></p>
</article>

View file

@ -0,0 +1,2 @@
{{- $url := or .url (site.GetPage .pageRef).Permalink}}
<p class="in-reply-to-prepend"><span class="in-reply-to-prepend__text">In response to <a class="u-in-reply-to h-entry"{{with $url}} href="{{.}}"{{end}}>{{or .name $url}}</a></span></p>

View file

@ -1,5 +1,5 @@
<form id="search-form" action='{{ with .GetPage (printf "%s%s" .CurrentSection.RelPermalink "search") }}{{.Permalink}}{{end}}' method="get"> <form id="search-form" action='{{ with .GetPage (printf "%s%s" .CurrentSection.RelPermalink "search") }}{{.Permalink}}{{end}}' method="get">
<label hidden for="search-input">Search site</label> <label hidden for="search-input">Search site</label>
<input id="search-input" type="text" name="query" placeholder="Type here to search"> <input id="search-input" type="text" name="query" placeholder="Type here to search">
<input id="search-submit" type="submit" value="search"> <input id="search-submit" type="submit" value="search">
</form> </form>

View file

@ -1,5 +1,15 @@
{{- $fallbackTitle := "" }}
{{- if eq .Section "responses" }}
{{ range .Params.inReplyTo }}
{{- if . }}
{{- $fallbackTitle = printf "in response to %s" (or .name .url) }}
{{- end }}
{{- end }}
{{- else if eq .Section "wiki" }}
{{- $firstH1 := partial "firstH1.html" . }} {{- $firstH1 := partial "firstH1.html" . }}
{{- $title := or .Title $firstH1 $.File.ContentBaseName }} {{- $fallbackTitle = or $firstH1 $.File.ContentBaseName }}
{{- end }}
{{- $title := or .Title $fallbackTitle }}
{{- $fullTitle := print .Site.Title " | " $title}} {{- $fullTitle := print .Site.Title " | " $title}}
{{- $cover := ($.Resources.ByType "image").GetMatch "{*opengraph*}" -}} {{- $cover := ($.Resources.ByType "image").GetMatch "{*opengraph*}" -}}
@ -21,7 +31,7 @@
{{- end -}} {{- end -}}
{{/*=== description ===*/}} {{/*=== description ===*/}}
{{- with or .Description .Summary .Site.Params.description }} {{- with or .Description .Params.summary .Site.Params.description (plainify (.Content | safeHTML) | strings.Truncate 140) }}
<meta name="description" itemprop="description" property="og:description" content="{{ . }}" /> <meta name="description" itemprop="description" property="og:description" content="{{ . }}" />
<meta name="twitter:description" content="{{ . }}" /> <meta name="twitter:description" content="{{ . }}" />
{{- end }} {{- end }}
@ -66,7 +76,9 @@
<meta name="author" property="article:author" content="{{ .name }}" /> <meta name="author" property="article:author" content="{{ .name }}" />
{{- end }} {{- end }}
<meta property="article:publisher" content="{{ .Site.BaseURL }}" /> <meta property="article:publisher" content="{{ .Site.BaseURL }}" />
{{- if or .Date .Lastmod }}
{{ "<!-- time -->" | safeHTML }} {{ "<!-- time -->" | safeHTML }}
{{- end }}
{{ with .Date -}} {{ with .Date -}}
<meta property="article:published_time" itemprop="datePublished" content={{ .Format "2006-01-02T03:04:05Z" | safeHTML }} /> <meta property="article:published_time" itemprop="datePublished" content={{ .Format "2006-01-02T03:04:05Z" | safeHTML }} />
{{ end -}} {{ end -}}
@ -150,14 +162,14 @@
{{ with .OutputFormats.Get "RSS" -}} {{ with .OutputFormats.Get "RSS" -}}
<link rel="feed alternate" type="application/rss+xml" title="{{ $fullTitle }}" href="{{ .Permalink }}" /> <link rel="feed alternate" type="application/rss+xml" title="{{ $fullTitle }}" href="{{ .Permalink }}" />
{{- end }} {{- end }}
{{ with .OutputFormats.Get "Atom" -}} {{- with .OutputFormats.Get "Atom" -}}
<link rel="feed alternate" type="application/atom+xml" title="{{ $fullTitle }}" href="{{ .Permalink }}" /> <link rel="feed alternate" type="application/atom+xml" title="{{ $fullTitle }}" href="{{ .Permalink }}" />
{{- end }} {{- end }}
{{ with .OutputFormats.Get "Sitemap" -}} {{- with .OutputFormats.Get "Sitemap" -}}
<link rel="sitemap" type="application/xml" title="Sitemap" href="{{ .Permalink }}" /> <link rel="sitemap" type="application/xml" title="Sitemap" href="{{ .Permalink }}" />
{{- end -}} {{- end -}}
{{/* TODO: more output formats? or possibly loop/iterate over all output formats? (probably not, don't want to link to lunr.json do we?) */ -}} {{- /* TODO: more output formats? or possibly loop/iterate over all output formats? (probably not, don't want to link to lunr.json do we?) */ -}}
{{/* robots */ -}} {{- /* robots */ -}}
{{ "<!-- robots -->" | safeHTML }} {{ "<!-- robots -->" | safeHTML }}
<meta name="robots" content="index,follow" /> <meta name="robots" content="index,follow" />
<meta name="googlebot" content="index,follow" /> <meta name="googlebot" content="index,follow" />

View file

@ -0,0 +1,5 @@
<footer class="site-footer">
<div class="container">
<a href="#main" class="back-to-top">Back to top</a>
</div>
</footer>

View file

@ -0,0 +1,5 @@
<header class="site-header">
<div class="container">
<p>trwnh.com is under construction! things may look weird until it's ready...</p>
</div>
</header>

View file

@ -2,8 +2,8 @@
a[href]:not(.footnote-ref):after { a[href]:not(.footnote-ref):after {
content: ''; content: '';
display: inline-grid; display: inline-grid;
width: 1rem; inline-size: 1rem;
height: 0.875rem; block-size: 0.875rem;
font-size: 1rem; font-size: 1rem;
background-color: currentColor; background-color: currentColor;
mask: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxnIGZpbGw9IndoaXRlIj48cGF0aCBkPSJNMTUuNjQgNy4wMjVoLTMuNjIydi0yaDd2N2gtMnYtMy41NWwtNC45MTQgNC45MTRsLTEuNDE0LTEuNDE0eiIvPjxwYXRoIGQ9Ik0xMC45ODIgNi45NzVoLTZ2MTJoMTJ2LTZoLTJ2NGgtOHYtOGg0eiIvPjwvZz48L3N2Zz4='); mask: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxnIGZpbGw9IndoaXRlIj48cGF0aCBkPSJNMTUuNjQgNy4wMjVoLTMuNjIydi0yaDd2N2gtMnYtMy41NWwtNC45MTQgNC45MTRsLTEuNDE0LTEuNDE0eiIvPjxwYXRoIGQ9Ik0xMC45ODIgNi45NzVoLTZ2MTJoMTJ2LTZoLTJ2NGgtOHYtOGg0eiIvPjwvZz48L3N2Zz4=');
@ -11,7 +11,8 @@ a[href]:not(.footnote-ref):after {
} }
a[href^="{{.Site.BaseURL}}"]:not(.footnote-ref):after, a[href^="{{.Site.BaseURL}}"]:not(.footnote-ref):after,
a[href^="#"]:not(.footnote-ref):after a[href^="#"]:not(.footnote-ref):after,
a[href^="/"]:not(.footnote-ref):after
{ {
background-image: none !important; background-image: none !important;
display: none; display: none;

View file

@ -1,27 +1,30 @@
<nav class="breadcrumb-nav"> <nav class="breadcrumb-nav">
<div class="container"> <div class="container">
<p class="title">You are here:</p> <p class="title">You are here:</p>
<ul class="breadcrumbs"> <ol class="breadcrumbs">
{{ template "breadcrumb" (dict "p1" . "p2" .) }} {{- range .Ancestors.Reverse }}
</ul> <li><a href="{{.RelPermalink}}">{{ template "name" . }}</a></li>
</div> {{- end }}
<li>{{ template "name" . }}</li>
</ol>
</div>
</nav> </nav>
{{ define "breadcrumb" }} {{- define "name" -}}
{{ if .p1.Parent }}
{{ template "breadcrumb" (dict "p1" .p1.Parent "p2" .p2 ) }}
{{ else if not .p1.IsHome }}
{{ template "breadcrumb" (dict "p1" .p1.Site.Home "p2" .p2 ) }}
{{ end }}
<li{{ if eq .p1 .p2 }} class="active"{{ end }}>
{{/* $header := substr (delimit (findRE "^#{1} ([^{\n]+)" .p1.RawContent 1) "") 2 */}}
<a href="{{ .p1.RelPermalink }}"> {{- $name := "" -}}
{{ if eq .p1.Kind "page" }} {{- if eq .Kind "page" -}}
{{ .p1.File.LogicalName }} {{- $name = .File.LogicalName -}}
{{ else }} {{- else -}}
{{ or .p1.File.ContentBaseName .p1.Site.Title }} {{- if eq .Kind "section" -}}
{{ end }} {{- $name = .File.ContentBaseName -}}
</a> {{- else -}}
</li> {{- if eq .Kind "home" -}}
{{ end }} {{- $name = or .Title .Site.Title -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $name -}}
{{- end -}}

View file

@ -1,7 +1,7 @@
<footer class="site-footer"> <footer class="site-footer">
<hr> <hr>
<div class="container"> <div class="container">
{{ partial "lastmod.html" . }} {{ partial "lastmod.html" . }}
</div> </div>
</footer> </footer>

View file

@ -1,11 +1,11 @@
<header class="site-header"> <header class="site-header">
<div class="container"> <div class="container">
<a href="/" class="site-masthead"> <a href="/" class="site-masthead">
<p class="site-title">{{.Site.Title}}</p> <p class="site-title">{{.Site.Title}}</p>
</a> </a>
{{ partial "search/search-form.html" . }} {{ partial "search/search-form.html" . }}
</div> </div>
</header> </header>
<div class="scroll-margin" style="position: relative;"> <div class="scroll-margin" style="position: relative;">
<div id="top" style="scroll-margin-top: var(--header-height);"></div> <div id="top" style="scroll-margin-top: var(--header-height);"></div>
</div> </div>

View file

@ -1,16 +1,18 @@
{{ $datapath := (split (.Get "card") "/") }} {{- $datapath := (split (.Get "card") "/") }}
{{ $author := .Page.Site.Data.people }} {{- $card := .Page.Site.Data.people }}
{{ range $datapath }} {{- range $datapath }}
{{ $author = index $author . }} {{- $card = index $card . }}
{{ end }} {{- end }}
{{ $content := .Page.RenderString (dict "display" "block") .Inner }} {{- $author := .Get "author" }}
{{ $cite := .Get "cite" }} {{- $content := .Page.RenderString (dict "display" "block") .Inner }}
{{ $title := .Get "title" }} {{- $cite := .Get "cite" }}
{{ $ref := .Get "ref" }} {{- $title := .Get "title" }}
{{ $caption := .Get "caption" }} {{- $ref := .Get "ref" }}
{{ $opts := dict {{- $caption := .Get "caption" }}
{{- $opts := dict
"ctx" . "ctx" .
"author" $author "author" $author
"card" $card
"content" $content "content" $content
"cite" $cite "cite" $cite
"title" $title "title" $title

View file

@ -1,56 +1,56 @@
{{ define "body" }} {{ define "body" }}
<body class="wiki layout-wiki-list"> <body class="wiki layout-wiki-list">
{{ $currentFolderName := or $.File.ContentBaseName "index" }} {{ $currentFolderName := or $.File.ContentBaseName "index" }}
{{ partial "wiki/site-header.html" .}} {{ partial "wiki/site-header.html" .}}
{{ partial "wiki/breadcrumbs.html" .}} {{ partial "wiki/breadcrumbs.html" .}}
<main> <main>
<section class="section list"> <section class="section list">
<div class="container"> <div class="container">
<header class="section-header"> <header class="section-header">
{{ if .IsHome }} {{ if .IsHome }}
<h1 class="section-title">{{.Site.Title}}</h1> <h1 class="section-title">{{.Site.Title}}</h1>
{{ else }} {{ else }}
<h1 class="section-title">{{or .Title .File.Dir}}</h1> <h1 class="section-title">{{or .Title .File.Dir}}</h1>
{{ end }} {{ end }}
</header> </header>
<div class="content hugo-content"> <div class="content hugo-content">
{{.Content}} {{.Content}}
</div> </div>
{{ with .Sections }} {{ with .Sections }}
<nav> <nav>
<h2 class="subsections-title">Sub-sections of {{ $currentFolderName }}</h2> <h2 class="subsections-title">Sub-sections of {{ $currentFolderName }}</h2>
<ul class="subsections"> <ul class="subsections">
{{ range where . "Section" "not in" (slice "search" "sitemap") }} {{ range where . "Section" "not in" (slice "search" "sitemap") }}
<li> <li>
<a href="{{ .Permalink }}"> <a href="{{ .Permalink }}">
{{ path.Base (path.Split .File.Path).Dir }}/ {{ path.Base (path.Split .File.Path).Dir }}/
</a> </a>
</li> </li>
{{ end }} {{ end }}
</ul> </ul>
</nav> </nav>
{{ end }} {{ end }}
{{ with .RegularPages }} {{ with .RegularPages }}
<nav> <nav>
<h2 class="subpages-title">Pages within {{ $currentFolderName }}</h2> <h2 class="subpages-title">Pages within {{ $currentFolderName }}</h2>
<ul class="subpages"> <ul class="subpages">
{{ range . }} {{ range . }}
<li> <li>
<a href="{{ .Permalink }}"> <a href="{{ .Permalink }}">
{{ $firstH1 := partial "firstH1.html" . }} {{ $firstH1 := partial "firstH1.html" . }}
{{ if .Site.Params.use_titles_in_section_lists}} {{ if .Site.Params.use_titles_in_section_lists}}
{{ or .Title $firstH1 .File.BaseFileName }} {{ or .Title $firstH1 .File.BaseFileName }}
{{ else }} {{ else }}
{{ .File.LogicalName }} {{ .File.LogicalName }}
{{ end }} {{ end }}
</a> </a>
</li> </li>
{{ end }} {{ end }}
</ul> </ul>
</nav> </nav>
{{ end }} {{ end }}
</div> </div>
</section> </section>
</main> </main>
</body> </body>
{{ end }} {{ end }}

View file

@ -1,33 +1,28 @@
{{ define "body" }} {{ define "body" }}
<body class="wiki layout-wiki-single"> <body class="wiki layout-wiki-single">
{{ $currentFolderName := or $.File.ContentBaseName "index" }} {{- $currentFolderName := or $.File.ContentBaseName "index" }}
{{ partial "wiki/site-header.html" .}} {{- partial "wiki/site-header.html" .}}
{{ partial "wiki/breadcrumbs.html" .}} {{- partial "wiki/breadcrumbs.html" .}}
<main> <main class="page" {{- if .Param "autonumbering" }} autonumbering {{- end }}>
<article class="page" {{- if .Param "autonumbering" }} autonumbering {{- end }}> {{- with .Title}}
{{ with .Title}} <header class="section page-header">
<header class="section page-header"> <div class="container">
<div class="container"> <h1 class="page-title">{{ . }}</h1>
<h1 class="page-title">{{ . }}</h1> </div>
</div> </header>
</header> {{- end }}
{{ end }} {{- if .Params.toc }}
{{ if .Params.toc }} <aside class="toc section">
<aside class="toc section"> <div class="container">
<div class="container"> {{- partial "components/table-of-contents.html" . }}
<details open> </div>
<summary class="toc-title">Contents</summary> </aside>
{{ .TableOfContents }} {{- end }}
</details> <section class="content section">
</div> <div class="container hugo-content">
</aside> {{ .Content -}}
{{ end }} </div>
<section class="content section"> </section>
<div class="container hugo-content"> </main>
{{ .Content }}
</div>
</section>
</article>
</main>
</body> </body>
{{ end }} {{ end }}

View file

@ -22,17 +22,17 @@ html {font-family: -apple-system, BlinkMacSystemFont,
"Fira Sans", "Droid Sans", "Helvetica Neue", "Segoe UI", sans-serif} "Fira Sans", "Droid Sans", "Helvetica Neue", "Segoe UI", sans-serif}
/* typography */ /* typography */
header h1 {font-size: clamp(1.5rem, 10vw, 3rem); line-height: 1.333} header h1 {font-size: clamp(1.5rem, 10vw, 3rem); line-height: 1.333}
header p {font-size: clamp(1em, 5vw, 1.5rem); line-height: 1.5; max-width: 32ch} header p {font-size: clamp(1em, 5vw, 1.5rem); line-height: 1.5; max-inline-size: 32ch}
h2 {font-size: 1.5rem; line-height: 1.333; margin-block-end: 1rem; max-width: 35ch} h2 {font-size: 1.5rem; line-height: 1.333; margin-block-end: 1rem; max-inline-size: 35ch}
p {font-size: 1rem; line-height: 1.5} p {font-size: 1rem; line-height: 1.5}
/* layout */ /* layout */
body {margin: auto; min-height: 100vh} body {margin: auto; min-block-size: 100vb}
section, footer {margin-block-start: 2.5rem} section, footer {margin-block-start: 2.5rem}
footer {padding-block-end: 1rem; display: flex; justify-content: center} footer {padding-block-end: 1rem; display: flex; justify-content: center}
.container {padding: 0 1rem; height: 100%;} .container {padding: 0 1rem; block-size: 100%;}
header {position: relative;} header {position: relative;}
header .container {position: absolute; inset-block-end: 0; width: 100%; height: fit-content} header .container {position: absolute; inset-block-end: 0; inline-size: 100%; block-size: fit-content}
header img {width: 100vw; height: 100vw; max-width: 100%; max-height: 600px; object-fit: cover; object-position: bottom} header img {inline-size: 100vi; block-size: 100vb; max-inline-size: 100%; max-block-size: 600px; object-fit: cover; object-position: bottom}
header h1 {grid-row: 2} header h1 {grid-row: 2}
header p {grid-row: 3} header p {grid-row: 3}
dl {display: grid; grid-template-columns: 6.5rem 1fr} dl {display: grid; grid-template-columns: 6.5rem 1fr}
@ -50,8 +50,8 @@ dl p {grid-column: span 2; max-width: 18rem}
body:before { body:before {
content: ''; content: '';
position: fixed; position: fixed;
width: 100vw; inline-size: 100vi;
height: 100vh; block-size: 100vb;
inset-inline-start: 0; inset-inline-start: 0;
inset-block-start: 0; inset-block-start: 0;
background: url(./.assets/images/sunset-square-bg-blue.min.jpg); background: url(./.assets/images/sunset-square-bg-blue.min.jpg);
@ -80,7 +80,7 @@ img {color: white}
body {margin: 0 auto; width: 40rem} body {margin: 0 auto; width: 40rem}
} }
@media (max-height: 30rem) and (min-aspect-ratio: 1) { @media (max-height: 30rem) and (min-aspect-ratio: 1) {
header img {width: 100vw; height: 100vh; object-position: center} header img {inline-size: 100vi; block-size: 100vb; object-position: center}
header .container {inset-block-end: 1rem} header .container {inset-block-end: 1rem}
} }
</style> </style>