@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
@@ -0,0 +1,88 @@
1
+ {#
2
+ The form under a page whose front matter says `contact: true`.
3
+
4
+ `contactForm` is on the context only when the page asked for one, so a layout
5
+ asks `{% if contactForm %}` and nothing else. A site replaces this whole
6
+ section with a `partials/contact-form.njk` of its own in the theme it wears;
7
+ the shape it is handed is documented in the theme README under "The contact
8
+ form".
9
+
10
+ Where the message goes is deliberately not here and not anywhere a template
11
+ can reach: the address is read when a submission arrives, so it cannot end up
12
+ in the HTML however this file is rewritten.
13
+
14
+ It wears `comment-respond`, which is the source design's name for a form
15
+ under an entry, because it is the same kind of form as the comment one and
16
+ the two are better off sharing a set of rules than keeping two that drift.
17
+
18
+ It works with JavaScript switched off, and there is no script on it.
19
+ #}
20
+ <section class="comment-respond contact-form" id="contact">
21
+ {% if contactNotice %}
22
+ {#
23
+ The thank-you the redirect after a submission landed on. The form is not
24
+ drawn again underneath it: the message has gone, and offering the fields
25
+ back would invite a second copy of it.
26
+ #}
27
+ <h2 class="contact-form-title">Thank you</h2>
28
+ <p class="contact-notice" role="status">{{ contactNotice }}</p>
29
+ {% else %}
30
+ <h2 class="contact-form-title">Send a message</h2>
31
+
32
+ {% if contactForm.error %}
33
+ <p class="contact-error" role="alert">{{ contactForm.error }}</p>
34
+ {% endif %}
35
+
36
+ <form method="post" action="{{ contactForm.action }}">
37
+ <input type="hidden" name="{{ contactForm.fields.page }}" value="{{ contactForm.page }}" />
38
+ <input type="hidden" name="{{ contactForm.fields.loaded }}" value="{{ contactForm.loaded }}" />
39
+
40
+ {#
41
+ The honeypot. Hidden from sight and from assistive technology, out of the
42
+ tab order, and told not to autofill: a person never sees it and never
43
+ fills it in, so anything that does is not a person.
44
+ #}
45
+ <div class="contact-trap" aria-hidden="true">
46
+ <label for="contact-website">Website</label>
47
+ <input id="contact-website" name="{{ contactForm.fields.trap }}" type="text" tabindex="-1" autocomplete="off" value="" />
48
+ </div>
49
+
50
+ <p class="contact-field">
51
+ <label for="contact-name">Name</label>
52
+ <input id="contact-name" name="{{ contactForm.fields.name }}" type="text" value="{{ contactForm.values.name }}" maxlength="{{ contactForm.nameLength }}" autocomplete="name" required />
53
+ {% if contactForm.problems.name %}
54
+ <span class="contact-field-error">{{ contactForm.problems.name }}</span>
55
+ {% endif %}
56
+ </p>
57
+
58
+ <p class="contact-field">
59
+ <label for="contact-email">Email</label>
60
+ <input id="contact-email" name="{{ contactForm.fields.email }}" type="email" value="{{ contactForm.values.email }}" autocomplete="email" required />
61
+ {% if contactForm.problems.email %}
62
+ <span class="contact-field-error">{{ contactForm.problems.email }}</span>
63
+ {% endif %}
64
+ <span class="contact-hint">So there is somewhere to reply to. It is never shown on the site.</span>
65
+ </p>
66
+
67
+ <p class="contact-field">
68
+ <label for="contact-subject">Subject <span class="contact-optional">(optional)</span></label>
69
+ <input id="contact-subject" name="{{ contactForm.fields.subject }}" type="text" value="{{ contactForm.values.subject }}" maxlength="{{ contactForm.subjectLength }}" />
70
+ {% if contactForm.problems.subject %}
71
+ <span class="contact-field-error">{{ contactForm.problems.subject }}</span>
72
+ {% endif %}
73
+ </p>
74
+
75
+ <p class="contact-field">
76
+ <label for="contact-message">Message</label>
77
+ <textarea id="contact-message" name="{{ contactForm.fields.message }}" rows="8" maxlength="{{ contactForm.messageLength }}" required>{{ contactForm.values.message }}</textarea>
78
+ {% if contactForm.problems.message %}
79
+ <span class="contact-field-error">{{ contactForm.problems.message }}</span>
80
+ {% endif %}
81
+ </p>
82
+
83
+ <p class="form-submit">
84
+ <button type="submit">Send message</button>
85
+ </p>
86
+ </form>
87
+ {% endif %}
88
+ </section>
@@ -0,0 +1,139 @@
1
+ {#
2
+ What has been said about a post: likes, boosts and mentions as facepiles
3
+ grouped by kind, and the replies as a thread, in the source design's markup
4
+ (decision-16, TASK-84).
5
+
6
+ Rendered from `layouts/post.njk` with the `conversation` on the context,
7
+ which is only there when there is something in it, so a post nobody has
8
+ answered renders none of this. A site replaces the whole section with a
9
+ `partials/conversation.njk` of its own in the theme it wears; the shape it is
10
+ handed is documented in the theme README under "The conversation".
11
+
12
+ The macros come first because Nunjucks defines one where it stands rather
13
+ than hoisting it, and the two sections below call them.
14
+ #}
15
+ {#
16
+ One face in a facepile: somebody's avatar, linked to wherever they are.
17
+
18
+ Without an avatar there is nothing to recognise them by, so the emoji badge
19
+ of their kind stands in and their name is printed beside it — which is what
20
+ a mention from a site with no `h-card` photo, and a like from an actor
21
+ nobody here follows, look like.
22
+ #}
23
+ {% macro face(item, icon, href) %}
24
+ {%- set name = item.author.name -%}
25
+ {%- if href %}<a class="u-url" href="{{ href }}" title="{{ name }}" rel="nofollow noopener noreferrer">{% else %}<span title="{{ name }}">{% endif %}
26
+ {%- if item.author.avatar -%}
27
+ <img class="avatar u-photo" src="{{ item.author.avatar }}" alt="{{ name }}" width="32" height="32" loading="lazy">
28
+ {%- else -%}
29
+ <span class="reaction-icon" aria-hidden="true">{{ icon }}</span><span class="reaction-name">{{ name }}</span>
30
+ {%- endif -%}
31
+ {%- if href %}</a>{% else %}</span>{% endif %}
32
+ {%- endmacro %}
33
+
34
+ {#
35
+ One kind of reaction: a title carrying the label and how many there are, and
36
+ the people behind them as a facepile. Nothing at all for a kind nothing has.
37
+
38
+ `source` says where a face links. A like or a boost is a person, so it links
39
+ to them; a mention is a page that wrote about this one, and the page is the
40
+ thing worth reading, so it links there and falls back to its author.
41
+ #}
42
+ {% macro group(items, label, kind, icon, source=false) %}
43
+ {% if items.length %}
44
+ <div class="reaction-group {{ kind }}">
45
+ <h2 class="reaction-title">{{ label }} ({{ items.length }})</h2>
46
+ <div class="facepile">
47
+ {%- for item in items %}{{ face(item, icon, (item.url or item.author.url) if source else (item.author.url or item.url)) }}{% endfor %}
48
+ </div>
49
+ </div>
50
+ {% endif %}
51
+ {% endmacro %}
52
+
53
+ {#
54
+ One reply and everything under it. A macro rather than an include so it can
55
+ call itself: a reply that answers a reply is the same thing one level in.
56
+ #}
57
+ {% macro comment(reply) %}
58
+ <li id="comment-{{ reply.id }}" class="comment h-entry comment-{{ reply.source }}">
59
+ <article class="comment-body">
60
+ <footer class="comment-meta">
61
+ <div class="comment-author vcard p-author h-card">
62
+ {%- if reply.author.avatar %}
63
+ <img class="avatar u-photo" src="{{ reply.author.avatar }}" alt="" width="40" height="40" loading="lazy">
64
+ {%- endif %}
65
+ <b class="fn p-name">{% if reply.author.url %}<a class="url u-url" href="{{ reply.author.url }}" rel="nofollow ugc noopener noreferrer">{{ reply.author.name }}</a>{% else %}{{ reply.author.name }}{% endif %}</b>
66
+ </div>
67
+ <div class="comment-metadata">
68
+ {%- if reply.url %}
69
+ <a class="u-url" href="{{ reply.url }}"{% if reply.source != "comment" %} rel="nofollow noopener noreferrer"{% endif %}><time class="dt-published" datetime="{{ reply.published | date("iso") }}">{{ reply.published | date }}</time></a>
70
+ {%- else %}
71
+ <time class="dt-published" datetime="{{ reply.published | date("iso") }}">{{ reply.published | date }}</time>
72
+ {%- endif %}
73
+ </div>
74
+ </footer>
75
+ <div class="comment-content e-content">
76
+ {{ reply.content | safe }}
77
+ </div>
78
+ {#
79
+ Answering a comment on this site needs no JavaScript: the link carries
80
+ the comment's id to the form, which puts it in a hidden field. A
81
+ fediverse reply is answered on the server that holds it, and a webmention
82
+ is answered on the page that sent it, so neither gets such a link.
83
+ #}
84
+ {% if commentForm and reply.source == "comment" %}
85
+ <div class="reply"><a class="comment-reply-link" href="{{ page.url }}?reply_to={{ reply.id }}#respond">Reply</a></div>
86
+ {% endif %}
87
+ </article>
88
+ {% if reply.replies.length %}
89
+ <ol class="children">
90
+ {% for child in reply.replies %}
91
+ {{ comment(child) }}
92
+ {% endfor %}
93
+ </ol>
94
+ {% endif %}
95
+ </li>
96
+ {% endmacro %}
97
+
98
+ {#
99
+ The reactions, above the thread. A like and a boost come from the fediverse
100
+ and a `repost` from a webmention; the CMS has already put a repost among the
101
+ boosts, which is why there are three groups and not four. `p-like`,
102
+ `p-repost` and `p-mention` are the source theme's classes for them.
103
+ #}
104
+ {% if conversation.likes.length or conversation.boosts.length or conversation.mentions.length %}
105
+ <div class="reactions-section">
106
+ {{- group(conversation.likes, "Likes", "p-like", "❤️") }}
107
+ {{- group(conversation.boosts, "Boosts", "p-repost", "🔁") }}
108
+ {{- group(conversation.mentions, "Mentions", "p-mention", "🔗", true) }}
109
+ </div>
110
+ {% endif %}
111
+
112
+ {#
113
+ And the thread. The title counts the whole of it rather than the top level,
114
+ which is what `counts.replies` is, and names the post the way the source
115
+ theme does.
116
+
117
+ "Comments are closed." is printed under a post that has been answered and is
118
+ no longer taking comments. That a post is closed is what the absence of
119
+ `commentForm` says: the CMS puts the form on the context only while the site
120
+ switch, the closing window and the post's own front matter all agree it is
121
+ open, so there is nothing else for a theme to work out.
122
+ #}
123
+ {% if conversation.replies.length %}
124
+ <div id="comments" class="comments-area">
125
+ <h2 class="comments-title">
126
+ {%- if conversation.counts.replies == 1 %}One comment{% else %}{{ conversation.counts.replies }} comments{% endif %} on &ldquo;<span>{{ title }}</span>&rdquo;
127
+ </h2>
128
+
129
+ <ol class="comment-list">
130
+ {% for reply in conversation.replies %}
131
+ {{ comment(reply) }}
132
+ {% endfor %}
133
+ </ol>
134
+
135
+ {% if not commentForm %}
136
+ <p class="no-comments">Comments are closed.</p>
137
+ {% endif %}
138
+ </div>
139
+ {% endif %}
@@ -0,0 +1,26 @@
1
+ {#
2
+ The `rel="alternate"` links for one listing's three feeds.
3
+
4
+ `root` is any listing URL ending in `/` — `/`, a tag archive, a category
5
+ archive — and `title` is what a reader should call the feed. RSS comes first
6
+ because it is what most subscribers hold.
7
+
8
+ Import it with `{% import "partials/feeds.njk" as feeds %}`; the arguments
9
+ carry everything, so it needs no context.
10
+ #}
11
+ {#
12
+ The `rel="alternate"` link for one comments feed.
13
+
14
+ `feed` is the feed's own URL — `/comments/feed/`, or a post's — because a
15
+ comments feed is RSS 2.0 and nothing else, so there is no set of three to
16
+ build from a root.
17
+ #}
18
+ {% macro commentsFeedLink(feed, title) %}
19
+ <link rel="alternate" type="application/rss+xml" title="{{ title }}" href="{{ feed | url }}">
20
+ {%- endmacro %}
21
+
22
+ {% macro feedLinks(root, title) %}
23
+ <link rel="alternate" type="application/rss+xml" title="{{ title }}" href="{{ (root + "feed/") | url }}">
24
+ <link rel="alternate" type="application/atom+xml" title="{{ title }}" href="{{ (root + "feed/atom/") | url }}">
25
+ <link rel="alternate" type="application/feed+json" title="{{ title }}" href="{{ (root + "feed/json/") | url }}">
26
+ {%- endmacro %}
@@ -0,0 +1,120 @@
1
+ {#
2
+ One schema.org graph for this page, as JSON-LD (decision-16).
3
+
4
+ All the structured data the theme emits is here, and there is no Microdata
5
+ anywhere: the visible markup carries microformats2 for the IndieWeb and this
6
+ file carries schema.org for everybody else, so neither has to be threaded
7
+ through the other's attributes. The CMS core knows nothing about schema.org —
8
+ a site that wants a different graph overrides this one file.
9
+
10
+ Everything is built from the context the visible markup uses, so what a
11
+ reader sees and what a consumer parses cannot drift. The Person is
12
+ `siteAuthor`: the site's own author on a page about nobody in particular, the
13
+ writer on a post, the archive's user on an author archive. Identity comes
14
+ from a user profile, so a name that answers to no account here has no Person
15
+ at all, and the author and publisher references go with it.
16
+
17
+ How it is printed: every value goes through `dump`, which is JSON.stringify,
18
+ with every `<` escaped to its `\u003C` form so nothing in a title or a
19
+ summary can close the script element. Each node opens with `@type`, which is
20
+ never optional, so every member after it can be written with a leading comma
21
+ and stay valid JSON however much of the page is missing. The nodes themselves
22
+ are collected and joined, so the comma between two of them is never a
23
+ question of which of them happened to be printed.
24
+ #}
25
+ {%- macro member(name, value) -%}
26
+ {%- if value %}, {{ name | dump | safe }}: {{ value | dump | replace("<", "\\u003C") | safe }}{% endif -%}
27
+ {%- endmacro -%}
28
+ {#- Who the page is by, and the id everything else points at. A `siteAuthor`
29
+ with no `url` is a byline naming somebody with no account here: there is
30
+ nothing to identify them by, so no Person is printed. -#}
31
+ {% set personUrl = siteAuthor.url | absoluteUrl if siteAuthor.url else "" %}
32
+ {% set personId = personUrl + "#person" if personUrl else "" %}
33
+ {% set home = "/" | absoluteUrl %}
34
+ {#- What the author, publisher and mainEntity members hold: a reference to the
35
+ Person rather than a second copy of them. -#}
36
+ {% set person = { "@id": personId } if personId else "" %}
37
+ {#- `sameAs` is everywhere else this person is: the profile links they listed,
38
+ and their actor id, which asserts that the schema.org Person and the
39
+ fediverse actor are one identity — decision-14 makes their archive URL the
40
+ actor id. -#}
41
+ {% set sameAs = [] %}
42
+ {% for link in siteAuthor.links %}{% set _ = sameAs.push(link.href) %}{% endfor %}
43
+ {% if personUrl %}{% set _ = sameAs.push(personUrl) %}{% endif %}
44
+ {% set address = { "@type": "PostalAddress", "addressLocality": siteAuthor.location } if siteAuthor.location else "" %}
45
+ {#- An author archive is the only page that is about a person: a listing whose
46
+ `author` is whose page this is. -#}
47
+ {% set isProfilePage = pagination and author.url and url and (author.url in url) %}
48
+ {% set entryType = "BlogPosting" if type == "post" else "Article" %}
49
+ {% set nodes = [] %}
50
+ {% set website %}
51
+ {
52
+ "@type": "WebSite"
53
+ {{- member("@id", home + "#website") }}
54
+ {{- member("name", site.title) }}
55
+ {{- member("description", site.tagline) }}
56
+ {{- member("url", home) }}
57
+ {#- The site's search (TASK-22), so a client that understands a
58
+ SearchAction can offer a box that searches this site. The template
59
+ is the search page's own URL with the words in `q`, which is what
60
+ the form in the footer sends. #}
61
+ {{- member("potentialAction", {
62
+ "@type": "SearchAction",
63
+ "target": {
64
+ "@type": "EntryPoint",
65
+ "urlTemplate": ("/search/" | absoluteUrl) + "?q={search_term_string}"
66
+ },
67
+ "query-input": "required name=search_term_string"
68
+ }) }}
69
+ {{- member("publisher", person) }}
70
+ }{% endset %}
71
+ {% set _ = nodes.push(website) %}
72
+ {% if personId %}
73
+ {% set profile %}
74
+ {
75
+ "@type": "Person"
76
+ {{- member("@id", personId) }}
77
+ {{- member("name", siteAuthor.name) }}
78
+ {{- member("url", personUrl) }}
79
+ {{- member("image", siteAuthor.avatar | absoluteUrl if siteAuthor.avatar else "") }}
80
+ {{- member("description", siteAuthor.bio) }}
81
+ {{- member("jobTitle", siteAuthor.jobTitle) }}
82
+ {{- member("address", address) }}
83
+ {{- member("sameAs", sameAs if sameAs.length else "") }}
84
+ }{% endset %}
85
+ {% set _ = nodes.push(profile) %}
86
+ {% endif %}
87
+ {% if isProfilePage %}
88
+ {% set profilePage %}
89
+ {
90
+ "@type": "ProfilePage"
91
+ {{- member("@id", (author.url | absoluteUrl) + "#profilepage") }}
92
+ {{- member("url", author.url | absoluteUrl) }}
93
+ {{- member("name", author.name) }}
94
+ {{- member("mainEntity", person) }}
95
+ }{% endset %}
96
+ {% set _ = nodes.push(profilePage) %}
97
+ {% elif isEntry %}
98
+ {% set entry %}
99
+ {
100
+ "@type": {{ entryType | dump | safe }}
101
+ {{- member("headline", title) }}
102
+ {{- member("url", metaUrl) }}
103
+ {{- member("mainEntityOfPage", metaUrl) }}
104
+ {{- member("datePublished", date | date("iso") if date else "") }}
105
+ {{- member("dateModified", (updated or date) | date("iso") if (updated or date) else "") }}
106
+ {{- member("description", metaDescription) }}
107
+ {{- member("image", metaImage | absoluteUrl if metaImage else "") }}
108
+ {{- member("author", person) }}
109
+ {{- member("publisher", person) }}
110
+ }{% endset %}
111
+ {% set _ = nodes.push(entry) %}
112
+ {% endif %}
113
+ <script type="application/ld+json">
114
+ {
115
+ "@context": "https://schema.org",
116
+ "@graph": [
117
+ {{ nodes.join(",\n") | safe }}
118
+ ]
119
+ }
120
+ </script>
@@ -0,0 +1,32 @@
1
+ {#
2
+ One menu, drawn.
3
+
4
+ The CMS puts every menu the site stores on the context as `menus`, keyed by
5
+ the name it is stored under, each item already knowing whether it is the page
6
+ being looked at (TASK-107). This theme declares two of those names in its
7
+ `theme.json` — `primary` and `footer` — and draws each through this macro, so
8
+ the markup of a menu is written once:
9
+
10
+ {% import "partials/menu.njk" as nav %}
11
+ {{ nav.list(menus.footer, "Footer") }}
12
+
13
+ Nothing is printed for a menu with nothing in it: an area a site has not
14
+ filled in is an area with no nav element, not an empty list.
15
+
16
+ `label` is the `aria-label`, which is what tells a reader on a screen reader
17
+ which of a page's menus this one is. Two navs with no labels are two navs
18
+ called "navigation".
19
+
20
+ An item marked `me` carries `rel="me"`, which is how Mastodon and the rest of
21
+ the IndieWeb verify that the site and the profile it links belong to the same
22
+ person: the profile links back, and the pair is the proof.
23
+ #}
24
+ {% macro list(items, label) %}{% if items.length %}
25
+ <nav class="site-nav" aria-label="{{ label }}">
26
+ <ul class="hlist">
27
+ {% for item in items %}
28
+ <li><a href="{{ item.url | url }}"{% if item.me %} rel="me"{% endif %}{% if item.current %} class="is-current" aria-current="page"{% endif %}>{{ item.label }}</a></li>
29
+ {% endfor %}
30
+ </ul>
31
+ </nav>
32
+ {% endif %}{% endmacro %}
@@ -1,14 +1,20 @@
1
- {# Previous/next pager. Expects `pagination`. Renders nothing on a one-page listing. #}
1
+ {#
2
+ Previous/next pager. Expects `pagination`. Renders nothing on a one-page
3
+ listing.
4
+
5
+ Two arrows and two words, as the source design pages (decision-16).
6
+ `previous` is the page before this one, which on a listing newest-first is
7
+ the newer posts, and `next` the page after it. The arrows are
8
+ `aria-hidden`: a screen reader announcing "left arrow Previous" reads the
9
+ decoration twice.
10
+ #}
2
11
  {% if pagination.totalPages > 1 %}
3
12
  <nav class="pagination" aria-label="Pagination">
4
13
  {% if pagination.href.previous %}
5
- <a class="pagination-previous" rel="prev" href="{{ pagination.href.previous | url }}">Newer</a>
14
+ <a class="pagination-previous" rel="prev" href="{{ pagination.href.previous | url }}"><span aria-hidden="true">&larr;</span> Previous</a>
6
15
  {% endif %}
7
- <span class="pagination-position">
8
- Page {{ pagination.pageNumber + 1 }} of {{ pagination.totalPages }}
9
- </span>
10
16
  {% if pagination.href.next %}
11
- <a class="pagination-next" rel="next" href="{{ pagination.href.next | url }}">Older</a>
17
+ <a class="pagination-next" rel="next" href="{{ pagination.href.next | url }}">Next <span aria-hidden="true">&rarr;</span></a>
12
18
  {% endif %}
13
19
  </nav>
14
20
  {% endif %}
@@ -1,24 +1,57 @@
1
- {# A list of documents, newest first. Expects `posts`. #}
2
- {% import "partials/tags.njk" as taxonomy %}
1
+ {#
2
+ The feed a listing is made of: `h-feed` of `h-entry` items, as the source
3
+ design lists them (decision-16).
4
+
5
+ Expects `posts`. Each entry prints its title as a linked `p-name`, its
6
+ `summary` — the very line the feeds publish — as a `p-summary` cut to about
7
+ 280 characters, a Continue reading link, its publish date and the categories
8
+ it is filed under. Tags are deliberately not here: an entry's tags belong
9
+ under the entry, and a feed of twenty posts listing everyone's would be a
10
+ wall of links rather than a list of writing.
11
+
12
+ `feedHeading` is the heading level, which belongs to the layout rather than
13
+ to the list: a listing is a page of entries and heads each one at 2, and a
14
+ front page whose feed sits under a heading of its own sets 3 so the outline
15
+ never skips a level.
16
+ #}
17
+ {% import "partials/tags.njk" as taxonomy with context %}
18
+ {% set feedTitleTag = "h" + (feedHeading | default(2)) %}
3
19
  {% if posts.length %}
4
- <ol class="post-list">
20
+ <div class="feed h-feed">
5
21
  {% for post in posts %}
6
- <li class="post-list-item">
7
- <article class="post-summary">
8
- <h2 class="post-summary-title"><a href="{{ post.url | url }}">{{ post.title }}</a></h2>
9
- {% if post.date %}
10
- <p class="post-meta">
11
- <time datetime="{{ post.date | date("html") }}">{{ post.date | date }}</time>
12
- </p>
13
- {% endif %}
14
- {% if post.description %}
15
- <p class="post-summary-description">{{ post.description }}</p>
22
+ {% if not loop.first %}
23
+ <hr class="feed-separator">
24
+ {% endif %}
25
+ <article class="feed-item h-entry">
26
+ <div class="feed-content">
27
+ <{{ feedTitleTag }} class="feed-title p-name">
28
+ <a href="{{ post.url | url }}" class="u-url">{{ post.title }}</a>
29
+ </{{ feedTitleTag }}>
30
+ {% if post.summary %}
31
+ <div class="feed-excerpt p-summary">
32
+ {#- `truncate` cuts at the last space before the length and adds an
33
+ ellipsis, so a description short enough is printed whole and a long
34
+ one never breaks a word. -#}
35
+ <p>{{ post.summary | truncate(280) }}</p>
36
+ </div>
16
37
  {% endif %}
17
- {{ taxonomy.list(post.tags) }}
18
- </article>
19
- </li>
38
+ <p class="feed-more">
39
+ <a href="{{ post.url | url }}" aria-label="Continue reading: {{ post.title }}">Continue reading<span aria-hidden="true"> &rarr;</span></a>
40
+ </p>
41
+ <div class="feed-meta">
42
+ {% if post.date %}
43
+ <p>
44
+ <time class="feed-date dt-published" datetime="{{ post.date | date("iso") }}">
45
+ {{ post.date | date }}
46
+ </time>
47
+ </p>
48
+ {% endif %}
49
+ {{ taxonomy.categories(post.categories) }}
50
+ </div>
51
+ </div>
52
+ </article>
20
53
  {% endfor %}
21
- </ol>
54
+ </div>
22
55
  {% else %}
23
- <p class="empty">Nothing published yet.</p>
56
+ <p class="empty">No posts found.</p>
24
57
  {% endif %}
@@ -0,0 +1,22 @@
1
+ {#
2
+ The site's search box (TASK-22): a plain GET form, so a search is a URL a
3
+ reader can bookmark or share and the box needs no JavaScript.
4
+
5
+ `layouts/search.njk` is the only thing that includes it (TASK-105): the box
6
+ was in the footer of every page as well, and search is a menu item now —
7
+ a `Search | /search/` line like any other — so the page about searching is
8
+ where the box is.
9
+
10
+ Expects nothing. `query`, when the page has one, goes back in the box, so the
11
+ results page shows what was searched for. The label is read out rather than
12
+ shown, because the button beside the box already says what it is for, and it
13
+ wraps the field rather than naming an id, so the form can appear more than
14
+ once on a page without two elements sharing one.
15
+ #}
16
+ <form class="search-form" role="search" action="{{ "/search/" | url }}" method="get">
17
+ <label>
18
+ <span class="screen-reader-text">Search this site</span>
19
+ <input type="search" name="q" value="{{ query }}" placeholder="Search" maxlength="256" required>
20
+ </label>
21
+ <button type="submit">Search</button>
22
+ </form>
@@ -1,12 +1,33 @@
1
- {# Macros for taxonomy links. Import as `{% import "partials/tags.njk" as taxonomy %}`. #}
1
+ {# Macros for taxonomy links. Import as
2
+ `{% import "partials/tags.njk" as taxonomy with context %}` — the macros read
3
+ the archive bases off `site`, and an import without the context cannot see
4
+ it. #}
2
5
 
3
- {# A list of tag links. Renders nothing when the list is empty. #}
6
+ {# A list of tag links, under whatever base the site serves its archives at
7
+ (`site.tagBase`, `tag` by default). The same paragraph of `p-category`
8
+ links the categories are — under an entry the two read as one line of what
9
+ it is filed under, categories first — with `rel="tag"`, which is what a
10
+ parser reads a tag by. Renders nothing when the list is empty. #}
4
11
  {% macro list(tags) %}
5
12
  {% if tags and tags.length %}
6
- <ul class="tag-list">
13
+ <p class="post-categories">
7
14
  {% for tag in tags %}
8
- <li><a class="tag" href="{{ ("/tags/" + (tag | urlencode) + "/") | url }}">{{ tag }}</a></li>
15
+ <a href="{{ ("/" + (site.tagBase or "tag") + "/" + (tag | urlencode) + "/") | url }}" class="p-category" rel="tag">{{ tag }}</a>
9
16
  {% endfor %}
10
- </ul>
17
+ </p>
18
+ {% endif %}
19
+ {% endmacro %}
20
+
21
+ {# The same for categories, which are the second taxonomy and archive under
22
+ `site.categoryBase` (`category` by default). One paragraph of `p-category`
23
+ links, which is what the design prints in a feed item's meta line and under
24
+ an entry. Renders nothing when the list is empty. #}
25
+ {% macro categories(categories) %}
26
+ {% if categories and categories.length %}
27
+ <p class="post-categories">
28
+ {% for category in categories %}
29
+ <a href="{{ ("/" + (site.categoryBase or "category") + "/" + (category | urlencode) + "/") | url }}" class="p-category" rel="category">{{ category }}</a>
30
+ {% endfor %}
31
+ </p>
11
32
  {% endif %}
12
33
  {% endmacro %}