@geekity/cms 0.13.0 → 0.15.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 (184) hide show
  1. package/README.md +181 -57
  2. package/admin/pages/documents/editor.njk +82 -0
  3. package/admin/pages/media/library.njk +4 -3
  4. package/admin/pages/settings/general.njk +51 -6
  5. package/admin/static/admin.css +33 -0
  6. package/dist/admin/documents.d.ts +5 -0
  7. package/dist/admin/documents.d.ts.map +1 -1
  8. package/dist/admin/documents.js +63 -6
  9. package/dist/admin/documents.js.map +1 -1
  10. package/dist/admin/enclosure-field.d.ts +91 -0
  11. package/dist/admin/enclosure-field.d.ts.map +1 -0
  12. package/dist/admin/enclosure-field.js +282 -0
  13. package/dist/admin/enclosure-field.js.map +1 -0
  14. package/dist/admin/federation.js +2 -2
  15. package/dist/admin/federation.js.map +1 -1
  16. package/dist/admin/headers.d.ts +4 -1
  17. package/dist/admin/headers.d.ts.map +1 -1
  18. package/dist/admin/headers.js +9 -4
  19. package/dist/admin/headers.js.map +1 -1
  20. package/dist/admin/media.d.ts +7 -2
  21. package/dist/admin/media.d.ts.map +1 -1
  22. package/dist/admin/media.js +4 -2
  23. package/dist/admin/media.js.map +1 -1
  24. package/dist/admin/settings-general.d.ts.map +1 -1
  25. package/dist/admin/settings-general.js +63 -4
  26. package/dist/admin/settings-general.js.map +1 -1
  27. package/dist/admin/settings-page.d.ts.map +1 -1
  28. package/dist/admin/settings-page.js +1 -2
  29. package/dist/admin/settings-page.js.map +1 -1
  30. package/dist/admin/settings.d.ts +37 -9
  31. package/dist/admin/settings.d.ts.map +1 -1
  32. package/dist/admin/settings.js +93 -11
  33. package/dist/admin/settings.js.map +1 -1
  34. package/dist/admin/uploads.d.ts +7 -2
  35. package/dist/admin/uploads.d.ts.map +1 -1
  36. package/dist/admin/uploads.js +23 -5
  37. package/dist/admin/uploads.js.map +1 -1
  38. package/dist/config.d.ts +21 -3
  39. package/dist/config.d.ts.map +1 -1
  40. package/dist/config.js +11 -7
  41. package/dist/config.js.map +1 -1
  42. package/dist/content/enclosure.d.ts +69 -0
  43. package/dist/content/enclosure.d.ts.map +1 -0
  44. package/dist/content/enclosure.js +165 -0
  45. package/dist/content/enclosure.js.map +1 -0
  46. package/dist/content/index.d.ts +3 -1
  47. package/dist/content/index.d.ts.map +1 -1
  48. package/dist/content/index.js +1 -0
  49. package/dist/content/index.js.map +1 -1
  50. package/dist/content/media.d.ts +15 -2
  51. package/dist/content/media.d.ts.map +1 -1
  52. package/dist/content/media.js +92 -9
  53. package/dist/content/media.js.map +1 -1
  54. package/dist/content/pinned.d.ts +26 -0
  55. package/dist/content/pinned.d.ts.map +1 -0
  56. package/dist/content/pinned.js +42 -0
  57. package/dist/content/pinned.js.map +1 -0
  58. package/dist/content/store.d.ts +7 -0
  59. package/dist/content/store.d.ts.map +1 -1
  60. package/dist/content/store.js +20 -0
  61. package/dist/content/store.js.map +1 -1
  62. package/dist/env.d.ts +7 -0
  63. package/dist/env.d.ts.map +1 -1
  64. package/dist/federation/actor.d.ts +15 -0
  65. package/dist/federation/actor.d.ts.map +1 -1
  66. package/dist/federation/actor.js +94 -3
  67. package/dist/federation/actor.js.map +1 -1
  68. package/dist/federation/article.d.ts +13 -1
  69. package/dist/federation/article.d.ts.map +1 -1
  70. package/dist/federation/article.js +62 -7
  71. package/dist/federation/article.js.map +1 -1
  72. package/dist/federation/delivery.d.ts.map +1 -1
  73. package/dist/federation/delivery.js +36 -4
  74. package/dist/federation/delivery.js.map +1 -1
  75. package/dist/federation/federation.d.ts.map +1 -1
  76. package/dist/federation/federation.js +24 -2
  77. package/dist/federation/federation.js.map +1 -1
  78. package/dist/federation/mount.js +2 -2
  79. package/dist/federation/mount.js.map +1 -1
  80. package/dist/federation/paths.d.ts +30 -0
  81. package/dist/federation/paths.d.ts.map +1 -1
  82. package/dist/federation/paths.js +36 -0
  83. package/dist/federation/paths.js.map +1 -1
  84. package/dist/images/icons.d.ts +5 -0
  85. package/dist/images/icons.d.ts.map +1 -1
  86. package/dist/images/icons.js +13 -8
  87. package/dist/images/icons.js.map +1 -1
  88. package/dist/images/paths.d.ts +1 -1
  89. package/dist/images/paths.d.ts.map +1 -1
  90. package/dist/images/paths.js.map +1 -1
  91. package/dist/images/variants.d.ts +11 -0
  92. package/dist/images/variants.d.ts.map +1 -1
  93. package/dist/images/variants.js +21 -0
  94. package/dist/images/variants.js.map +1 -1
  95. package/dist/index.d.ts +5 -5
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +7 -3
  98. package/dist/index.js.map +1 -1
  99. package/dist/indieauth/identity.d.ts +3 -3
  100. package/dist/indieauth/identity.d.ts.map +1 -1
  101. package/dist/indieauth/identity.js +6 -7
  102. package/dist/indieauth/identity.js.map +1 -1
  103. package/dist/web/admin-bar.d.ts +3 -1
  104. package/dist/web/admin-bar.d.ts.map +1 -1
  105. package/dist/web/admin-bar.js +5 -1
  106. package/dist/web/admin-bar.js.map +1 -1
  107. package/dist/web/assets.d.ts +14 -0
  108. package/dist/web/assets.d.ts.map +1 -1
  109. package/dist/web/assets.js +56 -1
  110. package/dist/web/assets.js.map +1 -1
  111. package/dist/web/authors.d.ts +19 -0
  112. package/dist/web/authors.d.ts.map +1 -1
  113. package/dist/web/authors.js +25 -0
  114. package/dist/web/authors.js.map +1 -1
  115. package/dist/web/context.d.ts +26 -0
  116. package/dist/web/context.d.ts.map +1 -1
  117. package/dist/web/context.js +15 -0
  118. package/dist/web/context.js.map +1 -1
  119. package/dist/web/feed-atom.d.ts.map +1 -1
  120. package/dist/web/feed-atom.js +22 -1
  121. package/dist/web/feed-atom.js.map +1 -1
  122. package/dist/web/feed-item.d.ts +34 -6
  123. package/dist/web/feed-item.d.ts.map +1 -1
  124. package/dist/web/feed-item.js +31 -7
  125. package/dist/web/feed-item.js.map +1 -1
  126. package/dist/web/feed-json.d.ts +15 -2
  127. package/dist/web/feed-json.d.ts.map +1 -1
  128. package/dist/web/feed-json.js +17 -1
  129. package/dist/web/feed-json.js.map +1 -1
  130. package/dist/web/feed-rss.d.ts.map +1 -1
  131. package/dist/web/feed-rss.js +60 -3
  132. package/dist/web/feed-rss.js.map +1 -1
  133. package/dist/web/feed-source.d.ts +3 -0
  134. package/dist/web/feed-source.d.ts.map +1 -1
  135. package/dist/web/feed-source.js.map +1 -1
  136. package/dist/web/feed-xml.d.ts +7 -1
  137. package/dist/web/feed-xml.d.ts.map +1 -1
  138. package/dist/web/feed-xml.js +8 -2
  139. package/dist/web/feed-xml.js.map +1 -1
  140. package/dist/web/feeds.d.ts +1 -1
  141. package/dist/web/feeds.d.ts.map +1 -1
  142. package/dist/web/feeds.js +13 -2
  143. package/dist/web/feeds.js.map +1 -1
  144. package/dist/web/index.d.ts +5 -2
  145. package/dist/web/index.d.ts.map +1 -1
  146. package/dist/web/index.js +3 -1
  147. package/dist/web/index.js.map +1 -1
  148. package/dist/web/license.d.ts +94 -0
  149. package/dist/web/license.d.ts.map +1 -0
  150. package/dist/web/license.js +116 -0
  151. package/dist/web/license.js.map +1 -0
  152. package/dist/web/oembed.d.ts +104 -0
  153. package/dist/web/oembed.d.ts.map +1 -0
  154. package/dist/web/oembed.js +289 -0
  155. package/dist/web/oembed.js.map +1 -0
  156. package/dist/web/opensearch.d.ts +35 -0
  157. package/dist/web/opensearch.d.ts.map +1 -0
  158. package/dist/web/opensearch.js +65 -0
  159. package/dist/web/opensearch.js.map +1 -0
  160. package/dist/web/render.d.ts.map +1 -1
  161. package/dist/web/render.js +16 -8
  162. package/dist/web/render.js.map +1 -1
  163. package/dist/web/routes.d.ts.map +1 -1
  164. package/dist/web/routes.js +82 -6
  165. package/dist/web/routes.js.map +1 -1
  166. package/dist/web/share-image.d.ts +7 -7
  167. package/dist/web/share-image.d.ts.map +1 -1
  168. package/dist/web/share-image.js +8 -7
  169. package/dist/web/share-image.js.map +1 -1
  170. package/dist/web/templates.d.ts.map +1 -1
  171. package/dist/web/templates.js +5 -0
  172. package/dist/web/templates.js.map +1 -1
  173. package/package.json +2 -1
  174. package/templates/site/content/_data/site.json +0 -1
  175. package/themes/default/README.md +142 -48
  176. package/themes/default/layouts/base.njk +25 -6
  177. package/themes/default/layouts/front-page.njk +1 -0
  178. package/themes/default/layouts/home.njk +1 -0
  179. package/themes/default/layouts/post.njk +4 -0
  180. package/themes/default/partials/bio.njk +7 -0
  181. package/themes/default/partials/jsonld.njk +30 -7
  182. package/themes/default/partials/recording.njk +41 -0
  183. package/themes/default/src/style.css +16 -0
  184. package/themes/default/static/style.css +29 -0
@@ -6,8 +6,12 @@
6
6
  * with a picture of their own, so the picture a site shows the fediverse is a
7
7
  * user's, edited on the users screen beside the rest of their profile.
8
8
  */
9
+ import { iconSetting, siteIcons } from '../images/icons.js';
10
+ import { userForAuthor } from '../web/authors.js';
11
+ import { CREATIVE_COMMONS_LICENSES } from '../web/license.js';
12
+ import { listUsers } from './accounts.js';
9
13
  import { bodyField, settingsPagePath } from './settings-page.js';
10
- import { effectiveBaseUrl, SETTINGS_FIELDS } from './settings.js';
14
+ import { effectiveBaseUrl, readSiteJson, SETTINGS_FIELDS } from './settings.js';
11
15
  import { ADMIN_TEMPLATES } from './templates.js';
12
16
  /** The General settings page. */
13
17
  export const GENERAL_SETTINGS = {
@@ -15,15 +19,52 @@ export const GENERAL_SETTINGS = {
15
19
  label: 'General',
16
20
  path: settingsPagePath('general'),
17
21
  template: ADMIN_TEMPLATES.settingsGeneral,
18
- fields: ['title', 'tagline', 'author', 'soloAuthor', 'baseUrl', 'timezone', 'language', 'locale'],
22
+ fields: [
23
+ 'title',
24
+ 'tagline',
25
+ 'author',
26
+ 'baseUrl',
27
+ 'timezone',
28
+ 'language',
29
+ 'locale',
30
+ 'icon',
31
+ 'license',
32
+ 'licenseUrl',
33
+ 'licenseName',
34
+ ],
19
35
  // The base URL field shows the one in effect rather than the one the file
20
36
  // happens to hold: a site.json with no `url` at all would otherwise render an
21
37
  // empty field that the validator refuses the moment anything is saved.
22
- shown: (config, settings) => ({ ...settings, baseUrl: effectiveBaseUrl(config, settings) }),
23
- panels: (c, settings) => baseUrlPanel(c.var.config, settings),
38
+ //
39
+ // The author is shown as the user it resolves to, so a site.json written
40
+ // before the select, holding a display name, selects that user and the
41
+ // first save writes their username (TASK-192). A name nobody answers to
42
+ // selects Several authors.
43
+ shown: (config, settings) => ({
44
+ ...settings,
45
+ baseUrl: effectiveBaseUrl(config, settings),
46
+ author: siteAuthorUsername(config, settings.author),
47
+ icon: iconInEffect(config, settings) ?? '',
48
+ }),
49
+ panels: (c, settings) => ({
50
+ ...baseUrlPanel(c.var.config, settings),
51
+ ...iconPanel(c.var.config, settings),
52
+ licenseChoices: Object.entries(CREATIVE_COMMONS_LICENSES).map(([key, license]) => ({
53
+ key,
54
+ name: `${license.name}, ${license.title}`,
55
+ })),
56
+ authorChoices: listUsers(c.var.config.dataDir).map((user) => ({
57
+ username: user.username,
58
+ name: user.profile?.displayName ?? user.username,
59
+ })),
60
+ }),
24
61
  // A field the form rendered read-only is not submitted, so an overridden base
25
62
  // URL keeps the value it had rather than being cleared by a save.
63
+ //
64
+ // The author is whoever the submitted username is, and nobody when it is
65
+ // not a user, so the file only ever holds a username or no author at all.
26
66
  reads: ({ c, body, current }) => ({
67
+ author: siteAuthorUsername(c.var.config, bodyField(body[SETTINGS_FIELDS.author])),
27
68
  baseUrl: c.var.config.baseUrlSource === 'default'
28
69
  ? bodyField(body[SETTINGS_FIELDS.baseUrl])
29
70
  : current.baseUrl === ''
@@ -31,6 +72,24 @@ export const GENERAL_SETTINGS = {
31
72
  : current.baseUrl,
32
73
  }),
33
74
  };
75
+ /** The username a stored or submitted author names, or empty for several authors. */
76
+ function siteAuthorUsername(config, author) {
77
+ return userForAuthor(listUsers(config.dataDir), author)?.username ?? '';
78
+ }
79
+ function iconInEffect(config, settings) {
80
+ return iconSetting({ icon: settings.icon, avatar: readSiteJson(config.contentDir)['avatar'] });
81
+ }
82
+ function iconPanel(config, settings) {
83
+ const inEffect = iconInEffect(config, settings);
84
+ const preview = siteIcons(config, inEffect).find((icon) => icon.rel === 'apple-touch-icon');
85
+ return {
86
+ iconInEffect: inEffect ?? '',
87
+ iconPreview: preview?.href ?? '',
88
+ iconFromAvatar: settings.icon === '' && inEffect !== undefined,
89
+ iconUnderived: inEffect !== undefined && preview === undefined,
90
+ imageOptimization: config.imageOptimization,
91
+ };
92
+ }
34
93
  /** What the page says about the base URL: the one in effect, and why it is. */
35
94
  function baseUrlPanel(config, settings) {
36
95
  const overridden = config.baseUrlSource !== 'default';
@@ -1 +1 @@
1
- {"version":3,"file":"settings-general.js","sourceRoot":"","sources":["../../src/admin/settings-general.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAElE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,iCAAiC;AACjC,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC;IACjC,QAAQ,EAAE,eAAe,CAAC,eAAe;IACzC,MAAM,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC;IAEjG,0EAA0E;IAC1E,8EAA8E;IAC9E,uEAAuE;IACvE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;IAE3F,MAAM,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC;IAE7D,8EAA8E;IAC9E,kEAAkE;IAClE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAChC,OAAO,EACL,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS;YACtC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC1C,CAAC,CAAC,OAAO,CAAC,OAAO,KAAK,EAAE;gBACtB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO;gBACtB,CAAC,CAAC,OAAO,CAAC,OAAO;KACxB,CAAC;CACH,CAAC;AAEF,+EAA+E;AAC/E,SAAS,YAAY,CACnB,MAAyD,EACzD,QAAsB;IAEtB,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC;IAEtD,OAAO;QACL,eAAe,EAAE,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC;QACnD,iBAAiB,EAAE,UAAU;QAC7B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,WAAW,EAAE,UAAU;YACrB,CAAC,CAAC,MAAM,CAAC,aAAa,KAAK,aAAa;gBACtC,CAAC,CAAC,+FAA+F;gBACjG,CAAC,CAAC,oGAAoG;YACxG,CAAC,CAAC,yFAAyF;KAC9F,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"settings-general.js","sourceRoot":"","sources":["../../src/admin/settings-general.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"settings-page.d.ts","sourceRoot":"","sources":["../../src/admin/settings-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAWlD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE/E,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACnC,oFAAoF;IACpF,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,iEAAiE;AACjE,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,KAAK,YAAY,CAAC;IACzE,kFAAkF;IAClF,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,YAAY,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrF;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE;QAChB,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACvB,IAAI,EAAE,aAAa,CAAC;QACpB,OAAO,EAAE,YAAY,CAAC;KACvB,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,CACN,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EACtB,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,YAAY,KAChB,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC9B;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC5E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,oBAAoB,GAC5B,IAAI,CA4CN;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAC5B,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EACtB,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,YAAY,GACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB;AA2BD,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,CAMxE"}
1
+ {"version":3,"file":"settings-page.d.ts","sourceRoot":"","sources":["../../src/admin/settings-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAWlD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE/E,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACnC,oFAAoF;IACpF,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,iEAAiE;AACjE,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,KAAK,YAAY,CAAC;IACzE,kFAAkF;IAClF,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,YAAY,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrF;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE;QAChB,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACvB,IAAI,EAAE,aAAa,CAAC;QACpB,OAAO,EAAE,YAAY,CAAC;KACvB,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,CACN,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EACtB,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,YAAY,KAChB,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC9B;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC5E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,oBAAoB,GAC5B,IAAI,CA2CN;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAC5B,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EACtB,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,YAAY,GACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB;AA2BD,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,CAMxE"}
@@ -45,10 +45,9 @@ export function mountSettingsPage(app, page, options) {
45
45
  const body = await c.req.parseBody();
46
46
  const stored = readSiteSettings(c.var.config.contentDir);
47
47
  const submitted = pageForm(c, page, body, stored);
48
- // The themes directory goes in because one check needs the file system:
49
- // whether the name a page submitted is a theme that is actually there.
50
48
  const problems = settingsProblems(submitted, page.fields, {
51
49
  themesDir: c.var.config.themesDir,
50
+ contentDir: c.var.config.contentDir,
52
51
  });
53
52
  if (Object.keys(problems).length > 0) {
54
53
  c.status(400);
@@ -1 +1 @@
1
- {"version":3,"file":"settings-page.js","sourceRoot":"","sources":["../../src/admin/settings-page.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settings-page.js","sourceRoot":"","sources":["../../src/admin/settings-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAQH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AA2EvB;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,aAAa,IAAI,KAAK,EAAE,CAAC;AAC3E,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAqB,EACrB,IAAkB,EAClB,OAA6B;IAE7B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE3B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CACvB,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAC7F,CAAC;IAEF,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,IAAI,GAAkB,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAElD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;YACxD,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS;YACjC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU;SACpC,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,OAAO,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE;gBAC9B,GAAG,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC;gBAClC,IAAI,EAAE,SAAS;gBACf,QAAQ;gBACR,WAAW,EAAE,IAAI;aAClB,CAAC,CAAC;QACL,CAAC;QAED,uEAAuE;QACvE,2EAA2E;QAC3E,wEAAwE;QACxE,0EAA0E;QAC1E,2EAA2E;QAC3E,YAAY;QACZ,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;YACxC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU;YACnC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC;SACjF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACnF,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,cAAc,CAC5B,CAAsB,EACtB,IAAkB,EAClB,QAAsB;IAEtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAEvF,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,UAAU;QACnC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,IAAI;QACtB,aAAa,EAAE,WAAW,CAAC,IAAI,CAAC;QAChC,MAAM,EAAE,eAAe;QACvB,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC;QAC7B,QAAQ,EAAE,EAAE;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,0CAA0C;QAC1C,WAAW,EAAE,KAAK;QAClB,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,SAAS,WAAW,CAAC,IAAkB;IACrC,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC;AACpC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,QAAQ,CACf,CAAsB,EACtB,IAAkB,EAClB,IAAmB,EACnB,OAAqB;IAErB,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpF,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,MAAkC;IAC9D,MAAM,KAAK,GAAG,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC;IAC7C,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3B,OAAO,KAAK,KAAK,CAAC;QAChB,CAAC,CAAC,8BAA8B;QAChC,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC;AACpD,CAAC"}
@@ -2,6 +2,7 @@ import type { RetentionPolicy } from '../privacy/policy.ts';
2
2
  import type { ResolvedConfig } from '../config.ts';
3
3
  import type { MailProviderName } from '../mail/provider.ts';
4
4
  import type { UpdatePeriod } from '../web/feed-source.ts';
5
+ import type { CreativeCommonsKey } from '../web/license.ts';
5
6
  import type { AiCrawlerPolicy, RobotsPolicy } from '../web/robots.ts';
6
7
  import type { NavigationMenus } from '../web/navigation.ts';
7
8
  import type { TaxonomyBases, TaxonomyRedirect } from '../web/taxonomy.ts';
@@ -90,15 +91,18 @@ export interface SiteSettings {
90
91
  * settings screen refuses one without it, exactly as WordPress does.
91
92
  */
92
93
  postsPage: string;
93
- /** Site author, used as the feed author. May be empty. */
94
- author: string;
95
94
  /**
96
- * Whether the site is one person's blog (TASK-180). On, the homepage speaks
97
- * for the {@link SiteSettings.author}: it carries their bio card and their
98
- * `rel="me"` links, and it and their archive claim each other. Off, the
99
- * default, the homepage speaks for nobody.
95
+ * Who the site is: one user's username, or empty for a site with several
96
+ * authors (TASK-192). A username makes it that user's blog: the homepage
97
+ * carries their bio card and their `rel="me"` links, it and their archive
98
+ * claim each other, and the root is their IndieAuth identity (decision-23).
99
+ *
100
+ * A file written before the Site author select may hold a display name or a
101
+ * name nobody has. It is read as stored and resolved where it is used, by
102
+ * `userForAuthor`, so a display name still names its user and anything else
103
+ * names nobody; the General page writes the username at its next save.
100
104
  */
101
- soloAuthor: boolean;
105
+ author: string;
102
106
  /**
103
107
  * The theme the site renders through: the name of one directory under the
104
108
  * configured themes directory, or empty for the theme the package ships
@@ -111,6 +115,24 @@ export interface SiteSettings {
111
115
  * site, so a hand-edited file is a warning in the log rather than a 500.
112
116
  */
113
117
  theme: string;
118
+ /**
119
+ * The upload the site's icons are derived from, as a path such as
120
+ * `/uploads/2026/10/icon.png`, or empty for none. Read from and written
121
+ * to the `icon` key of `site.json` only.
122
+ */
123
+ icon: string;
124
+ /**
125
+ * What readers may do with the site's posts: empty for no
126
+ * license, which is all rights reserved, a Creative Commons key, or
127
+ * `custom` for the URL and name beside it. `site.json` writes a key, or a
128
+ * custom license's URL, under `license`, so the file says it the way a
129
+ * post's front matter does.
130
+ */
131
+ license: LicenseChoice;
132
+ /** A custom license's terms, as an absolute URL. Empty unless `license` is `custom`. */
133
+ licenseUrl: string;
134
+ /** A custom license's name. Empty unless `license` is `custom`. */
135
+ licenseName: string;
114
136
  /**
115
137
  * The first URL segment the tag archives live under, `tag` by default: one
116
138
  * URL-safe path segment, no slashes. WordPress's own base, so a site
@@ -316,6 +338,7 @@ export interface SiteSettings {
316
338
  }
317
339
  /** What a site says about one Content-Signal: yes, no, or nothing. */
318
340
  export type ContentSignalChoice = '' | 'yes' | 'no';
341
+ export type LicenseChoice = '' | CreativeCommonsKey | 'custom';
319
342
  /** What the settings say the robots file should carry. */
320
343
  export declare function robotsPolicyOf(settings: SiteSettings): RobotsPolicy;
321
344
  /**
@@ -354,8 +377,11 @@ export declare const SETTINGS_FIELDS: {
354
377
  readonly homepage: 'homepage';
355
378
  readonly postsPage: 'posts_page';
356
379
  readonly author: 'author';
357
- readonly soloAuthor: 'solo_author';
358
380
  readonly theme: 'theme';
381
+ readonly icon: 'icon';
382
+ readonly license: 'license';
383
+ readonly licenseUrl: 'license_url';
384
+ readonly licenseName: 'license_name';
359
385
  readonly tagBase: 'tag_base';
360
386
  readonly categoryBase: 'category_base';
361
387
  readonly comments: 'comments';
@@ -404,6 +430,7 @@ export type SettingsProblems = Partial<Record<SettingsField, string>>;
404
430
  * with the settings screen there to put it right.
405
431
  */
406
432
  export declare function readSiteSettings(contentDir: string): SiteSettings;
433
+ export declare function readSiteJson(contentDir: string): Record<string, unknown>;
407
434
  /**
408
435
  * `content/_data/site.json` as the settings it names, defaults filled in.
409
436
  *
@@ -423,7 +450,7 @@ export declare function taxonomyBasesFromSettings(settings: SiteSettings): Taxon
423
450
  *
424
451
  * Every key the settings model is written whether or not it has a value, so
425
452
  * the file's shape is stable and an Eleventy template may reference
426
- * `site.author` without guarding it. Every other key the file already had is
453
+ * `site.tagline` without guarding it. Every other key the file already had is
427
454
  * kept: a site may put anything in there and reach it from its templates, and
428
455
  * the settings form is not going to be the thing that throws it away.
429
456
  *
@@ -506,6 +533,7 @@ export declare function effectiveBaseUrl(config: Pick<ResolvedConfig, 'baseUrl'
506
533
  export interface SettingsContext {
507
534
  /** Where the site's themes are: {@link ResolvedConfig.themesDir}. */
508
535
  themesDir?: string | undefined;
536
+ contentDir?: string | undefined;
509
537
  }
510
538
  /** Every field of the settings, in the order the form fields name them. */
511
539
  export declare const SETTINGS_FIELD_NAMES: readonly SettingsField[];
@@ -1 +1 @@
1
- {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/admin/settings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/admin/settings.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AASnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAI1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAI5D,OAAO,KAAK,EACV,eAAe,EAGf,YAAY,EACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAM5D,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG1E,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,YAAY,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,aAAa,oBAA6B,CAAC;AAExD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,QAA8C,CAAC;AAEhF;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,QAAsC,CAAC;AAEjE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;;;OASG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;OAUG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;;;;OAUG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,OAAO,EAAE,aAAa,CAAC;IACvB,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,yBAAyB,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,wBAAwB,EAAE,MAAM,CAAC;IACjC,6EAA6E;IAC7E,2BAA2B,EAAE,MAAM,CAAC;IACpC;;;;;OAKG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB;;;;;;;;OAQG;IACH,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,gBAAgB,EAAE,YAAY,CAAC;IAC/B,8FAA8F;IAC9F,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,UAAU,EAAE,eAAe,CAAC;IAC5B;;;OAGG;IACH,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,gEAAgE;IAChE,oBAAoB,EAAE,mBAAmB,CAAC;IAC1C,6DAA6D;IAC7D,oBAAoB,EAAE,mBAAmB,CAAC;IAC1C;;;;OAIG;IACH,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,YAAY,EAAE,gBAAgB,CAAC;IAC/B,uEAAuE;IACvE,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,0EAA0E;IAC1E,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B;;;;;;;;;;;OAWG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;;OAUG;IACH,KAAK,EAAE,eAAe,CAAC;IACvB;;;;;;;;OAQG;IACH,iBAAiB,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAChD;AAED,sEAAsE;AACtE,MAAM,MAAM,mBAAmB,GAAG,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC;AAEpD,MAAM,MAAM,aAAa,GAAG,EAAE,GAAG,kBAAkB,GAAG,QAAQ,CAAC;AAiB/D,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY,CAUnE;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CACjC,MAAM,YAAY,EAClB,mBAAmB,GAAG,OAAO,GAAG,aAAa,CAC9C,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,CACnC,IAAI,CAAC,YAAY,EAAE,mBAAmB,GAAG,OAAO,GAAG,aAAa,CAAC,CAClE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,YAkDnC,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,eAAe;oBACnB,OAAO;sBACL,SAAS;sBACT,UAAU;uBACT,UAAU;uBACV,UAAU;qBACZ,QAAQ;2BACF,gBAAgB;uBACpB,UAAU;wBACT,YAAY;qBACf,QAAQ;oBACT,OAAO;mBACR,MAAM;sBACH,SAAS;yBACN,aAAa;0BACZ,cAAc;sBAClB,UAAU;2BACL,eAAe;uBACnB,UAAU;qCACI,2BAA2B;wCACxB,8BAA8B;uCAC/B,6BAA6B;0CAC1B,gCAAgC;8BAC5C,kBAAkB;iCACf,qBAAqB;2BAC3B,eAAe;+BACX,oBAAoB;kCACjB,uBAAuB;yBAChC,aAAa;kCACJ,uBAAuB;mCACtB,yBAAyB;mCACzB,yBAAyB;0BAClC,cAAc;sBAClB,UAAU;uBACT,WAAW;2BACP,eAAe;2BACf,gBAAgB;8BACb,mBAAmB;0BACvB,eAAe;2BACd,eAAe;+BACX,mBAAmB;6BACrB,iBAAiB;gCACd,oBAAoB;qBAC/B,QAAQ;mCACM,uBAAuB;CACG,CAAC;AAEnD,iEAAiE;AACjE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;AAEzD,4EAA4E;AAC5E,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;AAEtE;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CAEjE;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAExE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,CAoIhF;AAED,8EAA8E;AAC9E,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,YAAY,GAAG,aAAa,CAE/E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,YAAY,EACtB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA0FzB;AAED,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvD;AAOD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;CACxB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,YAAY,CAAC;CACjD,GAAG,OAAO,CAAC,YAAY,CAAC,CAUxB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiB9F;AA8CD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,eAAe,CAAC,EACzD,QAAQ,EAAE,YAAY,GACrB,MAAM,CAGR;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAuRD,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,EAAE,SAAS,aAAa,EAErC,CAAC;AAErB;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,SAAS,aAAa,EAAyB,EACvD,OAAO,GAAE,eAAoB,GAC5B,gBAAgB,CASlB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,GAAE,eAAoB,GAAG,YAAY,CAsEhG;AAgBD,2CAA2C;AAC3C,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY,CA+CrE;AA0DD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAOjD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAcrE;AAwGD,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,eAAe,CAMzE"}
@@ -2,11 +2,14 @@ import { statSync } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { DEFAULT_COMMENTS_CLOSE_AFTER_DAYS } from '../comments/policy.js';
4
4
  import { readFileIfPresentSync, updateFileAtomically, writeFileAtomicallySync, } from '../files/atomic.js';
5
+ import { parseIconSetting } from '../images/icons.js';
6
+ import { sourceFile } from '../images/paths.js';
5
7
  import { MAIL_PROVIDERS } from '../mail/provider.js';
6
8
  import { SITE_DATA_FILE } from '../web/context.js';
7
9
  import { DEFAULT_FEED_CADENCE, isUpdatePeriod, UPDATE_PERIODS } from '../web/feed-source.js';
8
10
  import { DEFAULT_NOTIFY_SERVER } from '../web/feeds.js';
9
11
  import { generateIndexNowKey, isIndexNowKey } from '../web/indexnow.js';
12
+ import { classifyLicense, isCreativeCommonsKey, isLicenseUrl, NO_LICENSE } from '../web/license.js';
10
13
  import { canonicalLocale } from '../web/locale.js';
11
14
  import { DEFAULT_MENU_NAME, menuItemsFromText, menusOf } from '../web/navigation.js';
12
15
  import { AI_CRAWLER_POLICIES, robotsRuleLines, robotsRuleProblem } from '../web/robots.js';
@@ -82,8 +85,11 @@ export const DEFAULT_SITE_SETTINGS = {
82
85
  homepage: '',
83
86
  postsPage: '',
84
87
  author: '',
85
- soloAuthor: false,
86
88
  theme: '',
89
+ icon: '',
90
+ license: '',
91
+ licenseUrl: '',
92
+ licenseName: '',
87
93
  tagBase: DEFAULT_TAXONOMY_BASES.tag,
88
94
  categoryBase: DEFAULT_TAXONOMY_BASES.category,
89
95
  comments: true,
@@ -131,8 +137,11 @@ export const SETTINGS_FIELDS = {
131
137
  homepage: 'homepage',
132
138
  postsPage: 'posts_page',
133
139
  author: 'author',
134
- soloAuthor: 'solo_author',
135
140
  theme: 'theme',
141
+ icon: 'icon',
142
+ license: 'license',
143
+ licenseUrl: 'license_url',
144
+ licenseName: 'license_name',
136
145
  tagBase: 'tag_base',
137
146
  categoryBase: 'category_base',
138
147
  comments: 'comments',
@@ -177,7 +186,10 @@ export const SETTINGS_FIELDS = {
177
186
  * with the settings screen there to put it right.
178
187
  */
179
188
  export function readSiteSettings(contentDir) {
180
- return settingsFromSiteJson(readSiteJsonSync(siteDataPath(contentDir)));
189
+ return settingsFromSiteJson(readSiteJson(contentDir));
190
+ }
191
+ export function readSiteJson(contentDir) {
192
+ return readSiteJsonSync(siteDataPath(contentDir));
181
193
  }
182
194
  /**
183
195
  * `content/_data/site.json` as the settings it names, defaults filled in.
@@ -208,6 +220,8 @@ export function settingsFromSiteJson(file) {
208
220
  // Absent is the ordinary state of this one: a site on the packaged theme
209
221
  // has never written the key, so anything but a string is that site.
210
222
  ...(typeof file['theme'] === 'string' ? { theme: file['theme'] } : {}),
223
+ ...(typeof file['icon'] === 'string' ? { icon: file['icon'].trim() } : {}),
224
+ ...licenseFromSiteJson(file),
211
225
  // Absent is the ordinary state of these two: a site showing its latest
212
226
  // posts writes neither key, so anything but a string is read as none.
213
227
  ...(typeof file['homepage'] === 'string' ? { homepage: file['homepage'] } : {}),
@@ -256,7 +270,6 @@ export function settingsFromSiteJson(file) {
256
270
  robotsRules: robotsRuleLines(file['robotsRules'].filter((entry) => typeof entry === 'string')),
257
271
  }
258
272
  : {}),
259
- ...(typeof file['soloAuthor'] === 'boolean' ? { soloAuthor: file['soloAuthor'] } : {}),
260
273
  ...(typeof file['llmsTxt'] === 'boolean' ? { llmsTxt: file['llmsTxt'] } : {}),
261
274
  ...(typeof file['indexNow'] === 'boolean' ? { indexNow: file['indexNow'] } : {}),
262
275
  // A key IndexNow would refuse is no key: the site then has none to serve
@@ -326,7 +339,7 @@ export function taxonomyBasesFromSettings(settings) {
326
339
  *
327
340
  * Every key the settings model is written whether or not it has a value, so
328
341
  * the file's shape is stable and an Eleventy template may reference
329
- * `site.author` without guarding it. Every other key the file already had is
342
+ * `site.tagline` without guarding it. Every other key the file already had is
330
343
  * kept: a site may put anything in there and reach it from its templates, and
331
344
  * the settings form is not going to be the thing that throws it away.
332
345
  *
@@ -341,8 +354,6 @@ export function siteJsonFor(settings, existing = {}) {
341
354
  title: settings.title,
342
355
  tagline: settings.tagline,
343
356
  url: settings.baseUrl,
344
- author: settings.author,
345
- soloAuthor: settings.soloAuthor,
346
357
  postsPerPage: settings.postsPerPage,
347
358
  timezone: settings.timezone,
348
359
  language: settings.language,
@@ -389,12 +400,16 @@ export function siteJsonFor(settings, existing = {}) {
389
400
  // nothing reads it from is the kind of thing somebody edits for an hour
390
401
  // before noticing.
391
402
  delete file['navigation'];
403
+ // The Solo author switch, which the author setting now says on its own
404
+ // (TASK-192): a username is a solo author site and no author is not.
405
+ delete file['soloAuthor'];
392
406
  // `theme` is absent for a site on the packaged theme, on the same rule and
393
407
  // for the same reason as the two above: running what the package ships is
394
408
  // not a choice a site should have to write down, and a `theme` of `""` would
395
409
  // be a name no directory has. `locale` too: a site whose dates follow its
396
410
  // language has made no choice to write down.
397
- for (const key of ['homepage', 'postsPage', 'theme', 'locale']) {
411
+ // `author` too: a site with several authors names nobody (TASK-192).
412
+ for (const key of ['homepage', 'postsPage', 'theme', 'locale', 'author', 'icon']) {
398
413
  if (settings[key] === '')
399
414
  delete file[key];
400
415
  else
@@ -408,6 +423,15 @@ export function siteJsonFor(settings, existing = {}) {
408
423
  file['wordpressActivityPub'] = true;
409
424
  else
410
425
  delete file['wordpressActivityPub'];
426
+ delete file['licenseName'];
427
+ if (settings.license === '')
428
+ delete file['license'];
429
+ else if (settings.license !== 'custom')
430
+ file['license'] = settings.license;
431
+ else {
432
+ file['license'] = settings.licenseUrl;
433
+ file['licenseName'] = settings.licenseName;
434
+ }
411
435
  // A site that has never turned IndexNow on has no key to write down.
412
436
  if (settings.indexNowKey !== '')
413
437
  file['indexNowKey'] = settings.indexNowKey;
@@ -612,6 +636,14 @@ const FIELD_CHECKS = {
612
636
  const read = readTheme(path.join(context.themesDir, name));
613
637
  return read.ok ? undefined : `There is no theme called "${name}": ${read.reason}`;
614
638
  },
639
+ icon: (form, context) => iconProblem(form.icon.trim(), context),
640
+ license: (form) => isLicenseChoice(form.license.trim()) ? undefined : 'Choose a license from the list.',
641
+ licenseUrl: (form) => form.license.trim() === 'custom' && !isLicenseUrl(form.licenseUrl.trim())
642
+ ? 'A custom license needs the URL of its terms, starting http:// or https://.'
643
+ : undefined,
644
+ licenseName: (form) => form.license.trim() === 'custom' && form.licenseName.trim() === ''
645
+ ? 'A custom license needs a name for the footer to show.'
646
+ : undefined,
615
647
  comments: () => undefined,
616
648
  // The empty string is refused rather than read as zero, which is what
617
649
  // `Number('')` would make it: a cleared field is a mistake, and "never close
@@ -647,7 +679,6 @@ const FIELD_CHECKS = {
647
679
  contentSignalAiInput: (form) => contentSignalProblem(form.contentSignalAiInput),
648
680
  contentSignalAiTrain: (form) => contentSignalProblem(form.contentSignalAiTrain),
649
681
  robotsRules: (form) => robotsRuleProblem([form.robotsRules]),
650
- soloAuthor: () => undefined,
651
682
  llmsTxt: () => undefined,
652
683
  indexNow: () => undefined,
653
684
  mailProvider: (form) => MAIL_PROVIDERS.includes(form.mailProvider)
@@ -703,6 +734,42 @@ const FIELD_CHECKS = {
703
734
  tagBase: (form) => taxonomyBaseProblems({ tag: form.tagBase, category: form.categoryBase }).tag,
704
735
  categoryBase: (form) => taxonomyBaseProblems({ tag: form.tagBase, category: form.categoryBase }).category,
705
736
  };
737
+ function isLicenseChoice(value) {
738
+ return value === '' || value === 'custom' || isCreativeCommonsKey(value);
739
+ }
740
+ function licenseFromSiteJson(file) {
741
+ const said = classifyLicense(file['license']);
742
+ if (said === undefined || said === NO_LICENSE)
743
+ return {};
744
+ if ('key' in said)
745
+ return { license: said.key, licenseUrl: '', licenseName: '' };
746
+ const name = typeof file['licenseName'] === 'string' ? file['licenseName'].trim() : '';
747
+ return { license: 'custom', licenseUrl: said.url, licenseName: name };
748
+ }
749
+ function iconProblem(icon, context) {
750
+ if (icon === '')
751
+ return undefined;
752
+ const parsed = parseIconSetting(icon);
753
+ if ('problem' in parsed) {
754
+ return parsed.problem === 'not-an-upload'
755
+ ? 'The site icon has to be a file in the media library, a path such as /uploads/2026/10/icon.png.'
756
+ : 'The site icon has to be an image: PNG, JPEG, GIF, WebP, AVIF, TIFF or SVG.';
757
+ }
758
+ if (context.contentDir === undefined)
759
+ return undefined;
760
+ const file = sourceFile({ contentDir: context.contentDir }, parsed.source);
761
+ return file !== undefined && isFile(file)
762
+ ? undefined
763
+ : `There is no upload at ${icon}. Upload the picture on the Media screen first.`;
764
+ }
765
+ function isFile(file) {
766
+ try {
767
+ return statSync(file).isFile();
768
+ }
769
+ catch {
770
+ return false;
771
+ }
772
+ }
706
773
  /** What is wrong with a submitted Content-Signal choice. */
707
774
  function contentSignalProblem(value) {
708
775
  return isContentSignalChoice(value) ? undefined : 'A content signal is yes, no, or not said.';
@@ -753,8 +820,9 @@ export function settingsFromForm(form, carried = {}) {
753
820
  // the listing's own page with it rather than leave it stranded.
754
821
  postsPage: form.homepage.trim() === '' ? '' : form.postsPage.trim(),
755
822
  author: form.author.trim(),
756
- soloAuthor: form.soloAuthor !== '',
757
823
  theme: form.theme.trim(),
824
+ icon: form.icon.trim(),
825
+ ...licenseFromForm(form),
758
826
  tagBase: form.tagBase.trim(),
759
827
  categoryBase: form.categoryBase.trim(),
760
828
  // A checkbox submits nothing at all when it is clear, which is what the
@@ -805,6 +873,17 @@ export function settingsFromForm(form, carried = {}) {
805
873
  wordpressActivityPub: form.wordpressActivityPub !== '',
806
874
  };
807
875
  }
876
+ function licenseFromForm(form) {
877
+ const license = form.license.trim();
878
+ if (license === 'custom') {
879
+ return { license, licenseUrl: form.licenseUrl.trim(), licenseName: form.licenseName.trim() };
880
+ }
881
+ return {
882
+ license: isLicenseChoice(license) ? license : '',
883
+ licenseUrl: '',
884
+ licenseName: '',
885
+ };
886
+ }
808
887
  /** The settings as the form shows them. */
809
888
  export function formFromSettings(settings) {
810
889
  return {
@@ -818,8 +897,11 @@ export function formFromSettings(settings) {
818
897
  homepage: settings.homepage,
819
898
  postsPage: settings.postsPage,
820
899
  author: settings.author,
821
- soloAuthor: settings.soloAuthor ? '1' : '',
822
900
  theme: settings.theme,
901
+ icon: settings.icon,
902
+ license: settings.license,
903
+ licenseUrl: settings.licenseUrl,
904
+ licenseName: settings.licenseName,
823
905
  tagBase: settings.tagBase,
824
906
  categoryBase: settings.categoryBase,
825
907
  comments: settings.comments ? '1' : '',