@geekity/cms 0.3.0 → 0.5.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.
Files changed (660) hide show
  1. package/README.md +2217 -214
  2. package/admin/components/fields.njk +165 -0
  3. package/admin/layouts/base.njk +1 -1
  4. package/admin/layouts/settings-page.njk +26 -0
  5. package/admin/layouts/shell.njk +17 -3
  6. package/admin/pages/account/forgot.njk +47 -0
  7. package/admin/pages/account/login.njk +26 -0
  8. package/admin/pages/account/reset.njk +38 -0
  9. package/admin/pages/account/setup.njk +28 -0
  10. package/admin/pages/appearance/themes.njk +69 -0
  11. package/admin/pages/comments/all.njk +133 -0
  12. package/admin/{layouts/dashboard.njk → pages/dashboard/home.njk} +8 -15
  13. package/admin/{layouts/document-conflict.njk → pages/documents/conflict.njk} +1 -0
  14. package/admin/{layouts/document-editor.njk → pages/documents/editor.njk} +75 -59
  15. package/admin/{layouts/document-list.njk → pages/documents/list.njk} +19 -2
  16. package/admin/pages/documents/taxonomy.njk +95 -0
  17. package/admin/pages/federation/followers.njk +238 -0
  18. package/admin/pages/federation/settings.njk +77 -0
  19. package/admin/pages/media/library.njk +160 -0
  20. package/admin/pages/messages/all.njk +110 -0
  21. package/admin/pages/navigation/menus.njk +129 -0
  22. package/admin/{layouts → pages}/placeholder.njk +5 -1
  23. package/admin/pages/settings/discussion.njk +99 -0
  24. package/admin/pages/settings/email.njk +203 -0
  25. package/admin/pages/settings/general.njk +29 -0
  26. package/admin/pages/settings/permalinks.njk +50 -0
  27. package/admin/pages/settings/reading.njk +64 -0
  28. package/admin/pages/tools/content-index.njk +89 -0
  29. package/admin/pages/users/edit.njk +239 -0
  30. package/admin/pages/users/list.njk +51 -0
  31. package/admin/pages/users/new.njk +41 -0
  32. package/admin/static/admin.css +558 -3
  33. package/admin/static/copy.js +52 -0
  34. package/admin/static/editor.js +16 -16
  35. package/admin/static/slug.js +61 -0
  36. package/dist/access-log.d.ts +44 -0
  37. package/dist/access-log.d.ts.map +1 -0
  38. package/dist/access-log.js +71 -0
  39. package/dist/access-log.js.map +1 -0
  40. package/dist/admin/accounts.d.ts +413 -0
  41. package/dist/admin/accounts.d.ts.map +1 -0
  42. package/dist/admin/accounts.js +680 -0
  43. package/dist/admin/accounts.js.map +1 -0
  44. package/dist/admin/appearance.d.ts +80 -0
  45. package/dist/admin/appearance.d.ts.map +1 -0
  46. package/dist/admin/appearance.js +136 -0
  47. package/dist/admin/appearance.js.map +1 -0
  48. package/dist/admin/comments.d.ts +90 -0
  49. package/dist/admin/comments.d.ts.map +1 -0
  50. package/dist/admin/comments.js +244 -0
  51. package/dist/admin/comments.js.map +1 -0
  52. package/dist/admin/credentials.d.ts +26 -2
  53. package/dist/admin/credentials.d.ts.map +1 -1
  54. package/dist/admin/credentials.js +35 -2
  55. package/dist/admin/credentials.js.map +1 -1
  56. package/dist/admin/documents.d.ts +117 -10
  57. package/dist/admin/documents.d.ts.map +1 -1
  58. package/dist/admin/documents.js +328 -41
  59. package/dist/admin/documents.js.map +1 -1
  60. package/dist/admin/federation.d.ts +161 -50
  61. package/dist/admin/federation.d.ts.map +1 -1
  62. package/dist/admin/federation.js +235 -93
  63. package/dist/admin/federation.js.map +1 -1
  64. package/dist/admin/formatting.d.ts +20 -0
  65. package/dist/admin/formatting.d.ts.map +1 -0
  66. package/dist/admin/formatting.js +72 -0
  67. package/dist/admin/formatting.js.map +1 -0
  68. package/dist/admin/headers.d.ts +65 -0
  69. package/dist/admin/headers.d.ts.map +1 -0
  70. package/dist/admin/headers.js +104 -0
  71. package/dist/admin/headers.js.map +1 -0
  72. package/dist/admin/index.d.ts +38 -12
  73. package/dist/admin/index.d.ts.map +1 -1
  74. package/dist/admin/index.js +25 -7
  75. package/dist/admin/index.js.map +1 -1
  76. package/dist/admin/media.d.ts +168 -0
  77. package/dist/admin/media.d.ts.map +1 -0
  78. package/dist/admin/media.js +295 -0
  79. package/dist/admin/media.js.map +1 -0
  80. package/dist/admin/menu.d.ts +79 -0
  81. package/dist/admin/menu.d.ts.map +1 -0
  82. package/dist/admin/menu.js +143 -0
  83. package/dist/admin/menu.js.map +1 -0
  84. package/dist/admin/messages.d.ts +80 -0
  85. package/dist/admin/messages.d.ts.map +1 -0
  86. package/dist/admin/messages.js +152 -0
  87. package/dist/admin/messages.js.map +1 -0
  88. package/dist/admin/navigation.d.ts +155 -0
  89. package/dist/admin/navigation.d.ts.map +1 -0
  90. package/dist/admin/navigation.js +292 -0
  91. package/dist/admin/navigation.js.map +1 -0
  92. package/dist/admin/preview.d.ts.map +1 -1
  93. package/dist/admin/preview.js +31 -7
  94. package/dist/admin/preview.js.map +1 -1
  95. package/dist/admin/recovery.d.ts +92 -0
  96. package/dist/admin/recovery.d.ts.map +1 -0
  97. package/dist/admin/recovery.js +229 -0
  98. package/dist/admin/recovery.js.map +1 -0
  99. package/dist/admin/routes.d.ts +0 -20
  100. package/dist/admin/routes.d.ts.map +1 -1
  101. package/dist/admin/routes.js +164 -105
  102. package/dist/admin/routes.js.map +1 -1
  103. package/dist/admin/session.d.ts +17 -3
  104. package/dist/admin/session.d.ts.map +1 -1
  105. package/dist/admin/session.js +19 -5
  106. package/dist/admin/session.js.map +1 -1
  107. package/dist/admin/settings-discussion.d.ts +37 -0
  108. package/dist/admin/settings-discussion.d.ts.map +1 -0
  109. package/dist/admin/settings-discussion.js +117 -0
  110. package/dist/admin/settings-discussion.js.map +1 -0
  111. package/dist/admin/settings-email.d.ts +54 -0
  112. package/dist/admin/settings-email.d.ts.map +1 -0
  113. package/dist/admin/settings-email.js +189 -0
  114. package/dist/admin/settings-email.js.map +1 -0
  115. package/dist/admin/settings-federation.d.ts +48 -0
  116. package/dist/admin/settings-federation.d.ts.map +1 -0
  117. package/dist/admin/settings-federation.js +123 -0
  118. package/dist/admin/settings-federation.js.map +1 -0
  119. package/dist/admin/settings-general.d.ts +12 -0
  120. package/dist/admin/settings-general.d.ts.map +1 -0
  121. package/dist/admin/settings-general.js +48 -0
  122. package/dist/admin/settings-general.js.map +1 -0
  123. package/dist/admin/settings-page.d.ts +119 -0
  124. package/dist/admin/settings-page.d.ts.map +1 -0
  125. package/dist/admin/settings-page.js +132 -0
  126. package/dist/admin/settings-page.js.map +1 -0
  127. package/dist/admin/settings-pages.d.ts +30 -0
  128. package/dist/admin/settings-pages.d.ts.map +1 -0
  129. package/dist/admin/settings-pages.js +43 -0
  130. package/dist/admin/settings-pages.js.map +1 -0
  131. package/dist/admin/settings-permalinks.d.ts +16 -0
  132. package/dist/admin/settings-permalinks.d.ts.map +1 -0
  133. package/dist/admin/settings-permalinks.js +32 -0
  134. package/dist/admin/settings-permalinks.js.map +1 -0
  135. package/dist/admin/settings-reading.d.ts +34 -0
  136. package/dist/admin/settings-reading.d.ts.map +1 -0
  137. package/dist/admin/settings-reading.js +49 -0
  138. package/dist/admin/settings-reading.js.map +1 -0
  139. package/dist/admin/settings.d.ts +339 -96
  140. package/dist/admin/settings.d.ts.map +1 -1
  141. package/dist/admin/settings.js +600 -308
  142. package/dist/admin/settings.js.map +1 -1
  143. package/dist/admin/store.d.ts +606 -152
  144. package/dist/admin/store.d.ts.map +1 -1
  145. package/dist/admin/store.js +863 -268
  146. package/dist/admin/store.js.map +1 -1
  147. package/dist/admin/taxonomy.d.ts +114 -0
  148. package/dist/admin/taxonomy.d.ts.map +1 -0
  149. package/dist/admin/taxonomy.js +289 -0
  150. package/dist/admin/taxonomy.js.map +1 -0
  151. package/dist/admin/templates.d.ts +46 -14
  152. package/dist/admin/templates.d.ts.map +1 -1
  153. package/dist/admin/templates.js +46 -14
  154. package/dist/admin/templates.js.map +1 -1
  155. package/dist/admin/throttle.d.ts +84 -0
  156. package/dist/admin/throttle.d.ts.map +1 -0
  157. package/dist/admin/throttle.js +143 -0
  158. package/dist/admin/throttle.js.map +1 -0
  159. package/dist/admin/tools.d.ts +111 -0
  160. package/dist/admin/tools.d.ts.map +1 -0
  161. package/dist/admin/tools.js +182 -0
  162. package/dist/admin/tools.js.map +1 -0
  163. package/dist/admin/uploads.d.ts +28 -2
  164. package/dist/admin/uploads.d.ts.map +1 -1
  165. package/dist/admin/uploads.js +43 -4
  166. package/dist/admin/uploads.js.map +1 -1
  167. package/dist/admin/users.d.ts +100 -13
  168. package/dist/admin/users.d.ts.map +1 -1
  169. package/dist/admin/users.js +412 -39
  170. package/dist/admin/users.js.map +1 -1
  171. package/dist/cache.d.ts +141 -0
  172. package/dist/cache.d.ts.map +1 -0
  173. package/dist/cache.js +207 -0
  174. package/dist/cache.js.map +1 -0
  175. package/dist/cli.d.ts +14 -2
  176. package/dist/cli.d.ts.map +1 -1
  177. package/dist/cli.js +429 -21
  178. package/dist/cli.js.map +1 -1
  179. package/dist/comments/akismet.d.ts +130 -0
  180. package/dist/comments/akismet.d.ts.map +1 -0
  181. package/dist/comments/akismet.js +274 -0
  182. package/dist/comments/akismet.js.map +1 -0
  183. package/dist/comments/conversation.d.ts +29 -0
  184. package/dist/comments/conversation.d.ts.map +1 -0
  185. package/dist/comments/conversation.js +60 -0
  186. package/dist/comments/conversation.js.map +1 -0
  187. package/dist/comments/form.d.ts +123 -0
  188. package/dist/comments/form.d.ts.map +1 -0
  189. package/dist/comments/form.js +79 -0
  190. package/dist/comments/form.js.map +1 -0
  191. package/dist/comments/index.d.ts +16 -0
  192. package/dist/comments/index.d.ts.map +1 -0
  193. package/dist/comments/index.js +10 -0
  194. package/dist/comments/index.js.map +1 -0
  195. package/dist/comments/markdown.d.ts +8 -0
  196. package/dist/comments/markdown.d.ts.map +1 -0
  197. package/dist/comments/markdown.js +85 -0
  198. package/dist/comments/markdown.js.map +1 -0
  199. package/dist/comments/moderate.d.ts +71 -0
  200. package/dist/comments/moderate.d.ts.map +1 -0
  201. package/dist/comments/moderate.js +88 -0
  202. package/dist/comments/moderate.js.map +1 -0
  203. package/dist/comments/policy.d.ts +57 -0
  204. package/dist/comments/policy.d.ts.map +1 -0
  205. package/dist/comments/policy.js +80 -0
  206. package/dist/comments/policy.js.map +1 -0
  207. package/dist/comments/records.d.ts +266 -0
  208. package/dist/comments/records.d.ts.map +1 -0
  209. package/dist/comments/records.js +487 -0
  210. package/dist/comments/records.js.map +1 -0
  211. package/dist/comments/routes.d.ts +60 -0
  212. package/dist/comments/routes.d.ts.map +1 -0
  213. package/dist/comments/routes.js +212 -0
  214. package/dist/comments/routes.js.map +1 -0
  215. package/dist/comments/submission.d.ts +297 -0
  216. package/dist/comments/submission.d.ts.map +1 -0
  217. package/dist/comments/submission.js +280 -0
  218. package/dist/comments/submission.js.map +1 -0
  219. package/dist/comments/viewer.d.ts +21 -0
  220. package/dist/comments/viewer.d.ts.map +1 -0
  221. package/dist/comments/viewer.js +45 -0
  222. package/dist/comments/viewer.js.map +1 -0
  223. package/dist/config.d.ts +225 -5
  224. package/dist/config.d.ts.map +1 -1
  225. package/dist/config.js +121 -6
  226. package/dist/config.js.map +1 -1
  227. package/dist/contact/delivery.d.ts +60 -0
  228. package/dist/contact/delivery.d.ts.map +1 -0
  229. package/dist/contact/delivery.js +87 -0
  230. package/dist/contact/delivery.js.map +1 -0
  231. package/dist/contact/form.d.ts +130 -0
  232. package/dist/contact/form.d.ts.map +1 -0
  233. package/dist/contact/form.js +163 -0
  234. package/dist/contact/form.js.map +1 -0
  235. package/dist/contact/index.d.ts +17 -0
  236. package/dist/contact/index.d.ts.map +1 -0
  237. package/dist/contact/index.js +13 -0
  238. package/dist/contact/index.js.map +1 -0
  239. package/dist/contact/records.d.ts +124 -0
  240. package/dist/contact/records.d.ts.map +1 -0
  241. package/dist/contact/records.js +218 -0
  242. package/dist/contact/records.js.map +1 -0
  243. package/dist/contact/routes.d.ts +17 -0
  244. package/dist/contact/routes.d.ts.map +1 -0
  245. package/dist/contact/routes.js +127 -0
  246. package/dist/contact/routes.js.map +1 -0
  247. package/dist/contact/submission.d.ts +103 -0
  248. package/dist/contact/submission.d.ts.map +1 -0
  249. package/dist/contact/submission.js +166 -0
  250. package/dist/contact/submission.js.map +1 -0
  251. package/dist/content/document.d.ts +7 -2
  252. package/dist/content/document.d.ts.map +1 -1
  253. package/dist/content/document.js +1 -0
  254. package/dist/content/document.js.map +1 -1
  255. package/dist/content/index.d.ts +7 -2
  256. package/dist/content/index.d.ts.map +1 -1
  257. package/dist/content/index.js +4 -1
  258. package/dist/content/index.js.map +1 -1
  259. package/dist/content/markdown.d.ts.map +1 -1
  260. package/dist/content/markdown.js +24 -2
  261. package/dist/content/markdown.js.map +1 -1
  262. package/dist/content/parser.d.ts.map +1 -1
  263. package/dist/content/parser.js +11 -4
  264. package/dist/content/parser.js.map +1 -1
  265. package/dist/content/save.d.ts +5 -0
  266. package/dist/content/save.d.ts.map +1 -1
  267. package/dist/content/save.js +44 -1
  268. package/dist/content/save.js.map +1 -1
  269. package/dist/content/schedule.d.ts +125 -0
  270. package/dist/content/schedule.d.ts.map +1 -0
  271. package/dist/content/schedule.js +207 -0
  272. package/dist/content/schedule.js.map +1 -0
  273. package/dist/content/search.d.ts +64 -0
  274. package/dist/content/search.d.ts.map +1 -0
  275. package/dist/content/search.js +136 -0
  276. package/dist/content/search.js.map +1 -0
  277. package/dist/content/store.d.ts +220 -7
  278. package/dist/content/store.d.ts.map +1 -1
  279. package/dist/content/store.js +392 -67
  280. package/dist/content/store.js.map +1 -1
  281. package/dist/content/sync.d.ts +7 -1
  282. package/dist/content/sync.d.ts.map +1 -1
  283. package/dist/content/sync.js +18 -10
  284. package/dist/content/sync.js.map +1 -1
  285. package/dist/content/time.d.ts +56 -0
  286. package/dist/content/time.d.ts.map +1 -0
  287. package/dist/content/time.js +141 -0
  288. package/dist/content/time.js.map +1 -0
  289. package/dist/content/writer.d.ts.map +1 -1
  290. package/dist/content/writer.js +3 -0
  291. package/dist/content/writer.js.map +1 -1
  292. package/dist/env.d.ts +70 -5
  293. package/dist/env.d.ts.map +1 -1
  294. package/dist/federation/actor.d.ts +95 -41
  295. package/dist/federation/actor.d.ts.map +1 -1
  296. package/dist/federation/actor.js +180 -53
  297. package/dist/federation/actor.js.map +1 -1
  298. package/dist/federation/article.d.ts +44 -17
  299. package/dist/federation/article.d.ts.map +1 -1
  300. package/dist/federation/article.js +98 -46
  301. package/dist/federation/article.js.map +1 -1
  302. package/dist/federation/delivery.d.ts +63 -15
  303. package/dist/federation/delivery.d.ts.map +1 -1
  304. package/dist/federation/delivery.js +154 -80
  305. package/dist/federation/delivery.js.map +1 -1
  306. package/dist/federation/federation.d.ts +22 -17
  307. package/dist/federation/federation.d.ts.map +1 -1
  308. package/dist/federation/federation.js +98 -77
  309. package/dist/federation/federation.js.map +1 -1
  310. package/dist/federation/followers.d.ts +3 -2
  311. package/dist/federation/followers.d.ts.map +1 -1
  312. package/dist/federation/followers.js +6 -5
  313. package/dist/federation/followers.js.map +1 -1
  314. package/dist/federation/import-wordpress.d.ts +128 -0
  315. package/dist/federation/import-wordpress.d.ts.map +1 -0
  316. package/dist/federation/import-wordpress.js +426 -0
  317. package/dist/federation/import-wordpress.js.map +1 -0
  318. package/dist/federation/inbox.d.ts +36 -13
  319. package/dist/federation/inbox.d.ts.map +1 -1
  320. package/dist/federation/inbox.js +120 -49
  321. package/dist/federation/inbox.js.map +1 -1
  322. package/dist/federation/index.d.ts +22 -10
  323. package/dist/federation/index.d.ts.map +1 -1
  324. package/dist/federation/index.js +13 -8
  325. package/dist/federation/index.js.map +1 -1
  326. package/dist/federation/keys.d.ts +98 -20
  327. package/dist/federation/keys.d.ts.map +1 -1
  328. package/dist/federation/keys.js +269 -39
  329. package/dist/federation/keys.js.map +1 -1
  330. package/dist/federation/mount.d.ts +46 -10
  331. package/dist/federation/mount.d.ts.map +1 -1
  332. package/dist/federation/mount.js +300 -28
  333. package/dist/federation/mount.js.map +1 -1
  334. package/dist/federation/paths.d.ts +23 -35
  335. package/dist/federation/paths.d.ts.map +1 -1
  336. package/dist/federation/paths.js +26 -39
  337. package/dist/federation/paths.js.map +1 -1
  338. package/dist/federation/records.d.ts +223 -0
  339. package/dist/federation/records.d.ts.map +1 -0
  340. package/dist/federation/records.js +506 -0
  341. package/dist/federation/records.js.map +1 -0
  342. package/dist/federation/relays.d.ts +114 -0
  343. package/dist/federation/relays.d.ts.map +1 -0
  344. package/dist/federation/relays.js +290 -0
  345. package/dist/federation/relays.js.map +1 -0
  346. package/dist/federation/replies.d.ts +80 -0
  347. package/dist/federation/replies.d.ts.map +1 -0
  348. package/dist/federation/replies.js +166 -0
  349. package/dist/federation/replies.js.map +1 -0
  350. package/dist/federation/wordpress.d.ts +131 -0
  351. package/dist/federation/wordpress.d.ts.map +1 -0
  352. package/dist/federation/wordpress.js +341 -0
  353. package/dist/federation/wordpress.js.map +1 -0
  354. package/dist/files/atomic.d.ts +103 -0
  355. package/dist/files/atomic.d.ts.map +1 -0
  356. package/dist/files/atomic.js +150 -0
  357. package/dist/files/atomic.js.map +1 -0
  358. package/dist/files/index.d.ts +3 -0
  359. package/dist/files/index.d.ts.map +1 -0
  360. package/dist/files/index.js +2 -0
  361. package/dist/files/index.js.map +1 -0
  362. package/dist/forms/protection.d.ts +85 -0
  363. package/dist/forms/protection.d.ts.map +1 -0
  364. package/dist/forms/protection.js +116 -0
  365. package/dist/forms/protection.js.map +1 -0
  366. package/dist/images/icons.d.ts +59 -0
  367. package/dist/images/icons.d.ts.map +1 -0
  368. package/dist/images/icons.js +131 -0
  369. package/dist/images/icons.js.map +1 -0
  370. package/dist/images/index.d.ts +7 -0
  371. package/dist/images/index.d.ts.map +1 -0
  372. package/dist/images/index.js +4 -0
  373. package/dist/images/index.js.map +1 -0
  374. package/dist/images/markup.d.ts +47 -0
  375. package/dist/images/markup.d.ts.map +1 -0
  376. package/dist/images/markup.js +175 -0
  377. package/dist/images/markup.js.map +1 -0
  378. package/dist/images/paths.d.ts +34 -0
  379. package/dist/images/paths.d.ts.map +1 -0
  380. package/dist/images/paths.js +41 -0
  381. package/dist/images/paths.js.map +1 -0
  382. package/dist/images/variants.d.ts +104 -0
  383. package/dist/images/variants.d.ts.map +1 -0
  384. package/dist/images/variants.js +320 -0
  385. package/dist/images/variants.js.map +1 -0
  386. package/dist/index.d.ts +123 -19
  387. package/dist/index.d.ts.map +1 -1
  388. package/dist/index.js +344 -25
  389. package/dist/index.js.map +1 -1
  390. package/dist/init.d.ts +18 -0
  391. package/dist/init.d.ts.map +1 -1
  392. package/dist/init.js +34 -3
  393. package/dist/init.js.map +1 -1
  394. package/dist/mail/brevo.d.ts +35 -0
  395. package/dist/mail/brevo.d.ts.map +1 -0
  396. package/dist/mail/brevo.js +85 -0
  397. package/dist/mail/brevo.js.map +1 -0
  398. package/dist/mail/credentials.d.ts +62 -0
  399. package/dist/mail/credentials.d.ts.map +1 -0
  400. package/dist/mail/credentials.js +86 -0
  401. package/dist/mail/credentials.js.map +1 -0
  402. package/dist/mail/index.d.ts +15 -0
  403. package/dist/mail/index.d.ts.map +1 -0
  404. package/dist/mail/index.js +8 -0
  405. package/dist/mail/index.js.map +1 -0
  406. package/dist/mail/memory.d.ts +35 -0
  407. package/dist/mail/memory.d.ts.map +1 -0
  408. package/dist/mail/memory.js +29 -0
  409. package/dist/mail/memory.js.map +1 -0
  410. package/dist/mail/provider.d.ts +80 -0
  411. package/dist/mail/provider.d.ts.map +1 -0
  412. package/dist/mail/provider.js +23 -0
  413. package/dist/mail/provider.js.map +1 -0
  414. package/dist/mail/service.d.ts +156 -0
  415. package/dist/mail/service.d.ts.map +1 -0
  416. package/dist/mail/service.js +265 -0
  417. package/dist/mail/service.js.map +1 -0
  418. package/dist/mail/smtp.d.ts +39 -0
  419. package/dist/mail/smtp.d.ts.map +1 -0
  420. package/dist/mail/smtp.js +58 -0
  421. package/dist/mail/smtp.js.map +1 -0
  422. package/dist/mail/templates.d.ts +91 -0
  423. package/dist/mail/templates.d.ts.map +1 -0
  424. package/dist/mail/templates.js +69 -0
  425. package/dist/mail/templates.js.map +1 -0
  426. package/dist/notifications/comments.d.ts +66 -0
  427. package/dist/notifications/comments.d.ts.map +1 -0
  428. package/dist/notifications/comments.js +151 -0
  429. package/dist/notifications/comments.js.map +1 -0
  430. package/dist/notifications/digest.d.ts +135 -0
  431. package/dist/notifications/digest.d.ts.map +1 -0
  432. package/dist/notifications/digest.js +287 -0
  433. package/dist/notifications/digest.js.map +1 -0
  434. package/dist/notifications/index.d.ts +13 -0
  435. package/dist/notifications/index.d.ts.map +1 -0
  436. package/dist/notifications/index.js +8 -0
  437. package/dist/notifications/index.js.map +1 -0
  438. package/dist/notifications/links.d.ts +60 -0
  439. package/dist/notifications/links.d.ts.map +1 -0
  440. package/dist/notifications/links.js +63 -0
  441. package/dist/notifications/links.js.map +1 -0
  442. package/dist/notifications/optouts.d.ts +48 -0
  443. package/dist/notifications/optouts.d.ts.map +1 -0
  444. package/dist/notifications/optouts.js +93 -0
  445. package/dist/notifications/optouts.js.map +1 -0
  446. package/dist/notifications/preferences.d.ts +158 -0
  447. package/dist/notifications/preferences.d.ts.map +1 -0
  448. package/dist/notifications/preferences.js +195 -0
  449. package/dist/notifications/preferences.js.map +1 -0
  450. package/dist/notifications/routes.d.ts +28 -0
  451. package/dist/notifications/routes.d.ts.map +1 -0
  452. package/dist/notifications/routes.js +184 -0
  453. package/dist/notifications/routes.js.map +1 -0
  454. package/dist/notifications/tokens.d.ts +60 -0
  455. package/dist/notifications/tokens.d.ts.map +1 -0
  456. package/dist/notifications/tokens.js +125 -0
  457. package/dist/notifications/tokens.js.map +1 -0
  458. package/dist/notify.d.ts +84 -0
  459. package/dist/notify.d.ts.map +1 -0
  460. package/dist/notify.js +149 -0
  461. package/dist/notify.js.map +1 -0
  462. package/dist/web/archive.d.ts +49 -0
  463. package/dist/web/archive.d.ts.map +1 -0
  464. package/dist/web/archive.js +59 -0
  465. package/dist/web/archive.js.map +1 -0
  466. package/dist/web/assets.d.ts +6 -5
  467. package/dist/web/assets.d.ts.map +1 -1
  468. package/dist/web/assets.js +5 -7
  469. package/dist/web/assets.js.map +1 -1
  470. package/dist/web/authors.d.ts +143 -0
  471. package/dist/web/authors.d.ts.map +1 -0
  472. package/dist/web/authors.js +178 -0
  473. package/dist/web/authors.js.map +1 -0
  474. package/dist/web/comments.d.ts +60 -0
  475. package/dist/web/comments.d.ts.map +1 -0
  476. package/dist/web/comments.js +207 -0
  477. package/dist/web/comments.js.map +1 -0
  478. package/dist/web/context.d.ts +162 -28
  479. package/dist/web/context.d.ts.map +1 -1
  480. package/dist/web/context.js +123 -26
  481. package/dist/web/context.js.map +1 -1
  482. package/dist/web/conversation.d.ts +209 -0
  483. package/dist/web/conversation.d.ts.map +1 -0
  484. package/dist/web/conversation.js +557 -0
  485. package/dist/web/conversation.js.map +1 -0
  486. package/dist/web/documents.d.ts +36 -6
  487. package/dist/web/documents.d.ts.map +1 -1
  488. package/dist/web/documents.js +52 -10
  489. package/dist/web/documents.js.map +1 -1
  490. package/dist/web/feed-atom.d.ts +22 -0
  491. package/dist/web/feed-atom.d.ts.map +1 -0
  492. package/dist/web/feed-atom.js +83 -0
  493. package/dist/web/feed-atom.js.map +1 -0
  494. package/dist/web/feed-item.d.ts +145 -0
  495. package/dist/web/feed-item.d.ts.map +1 -0
  496. package/dist/web/feed-item.js +120 -0
  497. package/dist/web/feed-item.js.map +1 -0
  498. package/dist/web/feed-json.d.ts +79 -0
  499. package/dist/web/feed-json.d.ts.map +1 -0
  500. package/dist/web/feed-json.js +53 -0
  501. package/dist/web/feed-json.js.map +1 -0
  502. package/dist/web/feed-rss.d.ts +26 -0
  503. package/dist/web/feed-rss.d.ts.map +1 -0
  504. package/dist/web/feed-rss.js +203 -0
  505. package/dist/web/feed-rss.js.map +1 -0
  506. package/dist/web/feed-source.d.ts +244 -0
  507. package/dist/web/feed-source.d.ts.map +1 -0
  508. package/dist/web/feed-source.js +201 -0
  509. package/dist/web/feed-source.js.map +1 -0
  510. package/dist/web/feed-xml.d.ts +63 -0
  511. package/dist/web/feed-xml.d.ts.map +1 -0
  512. package/dist/web/feed-xml.js +116 -0
  513. package/dist/web/feed-xml.js.map +1 -0
  514. package/dist/web/feeds.d.ts +31 -96
  515. package/dist/web/feeds.d.ts.map +1 -1
  516. package/dist/web/feeds.js +94 -198
  517. package/dist/web/feeds.js.map +1 -1
  518. package/dist/web/health.d.ts +31 -0
  519. package/dist/web/health.d.ts.map +1 -0
  520. package/dist/web/health.js +44 -0
  521. package/dist/web/health.js.map +1 -0
  522. package/dist/web/index.d.ts +30 -10
  523. package/dist/web/index.d.ts.map +1 -1
  524. package/dist/web/index.js +18 -7
  525. package/dist/web/index.js.map +1 -1
  526. package/dist/web/navigation.d.ts +195 -0
  527. package/dist/web/navigation.d.ts.map +1 -0
  528. package/dist/web/navigation.js +300 -0
  529. package/dist/web/navigation.js.map +1 -0
  530. package/dist/web/negotiate.d.ts +31 -0
  531. package/dist/web/negotiate.d.ts.map +1 -1
  532. package/dist/web/negotiate.js +31 -11
  533. package/dist/web/negotiate.js.map +1 -1
  534. package/dist/web/recent.d.ts +43 -0
  535. package/dist/web/recent.d.ts.map +1 -0
  536. package/dist/web/recent.js +37 -0
  537. package/dist/web/recent.js.map +1 -0
  538. package/dist/web/render.d.ts +203 -9
  539. package/dist/web/render.d.ts.map +1 -1
  540. package/dist/web/render.js +341 -17
  541. package/dist/web/render.js.map +1 -1
  542. package/dist/web/routes.d.ts +25 -8
  543. package/dist/web/routes.d.ts.map +1 -1
  544. package/dist/web/routes.js +854 -93
  545. package/dist/web/routes.js.map +1 -1
  546. package/dist/web/sanitize.d.ts +19 -0
  547. package/dist/web/sanitize.d.ts.map +1 -0
  548. package/dist/web/sanitize.js +272 -0
  549. package/dist/web/sanitize.js.map +1 -0
  550. package/dist/web/search.d.ts +79 -0
  551. package/dist/web/search.d.ts.map +1 -0
  552. package/dist/web/search.js +94 -0
  553. package/dist/web/search.js.map +1 -0
  554. package/dist/web/sitemap.d.ts +120 -0
  555. package/dist/web/sitemap.d.ts.map +1 -0
  556. package/dist/web/sitemap.js +199 -0
  557. package/dist/web/sitemap.js.map +1 -0
  558. package/dist/web/taxonomy.d.ts +152 -0
  559. package/dist/web/taxonomy.d.ts.map +1 -0
  560. package/dist/web/taxonomy.js +237 -0
  561. package/dist/web/taxonomy.js.map +1 -0
  562. package/dist/web/templates.d.ts +54 -16
  563. package/dist/web/templates.d.ts.map +1 -1
  564. package/dist/web/templates.js +109 -28
  565. package/dist/web/templates.js.map +1 -1
  566. package/dist/web/themes.d.ts +226 -0
  567. package/dist/web/themes.d.ts.map +1 -0
  568. package/dist/web/themes.js +314 -0
  569. package/dist/web/themes.js.map +1 -0
  570. package/dist/webmention/discovery.d.ts +51 -0
  571. package/dist/webmention/discovery.d.ts.map +1 -0
  572. package/dist/webmention/discovery.js +176 -0
  573. package/dist/webmention/discovery.js.map +1 -0
  574. package/dist/webmention/html.d.ts +71 -0
  575. package/dist/webmention/html.d.ts.map +1 -0
  576. package/dist/webmention/html.js +285 -0
  577. package/dist/webmention/html.js.map +1 -0
  578. package/dist/webmention/index.d.ts +12 -0
  579. package/dist/webmention/index.d.ts.map +1 -0
  580. package/dist/webmention/index.js +8 -0
  581. package/dist/webmention/index.js.map +1 -0
  582. package/dist/webmention/links.d.ts +18 -0
  583. package/dist/webmention/links.d.ts.map +1 -0
  584. package/dist/webmention/links.js +64 -0
  585. package/dist/webmention/links.js.map +1 -0
  586. package/dist/webmention/microformats.d.ts +93 -0
  587. package/dist/webmention/microformats.d.ts.map +1 -0
  588. package/dist/webmention/microformats.js +376 -0
  589. package/dist/webmention/microformats.js.map +1 -0
  590. package/dist/webmention/receive.d.ts +141 -0
  591. package/dist/webmention/receive.d.ts.map +1 -0
  592. package/dist/webmention/receive.js +264 -0
  593. package/dist/webmention/receive.js.map +1 -0
  594. package/dist/webmention/routes.d.ts +37 -0
  595. package/dist/webmention/routes.d.ts.map +1 -0
  596. package/dist/webmention/routes.js +75 -0
  597. package/dist/webmention/routes.js.map +1 -0
  598. package/dist/webmention/service.d.ts +94 -0
  599. package/dist/webmention/service.d.ts.map +1 -0
  600. package/dist/webmention/service.js +207 -0
  601. package/dist/webmention/service.js.map +1 -0
  602. package/package.json +11 -6
  603. package/templates/site/content/_data/site.json +8 -0
  604. package/templates/site/content/pages/about.md +7 -0
  605. package/templates/site/content/posts/2026-01-01-hello-world.md +5 -3
  606. package/templates/site/geekity.config.ts +11 -1
  607. package/templates/site/tsconfig.json +1 -1
  608. package/themes/default/README.md +1216 -50
  609. package/themes/default/layouts/404.njk +2 -3
  610. package/themes/default/layouts/author.njk +36 -0
  611. package/themes/default/layouts/base.njk +161 -31
  612. package/themes/default/layouts/category.njk +27 -0
  613. package/themes/default/layouts/front-page.njk +56 -0
  614. package/themes/default/layouts/home.njk +17 -1
  615. package/themes/default/layouts/page.njk +57 -5
  616. package/themes/default/layouts/post.njk +78 -19
  617. package/themes/default/layouts/search.njk +57 -0
  618. package/themes/default/layouts/tag.njk +3 -6
  619. package/themes/default/mail/comment-digest.html.njk +37 -0
  620. package/themes/default/mail/comment-digest.subject.njk +3 -0
  621. package/themes/default/mail/comment-digest.txt.njk +40 -0
  622. package/themes/default/mail/comment-pending.html.njk +27 -0
  623. package/themes/default/mail/comment-pending.subject.njk +2 -0
  624. package/themes/default/mail/comment-pending.txt.njk +24 -0
  625. package/themes/default/mail/comment-reply.html.njk +21 -0
  626. package/themes/default/mail/comment-reply.subject.njk +2 -0
  627. package/themes/default/mail/comment-reply.txt.njk +22 -0
  628. package/themes/default/mail/contact-message.html.njk +24 -0
  629. package/themes/default/mail/contact-message.subject.njk +5 -0
  630. package/themes/default/mail/contact-message.txt.njk +20 -0
  631. package/themes/default/mail/password-changed.html.njk +18 -0
  632. package/themes/default/mail/password-changed.subject.njk +2 -0
  633. package/themes/default/mail/password-changed.txt.njk +17 -0
  634. package/themes/default/mail/password-reset.html.njk +22 -0
  635. package/themes/default/mail/password-reset.subject.njk +2 -0
  636. package/themes/default/mail/password-reset.txt.njk +18 -0
  637. package/themes/default/mail/test.html.njk +14 -0
  638. package/themes/default/mail/test.subject.njk +2 -0
  639. package/themes/default/mail/test.txt.njk +12 -0
  640. package/themes/default/partials/archive.njk +27 -0
  641. package/themes/default/partials/bio.njk +71 -0
  642. package/themes/default/partials/comment-form.njk +137 -0
  643. package/themes/default/partials/contact-form.njk +88 -0
  644. package/themes/default/partials/conversation.njk +139 -0
  645. package/themes/default/partials/feeds.njk +26 -0
  646. package/themes/default/partials/jsonld.njk +120 -0
  647. package/themes/default/partials/menu.njk +32 -0
  648. package/themes/default/partials/pagination.njk +12 -6
  649. package/themes/default/partials/post-list.njk +51 -18
  650. package/themes/default/partials/search-form.njk +22 -0
  651. package/themes/default/partials/tags.njk +26 -5
  652. package/themes/default/static/highlight.js +4 -0
  653. package/themes/default/static/style.css +1142 -194
  654. package/themes/default/theme.json +9 -0
  655. package/admin/layouts/federation.njk +0 -145
  656. package/admin/layouts/login.njk +0 -23
  657. package/admin/layouts/settings.njk +0 -116
  658. package/admin/layouts/setup.njk +0 -27
  659. package/admin/layouts/users.njk +0 -91
  660. /package/admin/{layouts/_flash.njk → components/flash.njk} +0 -0
@@ -1,6 +1,7 @@
1
1
  {# The editor behind /admin/posts/{slug} and /admin/pages/{slug}, and behind
2
2
  .../new. One template for both kinds: `kind` decides whether there is a date
3
- and a tag field, and the handler decides which buttons the form carries. #}
3
+ and the taxonomy fields, and the handler decides which buttons the form
4
+ carries. #}
4
5
  {% extends "layouts/shell.njk" %}
5
6
 
6
7
  {% block title %}{{ heading }}{% endblock %}
@@ -16,6 +17,10 @@
16
17
  <p class="admin-note">This {{ kind.singular }} is in the trash. The public site is not serving it.</p>
17
18
  {% endif %}
18
19
 
20
+ {% if scheduledFor %}
21
+ <p class="admin-note">Scheduled for {{ scheduledFor }}. The public site starts serving it then, and the followers are told then.</p>
22
+ {% endif %}
23
+
19
24
  <form class="admin-editor" method="post" action="{{ saveUrl }}">
20
25
  <input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
21
26
  {# The hash of the file this form was filled in from. A save whose hash no
@@ -66,6 +71,9 @@
66
71
  {% if kind.dated %}
67
72
  <label for="editor-date">Date</label>
68
73
  <input id="editor-date" name="date" type="text" value="{{ form.date }}" />
74
+ {# The file holds a UTC instant; this field is that instant as the
75
+ site's own clock reads it, so the zone has to be on the screen. #}
76
+ <p class="admin-hint">Wall-clock time in {{ dateZone }}. Stored as UTC.</p>
69
77
  {% endif %}
70
78
 
71
79
  {% if kind.tagged %}
@@ -74,14 +82,47 @@
74
82
  <p class="admin-hint">Separated by commas.</p>
75
83
  {% endif %}
76
84
 
85
+ {% if kind.categorised %}
86
+ <label for="editor-categories">Categories</label>
87
+ <input id="editor-categories" name="categories" type="text" value="{{ form.categories }}" />
88
+ <p class="admin-hint">Separated by commas.</p>
89
+ {% endif %}
90
+
77
91
  <label for="editor-description">Description</label>
78
92
  <input id="editor-description" name="description" type="text" value="{{ form.description }}" />
79
93
 
94
+ {# Who the front matter says wrote this (TASK-67). A select of the site's
95
+ users rather than a free box, because after decision-14 the value is a
96
+ person rather than a string: it decides whose archive the post is on
97
+ and, once the actors land, whose followers hear about it. A file that
98
+ still names somebody who has no account keeps an option of its own, so
99
+ opening the editor cannot silently reattribute it. #}
100
+ <label for="editor-author">Author</label>
101
+ <select id="editor-author" name="author">
102
+ {% for choice in authors %}
103
+ <option value="{{ choice.value }}"{% if choice.chosen %} selected{% endif %}>{{ choice.label }}</option>
104
+ {% endfor %}
105
+ </select>
106
+
80
107
  <p class="admin-check">
81
108
  <input id="editor-draft" name="draft" type="checkbox" value="1"{% if form.draft %} checked{% endif %} />
82
109
  <label for="editor-draft">Draft</label>
83
110
  </p>
84
111
 
112
+ {# What this document says about comments, if anything. Three answers
113
+ rather than two: the site's own rules, always open, always closed. #}
114
+ <label for="editor-comments">Comments</label>
115
+ <select id="editor-comments" name="comments">
116
+ <option value="{{ commentSettings.site }}"{% if form.comments == commentSettings.site %} selected{% endif %}>Follow the site settings</option>
117
+ <option value="{{ commentSettings.open }}"{% if form.comments == commentSettings.open %} selected{% endif %}>Open</option>
118
+ <option value="{{ commentSettings.closed }}"{% if form.comments == commentSettings.closed %} selected{% endif %}>Closed</option>
119
+ </select>
120
+ <p class="admin-hint">
121
+ Writes <code>comments: true</code> or <code>comments: false</code> into the front matter,
122
+ which beats the site's switch and its closing window in both directions. Fediverse replies
123
+ are shown either way.
124
+ </p>
125
+
85
126
  {% if kind.excludable %}
86
127
  {# doc-2's eleventyExcludeFromCollections: still published and still at
87
128
  its URL, but out of every collection a template lists from. #}
@@ -92,6 +133,21 @@
92
133
  <p class="admin-hint">Keeps the {{ kind.singular }} out of listings that gather content, without unpublishing it.</p>
93
134
  {% endif %}
94
135
 
136
+ {% if kind.contactable %}
137
+ {# The page offers a contact form under its content (TASK-56). Where a
138
+ message goes is the contact address on the Settings screen; it is
139
+ never on this page or in its HTML. #}
140
+ <p class="admin-check">
141
+ <input id="editor-contact" name="contact" type="checkbox" value="1"{% if form.contact %} checked{% endif %} />
142
+ <label for="editor-contact">Contact form</label>
143
+ </p>
144
+ <p class="admin-hint">
145
+ Writes <code>contact: true</code> into the front matter and puts a name, email, subject
146
+ and message form under this {{ kind.singular }}. Messages arrive on the Messages screen
147
+ and are emailed to the contact address on Settings.
148
+ </p>
149
+ {% endif %}
150
+
95
151
  <p class="admin-editor-buttons">
96
152
  {% for button in actions %}
97
153
  <button type="submit" name="action" value="{{ button.value }}">{{ button.label }}</button>
@@ -106,62 +162,22 @@
106
162
  {# CodeMirror, the preview tab and the upload control. A module script is
107
163
  deferred by definition, so it runs after the form is in the document.
108
164
  Nothing above depends on it: with the bundle missing or JavaScript off the
109
- textarea and the Preview button are the whole editor. #}
110
- <script type="module" src="{{ assetPrefix }}editor.js"></script>
111
-
112
- <script>
113
- /* The one bit of progressive enhancement doc-5 asks for: the slug follows
114
- the title until somebody types a slug of their own, and the permalink
115
- follows the slug on the same terms. Without this the form still works —
116
- an empty slug is derived from the title on the server. */
117
- (function () {
118
- var title = document.getElementById('editor-title');
119
- var slug = document.getElementById('editor-slug');
120
- var permalink = document.getElementById('editor-permalink');
121
- if (!title || !slug) return;
122
-
123
- var date = document.getElementById('editor-date');
124
- var slugFollows = slug.value === '';
125
- var permalinkFollows = !permalink || permalink.value === '';
126
-
127
- function slugify(value) {
128
- return value
129
- .normalize('NFKD')
130
- .toLowerCase()
131
- .replace(/[\u0300-\u036f]/g, '')
132
- .replace(/[^a-z0-9]+/g, '-')
133
- .replace(/^-+|-+$/g, '');
134
- }
135
-
136
- /* The same shape defaultPermalink() writes on the server: a post lives
137
- under the year and month of its date, a page at the top level. */
138
- function syncPermalink() {
139
- if (!permalink || !permalinkFollows) return;
140
- if (slug.value === '') {
141
- permalink.value = '';
142
- return;
143
- }
144
- var month = date ? /^(\d{4})-(\d{2})/.exec(date.value) : null;
145
- var prefix = month ? '/' + month[1] + '/' + month[2] + '/' : '/';
146
- permalink.value = prefix + slug.value + '/';
147
- }
148
-
149
- slug.addEventListener('input', function () {
150
- slugFollows = false;
151
- syncPermalink();
152
- });
153
-
154
- if (permalink) {
155
- permalink.addEventListener('input', function () {
156
- permalinkFollows = false;
157
- });
158
- }
159
-
160
- title.addEventListener('input', function () {
161
- if (!slugFollows) return;
162
- slug.value = slugify(title.value);
163
- syncPermalink();
164
- });
165
- })();
166
- </script>
165
+ textarea and the Preview button are the whole editor.
166
+
167
+ The nonce is not what lets it run — `script-src 'self'` already does, and
168
+ the admin has no inline script at all. It is here so the bundle can read
169
+ it back off this element and hand it to CodeMirror, whose themes are
170
+ injected as <style> elements at runtime and would otherwise be refused by
171
+ `style-src`. Reading it through the element's `.nonce` property rather
172
+ than a data attribute keeps it out of reach of a CSS selector. #}
173
+ <script
174
+ type="module"
175
+ id="editor-script"
176
+ src="{{ assetPrefix }}editor.js"
177
+ nonce="{{ cspNonce }}"
178
+ ></script>
179
+
180
+ {# The slug and permalink auto-fill, in a file of its own so the policy never
181
+ has to allow an inline script. #}
182
+ <script defer src="{{ assetPrefix }}slug.js"></script>
167
183
  {% endblock %}
@@ -1,5 +1,14 @@
1
1
  {# The listing behind /admin/posts and /admin/pages. One template for both:
2
- `kind` says which, and whether the table has a date column and a tag one. #}
2
+ `kind` says which, and whether the table has a date column and taxonomy
3
+ ones.
4
+
5
+ There is no `pages/posts/` or `pages/categories/` for the same reason.
6
+ Posts, Pages, Categories and Tags are four menu entries over three
7
+ templates — this listing, the editor beside it and the taxonomy screen —
8
+ because a post and a page differ by a `kind`, not by a screen. A folder per
9
+ menu entry would mean either a second copy of each template or a re-export
10
+ that exists only to make the directory look like the menu, so the folder is
11
+ named after what the screens are about instead. #}
3
12
  {% extends "layouts/shell.njk" %}
4
13
 
5
14
  {% block title %}{{ kind.plural }}{% endblock %}
@@ -24,6 +33,9 @@
24
33
  {% if kind.tagged %}
25
34
  <th scope="col">Tags</th>
26
35
  {% endif %}
36
+ {% if kind.categorised %}
37
+ <th scope="col">Categories</th>
38
+ {% endif %}
27
39
  {% if kind.dated %}
28
40
  <th scope="col">Date</th>
29
41
  {% else %}
@@ -36,11 +48,14 @@
36
48
  <tbody>
37
49
  {% for document in documents %}
38
50
  <tr>
39
- <td><a href="{{ document.editUrl }}">{{ document.title }}</a></td>
51
+ <td><a href="{{ document.editUrl }}">{{ document.title }}</a>{% if document.role %} &mdash; <span class="admin-page-role">{{ document.role }}</span>{% endif %}</td>
40
52
  <td>{{ document.author }}</td>
41
53
  {% if kind.tagged %}
42
54
  <td>{{ document.tags }}</td>
43
55
  {% endif %}
56
+ {% if kind.categorised %}
57
+ <td>{{ document.categories }}</td>
58
+ {% endif %}
44
59
  {% if kind.dated %}
45
60
  <td>{{ document.date | date('html') }}</td>
46
61
  {% else %}
@@ -51,6 +66,8 @@
51
66
  <span class="admin-status admin-status-trashed">Trash</span>
52
67
  {% elif document.draft %}
53
68
  <span class="admin-status admin-status-draft">Draft</span>
69
+ {% elif document.scheduled %}
70
+ <span class="admin-status admin-status-scheduled">Scheduled</span>
54
71
  {% else %}
55
72
  <span class="admin-status">Published</span>
56
73
  {% endif %}
@@ -0,0 +1,95 @@
1
+ {# /admin/tags and /admin/categories: every term in use, what carries it, and
2
+ the three things that can be done to it — rename, merge and delete. One
3
+ template for both taxonomies; `kind` says which. #}
4
+ {% extends "layouts/shell.njk" %}
5
+
6
+ {% block title %}{{ heading }}{% endblock %}
7
+
8
+ {% block content %}
9
+ <h1>{{ heading }}</h1>
10
+
11
+ {# Above the table rather than under the field it came from: a refusal may be
12
+ about a term the table no longer has a row for. #}
13
+ {% if problems.to %}
14
+ <p class="admin-error">{{ problems.to }}</p>
15
+ {% endif %}
16
+
17
+ {% if confirm %}
18
+ <form class="admin-settings" method="post" action="{{ renameUrl }}">
19
+ <input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
20
+ <input type="hidden" name="{{ fields.term }}" value="{{ confirm.term }}" />
21
+ <input type="hidden" name="{{ fields.to }}" value="{{ confirm.to }}" />
22
+ <input type="hidden" name="{{ fields.confirm }}" value="1" />
23
+
24
+ <h2>Merge “{{ confirm.term }}” into “{{ confirm.to }}”?</h2>
25
+
26
+ <p>
27
+ There is already a {{ label }} called “{{ confirm.to }}”, on
28
+ {{ confirm.targetFiles }} {% if confirm.targetFiles == 1 %}file{% else %}files{% endif %}.
29
+ Renaming “{{ confirm.term }}” merges the
30
+ {{ confirm.files }} {% if confirm.files == 1 %}file{% else %}files{% endif %} carrying it
31
+ into that one. A file that already carries both keeps it once.
32
+ </p>
33
+
34
+ <p class="admin-settings-buttons">
35
+ <button type="submit">Merge them</button>
36
+ <a href="{{ listUrl }}">Cancel</a>
37
+ </p>
38
+ </form>
39
+ {% endif %}
40
+
41
+ {% if terms.length == 0 %}
42
+ <p>Nothing carries a {{ label }} yet.</p>
43
+ {% else %}
44
+ <table class="admin-list">
45
+ <thead>
46
+ <tr>
47
+ <th scope="col">{{ kind.singular | capitalize }}</th>
48
+ <th scope="col">Posts</th>
49
+ <th scope="col">Files</th>
50
+ <th scope="col">Rename</th>
51
+ <th scope="col">Actions</th>
52
+ </tr>
53
+ </thead>
54
+ <tbody>
55
+ {% for entry in terms %}
56
+ <tr>
57
+ <td><a href="{{ entry.archiveUrl }}">{{ entry.term }}</a></td>
58
+ <td>{{ entry.published }}</td>
59
+ <td>{{ entry.total }}</td>
60
+ <td>
61
+ <form class="admin-inline" method="post" action="{{ renameUrl }}">
62
+ <input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
63
+ <input type="hidden" name="{{ fields.term }}" value="{{ entry.term }}" />
64
+ <label class="admin-visually-hidden" for="rename-{{ loop.index }}">
65
+ Rename {{ entry.term }} to
66
+ </label>
67
+ <input
68
+ id="rename-{{ loop.index }}"
69
+ name="{{ fields.to }}"
70
+ type="text"
71
+ value="{% if form.term == entry.term %}{{ form.to }}{% endif %}"
72
+ required
73
+ />
74
+ <button type="submit">Rename</button>
75
+ </form>
76
+ </td>
77
+ <td class="admin-actions">
78
+ <form method="post" action="{{ deleteUrl }}">
79
+ <input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
80
+ <input type="hidden" name="{{ fields.term }}" value="{{ entry.term }}" />
81
+ <button type="submit">Delete</button>
82
+ </form>
83
+ </td>
84
+ </tr>
85
+ {% endfor %}
86
+ </tbody>
87
+ </table>
88
+
89
+ <p class="admin-hint">
90
+ Renaming, merging and deleting rewrite the front matter of every file carrying the
91
+ {{ label }} — drafts, scheduled posts and the trash included — and tell the feeds and the
92
+ fediverse about each published post that changed. The Files column is how many that is.
93
+ </p>
94
+ {% endif %}
95
+ {% endblock %}
@@ -0,0 +1,238 @@
1
+ {# /admin/federation: who this site's people are to the fediverse, who follows
2
+ each of them, what arrived in the inbox, and how what went out landed. #}
3
+ {% extends "layouts/shell.njk" %}
4
+
5
+ {% block title %}Federation{% endblock %}
6
+
7
+ {% block content %}
8
+ <h1>Federation</h1>
9
+
10
+ {% if actors.length %}
11
+ {% for actor in actors %}
12
+ <section class="admin-panel admin-actor">
13
+ <h2>{{ actor.handle }}</h2>
14
+ <div class="admin-actor-identity">
15
+ {% if actor.avatarUrl %}
16
+ <img class="admin-avatar admin-avatar-large" src="{{ actor.avatarUrl }}" alt="" width="96" height="96" />
17
+ {% else %}
18
+ <span class="admin-avatar admin-avatar-large admin-avatar-blank" aria-hidden="true"></span>
19
+ {% endif %}
20
+ <p class="admin-actor-handle">{{ actor.name }}</p>
21
+ </div>
22
+ <dl class="admin-actor-fields">
23
+ <div>
24
+ <dt>Summary</dt>
25
+ <dd>{% if actor.summary %}{{ actor.summary }}{% else %}<span class="admin-empty">None set.</span>{% endif %}</dd>
26
+ </div>
27
+ <div>
28
+ <dt>Actor</dt>
29
+ <dd><a href="{{ actor.actorId }}">{{ actor.actorId }}</a></dd>
30
+ </div>
31
+ <div>
32
+ <dt>Profile</dt>
33
+ <dd><a href="{{ actor.url }}">{{ actor.url }}</a></dd>
34
+ </div>
35
+ <div>
36
+ <dt>Followers</dt>
37
+ <dd>{{ actor.followerCount }}</dd>
38
+ </div>
39
+ </dl>
40
+
41
+ {% if actor.followers.length %}
42
+ <table class="admin-list">
43
+ <thead>
44
+ <tr>
45
+ <th scope="col">Follower</th>
46
+ <th scope="col">Handle</th>
47
+ <th scope="col">Followed</th>
48
+ </tr>
49
+ </thead>
50
+ <tbody>
51
+ {% for follower in actor.followers %}
52
+ <tr>
53
+ <td class="admin-follower">
54
+ {% if follower.iconUrl %}
55
+ <img class="admin-avatar" src="{{ follower.iconUrl }}" alt="" width="32" height="32" loading="lazy" />
56
+ {% else %}
57
+ <span class="admin-avatar admin-avatar-blank" aria-hidden="true"></span>
58
+ {% endif %}
59
+ <a href="{{ follower.url }}">{{ follower.name }}</a>
60
+ </td>
61
+ <td>{{ follower.handle }}</td>
62
+ <td>{{ follower.followedAt | date('html') }}</td>
63
+ </tr>
64
+ {% endfor %}
65
+ </tbody>
66
+ </table>
67
+ {% else %}
68
+ <p class="admin-empty">Nobody follows {{ actor.name }} yet.</p>
69
+ {% endif %}
70
+ </section>
71
+ {% endfor %}
72
+ {% else %}
73
+ <section class="admin-panel admin-actor">
74
+ <h2>Actors</h2>
75
+ <p class="admin-empty">The site has no users, so it has no actors.</p>
76
+ </section>
77
+ {% endif %}
78
+
79
+ <section class="admin-panel">
80
+ <h2>Relays</h2>
81
+ {% if relays.length %}
82
+ <table class="admin-list">
83
+ <thead>
84
+ <tr>
85
+ <th scope="col">Relay</th>
86
+ <th scope="col">State</th>
87
+ <th scope="col">Since</th>
88
+ <th scope="col">Last delivery</th>
89
+ <th scope="col">Actions</th>
90
+ </tr>
91
+ </thead>
92
+ <tbody>
93
+ {% for relay in relays %}
94
+ <tr>
95
+ <td>
96
+ {% if relay.actorId %}
97
+ <a href="{{ relay.actorId }}">{{ relay.inboxId }}</a>
98
+ {% else %}
99
+ {{ relay.inboxId }}
100
+ {% endif %}
101
+ {% if relay.reason %}
102
+ <p class="admin-hint">{{ relay.reason }}</p>
103
+ {% endif %}
104
+ </td>
105
+ <td>
106
+ {% if relay.state == 'rejected' %}
107
+ <span class="admin-status admin-status-failed">{{ relay.stateLabel }}</span>
108
+ {% else %}
109
+ {{ relay.stateLabel }}
110
+ {% endif %}
111
+ </td>
112
+ <td>{{ relay.updatedAt | date('html') }}</td>
113
+ <td>
114
+ {% if relay.lastDelivery %}
115
+ {{ relay.lastDelivery.activityType }} {{ relay.lastDelivery.status }}
116
+ <span class="admin-inbox-when">{{ relay.lastDelivery.attemptedAt | date('html') }}</span>
117
+ {% if relay.lastDelivery.error %}
118
+ <p class="admin-hint">{{ relay.lastDelivery.error }}</p>
119
+ {% endif %}
120
+ {% else %}
121
+ <span class="admin-empty">Nothing yet.</span>
122
+ {% endif %}
123
+ </td>
124
+ <td class="admin-actions">
125
+ {% if relay.retriable %}
126
+ <form method="post" action="{{ relayRetryUrl }}">
127
+ <input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
128
+ <input type="hidden" name="{{ fields.relay }}" value="{{ relay.inboxId }}" />
129
+ <button type="submit">Retry</button>
130
+ </form>
131
+ {% endif %}
132
+ </td>
133
+ </tr>
134
+ {% endfor %}
135
+ </tbody>
136
+ </table>
137
+ <p class="admin-hint">
138
+ A relay boosts every public post it is sent on to instances nobody here
139
+ follows. The list lives on the Settings screen; Retry sends the follow
140
+ again to one that is still waiting.
141
+ </p>
142
+ {% else %}
143
+ <p class="admin-empty">The site subscribes to no relay. Add one on the Settings screen.</p>
144
+ {% endif %}
145
+ </section>
146
+
147
+ <section class="admin-panel">
148
+ <h2>Recent activity</h2>
149
+ {% if inbox.length %}
150
+ <ul class="admin-inbox">
151
+ {% for entry in inbox %}
152
+ <li>
153
+ <span class="admin-inbox-actor"><a href="{{ entry.actorId }}">{{ entry.actorLabel }}</a></span>
154
+ {% if entry.remoteUrl %}
155
+ <a href="{{ entry.remoteUrl }}">{{ entry.action }}</a>
156
+ {% else %}
157
+ {{ entry.action }}
158
+ {% endif %}
159
+ {% if entry.post %}
160
+ <a href="{{ entry.post.editUrl }}">{{ entry.post.title }}</a>
161
+ {% else %}
162
+ <span class="admin-empty">something of ours</span>
163
+ {% endif %}
164
+ <span class="admin-inbox-when">{{ entry.receivedAt | date('html') }}</span>
165
+ </li>
166
+ {% endfor %}
167
+ </ul>
168
+ {% else %}
169
+ <p class="admin-empty">Nothing has arrived yet: no likes, boosts or replies.</p>
170
+ {% endif %}
171
+ </section>
172
+
173
+ <section class="admin-panel">
174
+ <h2>Delivery</h2>
175
+ {% if posts.length %}
176
+ <table class="admin-list">
177
+ <thead>
178
+ <tr>
179
+ <th scope="col">Post</th>
180
+ <th scope="col">Announced by</th>
181
+ <th scope="col">Last activity</th>
182
+ <th scope="col">Sent</th>
183
+ <th scope="col">Queued</th>
184
+ <th scope="col">Failed</th>
185
+ <th scope="col">Webmentions</th>
186
+ <th scope="col">Actions</th>
187
+ </tr>
188
+ </thead>
189
+ <tbody>
190
+ {% for row in posts %}
191
+ <tr>
192
+ <td>
193
+ <a href="{{ row.post.editUrl }}">{{ row.post.title }}</a>
194
+ {% if row.trashed %}<p class="admin-hint">In the trash.</p>{% endif %}
195
+ </td>
196
+ <td>{% if row.author %}@{{ row.author }}{% else %}<span class="admin-empty">—</span>{% endif %}</td>
197
+ {% if row.lastActivity %}
198
+ <td>{{ row.lastActivity.activityType }} <span class="admin-inbox-when">{{ row.lastActivity.attemptedAt | date('html') }}</span></td>
199
+ <td>{{ row.lastActivity.counts.sent }}</td>
200
+ <td>{{ row.lastActivity.counts.queued }}</td>
201
+ <td>{% if row.lastActivity.counts.failed %}<span class="admin-status admin-status-failed">{{ row.lastActivity.counts.failed }}</span>{% else %}0{% endif %}</td>
202
+ {% else %}
203
+ <td><span class="admin-empty">Nothing recorded.</span></td>
204
+ <td>—</td>
205
+ <td>—</td>
206
+ <td>—</td>
207
+ {% endif %}
208
+ <td>
209
+ {% if row.webmentions.sent or row.webmentions["none"] or row.webmentions.failed %}
210
+ {{ row.webmentions.sent }} told{% if row.webmentions["none"] %}, {{ row.webmentions["none"] }} take none{% endif %}{% if row.webmentions.failed %}, <span class="admin-status admin-status-failed">{{ row.webmentions.failed }} failed</span>{% endif %}
211
+ {% else %}
212
+ <span class="admin-empty">—</span>
213
+ {% endif %}
214
+ </td>
215
+ <td class="admin-actions">
216
+ <form method="post" action="{{ resendUrl }}">
217
+ <input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
218
+ <input type="hidden" name="{{ fields.slug }}" value="{{ row.slug }}" />
219
+ <button type="submit">Resend</button>
220
+ </form>
221
+ </td>
222
+ </tr>
223
+ {% endfor %}
224
+ </tbody>
225
+ </table>
226
+ <p class="admin-hint">
227
+ Resending builds the post again from its file and sends it to every one
228
+ of its author's followers and every accepted relay the site has now, and tells every
229
+ page the post links to at the same time: an update for a
230
+ published post, a withdrawal for one in the trash. The outcomes are a
231
+ cache, so a database deleted since leaves the posts listed with nothing
232
+ recorded against them.
233
+ </p>
234
+ {% else %}
235
+ <p class="admin-empty">No post has been announced to the fediverse yet.</p>
236
+ {% endif %}
237
+ </section>
238
+ {% endblock %}
@@ -0,0 +1,77 @@
1
+ {# /admin/federation/settings: which relays boost the site, and whether it is
2
+ still answering the paths a WordPress site arrived with. It is Federation >
3
+ Settings rather than Settings > Federation (TASK-109): the section holds
4
+ everything about federation, and Followers beside it is where the actors and
5
+ the people following them are. Who the site's people are on the fediverse is
6
+ a user's profile now (decision-14). #}
7
+ {% extends "layouts/settings-page.njk" %}
8
+ {% import "components/fields.njk" as field %}
9
+
10
+ {% block settingsFields %}
11
+ {% set relaysHint %}
12
+ One relay inbox per line, such as
13
+ <code>https://tags.pub/user/_____relay_____/inbox</code>. Adding one sends
14
+ it a follow; every public post then goes to it as well as to the
15
+ followers, and it boosts them on to instances nobody here follows. The
16
+ Followers screen says where each subscription stands.
17
+ {% endset %}
18
+ {{ field.textarea('settings-relays', fields.relays, 'Relays', form.relays,
19
+ error=problems.relays, hint=relaysHint, rows='3', spellcheck='false', autofocus=true) }}
20
+
21
+ <h2>WordPress</h2>
22
+
23
+ {% set wordpressHint %}
24
+ Answer the inbox and collection paths the WordPress ActivityPub plugin
25
+ published, under <code>/wp-json/activitypub/1.0/</code>, for the users
26
+ carrying its numeric actor id. Only a site that moved here from that plugin
27
+ needs this: a follower's server keeps delivering to the inbox URL it cached
28
+ until it next refetches the actor, and this is what catches those
29
+ deliveries in the meantime.
30
+ {% endset %}
31
+ {{ field.checkbox('settings-wordpress-activitypub', fields.wordpressActivityPub,
32
+ 'WordPress ActivityPub compatibility', checked=form.wordpressActivityPub,
33
+ hint=wordpressHint) }}
34
+ {% endblock %}
35
+
36
+ {% block settingsPanels %}
37
+ {# When each compatibility path was last asked for. It is the whole reason
38
+ the instants are recorded: once every follower's server has refetched the
39
+ actor, nothing asks any more and the switch can go off. #}
40
+ <section class="admin-settings admin-wordpress-panel">
41
+ <h2>WordPress paths</h2>
42
+
43
+ {% if wordpressRoutes.length %}
44
+ <table class="admin-table">
45
+ <thead>
46
+ <tr><th scope="col">Path</th><th scope="col">For</th><th scope="col">Last asked for</th></tr>
47
+ </thead>
48
+ <tbody>
49
+ {% for route in wordpressRoutes %}
50
+ <tr>
51
+ <td><code>{{ route.path }}</code></td>
52
+ <td>{{ route.username or 'every user' }}</td>
53
+ <td>
54
+ {% if route.lastRequestedAt %}
55
+ {{ route.lastRequestedAt | date('readable') }}
56
+ {% else %}
57
+ Never
58
+ {% endif %}
59
+ </td>
60
+ </tr>
61
+ {% endfor %}
62
+ </tbody>
63
+ </table>
64
+ <p class="admin-hint">
65
+ Once every one of these has been quiet for long enough that every
66
+ follower's server has refetched the actor, turn the switch off: these
67
+ paths are a cache other servers hold, not this site's identity, and the
68
+ CMS carries them only until the caches have moved on.
69
+ </p>
70
+ {% else %}
71
+ <p class="admin-hint">
72
+ No user carries a WordPress actor id, so the switch would serve nothing.
73
+ The <code>geekity import wordpress-actor</code> command sets one.
74
+ </p>
75
+ {% endif %}
76
+ </section>
77
+ {% endblock %}