@geekity/cms 0.28.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +355 -53
- package/admin/pages/comments/all.njk +3 -1
- package/admin/pages/federation/followers.njk +8 -2
- package/dist/admin/comments.d.ts +2 -0
- package/dist/admin/comments.d.ts.map +1 -1
- package/dist/admin/comments.js +19 -49
- package/dist/admin/comments.js.map +1 -1
- package/dist/admin/documents.d.ts +5 -0
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +45 -17
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/federation.d.ts +21 -1
- package/dist/admin/federation.d.ts.map +1 -1
- package/dist/admin/federation.js +17 -7
- package/dist/admin/federation.js.map +1 -1
- package/dist/admin/store.d.ts +95 -14
- package/dist/admin/store.d.ts.map +1 -1
- package/dist/admin/store.js +206 -17
- package/dist/admin/store.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -1
- package/dist/cli.js.map +1 -1
- package/dist/comments/form.d.ts +3 -1
- package/dist/comments/form.d.ts.map +1 -1
- package/dist/comments/form.js +2 -1
- package/dist/comments/form.js.map +1 -1
- package/dist/comments/index.d.ts +3 -3
- package/dist/comments/index.d.ts.map +1 -1
- package/dist/comments/index.js +1 -1
- package/dist/comments/index.js.map +1 -1
- package/dist/comments/records.d.ts +56 -24
- package/dist/comments/records.d.ts.map +1 -1
- package/dist/comments/records.js +255 -31
- package/dist/comments/records.js.map +1 -1
- package/dist/comments/reply-notices.d.ts +42 -0
- package/dist/comments/reply-notices.d.ts.map +1 -0
- package/dist/comments/reply-notices.js +76 -0
- package/dist/comments/reply-notices.js.map +1 -0
- package/dist/comments/reply-post.d.ts +49 -0
- package/dist/comments/reply-post.d.ts.map +1 -0
- package/dist/comments/reply-post.js +66 -0
- package/dist/comments/reply-post.js.map +1 -0
- package/dist/comments/routes.d.ts +6 -1
- package/dist/comments/routes.d.ts.map +1 -1
- package/dist/comments/routes.js +49 -21
- package/dist/comments/routes.js.map +1 -1
- package/dist/comments/submission.d.ts +8 -25
- package/dist/comments/submission.d.ts.map +1 -1
- package/dist/comments/submission.js +19 -38
- package/dist/comments/submission.js.map +1 -1
- package/dist/comments/viewer.d.ts.map +1 -1
- package/dist/comments/viewer.js +1 -0
- package/dist/comments/viewer.js.map +1 -1
- package/dist/content/citation.d.ts +1 -0
- package/dist/content/citation.d.ts.map +1 -1
- package/dist/content/citation.js +2 -0
- package/dist/content/citation.js.map +1 -1
- package/dist/content/original.d.ts +6 -1
- package/dist/content/original.d.ts.map +1 -1
- package/dist/content/original.js +7 -4
- package/dist/content/original.js.map +1 -1
- package/dist/content/store.d.ts +43 -11
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +170 -10
- package/dist/content/store.js.map +1 -1
- package/dist/content/sync.d.ts +8 -0
- package/dist/content/sync.d.ts.map +1 -1
- package/dist/content/sync.js +164 -71
- package/dist/content/sync.js.map +1 -1
- package/dist/federation/article.d.ts.map +1 -1
- package/dist/federation/article.js +2 -1
- package/dist/federation/article.js.map +1 -1
- package/dist/federation/backfill.d.ts +114 -0
- package/dist/federation/backfill.d.ts.map +1 -0
- package/dist/federation/backfill.js +314 -0
- package/dist/federation/backfill.js.map +1 -0
- package/dist/federation/inbox.js +1 -1
- package/dist/federation/inbox.js.map +1 -1
- package/dist/federation/records.d.ts +13 -0
- package/dist/federation/records.d.ts.map +1 -1
- package/dist/federation/records.js +49 -10
- package/dist/federation/records.js.map +1 -1
- package/dist/federation/replies.d.ts +6 -0
- package/dist/federation/replies.d.ts.map +1 -1
- package/dist/federation/replies.js +18 -1
- package/dist/federation/replies.js.map +1 -1
- package/dist/index.d.ts +12 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +81 -11
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +1 -7
- package/dist/init.js.map +1 -1
- package/dist/plugin.d.ts +28 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +10 -2
- package/dist/plugin.js.map +1 -1
- package/dist/plugins/site.d.ts.map +1 -1
- package/dist/plugins/site.js +7 -1
- package/dist/plugins/site.js.map +1 -1
- package/dist/web/context.d.ts +18 -3
- package/dist/web/context.d.ts.map +1 -1
- package/dist/web/context.js +17 -4
- package/dist/web/context.js.map +1 -1
- package/dist/web/conversation.d.ts +191 -28
- package/dist/web/conversation.d.ts.map +1 -1
- package/dist/web/conversation.js +670 -172
- package/dist/web/conversation.js.map +1 -1
- package/dist/web/documents.d.ts +0 -22
- package/dist/web/documents.d.ts.map +1 -1
- package/dist/web/documents.js +1 -34
- package/dist/web/documents.js.map +1 -1
- package/dist/web/feed-item.d.ts +12 -8
- package/dist/web/feed-item.d.ts.map +1 -1
- package/dist/web/feed-item.js +10 -10
- package/dist/web/feed-item.js.map +1 -1
- package/dist/web/feed-rss.d.ts.map +1 -1
- package/dist/web/feed-rss.js +34 -10
- package/dist/web/feed-rss.js.map +1 -1
- package/dist/web/feed-source.d.ts +33 -1
- package/dist/web/feed-source.d.ts.map +1 -1
- package/dist/web/feed-source.js +33 -0
- package/dist/web/feed-source.js.map +1 -1
- package/dist/web/feeds.d.ts +1 -1
- package/dist/web/feeds.d.ts.map +1 -1
- package/dist/web/feeds.js +7 -2
- package/dist/web/feeds.js.map +1 -1
- package/dist/web/guids.d.ts +47 -0
- package/dist/web/guids.d.ts.map +1 -0
- package/dist/web/guids.js +67 -0
- package/dist/web/guids.js.map +1 -0
- package/dist/web/index.d.ts +5 -6
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +3 -3
- package/dist/web/index.js.map +1 -1
- package/dist/web/redirects.d.ts +12 -0
- package/dist/web/redirects.d.ts.map +1 -1
- package/dist/web/redirects.js +16 -4
- package/dist/web/redirects.js.map +1 -1
- package/dist/web/render.d.ts +19 -9
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +44 -42
- package/dist/web/render.js.map +1 -1
- package/dist/web/routes.d.ts +2 -2
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +157 -84
- package/dist/web/routes.js.map +1 -1
- package/dist/webmention/index.d.ts +1 -1
- package/dist/webmention/index.d.ts.map +1 -1
- package/dist/webmention/index.js +1 -1
- package/dist/webmention/index.js.map +1 -1
- package/dist/webmention/links.d.ts +55 -0
- package/dist/webmention/links.d.ts.map +1 -1
- package/dist/webmention/links.js +162 -0
- package/dist/webmention/links.js.map +1 -1
- package/dist/webmention/microformats.d.ts +15 -0
- package/dist/webmention/microformats.d.ts.map +1 -1
- package/dist/webmention/microformats.js +63 -1
- package/dist/webmention/microformats.js.map +1 -1
- package/dist/webmention/pingback.js +2 -1
- package/dist/webmention/pingback.js.map +1 -1
- package/dist/webmention/receive.d.ts +5 -0
- package/dist/webmention/receive.d.ts.map +1 -1
- package/dist/webmention/receive.js +99 -3
- package/dist/webmention/receive.js.map +1 -1
- package/dist/webmention/reply-context.d.ts +15 -0
- package/dist/webmention/reply-context.d.ts.map +1 -1
- package/dist/webmention/reply-context.js +29 -0
- package/dist/webmention/reply-context.js.map +1 -1
- package/dist/webmention/reply-contexts.d.ts +6 -0
- package/dist/webmention/reply-contexts.d.ts.map +1 -1
- package/dist/webmention/reply-contexts.js +16 -10
- package/dist/webmention/reply-contexts.js.map +1 -1
- package/dist/webmention/routes.d.ts.map +1 -1
- package/dist/webmention/routes.js +2 -1
- package/dist/webmention/routes.js.map +1 -1
- package/dist/webmention/service.d.ts +30 -1
- package/dist/webmention/service.d.ts.map +1 -1
- package/dist/webmention/service.js +172 -32
- package/dist/webmention/service.js.map +1 -1
- package/package.json +1 -2
- package/themes/default/README.md +269 -95
- package/themes/default/layouts/base.njk +8 -0
- package/themes/default/layouts/comment.njk +90 -0
- package/themes/default/layouts/front-page.njk +9 -47
- package/themes/default/layouts/page.njk +2 -0
- package/themes/default/layouts/post.njk +14 -2
- package/themes/default/partials/backlinks.njk +19 -0
- package/themes/default/partials/cited-page.njk +3 -1
- package/themes/default/partials/comment-form.njk +10 -0
- package/themes/default/partials/comment.njk +79 -0
- package/themes/default/partials/conversation.njk +14 -59
- package/themes/default/src/style.css +42 -0
- package/themes/default/static/style.css +67 -0
package/README.md
CHANGED
|
@@ -683,6 +683,51 @@ database.
|
|
|
683
683
|
|
|
684
684
|
[FEP-044f]: https://codeberg.org/fediverse/fep/src/branch/main/fep/044f/fep-044f.md
|
|
685
685
|
|
|
686
|
+
### Replies to fediverse replies
|
|
687
|
+
|
|
688
|
+
Somebody who answers a fediverse reply on one of the site's posts addresses
|
|
689
|
+
the person they answer, not the site, so their reply never reaches the inbox.
|
|
690
|
+
Most servers list a note's replies in its `replies` collection, and the site
|
|
691
|
+
reads those collections to bring such replies in. The sweep starts when
|
|
692
|
+
the site serves and runs every hour, within these limits:
|
|
693
|
+
|
|
694
|
+
| Limit | Value | Meaning |
|
|
695
|
+
| -------- | -------- | ----------------------------------------------------------------------------------------------------- |
|
|
696
|
+
| Interval | 6 hours | How long a thread is left alone after it was read. |
|
|
697
|
+
| Age | 30 days | How old a post gets before its thread is no longer read, by the post's date. |
|
|
698
|
+
| Depth | 4 levels | How far below the post a fediverse reply may sit and still have its collection read. |
|
|
699
|
+
| Pages | 3 | How many pages of one collection are read. Mastodon's first page holds the author's own replies only. |
|
|
700
|
+
|
|
701
|
+
Every request is signed as the site's first account, as the actor profile
|
|
702
|
+
fetches are. A reply is kept only when it answers the note whose collection
|
|
703
|
+
listed it, is addressed to the public, and is written by an actor on the
|
|
704
|
+
note's own server. A note on the site's own origin is never fetched, because
|
|
705
|
+
the site already knows what it published.
|
|
706
|
+
|
|
707
|
+
A reply found this way is logged as the `Create` nobody delivered: a line in
|
|
708
|
+
`content/_data/federation/inbox/{yyyy}-{mm}.jsonl` with `"fetched": true` in
|
|
709
|
+
front of it, an `actor` taken from the note's `attributedTo` and the id
|
|
710
|
+
`{note id}#fetched`. From there it is a reply like any other. It is threaded
|
|
711
|
+
under the reply it answers with its own URL, counted, given a `/replies/` feed
|
|
712
|
+
and listed on the federation screen, and its author's `Delete` takes it back.
|
|
713
|
+
A note held once is never logged twice. The sweep skips a note the inbox
|
|
714
|
+
already holds or the site holds as a [migrated comment](#migrated-comments),
|
|
715
|
+
and a delivery of a note the sweep fetched first replaces the fetched line. An
|
|
716
|
+
imported fediverse reply's collection is read by its note id, its `origin`.
|
|
717
|
+
|
|
718
|
+
The site removes a fetched reply, with the fetched replies under it, when its
|
|
719
|
+
server answers 404 or 410 for it, or when a collection read to its end no
|
|
720
|
+
longer lists it. A delivered reply is never removed this way. A note with no
|
|
721
|
+
`replies` collection, a server that answers with any other error, and a
|
|
722
|
+
collection cut off by the page limit change nothing. The thread keeps what it
|
|
723
|
+
holds, and the sweep goes on to the next reply.
|
|
724
|
+
|
|
725
|
+
The site reads `replies` and not the conversation a note names in `context`
|
|
726
|
+
([FEP-7888]), because Mastodon publishes `replies` and few servers publish a
|
|
727
|
+
`context` collection yet.
|
|
728
|
+
|
|
729
|
+
[FEP-7888]: https://codeberg.org/fediverse/fep/src/branch/main/fep/7888/fep-7888.md
|
|
730
|
+
|
|
686
731
|
### Relays
|
|
687
732
|
|
|
688
733
|
A [Mastodon-style relay][fepae0c] boosts every public activity it is sent on to
|
|
@@ -1002,7 +1047,7 @@ container never starts live:
|
|
|
1002
1047
|
|
|
1003
1048
|
```yaml
|
|
1004
1049
|
services:
|
|
1005
|
-
|
|
1050
|
+
geekity:
|
|
1006
1051
|
environment:
|
|
1007
1052
|
GEEKITY_DEV_MODE: 'true'
|
|
1008
1053
|
```
|
|
@@ -1011,7 +1056,7 @@ To go live, remove the variable, recreate the container (the file in the
|
|
|
1011
1056
|
`data` volume keeps the mode on through the restart), then run:
|
|
1012
1057
|
|
|
1013
1058
|
```sh
|
|
1014
|
-
docker compose exec
|
|
1059
|
+
docker compose exec geekity geekity dev-mode off
|
|
1015
1060
|
```
|
|
1016
1061
|
|
|
1017
1062
|
`geekity dev-mode status` in the same container says which state the site is
|
|
@@ -1035,6 +1080,56 @@ from a version that kept the email in the comment file has it moved there on
|
|
|
1035
1080
|
the next boot, and so does an email somebody types into a comment file by
|
|
1036
1081
|
hand.
|
|
1037
1082
|
|
|
1083
|
+
### Keys
|
|
1084
|
+
|
|
1085
|
+
Every comment has one key, 16 lowercase hex digits (decision-51). It is the
|
|
1086
|
+
comment's `id` in its file, its anchor `#comment-{key}` on the post, its
|
|
1087
|
+
replies feed `/replies/{key}/` and, for a comment left through the form, its
|
|
1088
|
+
page `/comment/{key}/`. No URL the site prints carries an id of any other shape.
|
|
1089
|
+
|
|
1090
|
+
| Comment | Its key |
|
|
1091
|
+
| ----------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
|
1092
|
+
| Left through the form | 16 random hex digits, minted when it is submitted. |
|
|
1093
|
+
| A webmention | The first 16 hex digits of the SHA-256 of its source URL, a space and the post's permalink. |
|
|
1094
|
+
| A fediverse reply, like or boost | The first 16 hex digits of the SHA-256 of its note or activity id. |
|
|
1095
|
+
| Imported, with an identity elsewhere (`origin`) | The key the same comment would get arriving here, from its `origin`. |
|
|
1096
|
+
| Imported, with none (a WordPress form comment) | The first 16 hex digits of the SHA-256 of its old comment URL. |
|
|
1097
|
+
|
|
1098
|
+
A comment file holding any other id is refused, naming the file and the id. A
|
|
1099
|
+
site upgrading from 0.29 has its UUID ids, and the URL ids plugin-wordpress
|
|
1100
|
+
0.2.0 wrote, re-keyed in place on the next boot to the key of the old id; the
|
|
1101
|
+
replies naming them, the emails in `data/comments/` and any Markdown linking
|
|
1102
|
+
`/comment/{old}/` or `#comment-{old}` follow. Nothing redirects from the old
|
|
1103
|
+
URLs. A site whose ids are all keys reads its files and writes nothing.
|
|
1104
|
+
|
|
1105
|
+
### Migrated comments
|
|
1106
|
+
|
|
1107
|
+
A comment imported from another system carries `migrated: true`, and `origin`
|
|
1108
|
+
when it had an identity elsewhere: a fediverse reply's note id, a like's or a
|
|
1109
|
+
boost's activity id, a webmention's source URL. A migrated fediverse comment
|
|
1110
|
+
also carries `actor`, the id of the actor who wrote it, when the export named
|
|
1111
|
+
one. plugin-wordpress writes all three.
|
|
1112
|
+
|
|
1113
|
+
A migrated comment shows on its post, in its thread and on its own page like
|
|
1114
|
+
any other, and replies to it thread under it. It is in no feed and no count a
|
|
1115
|
+
feed advertises: not `/comments/feed/`, not `{permalink}feed/`, not
|
|
1116
|
+
`/replies/{key}/` and not `source:comments`. It was published before the site
|
|
1117
|
+
moved here, so a reader of the old comments feed sees nothing new at cutover. A
|
|
1118
|
+
native reply under it is news, and names it in `source:inReplyTo` by its guid:
|
|
1119
|
+
its `/comment/{key}/` page for an imported form comment, its `origin`
|
|
1120
|
+
otherwise, else its `url`.
|
|
1121
|
+
|
|
1122
|
+
The same comment arriving again is the one the site holds, and the stored one
|
|
1123
|
+
wins, with the moderator's decision on it. A resent webmention is matched by
|
|
1124
|
+
its source. A redelivered `Create` or `Like`, and a note the
|
|
1125
|
+
[reply backfill](#replies-to-fediverse-replies) reads, are matched by their
|
|
1126
|
+
note or activity id against the stored comment's `origin`, so the inbox line is
|
|
1127
|
+
not shown and the backfill does not log the note. A like or a boost from the
|
|
1128
|
+
same actor as an imported one, matched by the inbox line's actor against the
|
|
1129
|
+
stored comment's `actor`, is the same reaction.
|
|
1130
|
+
An answer to an imported fediverse note threads under the imported comment,
|
|
1131
|
+
and the backfill reads that note's `replies` collection by its `origin`.
|
|
1132
|
+
|
|
1038
1133
|
Three settings and one front-matter key decide whether a post is still taking
|
|
1039
1134
|
them, and they are read in one place so the form and the endpoint can never
|
|
1040
1135
|
disagree:
|
|
@@ -1075,6 +1170,68 @@ A checker that throws is treated as having no opinion and logged, so a service
|
|
|
1075
1170
|
that is down never stops a site taking comments. `/admin/comments` is the
|
|
1076
1171
|
moderation queue and the dashboard carries the number waiting.
|
|
1077
1172
|
|
|
1173
|
+
### A comment's own page
|
|
1174
|
+
|
|
1175
|
+
A comment left through the form has a page of its own at `/comment/{key}/`
|
|
1176
|
+
(see [Keys](#keys)). That page is the comment's URL in the thread
|
|
1177
|
+
and in both comments feeds, so a site that replies to the comment fetches the
|
|
1178
|
+
comment rather than the whole post. The `#comment-{key}` anchor on the post
|
|
1179
|
+
stays, so an old link still scrolls to it. A webmention or a fediverse reply
|
|
1180
|
+
has no such page: its URL is where it came from.
|
|
1181
|
+
|
|
1182
|
+
The page holds the comment as its one `h-entry`, with `u-in-reply-to` the post
|
|
1183
|
+
or the comment it answers. Above it is the thread from the post down, each step
|
|
1184
|
+
a nested `u-in-reply-to h-cite`, and below it the replies to it at every depth.
|
|
1185
|
+
An ancestor a reader may not see is a placeholder saying the comment is no
|
|
1186
|
+
longer shown, and the thread on the post prints the same placeholder above an
|
|
1187
|
+
approved reply to a pending, spam or deleted comment. The page answers only an approved comment, and only as the post
|
|
1188
|
+
would: 410 once the post is deleted, 404 while the post is not public or not
|
|
1189
|
+
showing its conversation. It is `noindex` and absent from the sitemap, the post
|
|
1190
|
+
feeds and search. Backlog doc-6 has the rules.
|
|
1191
|
+
|
|
1192
|
+
### Replying while signed in
|
|
1193
|
+
|
|
1194
|
+
A comment is something somebody else says on the site. A post is something a
|
|
1195
|
+
signed-in user says. So a reply written by somebody signed in to the site, in
|
|
1196
|
+
the thread or in the Reply box on the moderation screen, is a reply post, not a
|
|
1197
|
+
comment. It is one file under `posts/`, saved
|
|
1198
|
+
the way the editor and Micropub save one, and the thread shows it inline under
|
|
1199
|
+
what it answers. Its `in-reply-to` is what it answers:
|
|
1200
|
+
|
|
1201
|
+
| Answering | `in-reply-to` | It also |
|
|
1202
|
+
| ------------------ | --------------------------------- | -------------------------------------------------------- |
|
|
1203
|
+
| The post | The post's permalink | |
|
|
1204
|
+
| A native comment | The comment's `/comment/{key}/` | Emails the commenter once, if they asked about replies. |
|
|
1205
|
+
| A webmention reply | The page the webmention came from | Sends that page a webmention. |
|
|
1206
|
+
| A fediverse reply | The note's id | Federates in reply to the note, addressed to its author. |
|
|
1207
|
+
| A reply post | The reply post's permalink | |
|
|
1208
|
+
|
|
1209
|
+
The signed-in form and the moderation screen's Reply box have an "Include in
|
|
1210
|
+
posts and feeds" checkbox, unchecked by default. Unchecked, the reply post is [unlisted](#unlisted-posts): its own page
|
|
1211
|
+
and the thread, but no listing or post feed. Checked, it is public. It reaches
|
|
1212
|
+
whoever it answers either way. A visitor's form has no such box.
|
|
1213
|
+
|
|
1214
|
+
Somebody signed in gets a Reply link on every reply in a thread, webmentions
|
|
1215
|
+
and fediverse replies included. A visitor gets one on native comments only. A
|
|
1216
|
+
visitor's reply is always a native comment, so a visitor answering a fediverse
|
|
1217
|
+
reply sends nothing over ActivityPub.
|
|
1218
|
+
|
|
1219
|
+
A reply post written in the editor or over Micropub joins a thread the same way
|
|
1220
|
+
when its `in-reply-to` names the post or anything in its thread: a comment's
|
|
1221
|
+
page or `#comment-` anchor, a webmention's page, a note's id. Its reply context
|
|
1222
|
+
quotes that comment from the site's own records instead of the page it is on,
|
|
1223
|
+
and says "In reply to a comment by" its writer. A reply post answering one of
|
|
1224
|
+
the site's own posts or pages takes that post's title, words and author from
|
|
1225
|
+
the index too, so the site never fetches its own page. The commenter's email
|
|
1226
|
+
goes once for a reply post from any of these doors, sent when the reply post is
|
|
1227
|
+
first published and never again when it is edited, trashed and restored, or the
|
|
1228
|
+
site restarts. In the thread, a reply post's author link carries no
|
|
1229
|
+
`rel="nofollow ugc"`, which is kept for visitors, webmentions and the
|
|
1230
|
+
fediverse. A
|
|
1231
|
+
webmention or a fediverse reply to a reply post threads under it in the
|
|
1232
|
+
original thread too. Comments written before this stay comments. Backlog doc-6
|
|
1233
|
+
and decision-47 have the rules.
|
|
1234
|
+
|
|
1078
1235
|
### Being told about one
|
|
1079
1236
|
|
|
1080
1237
|
With mail configured, a comment or a webmention entering the queue emails every
|
|
@@ -1207,6 +1364,19 @@ it was showing. One outcome is recorded per link (`sent`, `none` for a page that
|
|
|
1207
1364
|
takes none, or `failed`), shown per post on `/admin/federation`, and the Resend
|
|
1208
1365
|
button there sends them again from the file as it now reads.
|
|
1209
1366
|
|
|
1367
|
+
**Links to the site's own pages** send no webmention. A post that cites another
|
|
1368
|
+
post on the same site does not go through moderation, does not add to a comment
|
|
1369
|
+
count and does not make an HTTP request to the site itself. The index records
|
|
1370
|
+
the link instead. The linked post or page then lists the linking one among its
|
|
1371
|
+
backlinks, which the default theme prints as "Linked from" under it, apart from
|
|
1372
|
+
the comments. A link counts for the document the site serves at its URL: a link
|
|
1373
|
+
to `/` counts for the page the Reading setting makes the homepage, and a link
|
|
1374
|
+
to a URL the site redirects, such as an imported `/?p=123`, counts for the
|
|
1375
|
+
document the redirect leads to. Redirects are followed when the backlinks are
|
|
1376
|
+
read, so editing a redirect file moves a backlink without touching the post
|
|
1377
|
+
that holds the link. A draft, future-dated, unlisted, private or trashed post is never
|
|
1378
|
+
a backlink. See `themes/default/README.md` for the `backlinks` context.
|
|
1379
|
+
|
|
1210
1380
|
**Receiving** advertises `/_geekity/webmention` two ways — a `Link` header on
|
|
1211
1381
|
every representation of a document, and a `<link rel="webmention">` in the head
|
|
1212
1382
|
— and takes a form `POST` of `source` and `target`. It answers `202` for
|
|
@@ -1219,6 +1389,12 @@ queue as everything else — through the same `commentChecker` seam, so a checke
|
|
|
1219
1389
|
can tell one from a form submission by its `source`. Akismet is told it is a
|
|
1220
1390
|
`webmention` rather than a `comment`.
|
|
1221
1391
|
|
|
1392
|
+
A reply whose `u-in-reply-to` names a reply already on the post (a comment by
|
|
1393
|
+
its own page or its `#comment-{key}` anchor, an earlier webmention by the page it
|
|
1394
|
+
was sent from, a fediverse reply by its url or id) threads under that reply, and
|
|
1395
|
+
moves with it when the source is edited and sent again. A webmention sent to a
|
|
1396
|
+
comment's page, `/comment/{key}/`, lands on that comment's post.
|
|
1397
|
+
|
|
1222
1398
|
The source URL is its identity. A page that sends its webmention again updates
|
|
1223
1399
|
what it left rather than adding a second, and one whose link has gone — or which
|
|
1224
1400
|
answers 404 or 410 — takes it away. Closing rules do not apply: a post that
|
|
@@ -1787,8 +1963,8 @@ The rule works for pages too.
|
|
|
1787
1963
|
| -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1788
1964
|
| Its permalink, in every representation | 200, with `X-Robots-Tag: noindex`. The default theme also prints `<meta name="robots" content="noindex">`. |
|
|
1789
1965
|
| The home page, tag, category and author archives, the `archive: true` page | Absent, and not counted in a pager or a tag count. |
|
|
1790
|
-
| Previous and next links under other posts,
|
|
1791
|
-
| Every RSS, Atom and JSON feed, and the site-wide comments feed | Absent. Saving one pings no notify server.
|
|
1966
|
+
| Previous and next links under other posts, a front page's `newestPosts` | Absent. |
|
|
1967
|
+
| Every RSS, Atom and JSON feed, and the site-wide comments feed | Absent. Saving one pings no notify server. An unlisted reply post shown in a thread is still in that thread's comments feeds. |
|
|
1792
1968
|
| The sitemap, search (HTML and JSON) and `llms.txt` | Absent. |
|
|
1793
1969
|
| IndexNow | Not submitted. A public post that becomes unlisted is submitted once, so a search engine reads the `noindex`. |
|
|
1794
1970
|
| The ActivityPub outbox and featured collection | Absent. |
|
|
@@ -2132,9 +2308,38 @@ choice is WordPress's own, and so are its two answers:
|
|
|
2132
2308
|
the default, and it is what an empty `homepage` means.
|
|
2133
2309
|
- **A static page.** The page is served at `/`, its own permalink answers `301`
|
|
2134
2310
|
to `/` so the front page has one URL, and the menu links it at `/`. The
|
|
2135
|
-
default theme draws it with `layouts/front-page.njk
|
|
2136
|
-
|
|
2137
|
-
|
|
2311
|
+
default theme draws it with `layouts/front-page.njk`, which prints the
|
|
2312
|
+
page's own title and words and nothing else (decision-44). It lists no
|
|
2313
|
+
posts, prints no links and prints no bio.
|
|
2314
|
+
|
|
2315
|
+
A site that wants more on its front page, such as its newest posts or links
|
|
2316
|
+
to its archives, overrides `layouts/front-page.njk` in its own theme. The
|
|
2317
|
+
front page's context carries `newestPosts(count)`, a function that returns the
|
|
2318
|
+
newest `count` published posts as the same entries a listing prints. Drafts,
|
|
2319
|
+
future-dated, unlisted and trashed posts are left out. The theme chooses the
|
|
2320
|
+
count, and the query runs only when the theme calls it. For example, this
|
|
2321
|
+
override lists the five newest posts under the page's words:
|
|
2322
|
+
|
|
2323
|
+
```njk
|
|
2324
|
+
{% extends "layouts/base.njk" %}
|
|
2325
|
+
|
|
2326
|
+
{% block content %}
|
|
2327
|
+
<div class="page-body e-content">{{ content | safe }}</div>
|
|
2328
|
+
|
|
2329
|
+
<h2 class="section-title">Recent Posts</h2>
|
|
2330
|
+
{% set posts = newestPosts(5) %}
|
|
2331
|
+
{% set feedHeading = 3 %}
|
|
2332
|
+
{% include "partials/post-list.njk" %}
|
|
2333
|
+
{% endblock %}
|
|
2334
|
+
```
|
|
2335
|
+
|
|
2336
|
+
On a solo author site the default theme's base layout puts the author's
|
|
2337
|
+
`rel="me"` claims in the head of `/` as `<link rel="me">` elements, one for
|
|
2338
|
+
their author archive and one for each profile link, whatever the front page
|
|
2339
|
+
prints (decision-45). A static front page prints no h-card. A site that wants
|
|
2340
|
+
its homepage to carry a representative h-card writes one in the homepage's
|
|
2341
|
+
words, or includes `partials/bio.njk` with `bioHome` set in its override, as
|
|
2342
|
+
the [theme README](./themes/default/README.md#the-front-page) shows.
|
|
2138
2343
|
|
|
2139
2344
|
With a homepage set, a second pick gives the listing a page of its own: the
|
|
2140
2345
|
**posts page**. Its permalink carries the listing, with the page's own title
|
|
@@ -2663,6 +2868,7 @@ Booting mounts the public site on the app. The routes are:
|
|
|
2663
2868
|
| `/author/{username}/feed/` and siblings | The same, for one person. |
|
|
2664
2869
|
| `/comments/feed/` | Every reply the inbox has been sent, as RSS 2.0. |
|
|
2665
2870
|
| `{permalink}feed/` | One post's replies, the same way. |
|
|
2871
|
+
| `/comment/{key}/` | One comment left through the form, on a page of its own: see [Comments](#comments). Noindex and on no list. |
|
|
2666
2872
|
| `/sitemap.xml` | Every public URL, for a search engine. |
|
|
2667
2873
|
| `/sitemap-{n}.xml` | One file of a sitemap too big to be a single one. |
|
|
2668
2874
|
| `/robots.txt` | What a crawler may have, and where the sitemap is. |
|
|
@@ -2847,9 +3053,20 @@ The list is in the file, so deleting `data/geekity.db` keeps it working.
|
|
|
2847
3053
|
|
|
2848
3054
|
A URL in the list only redirects while nothing else lives there: a new document
|
|
2849
3055
|
given that URL takes it over. Moving a document back to a URL in its list takes
|
|
2850
|
-
that URL off the list. A draft that was never published
|
|
2851
|
-
anything behind
|
|
2852
|
-
|
|
3056
|
+
that URL off the list. A draft that was never published and has no comments
|
|
3057
|
+
moves without leaving anything behind; one with comments was read at its URL,
|
|
3058
|
+
so it keeps a `redirect_from` like a published one. Correcting a published
|
|
3059
|
+
post's date files it under the new day but keeps its URL.
|
|
3060
|
+
|
|
3061
|
+
A moved document keeps its conversation. Its comments and stored webmentions
|
|
3062
|
+
move to its new slug, a reply post answering any URL in its `redirect_from`
|
|
3063
|
+
stays in its thread, and its feeds keep their guid: a post keeps its object id
|
|
3064
|
+
as its `activitypub.id`, and a page keeps the URL it left as its `guid`, so the
|
|
3065
|
+
`/replies/` feed a reader subscribed to keeps answering. The record of the
|
|
3066
|
+
webmentions a post has sent moves with it too. A move made by hand is followed
|
|
3067
|
+
the same way when the file names the old URL in `redirect_from`; a permalink
|
|
3068
|
+
changed by hand with no `redirect_from` leaves the old URL answering 404 and its
|
|
3069
|
+
comments where they were, until the file names it.
|
|
2853
3070
|
|
|
2854
3071
|
### Declared redirects
|
|
2855
3072
|
|
|
@@ -3065,6 +3282,7 @@ so a site moving off it keeps every subscriber it had:
|
|
|
3065
3282
|
| `/category/{name}/feed/` | One category archive, the same three |
|
|
3066
3283
|
| `/comments/feed/` | Every reply the site has been sent, in RSS |
|
|
3067
3284
|
| `{permalink}feed/` | One post's replies, in RSS |
|
|
3285
|
+
| `/replies/{key}/` | One item's direct replies, in RSS |
|
|
3068
3286
|
|
|
3069
3287
|
`/feed/` is RSS because that is the format nearly every existing subscriber
|
|
3070
3288
|
holds. The two archive bases are settings (`tagBase`, `categoryBase`), so the
|
|
@@ -3104,15 +3322,17 @@ The three formats render one **feed item**, derived once per post, rather than
|
|
|
3104
3322
|
each reading the file for itself. So they agree about the three things a reader
|
|
3105
3323
|
actually keys on.
|
|
3106
3324
|
|
|
3107
|
-
**Identity.** A post is named by
|
|
3108
|
-
|
|
3109
|
-
matter stores for a post migrated from elsewhere
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3325
|
+
**Identity.** A post is named by the first of three things it has: the `guid`
|
|
3326
|
+
its front matter sets, when that parses as a URL; else the `activitypub.id`
|
|
3327
|
+
the front matter stores for a post migrated from elsewhere; else its permalink
|
|
3328
|
+
(see [Federation](#federation)). That name is RSS's `guid`, Atom's `id` and
|
|
3329
|
+
JSON Feed's `id`. The permalink is always the link: RSS's `link`, Atom's
|
|
3330
|
+
`link rel="alternate"` and JSON Feed's `url`. The two are the same URL for
|
|
3331
|
+
every post born on this CMS, and differ only for one carrying a stored id or a
|
|
3332
|
+
`guid` — which is what lets a migrated post keep the name its WordPress
|
|
3114
3333
|
subscribers already hold. RSS's `isPermaLink` says which of the two a `guid`
|
|
3115
|
-
is: `true` when it
|
|
3334
|
+
is: `true` only when it equals the permalink, `false` for anything else, such
|
|
3335
|
+
as a stored `?p=813`.
|
|
3116
3336
|
|
|
3117
3337
|
**Terms.** Every format lists the post's categories and then its tags, in file
|
|
3118
3338
|
order, as one flat list: RSS's `category` elements, Atom's `category term`
|
|
@@ -3149,8 +3369,8 @@ do not know it to ignore:
|
|
|
3149
3369
|
The key is `_geekity` because an extension is named after its publisher, and
|
|
3150
3370
|
`in_reply_to` spells the microformats `in-reply-to` property the JSON way. A
|
|
3151
3371
|
post that is not a reply, or whose `in-reply-to` is not such a URL, carries
|
|
3152
|
-
neither. RSS 2.0 has no equivalent element, so an RSS item
|
|
3153
|
-
|
|
3372
|
+
neither. RSS 2.0 has no equivalent element, so an RSS item carries the target
|
|
3373
|
+
as the [source namespace][source-ns]'s `<source:inReplyTo>`.
|
|
3154
3374
|
|
|
3155
3375
|
**Languages.** Every feed declares the site's `language` once: RSS as the
|
|
3156
3376
|
channel's `language`, Atom as the feed's `xml:lang` and JSON Feed as its
|
|
@@ -3180,17 +3400,21 @@ avatar when the site has one.
|
|
|
3180
3400
|
An item carries `title`, `link`, `guid`, `pubDate` in RFC 822, `dc:creator` from
|
|
3181
3401
|
the post's author or the site's, one `category` per term, `description` holding
|
|
3182
3402
|
the summary, `content:encoded` holding the whole rendered post, and
|
|
3183
|
-
`source:markdown` holding the Markdown the post was written from.
|
|
3184
|
-
|
|
3403
|
+
`source:markdown` holding the Markdown the post was written from. A reply also
|
|
3404
|
+
carries `source:inReplyTo` holding the URL it answers. The `guid`, the terms
|
|
3405
|
+
and the summary are the ones described above.
|
|
3185
3406
|
|
|
3186
3407
|
`source:markdown` is Dave Winer's [source namespace][source-ns]: a reader that
|
|
3187
3408
|
understands Markdown should render from it rather than from `content:encoded`.
|
|
3188
3409
|
It is the same text the ActivityStreams `Article` carries as its `source`.
|
|
3189
3410
|
|
|
3190
|
-
Every item also says where its comments are
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3411
|
+
Every item also says where its comments are: `comments` is the page to read
|
|
3412
|
+
them on and `wfw:commentRss` (the [Well-Formed Web][wfw-ns] comment API) is the
|
|
3413
|
+
feed of the whole thread to poll. A post with replies also carries
|
|
3414
|
+
`source:comments`, whose `count` is how many replies answer the post directly
|
|
3415
|
+
and whose `feedUrl` is its `/replies/{key}/` feed holding only those (see
|
|
3416
|
+
[Walking a thread](#walking-a-thread)). A post nobody answered carries no
|
|
3417
|
+
`source:comments`.
|
|
3194
3418
|
|
|
3195
3419
|
When the site has a license (Settings > General, or `license` in `site.json`),
|
|
3196
3420
|
the channel carries a `creativeCommons:license` holding its URL, and every item
|
|
@@ -3211,34 +3435,73 @@ post as under it.
|
|
|
3211
3435
|
|
|
3212
3436
|
### Comments
|
|
3213
3437
|
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3438
|
+
The comments feeds publish a document's conversation, at the URLs WordPress
|
|
3439
|
+
publishes its own at: `{permalink}feed/` for one post or page, and
|
|
3440
|
+
`/comments/feed/` for the whole site. Both are read from the same conversation
|
|
3441
|
+
the page draws under the post, so they carry what a reader sees there:
|
|
3442
|
+
|
|
3443
|
+
- native comments left through the form, once a moderator approves them;
|
|
3444
|
+
- webmention replies and mentions;
|
|
3445
|
+
- fediverse replies, a `Create` of a `Note` whose `inReplyTo` names the post
|
|
3446
|
+
or a reply under it (see [Federation](#federation)), and the quotes of a
|
|
3447
|
+
post its author approved;
|
|
3448
|
+
- reply posts written on this site that answer the post or a reply under it.
|
|
3449
|
+
|
|
3450
|
+
That is replies and mentions. Likes, boosts and reposts say nothing, so they
|
|
3451
|
+
are shown and counted on the page and are in no feed, and no `source:comments`
|
|
3452
|
+
count includes them: a post answered only with reactions advertises no replies
|
|
3453
|
+
feed. An RSVP to an event is shown with the people answering, not in the
|
|
3454
|
+
thread, so it is in no feed either, words or not; an RSVP sent to a post that
|
|
3455
|
+
is no event is a reply like any other. Neither feed carries a
|
|
3456
|
+
[migrated comment](#migrated-comments).
|
|
3219
3457
|
|
|
3220
3458
|
Both are RSS 2.0 and nothing else: a comments feed has no Atom or JSON spelling
|
|
3221
|
-
here, so `{permalink}feed/atom/` 404s. A post
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3459
|
+
here, so `{permalink}feed/atom/` 404s. A post has a comments feed whether or
|
|
3460
|
+
not it still takes comments. A page has one while it takes comments
|
|
3461
|
+
(`comments: true` in its front matter, and comments on for the site), which is
|
|
3462
|
+
when it shows its conversation; any other page's `{permalink}feed/` 404s, and
|
|
3463
|
+
its comments are left out of `/comments/feed/` too. A document with no replies
|
|
3464
|
+
answers an empty feed rather than a 404, because it exists and a reader that
|
|
3465
|
+
subscribed before anybody answered should keep polling. A permalink that is no
|
|
3466
|
+
published document 404s like any other. The page advertises its own feed with
|
|
3467
|
+
a `<link rel="alternate" type="application/rss+xml">` in its `<head>`.
|
|
3226
3468
|
|
|
3227
3469
|
A channel carries the usual `title` (`Comments on: {post}`), `link`,
|
|
3228
3470
|
`description`, `language`, `lastBuildDate`, `generator`, `atom:link rel="self"`
|
|
3229
3471
|
and the same notify-server elements every other feed carries. An item carries the author's name as its `title` and `dc:creator`,
|
|
3230
|
-
the reply's `url` as its `link`
|
|
3231
|
-
`published` time the
|
|
3232
|
-
`description` holding a plain-text excerpt
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3472
|
+
the reply's `url` as its `link` (a comment left through the form links to its
|
|
3473
|
+
own page at `/comment/{key}/`), a `guid`, the `published` time the reply gave (or
|
|
3474
|
+
when it arrived, if it gave none), `description` holding a plain-text excerpt
|
|
3475
|
+
and `content:encoded` holding the reply. The `guid` of a comment left through the
|
|
3476
|
+
form is its page, `isPermaLink="true"`; a fediverse note's is its id, a
|
|
3477
|
+
webmention's its source URL, a reply post's its object id. A migrated comment
|
|
3478
|
+
is in neither feed, so its old `guid` never has to survive the move.
|
|
3479
|
+
`isPermaLink` is `true` exactly when the `guid` is the `link`.
|
|
3480
|
+
|
|
3481
|
+
Each item also carries, from the [source namespace][source-ns]:
|
|
3482
|
+
|
|
3483
|
+
- `source:inReplyTo`, the `guid` of what it answers in these feeds: the post's
|
|
3484
|
+
feed `guid` for an answer to the post, else the `guid` of the reply it
|
|
3485
|
+
answers. A reply under a comment a reader may not see (one waiting for a
|
|
3486
|
+
moderator, spam or deleted) names the nearest reply above it a reader can
|
|
3487
|
+
see, or the post, and is counted as that one's reply.
|
|
3488
|
+
- `source:comments`, only on an item with replies: `count` is how many answer
|
|
3489
|
+
it directly and `feedUrl` its `/replies/` feed.
|
|
3490
|
+
- `<source url="…">Name</source>`, the core RSS element, when the site knows a
|
|
3491
|
+
feed for the author: a webmention author's `h-card` URL or site, or a site
|
|
3492
|
+
user's author feed `/author/{username}/feed/`. A comment left through the
|
|
3493
|
+
form and a fediverse reply carry none.
|
|
3494
|
+
|
|
3495
|
+
On the site-wide feed the title names the post or page as well: `{author} on
|
|
3496
|
+
{post}`, or `{author} replying to {parent author} on {post}` for an answer to
|
|
3497
|
+
another reply a reader can see.
|
|
3498
|
+
|
|
3499
|
+
A fediverse reply's author is named by the profile the site stored when that
|
|
3500
|
+
actor followed it, and otherwise the `@user@host` the actor's own URL implies. Naming them
|
|
3238
3501
|
properly would mean dereferencing the actor, which is a network round trip per
|
|
3239
3502
|
comment shown.
|
|
3240
3503
|
|
|
3241
|
-
**
|
|
3504
|
+
**A reply's HTML is sanitised before it is published.** It is markup a
|
|
3242
3505
|
stranger wrote, so it is tokenised and rebuilt from an allowlist rather than
|
|
3243
3506
|
passed through: `p`, `br`, `a`, `em`, `strong`, `del`, `code`, `pre`,
|
|
3244
3507
|
`blockquote` and the list elements survive; `script` and `style` are dropped
|
|
@@ -3247,10 +3510,33 @@ every attribute goes except an `a`'s `href`, which must be `http`, `https` or
|
|
|
3247
3510
|
`mailto` and is marked `rel="nofollow noopener noreferrer"`. `sanitizeCommentHtml`
|
|
3248
3511
|
is exported for a site that shows comments in its own templates.
|
|
3249
3512
|
|
|
3250
|
-
A reply to a
|
|
3251
|
-
disappears from `/comments/feed/`, and that
|
|
3513
|
+
A reply to a document that has since been unpublished or moved to the trash
|
|
3514
|
+
disappears from `/comments/feed/`, and that document's own feed 404s with it.
|
|
3252
3515
|
`feedSize` caps both feeds.
|
|
3253
3516
|
|
|
3517
|
+
### Walking a thread
|
|
3518
|
+
|
|
3519
|
+
`{permalink}feed/` is the whole thread, flat, which is what WordPress
|
|
3520
|
+
publishes and `wfw:commentRss` points at. A program that wants the tree
|
|
3521
|
+
(Dave Winer's [rss.chat][rss-chat] reads conversations this way) walks it one
|
|
3522
|
+
level at a time instead: from a post item's `source:comments` to a feed of the
|
|
3523
|
+
replies that answer the post directly, and from each of those items' own
|
|
3524
|
+
`source:comments` to the replies that answer it, until an item has none.
|
|
3525
|
+
Every reply a reader can see is reached once.
|
|
3526
|
+
|
|
3527
|
+
Each of those feeds is `/replies/{key}/`, RSS 2.0, newest first, its items in
|
|
3528
|
+
the same shape as the comments feeds. It carries replies only: a mention
|
|
3529
|
+
answers nothing in the thread, and a like, a boost, a repost or an event's RSVP
|
|
3530
|
+
is in no feed. A comment's key is its id (see
|
|
3531
|
+
[Keys](#keys)); a post's, a page's, a fediverse reply's or a reply post's is
|
|
3532
|
+
the first 16 hex digits of the SHA-256 of its feed `guid`, since a document has
|
|
3533
|
+
no id of its own and slugs are not unique across posts and pages. An item
|
|
3534
|
+
nobody answered answers an empty feed; a segment that is no key, or a key that
|
|
3535
|
+
names nothing a reader can see, 404s. A migrated comment's feed still answers,
|
|
3536
|
+
with the native replies under it, though no feed links to it.
|
|
3537
|
+
|
|
3538
|
+
[rss-chat]: https://github.com/scripting/rss.chat
|
|
3539
|
+
|
|
3254
3540
|
### Atom and JSON Feed
|
|
3255
3541
|
|
|
3256
3542
|
An Atom entry carries `id` (the post's object id), `title`, `updated`,
|
|
@@ -3540,8 +3826,10 @@ commentsRssFeed({
|
|
|
3540
3826
|
|
|
3541
3827
|
`conversation.thread(document)` is the same reading for one post — the shape the
|
|
3542
3828
|
theme's `conversation.njk` is handed — `spokenIn` flattens it into the entries a
|
|
3543
|
-
feed carries,
|
|
3544
|
-
puts beside each item of a
|
|
3829
|
+
feed carries, each with the reply it sits under, `conversation.counts(documents)`
|
|
3830
|
+
is the number of direct replies `source:comments` puts beside each item of a
|
|
3831
|
+
post feed, and `conversation.repliesTo(segment)` is what one `/replies/` feed
|
|
3832
|
+
holds.
|
|
3545
3833
|
|
|
3546
3834
|
## Sitemap and robots.txt
|
|
3547
3835
|
|
|
@@ -3969,10 +4257,24 @@ Layouts are yours. The directory data files name them — `posts.json` says
|
|
|
3969
4257
|
Eleventy layout receives is the one this package's theme mirrors, so a layout
|
|
3970
4258
|
can often be moved across with only its `{% extends %}` removed.
|
|
3971
4259
|
|
|
3972
|
-
The
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
4260
|
+
The default theme's own layouts and partials build too, copied into
|
|
4261
|
+
`content/_includes/` as `layouts/` and `partials/`: the config adds the theme's
|
|
4262
|
+
other filters (`absoluteUrl`, `asset`, `host`, `fediverseHandle`) and the
|
|
4263
|
+
`newestPosts(count)` a front page override lists posts with, so a site theme's
|
|
4264
|
+
`front-page.njk` calling `{% set posts = newestPosts(5) %}` builds. They get
|
|
4265
|
+
only the context the config gives, though: `collections.menus` rather than
|
|
4266
|
+
`menus`, the `conversation` filter rather than the key, and no comment form,
|
|
4267
|
+
search or listing pagination.
|
|
4268
|
+
|
|
4269
|
+
Some things do not carry over. `/feed/`, `/feed/atom/` and `/feed/json/` are
|
|
4270
|
+
generated in code here, not by a template, so an Eleventy build needs its own;
|
|
4271
|
+
`/sitemap.xml` and `/robots.txt` are the same story, for the same reason. A
|
|
4272
|
+
comment's own page at `/comment/{key}/` is not written, since a build has no
|
|
4273
|
+
server to take a comment, so a comment links to its `#comment-{key}` anchor on
|
|
4274
|
+
the post. The site's own reply posts are not threaded under what they answer,
|
|
4275
|
+
and a document's backlinks are not listed: both read the CMS's index of every
|
|
4276
|
+
document, which the config's filters do not have. The config's header lists
|
|
4277
|
+
the same.
|
|
3976
4278
|
|
|
3977
4279
|
### The compatibility test
|
|
3978
4280
|
|
|
@@ -95,7 +95,9 @@
|
|
|
95
95
|
{{ rowFields(row, fields, status, csrfToken) }}
|
|
96
96
|
{% set replyLabel %}Reply to {{ row.author }}{% endset %}
|
|
97
97
|
{{ field.textarea('reply-' + loop.index, fields.body, replyLabel, rows='4', required=true,
|
|
98
|
-
hint='Markdown
|
|
98
|
+
hint='Markdown. It is saved as a reply post of yours and shown under this one.') }}
|
|
99
|
+
{{ field.checkbox('reply-listed-' + loop.index, fields.listed, 'Include in posts and feeds',
|
|
100
|
+
hint='Left unticked, the reply is Unlisted: its own page, and no listing or feed.') }}
|
|
99
101
|
<div class="mt-2">{{ button('Post reply', type='submit', color='primary') }}</div>
|
|
100
102
|
</form>
|
|
101
103
|
{% endcall %}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{# /admin/federation: who this site's people are to the fediverse, who follows
|
|
2
2
|
each of them, what arrived in the inbox, and how what went out landed. #}
|
|
3
3
|
{% extends "layouts/shell.njk" %}
|
|
4
|
-
{% from "components/badge.njk" import status %}
|
|
4
|
+
{% from "components/badge.njk" import badge, status %}
|
|
5
5
|
{% from "components/button.njk" import button %}
|
|
6
6
|
{% from "components/card.njk" import card %}
|
|
7
7
|
{% from "components/table.njk" import table %}
|
|
@@ -154,11 +154,17 @@
|
|
|
154
154
|
{{ entry.action }}
|
|
155
155
|
{% endif %}
|
|
156
156
|
{% if entry.post %}
|
|
157
|
-
<a class="link" href="{{ entry.post.editUrl }}">{{ entry.post.title }}</a>
|
|
157
|
+
{% if entry.post.inThread %}in the thread on {% endif %}<a class="link" href="{{ entry.post.editUrl }}">{{ entry.post.title }}</a>
|
|
158
158
|
{% else %}
|
|
159
159
|
<em>something of ours</em>
|
|
160
160
|
{% endif %}
|
|
161
161
|
<span class="whitespace-nowrap text-sm">{{ entry.receivedAt | date('html') }}</span>
|
|
162
|
+
{% if entry.via.kind == 'fetched' %}
|
|
163
|
+
{{ badge('fetched', color='info', style='soft') }}
|
|
164
|
+
{% if entry.via.from %}<a class="link text-sm" href="{{ entry.via.from }}">from the replies to the note it answers</a>{% endif %}
|
|
165
|
+
{% elif entry.via.kind == 'delivered' %}
|
|
166
|
+
{{ badge('delivered') }}
|
|
167
|
+
{% endif %}
|
|
162
168
|
</li>
|
|
163
169
|
{% endfor %}
|
|
164
170
|
</ul>
|
package/dist/admin/comments.d.ts
CHANGED
|
@@ -33,6 +33,8 @@ export declare const COMMENT_ADMIN_FIELDS: {
|
|
|
33
33
|
readonly action: 'action';
|
|
34
34
|
/** The reply's own text, on the reply form. */
|
|
35
35
|
readonly body: 'body';
|
|
36
|
+
/** The reply form's "Include in posts and feeds" box: ticked is Public, else Unlisted. */
|
|
37
|
+
readonly listed: 'listed';
|
|
36
38
|
/** Which list to go back to afterwards. */
|
|
37
39
|
readonly status: 'status';
|
|
38
40
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/admin/comments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/admin/comments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,MAAM,CAAC;AAM1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMlD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAe,MAAM,YAAY,CAAC;AAGzE;;;;;;;;;;;;;;GAcG;AAEH,uCAAuC;AACvC,eAAO,MAAM,aAAa,oBAA6B,CAAC;AAExD,kDAAkD;AAClD,eAAO,MAAM,gBAAgB,aAAa,CAAC;AAE3C,kCAAkC;AAClC,eAAO,MAAM,sBAAsB,6BAA8B,CAAC;AAElE,kCAAkC;AAClC,eAAO,MAAM,mBAAmB,0BAA2B,CAAC;AAE5D,kDAAkD;AAClD,eAAO,MAAM,oBAAoB;IAC/B,uCAAuC;aACvC,EAAE,EAAE,IAAI;IACR,gEAAgE;aAChE,MAAM,EAAE,QAAQ;IAChB,+CAA+C;aAC/C,IAAI,EAAE,MAAM;IACZ,0FAA0F;aAC1F,MAAM,EAAE,QAAQ;IAChB,2CAA2C;aAC3C,MAAM,EAAE,QAAQ;CACR,CAAC;AAEX,mCAAmC;AACnC,eAAO,MAAM,eAAe,YAAI,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAEtE,sCAAsC;AACtC,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,qDAAqD;AACrD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,4DAA4D;AAC5D,eAAO,MAAM,YAAY,EAAE,SAAS;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAI3E,CAAC;AAEF,0CAA0C;AAC1C,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,uBAAuB;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,sDAAsD;IACtD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;OAGG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,sEAAsE;IACtE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,uEAAuE;AACvE,MAAM,WAAW,0BAA0B;IACzC,oFAAoF;IACpF,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,sCAAsC;AACtC,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,OAAO,EAAE,0BAA0B,GAClC,IAAI,CAkIN;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEzD;AAED,yCAAyC;AACzC,wBAAgB,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,SAAI,GAAG,MAAM,CAG/D"}
|