@geekity/cms 0.4.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.
- package/README.md +234 -108
- package/admin/pages/documents/editor.njk +0 -13
- package/admin/pages/{settings/federation.njk → federation/settings.njk} +7 -5
- package/admin/pages/navigation/menus.njk +129 -0
- package/admin/pages/settings/reading.njk +2 -10
- package/admin/pages/tools/content-index.njk +89 -0
- package/admin/pages/users/list.njk +5 -2
- package/admin/static/admin.css +60 -0
- package/dist/access-log.d.ts +44 -0
- package/dist/access-log.d.ts.map +1 -0
- package/dist/access-log.js +71 -0
- package/dist/access-log.js.map +1 -0
- package/dist/admin/documents.d.ts +3 -13
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +2 -34
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/federation.d.ts +10 -0
- package/dist/admin/federation.d.ts.map +1 -1
- package/dist/admin/federation.js +10 -0
- package/dist/admin/federation.js.map +1 -1
- package/dist/admin/index.d.ts +3 -3
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +2 -2
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/menu.d.ts.map +1 -1
- package/dist/admin/menu.js +19 -2
- package/dist/admin/menu.js.map +1 -1
- package/dist/admin/navigation.d.ts +155 -0
- package/dist/admin/navigation.d.ts.map +1 -0
- package/dist/admin/navigation.js +292 -0
- package/dist/admin/navigation.js.map +1 -0
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +9 -0
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/session.d.ts +17 -3
- package/dist/admin/session.d.ts.map +1 -1
- package/dist/admin/session.js +19 -5
- package/dist/admin/session.js.map +1 -1
- package/dist/admin/settings-federation.d.ts +10 -1
- package/dist/admin/settings-federation.d.ts.map +1 -1
- package/dist/admin/settings-federation.js +26 -6
- package/dist/admin/settings-federation.js.map +1 -1
- package/dist/admin/settings-page.d.ts +26 -9
- package/dist/admin/settings-page.d.ts.map +1 -1
- package/dist/admin/settings-page.js +18 -12
- package/dist/admin/settings-page.js.map +1 -1
- package/dist/admin/settings-pages.d.ts +14 -3
- package/dist/admin/settings-pages.d.ts.map +1 -1
- package/dist/admin/settings-pages.js +15 -5
- package/dist/admin/settings-pages.js.map +1 -1
- package/dist/admin/settings-reading.d.ts +5 -4
- package/dist/admin/settings-reading.d.ts.map +1 -1
- package/dist/admin/settings-reading.js +6 -5
- package/dist/admin/settings-reading.js.map +1 -1
- package/dist/admin/settings.d.ts +29 -15
- package/dist/admin/settings.d.ts.map +1 -1
- package/dist/admin/settings.js +28 -78
- package/dist/admin/settings.js.map +1 -1
- package/dist/admin/templates.d.ts +3 -1
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +3 -1
- package/dist/admin/templates.js.map +1 -1
- package/dist/admin/tools.d.ts +111 -0
- package/dist/admin/tools.d.ts.map +1 -0
- package/dist/admin/tools.js +182 -0
- package/dist/admin/tools.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -1
- package/dist/cli.js.map +1 -1
- package/dist/comments/form.d.ts +48 -0
- package/dist/comments/form.d.ts.map +1 -1
- package/dist/comments/form.js +15 -0
- package/dist/comments/form.js.map +1 -1
- package/dist/comments/index.d.ts +4 -3
- package/dist/comments/index.d.ts.map +1 -1
- package/dist/comments/index.js +2 -1
- package/dist/comments/index.js.map +1 -1
- package/dist/comments/routes.d.ts +3 -1
- package/dist/comments/routes.d.ts.map +1 -1
- package/dist/comments/routes.js +46 -11
- package/dist/comments/routes.js.map +1 -1
- package/dist/comments/submission.d.ts +37 -3
- package/dist/comments/submission.d.ts.map +1 -1
- package/dist/comments/submission.js +59 -20
- package/dist/comments/submission.js.map +1 -1
- package/dist/comments/viewer.d.ts +21 -0
- package/dist/comments/viewer.d.ts.map +1 -0
- package/dist/comments/viewer.js +45 -0
- package/dist/comments/viewer.js.map +1 -0
- package/dist/config.d.ts +35 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -1
- package/dist/content/store.d.ts +18 -0
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +18 -0
- package/dist/content/store.js.map +1 -1
- package/dist/env.d.ts +12 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/federation/mount.d.ts +4 -0
- package/dist/federation/mount.d.ts.map +1 -1
- package/dist/federation/mount.js +44 -12
- package/dist/federation/mount.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -4
- package/dist/index.js.map +1 -1
- package/dist/web/index.d.ts +3 -3
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +1 -1
- package/dist/web/index.js.map +1 -1
- package/dist/web/navigation.d.ts +158 -36
- package/dist/web/navigation.d.ts.map +1 -1
- package/dist/web/navigation.js +250 -60
- package/dist/web/navigation.js.map +1 -1
- package/dist/web/negotiate.d.ts +22 -0
- package/dist/web/negotiate.d.ts.map +1 -1
- package/dist/web/negotiate.js +25 -10
- package/dist/web/negotiate.js.map +1 -1
- package/dist/web/render.d.ts +16 -10
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +21 -14
- package/dist/web/render.js.map +1 -1
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +11 -2
- package/dist/web/routes.js.map +1 -1
- package/dist/web/themes.d.ts +21 -0
- package/dist/web/themes.d.ts.map +1 -1
- package/dist/web/themes.js +37 -0
- package/dist/web/themes.js.map +1 -1
- package/package.json +1 -1
- package/templates/site/content/_data/site.json +7 -0
- package/templates/site/content/pages/about.md +7 -0
- package/themes/default/README.md +200 -80
- package/themes/default/layouts/author.njk +3 -4
- package/themes/default/layouts/base.njk +38 -49
- package/themes/default/layouts/front-page.njk +1 -2
- package/themes/default/partials/bio.njk +15 -21
- package/themes/default/partials/comment-form.njk +31 -3
- package/themes/default/partials/menu.njk +32 -0
- package/themes/default/partials/search-form.njk +5 -0
- package/themes/default/static/style.css +31 -8
- package/themes/default/theme.json +5 -1
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* What every settings page is made of.
|
|
3
3
|
*
|
|
4
4
|
* The settings used to be one form with twelve headings. They are six pages
|
|
5
|
-
* now — General, Reading, Permalinks, Discussion
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* about how a page is wired lives
|
|
5
|
+
* now — General, Reading, Permalinks, Discussion and Email under Settings, and
|
|
6
|
+
* Federation under its own section (TASK-109) — and this is what they have in
|
|
7
|
+
* common: a description of the page, and the one pair of routes that turns it
|
|
8
|
+
* into a screen you can read and a form you can save. A page module describes
|
|
9
|
+
* itself and writes its own template; nothing about how a page is wired lives
|
|
10
|
+
* in the page.
|
|
10
11
|
*
|
|
11
12
|
* The save is the part worth reading twice. A page writes only the fields it
|
|
12
13
|
* carries, and it writes them onto `content/_data/site.json` as re-read inside
|
|
@@ -28,13 +29,29 @@ export interface MountSettingsOptions {
|
|
|
28
29
|
}
|
|
29
30
|
/** A submitted form, before anything has been read out of it. */
|
|
30
31
|
export type SubmittedBody = Record<string, unknown>;
|
|
31
|
-
/** One page
|
|
32
|
+
/** One settings page, wherever the menu files it. */
|
|
32
33
|
export interface SettingsPage {
|
|
33
|
-
/** The child of
|
|
34
|
+
/** The child of its section it is, as `src/admin/menu.ts` names it. */
|
|
34
35
|
child: string;
|
|
35
|
-
/** What the menu calls it
|
|
36
|
+
/** What the menu calls it. */
|
|
36
37
|
label: string;
|
|
37
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* The section it is under, when it is not Settings.
|
|
40
|
+
*
|
|
41
|
+
* Five of the six are Settings' own children. Federation's is a child of
|
|
42
|
+
* the Federation section instead (TASK-109): what a settings page is has
|
|
43
|
+
* nothing to do with where the menu files it, so the page says where it is
|
|
44
|
+
* and the rest of this module carries on as before.
|
|
45
|
+
*/
|
|
46
|
+
section?: string;
|
|
47
|
+
/**
|
|
48
|
+
* What the page is headed and what a save says it saved, when the menu's
|
|
49
|
+
* label is not that on its own. Only Federation has one: under its own
|
|
50
|
+
* section it is listed as Settings, and "Settings settings saved" is not a
|
|
51
|
+
* sentence.
|
|
52
|
+
*/
|
|
53
|
+
heading?: string;
|
|
54
|
+
/** Where it is: {@link settingsPagePath}, or its own section's path. */
|
|
38
55
|
path: string;
|
|
39
56
|
/** The template it renders, from {@link ADMIN_TEMPLATES}. */
|
|
40
57
|
template: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-page.d.ts","sourceRoot":"","sources":["../../src/admin/settings-page.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* What every settings page is made of.
|
|
3
3
|
*
|
|
4
4
|
* The settings used to be one form with twelve headings. They are six pages
|
|
5
|
-
* now — General, Reading, Permalinks, Discussion
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* about how a page is wired lives
|
|
5
|
+
* now — General, Reading, Permalinks, Discussion and Email under Settings, and
|
|
6
|
+
* Federation under its own section (TASK-109) — and this is what they have in
|
|
7
|
+
* common: a description of the page, and the one pair of routes that turns it
|
|
8
|
+
* into a screen you can read and a form you can save. A page module describes
|
|
9
|
+
* itself and writes its own template; nothing about how a page is wired lives
|
|
10
|
+
* in the page.
|
|
10
11
|
*
|
|
11
12
|
* The save is the part worth reading twice. A page writes only the fields it
|
|
12
13
|
* carries, and it writes them onto `content/_data/site.json` as re-read inside
|
|
@@ -60,15 +61,16 @@ export function mountSettingsPage(app, page, options) {
|
|
|
60
61
|
}
|
|
61
62
|
// The change is applied to the settings re-read inside the write, so a
|
|
62
63
|
// field this page does not carry is whatever the file says now rather than
|
|
63
|
-
// whatever it said when the form was drawn. The
|
|
64
|
-
// come from there for the same reason: a save of the title must not
|
|
65
|
-
// term somebody renamed while this form
|
|
64
|
+
// whatever it said when the form was drawn. The archive renames and the
|
|
65
|
+
// menus come from there for the same reason: a save of the title must not
|
|
66
|
+
// undo a term somebody renamed, or a menu somebody edited, while this form
|
|
67
|
+
// was open.
|
|
66
68
|
const settings = await updateSiteSettings({
|
|
67
69
|
contentDir: c.var.config.contentDir,
|
|
68
|
-
change: (current) => settingsFromForm(pageForm(c, page, body, current), current
|
|
70
|
+
change: (current) => settingsFromForm(pageForm(c, page, body, current), current),
|
|
69
71
|
});
|
|
70
72
|
const note = page.saved === undefined ? '' : await page.saved(c, stored, settings);
|
|
71
|
-
flash(c, 'notice', `${page
|
|
73
|
+
flash(c, 'notice', `${pageHeading(page)} settings saved.${note}`);
|
|
72
74
|
return c.redirect(page.path, 303);
|
|
73
75
|
});
|
|
74
76
|
page.endpoints?.(app, options);
|
|
@@ -77,10 +79,10 @@ export function mountSettingsPage(app, page, options) {
|
|
|
77
79
|
export function settingsScreen(c, page, settings) {
|
|
78
80
|
const shown = page.shown === undefined ? settings : page.shown(c.var.config, settings);
|
|
79
81
|
return {
|
|
80
|
-
section: 'settings',
|
|
82
|
+
section: page.section ?? 'settings',
|
|
81
83
|
child: page.child,
|
|
82
84
|
settingsUrl: page.path,
|
|
83
|
-
settingsLabel: page
|
|
85
|
+
settingsLabel: pageHeading(page),
|
|
84
86
|
fields: SETTINGS_FIELDS,
|
|
85
87
|
form: formFromSettings(shown),
|
|
86
88
|
problems: {},
|
|
@@ -91,6 +93,10 @@ export function settingsScreen(c, page, settings) {
|
|
|
91
93
|
...page.panels?.(c, settings),
|
|
92
94
|
};
|
|
93
95
|
}
|
|
96
|
+
/** What the page is headed, and what a save of it says it saved. */
|
|
97
|
+
function pageHeading(page) {
|
|
98
|
+
return page.heading ?? page.label;
|
|
99
|
+
}
|
|
94
100
|
/**
|
|
95
101
|
* The whole form as this page's save means it: what is stored, with the
|
|
96
102
|
* page's own fields taken from what was submitted.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-page.js","sourceRoot":"","sources":["../../src/admin/settings-page.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"settings-page.js","sourceRoot":"","sources":["../../src/admin/settings-page.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Every settings page there is, and which of them Settings lists.
|
|
3
3
|
*
|
|
4
4
|
* This module is the list. What a page is made of is `settings-page.ts`, what
|
|
5
5
|
* each page carries is its own module, and what a setting means is
|
|
@@ -8,12 +8,23 @@
|
|
|
8
8
|
*
|
|
9
9
|
* The order is the order the menu shows them, General first: the Settings
|
|
10
10
|
* heading lands on its first child, and General is `/admin/settings` itself.
|
|
11
|
+
*
|
|
12
|
+
* Five of the six are Settings' own children. Federation's is a settings page
|
|
13
|
+
* in every other respect — the same fields, the same save, the same refusals —
|
|
14
|
+
* but the menu files it under the Federation section, beside the followers it
|
|
15
|
+
* is about (TASK-109), so it is in {@link ALL_SETTINGS_PAGES} and not in
|
|
16
|
+
* {@link SETTINGS_PAGES}. Both lists matter: {@link ALL_SETTINGS_PAGES} is
|
|
17
|
+
* what the mount registers and what "every setting is on exactly one page" is
|
|
18
|
+
* checked against, and {@link SETTINGS_PAGES} is what the Settings menu has to
|
|
19
|
+
* agree with.
|
|
11
20
|
*/
|
|
12
21
|
import type { Hono } from 'hono';
|
|
13
22
|
import type { GeekityEnv } from '../env.ts';
|
|
14
23
|
import type { MountSettingsOptions, SettingsPage } from './settings-page.ts';
|
|
15
|
-
/**
|
|
24
|
+
/** The settings pages the Settings menu lists, in the order it lists them. */
|
|
16
25
|
export declare const SETTINGS_PAGES: readonly SettingsPage[];
|
|
17
|
-
/**
|
|
26
|
+
/** Every settings page, wherever the menu files it. */
|
|
27
|
+
export declare const ALL_SETTINGS_PAGES: readonly SettingsPage[];
|
|
28
|
+
/** Register every settings page, including the one filed under Federation. */
|
|
18
29
|
export declare function mountSettings(app: Hono<GeekityEnv>, options: MountSettingsOptions): void;
|
|
19
30
|
//# sourceMappingURL=settings-pages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-pages.d.ts","sourceRoot":"","sources":["../../src/admin/settings-pages.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"settings-pages.d.ts","sourceRoot":"","sources":["../../src/admin/settings-pages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM5C,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAI7E,8EAA8E;AAC9E,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAMjD,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,kBAAkB,EAAE,SAAS,YAAY,EAA6C,CAAC;AAEpG,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAExF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Every settings page there is, and which of them Settings lists.
|
|
3
3
|
*
|
|
4
4
|
* This module is the list. What a page is made of is `settings-page.ts`, what
|
|
5
5
|
* each page carries is its own module, and what a setting means is
|
|
@@ -8,6 +8,15 @@
|
|
|
8
8
|
*
|
|
9
9
|
* The order is the order the menu shows them, General first: the Settings
|
|
10
10
|
* heading lands on its first child, and General is `/admin/settings` itself.
|
|
11
|
+
*
|
|
12
|
+
* Five of the six are Settings' own children. Federation's is a settings page
|
|
13
|
+
* in every other respect — the same fields, the same save, the same refusals —
|
|
14
|
+
* but the menu files it under the Federation section, beside the followers it
|
|
15
|
+
* is about (TASK-109), so it is in {@link ALL_SETTINGS_PAGES} and not in
|
|
16
|
+
* {@link SETTINGS_PAGES}. Both lists matter: {@link ALL_SETTINGS_PAGES} is
|
|
17
|
+
* what the mount registers and what "every setting is on exactly one page" is
|
|
18
|
+
* checked against, and {@link SETTINGS_PAGES} is what the Settings menu has to
|
|
19
|
+
* agree with.
|
|
11
20
|
*/
|
|
12
21
|
import { DISCUSSION_SETTINGS } from './settings-discussion.js';
|
|
13
22
|
import { EMAIL_SETTINGS } from './settings-email.js';
|
|
@@ -16,18 +25,19 @@ import { GENERAL_SETTINGS } from './settings-general.js';
|
|
|
16
25
|
import { mountSettingsPage } from './settings-page.js';
|
|
17
26
|
import { PERMALINKS_SETTINGS } from './settings-permalinks.js';
|
|
18
27
|
import { READING_SETTINGS } from './settings-reading.js';
|
|
19
|
-
/**
|
|
28
|
+
/** The settings pages the Settings menu lists, in the order it lists them. */
|
|
20
29
|
export const SETTINGS_PAGES = [
|
|
21
30
|
GENERAL_SETTINGS,
|
|
22
31
|
READING_SETTINGS,
|
|
23
32
|
PERMALINKS_SETTINGS,
|
|
24
33
|
DISCUSSION_SETTINGS,
|
|
25
34
|
EMAIL_SETTINGS,
|
|
26
|
-
FEDERATION_SETTINGS,
|
|
27
35
|
];
|
|
28
|
-
/**
|
|
36
|
+
/** Every settings page, wherever the menu files it. */
|
|
37
|
+
export const ALL_SETTINGS_PAGES = [...SETTINGS_PAGES, FEDERATION_SETTINGS];
|
|
38
|
+
/** Register every settings page, including the one filed under Federation. */
|
|
29
39
|
export function mountSettings(app, options) {
|
|
30
|
-
for (const page of
|
|
40
|
+
for (const page of ALL_SETTINGS_PAGES)
|
|
31
41
|
mountSettingsPage(app, page, options);
|
|
32
42
|
}
|
|
33
43
|
//# sourceMappingURL=settings-pages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-pages.js","sourceRoot":"","sources":["../../src/admin/settings-pages.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"settings-pages.js","sourceRoot":"","sources":["../../src/admin/settings-pages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD,gBAAgB;IAChB,gBAAgB;IAChB,mBAAmB;IACnB,mBAAmB;IACnB,cAAc;CACf,CAAC;AAEF,uDAAuD;AACvD,MAAM,CAAC,MAAM,kBAAkB,GAA4B,CAAC,GAAG,cAAc,EAAE,mBAAmB,CAAC,CAAC;AAEpG,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,GAAqB,EAAE,OAA6B;IAChF,KAAK,MAAM,IAAI,IAAI,kBAAkB;QAAE,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC/E,CAAC"}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* Reading: what a visitor is shown, and who is told when it changes.
|
|
3
3
|
*
|
|
4
4
|
* WordPress's Reading page is what the homepage displays and how many posts a
|
|
5
|
-
* listing holds; this one adds the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* listing holds; this one adds the notify server, which is how a subscriber
|
|
6
|
+
* hears that a feed moved on without waiting for their next poll. The site
|
|
7
|
+
* menu was here too until TASK-108 gave the menus a screen of their own: which
|
|
8
|
+
* menus there are to edit comes from the active theme, which is not something
|
|
9
|
+
* a page of fields can be.
|
|
9
10
|
*/
|
|
10
11
|
import type { Context } from 'hono';
|
|
11
12
|
import type { GeekityEnv } from '../env.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-reading.d.ts","sourceRoot":"","sources":["../../src/admin/settings-reading.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"settings-reading.d.ts","sourceRoot":"","sources":["../../src/admin/settings-reading.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAGpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACzB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,EAAE,CAQhE;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,EAAE,YAkB9B,CAAC"}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* Reading: what a visitor is shown, and who is told when it changes.
|
|
3
3
|
*
|
|
4
4
|
* WordPress's Reading page is what the homepage displays and how many posts a
|
|
5
|
-
* listing holds; this one adds the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* listing holds; this one adds the notify server, which is how a subscriber
|
|
6
|
+
* hears that a feed moved on without waiting for their next poll. The site
|
|
7
|
+
* menu was here too until TASK-108 gave the menus a screen of their own: which
|
|
8
|
+
* menus there are to edit comes from the active theme, which is not something
|
|
9
|
+
* a page of fields can be.
|
|
9
10
|
*/
|
|
10
11
|
import { isPublicDocument } from '../web/documents.js';
|
|
11
12
|
import { settingsPagePath } from './settings-page.js';
|
|
@@ -34,7 +35,7 @@ export const READING_SETTINGS = {
|
|
|
34
35
|
label: 'Reading',
|
|
35
36
|
path: settingsPagePath('reading'),
|
|
36
37
|
template: ADMIN_TEMPLATES.settingsReading,
|
|
37
|
-
fields: ['homepage', 'postsPage', 'postsPerPage', '
|
|
38
|
+
fields: ['homepage', 'postsPage', 'postsPerPage', 'notifyServer'],
|
|
38
39
|
panels: (c, settings) => {
|
|
39
40
|
const choices = pageChoices(c);
|
|
40
41
|
const missing = (slug) => slug !== '' && !choices.some((choice) => choice.slug === slug);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-reading.js","sourceRoot":"","sources":["../../src/admin/settings-reading.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"settings-reading.js","sourceRoot":"","sources":["../../src/admin/settings-reading.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAUjD,kEAAkE;AAClE,MAAM,UAAU,WAAW,CAAC,CAAsB;IAChD,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IAE9B,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK;SACf,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;SACzE,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;SACrD,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;SACnE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;GASG;AACH,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,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,CAAC;IAEjE,MAAM,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE;QACtB,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,CAAC,IAAY,EAAW,EAAE,CACxC,IAAI,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAEjE,OAAO;YACL,WAAW,EAAE,OAAO;YACpB,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC3C,gBAAgB,EAAE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;SAC9C,CAAC;IACJ,CAAC;CACF,CAAC"}
|
package/dist/admin/settings.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ResolvedConfig } from '../config.ts';
|
|
2
2
|
import type { MailProviderName } from '../mail/provider.ts';
|
|
3
|
-
import type {
|
|
3
|
+
import type { NavigationMenus } from '../web/navigation.ts';
|
|
4
4
|
import type { TaxonomyBases, TaxonomyRedirect } from '../web/taxonomy.ts';
|
|
5
5
|
import type { AdminStore } from './store.ts';
|
|
6
6
|
/**
|
|
@@ -199,14 +199,17 @@ export interface SiteSettings {
|
|
|
199
199
|
*/
|
|
200
200
|
wordpressActivityPub: boolean;
|
|
201
201
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
202
|
+
* Every menu the site holds, by name: `site.json`'s `menus`, each an ordered
|
|
203
|
+
* list of items a theme renders wherever it declares an area of that name
|
|
204
|
+
* and an Eleventy build reads out of the same file.
|
|
204
205
|
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
206
|
+
* Not a field of the settings form, and deliberately: a menu is content a
|
|
207
|
+
* site arranges rather than a switch it sets, and which menus there are to
|
|
208
|
+
* edit comes from the active theme. The Navigation screen is what writes
|
|
209
|
+
* them (TASK-108); a settings page carries them through a save untouched,
|
|
210
|
+
* the way it carries the archive renames.
|
|
208
211
|
*/
|
|
209
|
-
|
|
212
|
+
menus: NavigationMenus;
|
|
210
213
|
/**
|
|
211
214
|
* The taxonomy archives that have moved: one `{ taxonomy, from, to }` per
|
|
212
215
|
* term the taxonomy screens renamed or merged away, so the URL it used to
|
|
@@ -221,10 +224,20 @@ export interface SiteSettings {
|
|
|
221
224
|
/**
|
|
222
225
|
* The settings the form on the settings screen carries.
|
|
223
226
|
*
|
|
224
|
-
* Every setting but the
|
|
225
|
-
* write
|
|
227
|
+
* Every setting but the two that a screen of its own writes: the recorded
|
|
228
|
+
* archive renames, which the taxonomy screens write, and the menus, which the
|
|
229
|
+
* Navigation screen writes. See {@link CarriedSettings}.
|
|
226
230
|
*/
|
|
227
|
-
export type SettingsField = Exclude<keyof SiteSettings, 'taxonomyRedirects'>;
|
|
231
|
+
export type SettingsField = Exclude<keyof SiteSettings, 'taxonomyRedirects' | 'menus'>;
|
|
232
|
+
/**
|
|
233
|
+
* The settings no settings form carries, as a save takes them from the file.
|
|
234
|
+
*
|
|
235
|
+
* Both are records of what another screen did rather than preferences typed
|
|
236
|
+
* into a box, so a save of the title reads them off `site.json` as it stands
|
|
237
|
+
* inside the write rather than off the form — which is what makes a menu
|
|
238
|
+
* edited while the settings page was open survive the save.
|
|
239
|
+
*/
|
|
240
|
+
export type CarriedSettings = Partial<Pick<SiteSettings, 'taxonomyRedirects' | 'menus'>>;
|
|
228
241
|
/**
|
|
229
242
|
* What a site is worth before anybody has said otherwise.
|
|
230
243
|
*
|
|
@@ -258,7 +271,6 @@ export declare const SETTINGS_FIELDS: {
|
|
|
258
271
|
readonly contactEmail: 'contact_email';
|
|
259
272
|
readonly relays: 'relays';
|
|
260
273
|
readonly wordpressActivityPub: 'wordpress_activitypub';
|
|
261
|
-
readonly navigation: 'navigation';
|
|
262
274
|
};
|
|
263
275
|
/** A submitted settings form, before it is known to be valid. */
|
|
264
276
|
export type SettingsForm = Record<SettingsField, string>;
|
|
@@ -396,11 +408,13 @@ export declare function settingsProblems(form: SettingsForm, fields?: readonly S
|
|
|
396
408
|
* A validated form as settings. Only call it on a form
|
|
397
409
|
* {@link settingsProblems} found nothing wrong with.
|
|
398
410
|
*
|
|
399
|
-
* The
|
|
400
|
-
* because they are not on it: the taxonomy screens write
|
|
401
|
-
* the other fields
|
|
411
|
+
* The archive renames and the menus are carried in rather than read off the
|
|
412
|
+
* form, because they are not on it: the taxonomy screens write the one and the
|
|
413
|
+
* Navigation screen the other, and a save of the fields that are on the form
|
|
414
|
+
* keeps whatever is stored. Passing the settings read inside the write is all
|
|
415
|
+
* a caller has to do, since they hold both.
|
|
402
416
|
*/
|
|
403
|
-
export declare function settingsFromForm(form: SettingsForm,
|
|
417
|
+
export declare function settingsFromForm(form: SettingsForm, carried?: CarriedSettings): SiteSettings;
|
|
404
418
|
/** The settings as the form shows them. */
|
|
405
419
|
export declare function formFromSettings(settings: SiteSettings): SettingsForm;
|
|
406
420
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/admin/settings.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAOnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAI5D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/admin/settings.ts"],"names":[],"mappings":"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"}
|
package/dist/admin/settings.js
CHANGED
|
@@ -5,7 +5,7 @@ import { readFileIfPresentSync, updateFileAtomically, writeFileAtomicallySync, }
|
|
|
5
5
|
import { MAIL_PROVIDERS } from '../mail/provider.js';
|
|
6
6
|
import { SITE_DATA_FILE } from '../web/context.js';
|
|
7
7
|
import { DEFAULT_NOTIFY_SERVER } from '../web/feeds.js';
|
|
8
|
-
import {
|
|
8
|
+
import { DEFAULT_MENU_NAME, menuItemsFromText, menusOf } from '../web/navigation.js';
|
|
9
9
|
import { DEFAULT_TAXONOMY_BASES, taxonomyBaseProblems, taxonomyRedirectsOf, } from '../web/taxonomy.js';
|
|
10
10
|
import { readTheme, themeNameProblem } from '../web/themes.js';
|
|
11
11
|
import { ADMIN_PREFIX } from './session.js';
|
|
@@ -67,7 +67,7 @@ export const DEFAULT_SITE_SETTINGS = {
|
|
|
67
67
|
contactEmail: '',
|
|
68
68
|
relays: [],
|
|
69
69
|
wordpressActivityPub: false,
|
|
70
|
-
|
|
70
|
+
menus: {},
|
|
71
71
|
taxonomyRedirects: [],
|
|
72
72
|
};
|
|
73
73
|
/** The form field each setting is submitted under. */
|
|
@@ -96,7 +96,6 @@ export const SETTINGS_FIELDS = {
|
|
|
96
96
|
contactEmail: 'contact_email',
|
|
97
97
|
relays: 'relays',
|
|
98
98
|
wordpressActivityPub: 'wordpress_activitypub',
|
|
99
|
-
navigation: 'navigation',
|
|
100
99
|
};
|
|
101
100
|
/**
|
|
102
101
|
* A site's settings, as its `content/_data/site.json` says them right now.
|
|
@@ -188,9 +187,10 @@ export function settingsFromSiteJson(file) {
|
|
|
188
187
|
...(typeof file['wordpressActivityPub'] === 'boolean'
|
|
189
188
|
? { wordpressActivityPub: file['wordpressActivityPub'] }
|
|
190
189
|
: {}),
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
190
|
+
// Every menu the site holds, whether or not the theme in use renders it.
|
|
191
|
+
// The `navigation` key the one menu used to live under is not read at all:
|
|
192
|
+
// menus were renamed rather than migrated (TASK-107).
|
|
193
|
+
...(file['menus'] === undefined ? {} : { menus: menusOf(file['menus']) }),
|
|
194
194
|
// The renames a site has published redirects for: facts about its URLs
|
|
195
195
|
// rather than preferences, which is why a content directory restored on
|
|
196
196
|
// its own keeps answering the archive URLs it used to.
|
|
@@ -242,9 +242,21 @@ export function siteJsonFor(settings, existing = {}) {
|
|
|
242
242
|
mailReplyTo: settings.mailReplyTo,
|
|
243
243
|
contactEmail: settings.contactEmail,
|
|
244
244
|
relays: [...settings.relays],
|
|
245
|
-
|
|
245
|
+
// Every menu the site holds, written whole. A settings page never has
|
|
246
|
+
// them off its own form — it reads them out of the file inside the write
|
|
247
|
+
// and hands them straight back — so the one screen that models them is the
|
|
248
|
+
// one that edits them (TASK-108).
|
|
249
|
+
menus: Object.fromEntries(Object.entries(settings.menus).map(([name, items]) => [
|
|
250
|
+
name,
|
|
251
|
+
items.map((item) => ({ ...item })),
|
|
252
|
+
])),
|
|
246
253
|
taxonomyRedirects: settings.taxonomyRedirects.map((entry) => ({ ...entry })),
|
|
247
254
|
};
|
|
255
|
+
// The key the menu lived under before menus had names. A rename leaves
|
|
256
|
+
// nothing behind: a `navigation` array sitting beside `menus` in a file
|
|
257
|
+
// nothing reads it from is the kind of thing somebody edits for an hour
|
|
258
|
+
// before noticing.
|
|
259
|
+
delete file['navigation'];
|
|
248
260
|
// `theme` is absent for a site on the packaged theme, on the same rule and
|
|
249
261
|
// for the same reason as the two above: running what the package ships is
|
|
250
262
|
// not a choice a site should have to write down, and a `theme` of `""` would
|
|
@@ -353,7 +365,7 @@ function settingsFromRows(rows) {
|
|
|
353
365
|
? {}
|
|
354
366
|
: { postsPerPage: Number(stored['postsPerPage']) }),
|
|
355
367
|
relays: relayList(stored['relays'] ?? ''),
|
|
356
|
-
|
|
368
|
+
menus: { [DEFAULT_MENU_NAME]: menuItemsFromText(stored['navigation'] ?? '') },
|
|
357
369
|
taxonomyRedirects: redirectList(stored['taxonomyRedirects'] ?? ''),
|
|
358
370
|
});
|
|
359
371
|
}
|
|
@@ -504,16 +516,6 @@ const FIELD_CHECKS = {
|
|
|
504
516
|
// A checkbox is either submitted or not, so there is nothing a person could
|
|
505
517
|
// get wrong about it.
|
|
506
518
|
wordpressActivityPub: () => undefined,
|
|
507
|
-
// A menu is checked line by line like the relays, and for the same reason:
|
|
508
|
-
// one message on a textarea is more use pointing at the line to fix than
|
|
509
|
-
// counting how many are wrong.
|
|
510
|
-
navigation: (form) => {
|
|
511
|
-
const bad = navigationLines(form.navigation).find((line) => navigationItem(line) === undefined);
|
|
512
|
-
return bad === undefined
|
|
513
|
-
? undefined
|
|
514
|
-
: `A menu item is "Label | URL", one per line, where the URL is a path ` +
|
|
515
|
-
`like /about/ or an absolute http:// or https:// URL. "${bad}" is not one.`;
|
|
516
|
-
},
|
|
517
519
|
// The two archive bases are checked as a pair, because two of the rules —
|
|
518
520
|
// that they differ, and that neither takes a path the site already answers
|
|
519
521
|
// on — are about the pair rather than either one. They are on one page for
|
|
@@ -544,13 +546,16 @@ export function settingsProblems(form, fields = SETTINGS_FIELD_NAMES, context =
|
|
|
544
546
|
* A validated form as settings. Only call it on a form
|
|
545
547
|
* {@link settingsProblems} found nothing wrong with.
|
|
546
548
|
*
|
|
547
|
-
* The
|
|
548
|
-
* because they are not on it: the taxonomy screens write
|
|
549
|
-
* the other fields
|
|
549
|
+
* The archive renames and the menus are carried in rather than read off the
|
|
550
|
+
* form, because they are not on it: the taxonomy screens write the one and the
|
|
551
|
+
* Navigation screen the other, and a save of the fields that are on the form
|
|
552
|
+
* keeps whatever is stored. Passing the settings read inside the write is all
|
|
553
|
+
* a caller has to do, since they hold both.
|
|
550
554
|
*/
|
|
551
|
-
export function settingsFromForm(form,
|
|
555
|
+
export function settingsFromForm(form, carried = {}) {
|
|
552
556
|
return {
|
|
553
|
-
taxonomyRedirects,
|
|
557
|
+
taxonomyRedirects: carried.taxonomyRedirects ?? DEFAULT_SITE_SETTINGS.taxonomyRedirects,
|
|
558
|
+
menus: carried.menus ?? DEFAULT_SITE_SETTINGS.menus,
|
|
554
559
|
title: form.title.trim(),
|
|
555
560
|
tagline: form.tagline.trim(),
|
|
556
561
|
baseUrl: normalizeBaseUrl(form.baseUrl) ?? '',
|
|
@@ -582,7 +587,6 @@ export function settingsFromForm(form, taxonomyRedirects = DEFAULT_SITE_SETTINGS
|
|
|
582
587
|
contactEmail: form.contactEmail.trim(),
|
|
583
588
|
relays: relayList(form.relays),
|
|
584
589
|
wordpressActivityPub: form.wordpressActivityPub !== '',
|
|
585
|
-
navigation: navigationList(form.navigation),
|
|
586
590
|
};
|
|
587
591
|
}
|
|
588
592
|
/** The settings as the form shows them. */
|
|
@@ -612,7 +616,6 @@ export function formFromSettings(settings) {
|
|
|
612
616
|
contactEmail: settings.contactEmail,
|
|
613
617
|
relays: settings.relays.join('\n'),
|
|
614
618
|
wordpressActivityPub: settings.wordpressActivityPub ? '1' : '',
|
|
615
|
-
navigation: navigationText(settings.navigation),
|
|
616
619
|
};
|
|
617
620
|
}
|
|
618
621
|
/**
|
|
@@ -756,57 +759,4 @@ function parseSiteJson(source) {
|
|
|
756
759
|
? parsed
|
|
757
760
|
: {};
|
|
758
761
|
}
|
|
759
|
-
/**
|
|
760
|
-
* The non-empty lines of the navigation textarea, trimmed.
|
|
761
|
-
*
|
|
762
|
-
* Blank lines are not an error, exactly as they are not in the relay list: a
|
|
763
|
-
* pasted menu leaves them, and a blank line asks for nothing.
|
|
764
|
-
*/
|
|
765
|
-
function navigationLines(value) {
|
|
766
|
-
return value
|
|
767
|
-
.split('\n')
|
|
768
|
-
.map((line) => line.trim())
|
|
769
|
-
.filter((line) => line !== '');
|
|
770
|
-
}
|
|
771
|
-
/**
|
|
772
|
-
* One `Label | URL` line as a menu item, or `undefined` when it is not one.
|
|
773
|
-
*
|
|
774
|
-
* The split is at the first bar, so a URL holding one — a query string, say —
|
|
775
|
-
* survives and a label cannot hold one. The URL is either a site-root path or
|
|
776
|
-
* an absolute http(s) URL: a bare `about/` would be resolved against whatever
|
|
777
|
-
* page it was printed on, which is never what a menu means.
|
|
778
|
-
*/
|
|
779
|
-
function navigationItem(line) {
|
|
780
|
-
const bar = line.indexOf('|');
|
|
781
|
-
if (bar === -1)
|
|
782
|
-
return undefined;
|
|
783
|
-
const label = line.slice(0, bar).trim();
|
|
784
|
-
const url = line.slice(bar + 1).trim();
|
|
785
|
-
if (label === '' || url === '')
|
|
786
|
-
return undefined;
|
|
787
|
-
if (url.startsWith('/'))
|
|
788
|
-
return { label, url };
|
|
789
|
-
return normalizeRelayInbox(url) === undefined ? undefined : { label, url };
|
|
790
|
-
}
|
|
791
|
-
/**
|
|
792
|
-
* A navigation textarea as the ordered items it names.
|
|
793
|
-
*
|
|
794
|
-
* Exported nowhere: the same parsing turns the stored setting and the
|
|
795
|
-
* submitted form into one list, and `site.json` is read by
|
|
796
|
-
* {@link navigationItemsOf} instead, because the file holds objects rather
|
|
797
|
-
* than lines.
|
|
798
|
-
*/
|
|
799
|
-
function navigationList(value) {
|
|
800
|
-
const items = [];
|
|
801
|
-
for (const line of navigationLines(value)) {
|
|
802
|
-
const item = navigationItem(line);
|
|
803
|
-
if (item !== undefined)
|
|
804
|
-
items.push(item);
|
|
805
|
-
}
|
|
806
|
-
return items;
|
|
807
|
-
}
|
|
808
|
-
/** The items as the textarea shows them, and as the settings table holds them. */
|
|
809
|
-
function navigationText(items) {
|
|
810
|
-
return items.map((item) => `${item.label} | ${item.url}`).join('\n');
|
|
811
|
-
}
|
|
812
762
|
//# sourceMappingURL=settings.js.map
|