@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.
- package/README.md +2217 -214
- package/admin/components/fields.njk +165 -0
- package/admin/layouts/base.njk +1 -1
- package/admin/layouts/settings-page.njk +26 -0
- package/admin/layouts/shell.njk +17 -3
- package/admin/pages/account/forgot.njk +47 -0
- package/admin/pages/account/login.njk +26 -0
- package/admin/pages/account/reset.njk +38 -0
- package/admin/pages/account/setup.njk +28 -0
- package/admin/pages/appearance/themes.njk +69 -0
- package/admin/pages/comments/all.njk +133 -0
- package/admin/{layouts/dashboard.njk → pages/dashboard/home.njk} +8 -15
- package/admin/{layouts/document-conflict.njk → pages/documents/conflict.njk} +1 -0
- package/admin/{layouts/document-editor.njk → pages/documents/editor.njk} +75 -59
- package/admin/{layouts/document-list.njk → pages/documents/list.njk} +19 -2
- package/admin/pages/documents/taxonomy.njk +95 -0
- package/admin/pages/federation/followers.njk +238 -0
- package/admin/pages/federation/settings.njk +77 -0
- package/admin/pages/media/library.njk +160 -0
- package/admin/pages/messages/all.njk +110 -0
- package/admin/pages/navigation/menus.njk +129 -0
- package/admin/{layouts → pages}/placeholder.njk +5 -1
- package/admin/pages/settings/discussion.njk +99 -0
- package/admin/pages/settings/email.njk +203 -0
- package/admin/pages/settings/general.njk +29 -0
- package/admin/pages/settings/permalinks.njk +50 -0
- package/admin/pages/settings/reading.njk +64 -0
- package/admin/pages/tools/content-index.njk +89 -0
- package/admin/pages/users/edit.njk +239 -0
- package/admin/pages/users/list.njk +51 -0
- package/admin/pages/users/new.njk +41 -0
- package/admin/static/admin.css +558 -3
- package/admin/static/copy.js +52 -0
- package/admin/static/editor.js +16 -16
- package/admin/static/slug.js +61 -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/accounts.d.ts +413 -0
- package/dist/admin/accounts.d.ts.map +1 -0
- package/dist/admin/accounts.js +680 -0
- package/dist/admin/accounts.js.map +1 -0
- package/dist/admin/appearance.d.ts +80 -0
- package/dist/admin/appearance.d.ts.map +1 -0
- package/dist/admin/appearance.js +136 -0
- package/dist/admin/appearance.js.map +1 -0
- package/dist/admin/comments.d.ts +90 -0
- package/dist/admin/comments.d.ts.map +1 -0
- package/dist/admin/comments.js +244 -0
- package/dist/admin/comments.js.map +1 -0
- package/dist/admin/credentials.d.ts +26 -2
- package/dist/admin/credentials.d.ts.map +1 -1
- package/dist/admin/credentials.js +35 -2
- package/dist/admin/credentials.js.map +1 -1
- package/dist/admin/documents.d.ts +117 -10
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +328 -41
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/federation.d.ts +161 -50
- package/dist/admin/federation.d.ts.map +1 -1
- package/dist/admin/federation.js +235 -93
- package/dist/admin/federation.js.map +1 -1
- package/dist/admin/formatting.d.ts +20 -0
- package/dist/admin/formatting.d.ts.map +1 -0
- package/dist/admin/formatting.js +72 -0
- package/dist/admin/formatting.js.map +1 -0
- package/dist/admin/headers.d.ts +65 -0
- package/dist/admin/headers.d.ts.map +1 -0
- package/dist/admin/headers.js +104 -0
- package/dist/admin/headers.js.map +1 -0
- package/dist/admin/index.d.ts +38 -12
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +25 -7
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/media.d.ts +168 -0
- package/dist/admin/media.d.ts.map +1 -0
- package/dist/admin/media.js +295 -0
- package/dist/admin/media.js.map +1 -0
- package/dist/admin/menu.d.ts +79 -0
- package/dist/admin/menu.d.ts.map +1 -0
- package/dist/admin/menu.js +143 -0
- package/dist/admin/menu.js.map +1 -0
- package/dist/admin/messages.d.ts +80 -0
- package/dist/admin/messages.d.ts.map +1 -0
- package/dist/admin/messages.js +152 -0
- package/dist/admin/messages.js.map +1 -0
- 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/preview.d.ts.map +1 -1
- package/dist/admin/preview.js +31 -7
- package/dist/admin/preview.js.map +1 -1
- package/dist/admin/recovery.d.ts +92 -0
- package/dist/admin/recovery.d.ts.map +1 -0
- package/dist/admin/recovery.js +229 -0
- package/dist/admin/recovery.js.map +1 -0
- package/dist/admin/routes.d.ts +0 -20
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +164 -105
- 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-discussion.d.ts +37 -0
- package/dist/admin/settings-discussion.d.ts.map +1 -0
- package/dist/admin/settings-discussion.js +117 -0
- package/dist/admin/settings-discussion.js.map +1 -0
- package/dist/admin/settings-email.d.ts +54 -0
- package/dist/admin/settings-email.d.ts.map +1 -0
- package/dist/admin/settings-email.js +189 -0
- package/dist/admin/settings-email.js.map +1 -0
- package/dist/admin/settings-federation.d.ts +48 -0
- package/dist/admin/settings-federation.d.ts.map +1 -0
- package/dist/admin/settings-federation.js +123 -0
- package/dist/admin/settings-federation.js.map +1 -0
- package/dist/admin/settings-general.d.ts +12 -0
- package/dist/admin/settings-general.d.ts.map +1 -0
- package/dist/admin/settings-general.js +48 -0
- package/dist/admin/settings-general.js.map +1 -0
- package/dist/admin/settings-page.d.ts +119 -0
- package/dist/admin/settings-page.d.ts.map +1 -0
- package/dist/admin/settings-page.js +132 -0
- package/dist/admin/settings-page.js.map +1 -0
- package/dist/admin/settings-pages.d.ts +30 -0
- package/dist/admin/settings-pages.d.ts.map +1 -0
- package/dist/admin/settings-pages.js +43 -0
- package/dist/admin/settings-pages.js.map +1 -0
- package/dist/admin/settings-permalinks.d.ts +16 -0
- package/dist/admin/settings-permalinks.d.ts.map +1 -0
- package/dist/admin/settings-permalinks.js +32 -0
- package/dist/admin/settings-permalinks.js.map +1 -0
- package/dist/admin/settings-reading.d.ts +34 -0
- package/dist/admin/settings-reading.d.ts.map +1 -0
- package/dist/admin/settings-reading.js +49 -0
- package/dist/admin/settings-reading.js.map +1 -0
- package/dist/admin/settings.d.ts +339 -96
- package/dist/admin/settings.d.ts.map +1 -1
- package/dist/admin/settings.js +600 -308
- package/dist/admin/settings.js.map +1 -1
- package/dist/admin/store.d.ts +606 -152
- package/dist/admin/store.d.ts.map +1 -1
- package/dist/admin/store.js +863 -268
- package/dist/admin/store.js.map +1 -1
- package/dist/admin/taxonomy.d.ts +114 -0
- package/dist/admin/taxonomy.d.ts.map +1 -0
- package/dist/admin/taxonomy.js +289 -0
- package/dist/admin/taxonomy.js.map +1 -0
- package/dist/admin/templates.d.ts +46 -14
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +46 -14
- package/dist/admin/templates.js.map +1 -1
- package/dist/admin/throttle.d.ts +84 -0
- package/dist/admin/throttle.d.ts.map +1 -0
- package/dist/admin/throttle.js +143 -0
- package/dist/admin/throttle.js.map +1 -0
- 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/admin/uploads.d.ts +28 -2
- package/dist/admin/uploads.d.ts.map +1 -1
- package/dist/admin/uploads.js +43 -4
- package/dist/admin/uploads.js.map +1 -1
- package/dist/admin/users.d.ts +100 -13
- package/dist/admin/users.d.ts.map +1 -1
- package/dist/admin/users.js +412 -39
- package/dist/admin/users.js.map +1 -1
- package/dist/cache.d.ts +141 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +207 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +14 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +429 -21
- package/dist/cli.js.map +1 -1
- package/dist/comments/akismet.d.ts +130 -0
- package/dist/comments/akismet.d.ts.map +1 -0
- package/dist/comments/akismet.js +274 -0
- package/dist/comments/akismet.js.map +1 -0
- package/dist/comments/conversation.d.ts +29 -0
- package/dist/comments/conversation.d.ts.map +1 -0
- package/dist/comments/conversation.js +60 -0
- package/dist/comments/conversation.js.map +1 -0
- package/dist/comments/form.d.ts +123 -0
- package/dist/comments/form.d.ts.map +1 -0
- package/dist/comments/form.js +79 -0
- package/dist/comments/form.js.map +1 -0
- package/dist/comments/index.d.ts +16 -0
- package/dist/comments/index.d.ts.map +1 -0
- package/dist/comments/index.js +10 -0
- package/dist/comments/index.js.map +1 -0
- package/dist/comments/markdown.d.ts +8 -0
- package/dist/comments/markdown.d.ts.map +1 -0
- package/dist/comments/markdown.js +85 -0
- package/dist/comments/markdown.js.map +1 -0
- package/dist/comments/moderate.d.ts +71 -0
- package/dist/comments/moderate.d.ts.map +1 -0
- package/dist/comments/moderate.js +88 -0
- package/dist/comments/moderate.js.map +1 -0
- package/dist/comments/policy.d.ts +57 -0
- package/dist/comments/policy.d.ts.map +1 -0
- package/dist/comments/policy.js +80 -0
- package/dist/comments/policy.js.map +1 -0
- package/dist/comments/records.d.ts +266 -0
- package/dist/comments/records.d.ts.map +1 -0
- package/dist/comments/records.js +487 -0
- package/dist/comments/records.js.map +1 -0
- package/dist/comments/routes.d.ts +60 -0
- package/dist/comments/routes.d.ts.map +1 -0
- package/dist/comments/routes.js +212 -0
- package/dist/comments/routes.js.map +1 -0
- package/dist/comments/submission.d.ts +297 -0
- package/dist/comments/submission.d.ts.map +1 -0
- package/dist/comments/submission.js +280 -0
- package/dist/comments/submission.js.map +1 -0
- 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 +225 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +121 -6
- package/dist/config.js.map +1 -1
- package/dist/contact/delivery.d.ts +60 -0
- package/dist/contact/delivery.d.ts.map +1 -0
- package/dist/contact/delivery.js +87 -0
- package/dist/contact/delivery.js.map +1 -0
- package/dist/contact/form.d.ts +130 -0
- package/dist/contact/form.d.ts.map +1 -0
- package/dist/contact/form.js +163 -0
- package/dist/contact/form.js.map +1 -0
- package/dist/contact/index.d.ts +17 -0
- package/dist/contact/index.d.ts.map +1 -0
- package/dist/contact/index.js +13 -0
- package/dist/contact/index.js.map +1 -0
- package/dist/contact/records.d.ts +124 -0
- package/dist/contact/records.d.ts.map +1 -0
- package/dist/contact/records.js +218 -0
- package/dist/contact/records.js.map +1 -0
- package/dist/contact/routes.d.ts +17 -0
- package/dist/contact/routes.d.ts.map +1 -0
- package/dist/contact/routes.js +127 -0
- package/dist/contact/routes.js.map +1 -0
- package/dist/contact/submission.d.ts +103 -0
- package/dist/contact/submission.d.ts.map +1 -0
- package/dist/contact/submission.js +166 -0
- package/dist/contact/submission.js.map +1 -0
- package/dist/content/document.d.ts +7 -2
- package/dist/content/document.d.ts.map +1 -1
- package/dist/content/document.js +1 -0
- package/dist/content/document.js.map +1 -1
- package/dist/content/index.d.ts +7 -2
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +4 -1
- package/dist/content/index.js.map +1 -1
- package/dist/content/markdown.d.ts.map +1 -1
- package/dist/content/markdown.js +24 -2
- package/dist/content/markdown.js.map +1 -1
- package/dist/content/parser.d.ts.map +1 -1
- package/dist/content/parser.js +11 -4
- package/dist/content/parser.js.map +1 -1
- package/dist/content/save.d.ts +5 -0
- package/dist/content/save.d.ts.map +1 -1
- package/dist/content/save.js +44 -1
- package/dist/content/save.js.map +1 -1
- package/dist/content/schedule.d.ts +125 -0
- package/dist/content/schedule.d.ts.map +1 -0
- package/dist/content/schedule.js +207 -0
- package/dist/content/schedule.js.map +1 -0
- package/dist/content/search.d.ts +64 -0
- package/dist/content/search.d.ts.map +1 -0
- package/dist/content/search.js +136 -0
- package/dist/content/search.js.map +1 -0
- package/dist/content/store.d.ts +220 -7
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +392 -67
- package/dist/content/store.js.map +1 -1
- package/dist/content/sync.d.ts +7 -1
- package/dist/content/sync.d.ts.map +1 -1
- package/dist/content/sync.js +18 -10
- package/dist/content/sync.js.map +1 -1
- package/dist/content/time.d.ts +56 -0
- package/dist/content/time.d.ts.map +1 -0
- package/dist/content/time.js +141 -0
- package/dist/content/time.js.map +1 -0
- package/dist/content/writer.d.ts.map +1 -1
- package/dist/content/writer.js +3 -0
- package/dist/content/writer.js.map +1 -1
- package/dist/env.d.ts +70 -5
- package/dist/env.d.ts.map +1 -1
- package/dist/federation/actor.d.ts +95 -41
- package/dist/federation/actor.d.ts.map +1 -1
- package/dist/federation/actor.js +180 -53
- package/dist/federation/actor.js.map +1 -1
- package/dist/federation/article.d.ts +44 -17
- package/dist/federation/article.d.ts.map +1 -1
- package/dist/federation/article.js +98 -46
- package/dist/federation/article.js.map +1 -1
- package/dist/federation/delivery.d.ts +63 -15
- package/dist/federation/delivery.d.ts.map +1 -1
- package/dist/federation/delivery.js +154 -80
- package/dist/federation/delivery.js.map +1 -1
- package/dist/federation/federation.d.ts +22 -17
- package/dist/federation/federation.d.ts.map +1 -1
- package/dist/federation/federation.js +98 -77
- package/dist/federation/federation.js.map +1 -1
- package/dist/federation/followers.d.ts +3 -2
- package/dist/federation/followers.d.ts.map +1 -1
- package/dist/federation/followers.js +6 -5
- package/dist/federation/followers.js.map +1 -1
- package/dist/federation/import-wordpress.d.ts +128 -0
- package/dist/federation/import-wordpress.d.ts.map +1 -0
- package/dist/federation/import-wordpress.js +426 -0
- package/dist/federation/import-wordpress.js.map +1 -0
- package/dist/federation/inbox.d.ts +36 -13
- package/dist/federation/inbox.d.ts.map +1 -1
- package/dist/federation/inbox.js +120 -49
- package/dist/federation/inbox.js.map +1 -1
- package/dist/federation/index.d.ts +22 -10
- package/dist/federation/index.d.ts.map +1 -1
- package/dist/federation/index.js +13 -8
- package/dist/federation/index.js.map +1 -1
- package/dist/federation/keys.d.ts +98 -20
- package/dist/federation/keys.d.ts.map +1 -1
- package/dist/federation/keys.js +269 -39
- package/dist/federation/keys.js.map +1 -1
- package/dist/federation/mount.d.ts +46 -10
- package/dist/federation/mount.d.ts.map +1 -1
- package/dist/federation/mount.js +300 -28
- package/dist/federation/mount.js.map +1 -1
- package/dist/federation/paths.d.ts +23 -35
- package/dist/federation/paths.d.ts.map +1 -1
- package/dist/federation/paths.js +26 -39
- package/dist/federation/paths.js.map +1 -1
- package/dist/federation/records.d.ts +223 -0
- package/dist/federation/records.d.ts.map +1 -0
- package/dist/federation/records.js +506 -0
- package/dist/federation/records.js.map +1 -0
- package/dist/federation/relays.d.ts +114 -0
- package/dist/federation/relays.d.ts.map +1 -0
- package/dist/federation/relays.js +290 -0
- package/dist/federation/relays.js.map +1 -0
- package/dist/federation/replies.d.ts +80 -0
- package/dist/federation/replies.d.ts.map +1 -0
- package/dist/federation/replies.js +166 -0
- package/dist/federation/replies.js.map +1 -0
- package/dist/federation/wordpress.d.ts +131 -0
- package/dist/federation/wordpress.d.ts.map +1 -0
- package/dist/federation/wordpress.js +341 -0
- package/dist/federation/wordpress.js.map +1 -0
- package/dist/files/atomic.d.ts +103 -0
- package/dist/files/atomic.d.ts.map +1 -0
- package/dist/files/atomic.js +150 -0
- package/dist/files/atomic.js.map +1 -0
- package/dist/files/index.d.ts +3 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +2 -0
- package/dist/files/index.js.map +1 -0
- package/dist/forms/protection.d.ts +85 -0
- package/dist/forms/protection.d.ts.map +1 -0
- package/dist/forms/protection.js +116 -0
- package/dist/forms/protection.js.map +1 -0
- package/dist/images/icons.d.ts +59 -0
- package/dist/images/icons.d.ts.map +1 -0
- package/dist/images/icons.js +131 -0
- package/dist/images/icons.js.map +1 -0
- package/dist/images/index.d.ts +7 -0
- package/dist/images/index.d.ts.map +1 -0
- package/dist/images/index.js +4 -0
- package/dist/images/index.js.map +1 -0
- package/dist/images/markup.d.ts +47 -0
- package/dist/images/markup.d.ts.map +1 -0
- package/dist/images/markup.js +175 -0
- package/dist/images/markup.js.map +1 -0
- package/dist/images/paths.d.ts +34 -0
- package/dist/images/paths.d.ts.map +1 -0
- package/dist/images/paths.js +41 -0
- package/dist/images/paths.js.map +1 -0
- package/dist/images/variants.d.ts +104 -0
- package/dist/images/variants.d.ts.map +1 -0
- package/dist/images/variants.js +320 -0
- package/dist/images/variants.js.map +1 -0
- package/dist/index.d.ts +123 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +344 -25
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +18 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +34 -3
- package/dist/init.js.map +1 -1
- package/dist/mail/brevo.d.ts +35 -0
- package/dist/mail/brevo.d.ts.map +1 -0
- package/dist/mail/brevo.js +85 -0
- package/dist/mail/brevo.js.map +1 -0
- package/dist/mail/credentials.d.ts +62 -0
- package/dist/mail/credentials.d.ts.map +1 -0
- package/dist/mail/credentials.js +86 -0
- package/dist/mail/credentials.js.map +1 -0
- package/dist/mail/index.d.ts +15 -0
- package/dist/mail/index.d.ts.map +1 -0
- package/dist/mail/index.js +8 -0
- package/dist/mail/index.js.map +1 -0
- package/dist/mail/memory.d.ts +35 -0
- package/dist/mail/memory.d.ts.map +1 -0
- package/dist/mail/memory.js +29 -0
- package/dist/mail/memory.js.map +1 -0
- package/dist/mail/provider.d.ts +80 -0
- package/dist/mail/provider.d.ts.map +1 -0
- package/dist/mail/provider.js +23 -0
- package/dist/mail/provider.js.map +1 -0
- package/dist/mail/service.d.ts +156 -0
- package/dist/mail/service.d.ts.map +1 -0
- package/dist/mail/service.js +265 -0
- package/dist/mail/service.js.map +1 -0
- package/dist/mail/smtp.d.ts +39 -0
- package/dist/mail/smtp.d.ts.map +1 -0
- package/dist/mail/smtp.js +58 -0
- package/dist/mail/smtp.js.map +1 -0
- package/dist/mail/templates.d.ts +91 -0
- package/dist/mail/templates.d.ts.map +1 -0
- package/dist/mail/templates.js +69 -0
- package/dist/mail/templates.js.map +1 -0
- package/dist/notifications/comments.d.ts +66 -0
- package/dist/notifications/comments.d.ts.map +1 -0
- package/dist/notifications/comments.js +151 -0
- package/dist/notifications/comments.js.map +1 -0
- package/dist/notifications/digest.d.ts +135 -0
- package/dist/notifications/digest.d.ts.map +1 -0
- package/dist/notifications/digest.js +287 -0
- package/dist/notifications/digest.js.map +1 -0
- package/dist/notifications/index.d.ts +13 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +8 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/links.d.ts +60 -0
- package/dist/notifications/links.d.ts.map +1 -0
- package/dist/notifications/links.js +63 -0
- package/dist/notifications/links.js.map +1 -0
- package/dist/notifications/optouts.d.ts +48 -0
- package/dist/notifications/optouts.d.ts.map +1 -0
- package/dist/notifications/optouts.js +93 -0
- package/dist/notifications/optouts.js.map +1 -0
- package/dist/notifications/preferences.d.ts +158 -0
- package/dist/notifications/preferences.d.ts.map +1 -0
- package/dist/notifications/preferences.js +195 -0
- package/dist/notifications/preferences.js.map +1 -0
- package/dist/notifications/routes.d.ts +28 -0
- package/dist/notifications/routes.d.ts.map +1 -0
- package/dist/notifications/routes.js +184 -0
- package/dist/notifications/routes.js.map +1 -0
- package/dist/notifications/tokens.d.ts +60 -0
- package/dist/notifications/tokens.d.ts.map +1 -0
- package/dist/notifications/tokens.js +125 -0
- package/dist/notifications/tokens.js.map +1 -0
- package/dist/notify.d.ts +84 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.js +149 -0
- package/dist/notify.js.map +1 -0
- package/dist/web/archive.d.ts +49 -0
- package/dist/web/archive.d.ts.map +1 -0
- package/dist/web/archive.js +59 -0
- package/dist/web/archive.js.map +1 -0
- package/dist/web/assets.d.ts +6 -5
- package/dist/web/assets.d.ts.map +1 -1
- package/dist/web/assets.js +5 -7
- package/dist/web/assets.js.map +1 -1
- package/dist/web/authors.d.ts +143 -0
- package/dist/web/authors.d.ts.map +1 -0
- package/dist/web/authors.js +178 -0
- package/dist/web/authors.js.map +1 -0
- package/dist/web/comments.d.ts +60 -0
- package/dist/web/comments.d.ts.map +1 -0
- package/dist/web/comments.js +207 -0
- package/dist/web/comments.js.map +1 -0
- package/dist/web/context.d.ts +162 -28
- package/dist/web/context.d.ts.map +1 -1
- package/dist/web/context.js +123 -26
- package/dist/web/context.js.map +1 -1
- package/dist/web/conversation.d.ts +209 -0
- package/dist/web/conversation.d.ts.map +1 -0
- package/dist/web/conversation.js +557 -0
- package/dist/web/conversation.js.map +1 -0
- package/dist/web/documents.d.ts +36 -6
- package/dist/web/documents.d.ts.map +1 -1
- package/dist/web/documents.js +52 -10
- package/dist/web/documents.js.map +1 -1
- package/dist/web/feed-atom.d.ts +22 -0
- package/dist/web/feed-atom.d.ts.map +1 -0
- package/dist/web/feed-atom.js +83 -0
- package/dist/web/feed-atom.js.map +1 -0
- package/dist/web/feed-item.d.ts +145 -0
- package/dist/web/feed-item.d.ts.map +1 -0
- package/dist/web/feed-item.js +120 -0
- package/dist/web/feed-item.js.map +1 -0
- package/dist/web/feed-json.d.ts +79 -0
- package/dist/web/feed-json.d.ts.map +1 -0
- package/dist/web/feed-json.js +53 -0
- package/dist/web/feed-json.js.map +1 -0
- package/dist/web/feed-rss.d.ts +26 -0
- package/dist/web/feed-rss.d.ts.map +1 -0
- package/dist/web/feed-rss.js +203 -0
- package/dist/web/feed-rss.js.map +1 -0
- package/dist/web/feed-source.d.ts +244 -0
- package/dist/web/feed-source.d.ts.map +1 -0
- package/dist/web/feed-source.js +201 -0
- package/dist/web/feed-source.js.map +1 -0
- package/dist/web/feed-xml.d.ts +63 -0
- package/dist/web/feed-xml.d.ts.map +1 -0
- package/dist/web/feed-xml.js +116 -0
- package/dist/web/feed-xml.js.map +1 -0
- package/dist/web/feeds.d.ts +31 -96
- package/dist/web/feeds.d.ts.map +1 -1
- package/dist/web/feeds.js +94 -198
- package/dist/web/feeds.js.map +1 -1
- package/dist/web/health.d.ts +31 -0
- package/dist/web/health.d.ts.map +1 -0
- package/dist/web/health.js +44 -0
- package/dist/web/health.js.map +1 -0
- package/dist/web/index.d.ts +30 -10
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +18 -7
- package/dist/web/index.js.map +1 -1
- package/dist/web/navigation.d.ts +195 -0
- package/dist/web/navigation.d.ts.map +1 -0
- package/dist/web/navigation.js +300 -0
- package/dist/web/navigation.js.map +1 -0
- package/dist/web/negotiate.d.ts +31 -0
- package/dist/web/negotiate.d.ts.map +1 -1
- package/dist/web/negotiate.js +31 -11
- package/dist/web/negotiate.js.map +1 -1
- package/dist/web/recent.d.ts +43 -0
- package/dist/web/recent.d.ts.map +1 -0
- package/dist/web/recent.js +37 -0
- package/dist/web/recent.js.map +1 -0
- package/dist/web/render.d.ts +203 -9
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +341 -17
- package/dist/web/render.js.map +1 -1
- package/dist/web/routes.d.ts +25 -8
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +854 -93
- package/dist/web/routes.js.map +1 -1
- package/dist/web/sanitize.d.ts +19 -0
- package/dist/web/sanitize.d.ts.map +1 -0
- package/dist/web/sanitize.js +272 -0
- package/dist/web/sanitize.js.map +1 -0
- package/dist/web/search.d.ts +79 -0
- package/dist/web/search.d.ts.map +1 -0
- package/dist/web/search.js +94 -0
- package/dist/web/search.js.map +1 -0
- package/dist/web/sitemap.d.ts +120 -0
- package/dist/web/sitemap.d.ts.map +1 -0
- package/dist/web/sitemap.js +199 -0
- package/dist/web/sitemap.js.map +1 -0
- package/dist/web/taxonomy.d.ts +152 -0
- package/dist/web/taxonomy.d.ts.map +1 -0
- package/dist/web/taxonomy.js +237 -0
- package/dist/web/taxonomy.js.map +1 -0
- package/dist/web/templates.d.ts +54 -16
- package/dist/web/templates.d.ts.map +1 -1
- package/dist/web/templates.js +109 -28
- package/dist/web/templates.js.map +1 -1
- package/dist/web/themes.d.ts +226 -0
- package/dist/web/themes.d.ts.map +1 -0
- package/dist/web/themes.js +314 -0
- package/dist/web/themes.js.map +1 -0
- package/dist/webmention/discovery.d.ts +51 -0
- package/dist/webmention/discovery.d.ts.map +1 -0
- package/dist/webmention/discovery.js +176 -0
- package/dist/webmention/discovery.js.map +1 -0
- package/dist/webmention/html.d.ts +71 -0
- package/dist/webmention/html.d.ts.map +1 -0
- package/dist/webmention/html.js +285 -0
- package/dist/webmention/html.js.map +1 -0
- package/dist/webmention/index.d.ts +12 -0
- package/dist/webmention/index.d.ts.map +1 -0
- package/dist/webmention/index.js +8 -0
- package/dist/webmention/index.js.map +1 -0
- package/dist/webmention/links.d.ts +18 -0
- package/dist/webmention/links.d.ts.map +1 -0
- package/dist/webmention/links.js +64 -0
- package/dist/webmention/links.js.map +1 -0
- package/dist/webmention/microformats.d.ts +93 -0
- package/dist/webmention/microformats.d.ts.map +1 -0
- package/dist/webmention/microformats.js +376 -0
- package/dist/webmention/microformats.js.map +1 -0
- package/dist/webmention/receive.d.ts +141 -0
- package/dist/webmention/receive.d.ts.map +1 -0
- package/dist/webmention/receive.js +264 -0
- package/dist/webmention/receive.js.map +1 -0
- package/dist/webmention/routes.d.ts +37 -0
- package/dist/webmention/routes.d.ts.map +1 -0
- package/dist/webmention/routes.js +75 -0
- package/dist/webmention/routes.js.map +1 -0
- package/dist/webmention/service.d.ts +94 -0
- package/dist/webmention/service.d.ts.map +1 -0
- package/dist/webmention/service.js +207 -0
- package/dist/webmention/service.js.map +1 -0
- package/package.json +11 -6
- package/templates/site/content/_data/site.json +8 -0
- package/templates/site/content/pages/about.md +7 -0
- package/templates/site/content/posts/2026-01-01-hello-world.md +5 -3
- package/templates/site/geekity.config.ts +11 -1
- package/templates/site/tsconfig.json +1 -1
- package/themes/default/README.md +1216 -50
- package/themes/default/layouts/404.njk +2 -3
- package/themes/default/layouts/author.njk +36 -0
- package/themes/default/layouts/base.njk +161 -31
- package/themes/default/layouts/category.njk +27 -0
- package/themes/default/layouts/front-page.njk +56 -0
- package/themes/default/layouts/home.njk +17 -1
- package/themes/default/layouts/page.njk +57 -5
- package/themes/default/layouts/post.njk +78 -19
- package/themes/default/layouts/search.njk +57 -0
- package/themes/default/layouts/tag.njk +3 -6
- package/themes/default/mail/comment-digest.html.njk +37 -0
- package/themes/default/mail/comment-digest.subject.njk +3 -0
- package/themes/default/mail/comment-digest.txt.njk +40 -0
- package/themes/default/mail/comment-pending.html.njk +27 -0
- package/themes/default/mail/comment-pending.subject.njk +2 -0
- package/themes/default/mail/comment-pending.txt.njk +24 -0
- package/themes/default/mail/comment-reply.html.njk +21 -0
- package/themes/default/mail/comment-reply.subject.njk +2 -0
- package/themes/default/mail/comment-reply.txt.njk +22 -0
- package/themes/default/mail/contact-message.html.njk +24 -0
- package/themes/default/mail/contact-message.subject.njk +5 -0
- package/themes/default/mail/contact-message.txt.njk +20 -0
- package/themes/default/mail/password-changed.html.njk +18 -0
- package/themes/default/mail/password-changed.subject.njk +2 -0
- package/themes/default/mail/password-changed.txt.njk +17 -0
- package/themes/default/mail/password-reset.html.njk +22 -0
- package/themes/default/mail/password-reset.subject.njk +2 -0
- package/themes/default/mail/password-reset.txt.njk +18 -0
- package/themes/default/mail/test.html.njk +14 -0
- package/themes/default/mail/test.subject.njk +2 -0
- package/themes/default/mail/test.txt.njk +12 -0
- package/themes/default/partials/archive.njk +27 -0
- package/themes/default/partials/bio.njk +71 -0
- package/themes/default/partials/comment-form.njk +137 -0
- package/themes/default/partials/contact-form.njk +88 -0
- package/themes/default/partials/conversation.njk +139 -0
- package/themes/default/partials/feeds.njk +26 -0
- package/themes/default/partials/jsonld.njk +120 -0
- package/themes/default/partials/menu.njk +32 -0
- package/themes/default/partials/pagination.njk +12 -6
- package/themes/default/partials/post-list.njk +51 -18
- package/themes/default/partials/search-form.njk +22 -0
- package/themes/default/partials/tags.njk +26 -5
- package/themes/default/static/highlight.js +4 -0
- package/themes/default/static/style.css +1142 -194
- package/themes/default/theme.json +9 -0
- package/admin/layouts/federation.njk +0 -145
- package/admin/layouts/login.njk +0 -23
- package/admin/layouts/settings.njk +0 -116
- package/admin/layouts/setup.njk +0 -27
- package/admin/layouts/users.njk +0 -91
- /package/admin/{layouts/_flash.njk → components/flash.njk} +0 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { countContactMessagesByStatus, countUnreadContactMessages, deleteContactMessage, listContactMessages, setContactMessageRead, } from '../contact/records.js';
|
|
2
|
+
import { flash } from './flash.js';
|
|
3
|
+
import { formatInTimezone } from './formatting.js';
|
|
4
|
+
import { ADMIN_PREFIX } from './session.js';
|
|
5
|
+
import { readSiteSettings } from './settings.js';
|
|
6
|
+
import { ADMIN_TEMPLATES } from './templates.js';
|
|
7
|
+
/**
|
|
8
|
+
* The inbox: what the contact form left behind (TASK-56).
|
|
9
|
+
*
|
|
10
|
+
* A message is a file under `data/contact/` and nothing else — there is no
|
|
11
|
+
* index, because this screen reads every file to sort them anyway and a second
|
|
12
|
+
* copy of the truth would only be a second thing to keep true. So the two
|
|
13
|
+
* actions here are a rewrite and an unlink, and the screen is a view of the
|
|
14
|
+
* directory as it is at that moment (decision-9).
|
|
15
|
+
*
|
|
16
|
+
* Two lists rather than one. A checker's `spam` is an opinion about a message
|
|
17
|
+
* somebody may really have sent, so it is kept rather than thrown away — but a
|
|
18
|
+
* run of it must not bury the messages a person actually has to answer.
|
|
19
|
+
*/
|
|
20
|
+
/** Where the Messages screen lives. */
|
|
21
|
+
export const MESSAGES_PATH = `${ADMIN_PREFIX}/messages`;
|
|
22
|
+
/** The navigation section it marks as current. */
|
|
23
|
+
export const MESSAGES_SECTION = 'messages';
|
|
24
|
+
/** Where the Mark read and Mark unread buttons post. */
|
|
25
|
+
export const MESSAGES_READ_PATH = `${MESSAGES_PATH}/read`;
|
|
26
|
+
/** Where the Delete button posts. */
|
|
27
|
+
export const MESSAGES_DELETE_PATH = `${MESSAGES_PATH}/delete`;
|
|
28
|
+
/** The fields the forms on this screen submit. */
|
|
29
|
+
export const MESSAGE_FIELDS = {
|
|
30
|
+
/** Which message a button is about. */
|
|
31
|
+
id: 'id',
|
|
32
|
+
/** Whether Mark read means read or unread. Empty is unread. */
|
|
33
|
+
read: 'read',
|
|
34
|
+
/** Which list to go back to afterwards. */
|
|
35
|
+
status: 'status',
|
|
36
|
+
};
|
|
37
|
+
/** How many messages one page of a list shows. */
|
|
38
|
+
export const MESSAGES_PER_PAGE = 25;
|
|
39
|
+
/** The two lists, in the order the screen offers them. */
|
|
40
|
+
export const MESSAGE_TABS = [
|
|
41
|
+
{ status: 'received', label: 'Inbox' },
|
|
42
|
+
{ status: 'spam', label: 'Spam' },
|
|
43
|
+
];
|
|
44
|
+
/** Register the Messages screen. */
|
|
45
|
+
export function mountMessagesScreen(app, options) {
|
|
46
|
+
const { render } = options;
|
|
47
|
+
app.get(MESSAGES_PATH, (c) => {
|
|
48
|
+
const { dataDir, contentDir } = c.var.config;
|
|
49
|
+
const status = statusOf(c.req.query('status'));
|
|
50
|
+
const page = Math.max(1, Math.trunc(Number(c.req.query('page') ?? '1')) || 1);
|
|
51
|
+
const counts = countContactMessagesByStatus(dataDir);
|
|
52
|
+
const timezone = readSiteSettings(contentDir).timezone;
|
|
53
|
+
const rows = listContactMessages(dataDir, { status })
|
|
54
|
+
.slice((page - 1) * MESSAGES_PER_PAGE, page * MESSAGES_PER_PAGE)
|
|
55
|
+
.map((message) => messageRow(message, timezone));
|
|
56
|
+
const pages = Math.max(1, Math.ceil(counts[status] / MESSAGES_PER_PAGE));
|
|
57
|
+
return render(c, ADMIN_TEMPLATES.messages, {
|
|
58
|
+
section: MESSAGES_SECTION,
|
|
59
|
+
child: 'all',
|
|
60
|
+
heading: 'Messages',
|
|
61
|
+
status,
|
|
62
|
+
counts,
|
|
63
|
+
unread: countUnreadContactMessages(dataDir),
|
|
64
|
+
tabs: MESSAGE_TABS.map((tab) => ({
|
|
65
|
+
...tab,
|
|
66
|
+
url: listUrl(tab.status),
|
|
67
|
+
count: counts[tab.status],
|
|
68
|
+
current: tab.status === status,
|
|
69
|
+
})),
|
|
70
|
+
rows,
|
|
71
|
+
fields: MESSAGE_FIELDS,
|
|
72
|
+
readUrl: MESSAGES_READ_PATH,
|
|
73
|
+
deleteUrl: MESSAGES_DELETE_PATH,
|
|
74
|
+
page,
|
|
75
|
+
pages,
|
|
76
|
+
previousUrl: page > 1 ? listUrl(status, page - 1) : undefined,
|
|
77
|
+
nextUrl: page < pages ? listUrl(status, page + 1) : undefined,
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
app.post(MESSAGES_READ_PATH, async (c) => {
|
|
81
|
+
const body = await c.req.parseBody();
|
|
82
|
+
const back = listUrl(statusOf(text(body[MESSAGE_FIELDS.status])));
|
|
83
|
+
// A checkbox submits nothing at all when it is clear, which is what the
|
|
84
|
+
// empty string here means: this button marks the message unread again.
|
|
85
|
+
const read = text(body[MESSAGE_FIELDS.read]) !== '';
|
|
86
|
+
const updated = await setContactMessageRead(c.var.config.dataDir, text(body[MESSAGE_FIELDS.id]), read);
|
|
87
|
+
if (updated === undefined) {
|
|
88
|
+
flash(c, 'error', 'That message is not here any more.');
|
|
89
|
+
return c.redirect(back, 303);
|
|
90
|
+
}
|
|
91
|
+
flash(c, 'notice', read
|
|
92
|
+
? `Marked ${updated.from.name}’s message read.`
|
|
93
|
+
: `Marked ${updated.from.name}’s message unread.`);
|
|
94
|
+
return c.redirect(back, 303);
|
|
95
|
+
});
|
|
96
|
+
app.post(MESSAGES_DELETE_PATH, async (c) => {
|
|
97
|
+
const body = await c.req.parseBody();
|
|
98
|
+
const back = listUrl(statusOf(text(body[MESSAGE_FIELDS.status])));
|
|
99
|
+
const id = text(body[MESSAGE_FIELDS.id]);
|
|
100
|
+
// Read before it goes, so the flash can say whose message it was. An id
|
|
101
|
+
// that is not one never reaches the filesystem: the records module refuses
|
|
102
|
+
// anything but the shape it mints.
|
|
103
|
+
const held = listContactMessages(c.var.config.dataDir).find((message) => message.id === id)
|
|
104
|
+
?.from.name;
|
|
105
|
+
if (!(await deleteContactMessage(c.var.config.dataDir, id))) {
|
|
106
|
+
flash(c, 'error', 'That message is not here any more.');
|
|
107
|
+
return c.redirect(back, 303);
|
|
108
|
+
}
|
|
109
|
+
flash(c, 'notice', `Deleted ${held ?? 'the'} message.`);
|
|
110
|
+
return c.redirect(back, 303);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/** How many messages are waiting to be read, which is the number on the dashboard. */
|
|
114
|
+
export function unreadMessages(dataDir) {
|
|
115
|
+
return countUnreadContactMessages(dataDir);
|
|
116
|
+
}
|
|
117
|
+
/** Where one list of the inbox lives. */
|
|
118
|
+
export function listUrl(status, page = 1) {
|
|
119
|
+
const query = page > 1 ? `&page=${String(page)}` : '';
|
|
120
|
+
return `${MESSAGES_PATH}?status=${status}${query}`;
|
|
121
|
+
}
|
|
122
|
+
/** A requested status, or the inbox for anything else. */
|
|
123
|
+
function statusOf(value) {
|
|
124
|
+
return value === 'spam' ? 'spam' : 'received';
|
|
125
|
+
}
|
|
126
|
+
/** One stored message as the screen shows it. */
|
|
127
|
+
function messageRow(message, timezone) {
|
|
128
|
+
const subject = message.subject === '' ? `A message from ${message.from.name}` : message.subject;
|
|
129
|
+
return {
|
|
130
|
+
id: message.id,
|
|
131
|
+
status: message.status,
|
|
132
|
+
read: message.read,
|
|
133
|
+
author: message.from.name,
|
|
134
|
+
email: message.from.email,
|
|
135
|
+
subject: message.subject,
|
|
136
|
+
message: message.message,
|
|
137
|
+
received: formatInTimezone(message.received, timezone),
|
|
138
|
+
// The first eight characters are enough to see that two messages came from
|
|
139
|
+
// one place, which is the only question the hash is there to answer.
|
|
140
|
+
address: message.addressHash === null ? null : message.addressHash.slice(0, 8),
|
|
141
|
+
page: message.page.title === '' ? message.page.slug : message.page.title,
|
|
142
|
+
pageUrl: message.page.permalink === '' ? null : message.page.permalink,
|
|
143
|
+
// Answering from here rather than from a mail client is one click; the
|
|
144
|
+
// subject comes back with `Re:` on it the way a reply would.
|
|
145
|
+
replyUrl: `mailto:${encodeURIComponent(message.from.email)}?subject=${encodeURIComponent(`Re: ${subject}`)}`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/** A form field as a string. A file upload, or a missing field, is the empty one. */
|
|
149
|
+
function text(value) {
|
|
150
|
+
return typeof value === 'string' ? value : '';
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/admin/messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation: every menu this site holds, and what renders it.
|
|
3
|
+
*
|
|
4
|
+
* A menu is a named thing the site stores and the theme asks for (TASK-107),
|
|
5
|
+
* and this is where somebody manages them. It is a top-level section after
|
|
6
|
+
* Pages rather than a settings page, on purpose: a menu is content a site
|
|
7
|
+
* arranges, the way its pages are, rather than a switch that changes how the
|
|
8
|
+
* site behaves — and the shape of this screen comes from the active theme,
|
|
9
|
+
* which is not something a page of fields can be.
|
|
10
|
+
*
|
|
11
|
+
* The screen is the cross product of two lists. The theme declares the areas
|
|
12
|
+
* it renders, in `theme.json`, each a name and a label; the site stores menus
|
|
13
|
+
* by name, in `content/_data/site.json`. An area with no stored menu is an
|
|
14
|
+
* empty box to fill in, not a missing one. A stored menu no area names is
|
|
15
|
+
* kept, rendered nowhere, and listed under a heading that says so — and this
|
|
16
|
+
* is the only screen that can show it, because nothing on the public site ever
|
|
17
|
+
* will.
|
|
18
|
+
*
|
|
19
|
+
* Adding a menu asks for a name, and that is the whole of adding one: a name
|
|
20
|
+
* the theme declares moves the box up into place, and a name it does not is a
|
|
21
|
+
* block waiting for the theme that will use it, which is what somebody writing
|
|
22
|
+
* a menu before switching themes wants. Deleting is offered only for the
|
|
23
|
+
* second kind, because an area the theme declares is emptied rather than
|
|
24
|
+
* removed — the theme would render nothing there either way, and the box has
|
|
25
|
+
* to stay for the next thing typed into it.
|
|
26
|
+
*/
|
|
27
|
+
import type { Hono } from 'hono';
|
|
28
|
+
import type { GeekityEnv } from '../env.ts';
|
|
29
|
+
import type { NavigationMenus } from '../web/navigation.ts';
|
|
30
|
+
import type { ThemeArea } from '../web/themes.ts';
|
|
31
|
+
import type { AdminRender } from './documents.ts';
|
|
32
|
+
/**
|
|
33
|
+
* Where the Navigation screen lives.
|
|
34
|
+
*
|
|
35
|
+
* `/admin/navigation` itself rather than `/admin/navigation/menus`, the way
|
|
36
|
+
* Tools is `/admin/tools`: a section's heading lands on its first child, and
|
|
37
|
+
* this is the only one. It is also where one menu's items are saved.
|
|
38
|
+
*/
|
|
39
|
+
export declare const NAVIGATION_PATH = "/admin/navigation";
|
|
40
|
+
/** Where the Add a menu form posts. */
|
|
41
|
+
export declare const ADD_MENU_PATH = "/admin/navigation/add";
|
|
42
|
+
/** Where a Delete button posts. */
|
|
43
|
+
export declare const DELETE_MENU_PATH = "/admin/navigation/delete";
|
|
44
|
+
/** The navigation section the screen marks as current. */
|
|
45
|
+
export declare const NAVIGATION_SECTION = "navigation";
|
|
46
|
+
/** The child of that section it is. */
|
|
47
|
+
export declare const MENUS_CHILD = "menus";
|
|
48
|
+
/** The fields the forms on the screen submit. */
|
|
49
|
+
export declare const NAVIGATION_FIELDS: {
|
|
50
|
+
/** Which menu a save or a delete is about: its name. */
|
|
51
|
+
readonly menu: 'menu';
|
|
52
|
+
/** One menu's items, one `Label | URL` per line. */
|
|
53
|
+
readonly items: 'items';
|
|
54
|
+
/** The name the Add form asks for. */
|
|
55
|
+
readonly name: 'name';
|
|
56
|
+
};
|
|
57
|
+
/** One menu as the screen draws it. */
|
|
58
|
+
export interface MenuBox {
|
|
59
|
+
/** The menu's name: what `site.json` keys it by and a theme loops over. */
|
|
60
|
+
name: string;
|
|
61
|
+
/** What the box is headed: the theme's label for the area, or the name. */
|
|
62
|
+
label: string;
|
|
63
|
+
/** Its items, as the textarea shows them, one line each. */
|
|
64
|
+
items: string;
|
|
65
|
+
/** Whether the active theme declares an area of this name. */
|
|
66
|
+
declared: boolean;
|
|
67
|
+
/** Whether the site stores a menu under this name at all. */
|
|
68
|
+
stored: boolean;
|
|
69
|
+
/** How many items it holds, for the line under the heading. */
|
|
70
|
+
count: number;
|
|
71
|
+
/** What was wrong with what was just typed into it, when something was. */
|
|
72
|
+
problem?: string | undefined;
|
|
73
|
+
}
|
|
74
|
+
/** The two lists the screen is, and the theme they were worked out from. */
|
|
75
|
+
export interface NavigationScreen {
|
|
76
|
+
/** The active theme's areas, in the order it declares them. */
|
|
77
|
+
areas: MenuBox[];
|
|
78
|
+
/** Every stored menu no area names, by name. */
|
|
79
|
+
others: MenuBox[];
|
|
80
|
+
/** What the active theme is called, for the prose above both lists. */
|
|
81
|
+
themeName: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The theme whose areas this screen offers, and what it is called.
|
|
85
|
+
*
|
|
86
|
+
* The first theme on the render's own search path that declares any areas,
|
|
87
|
+
* which for a site on the packaged theme is the packaged theme itself. That is
|
|
88
|
+
* the same rule Nunjucks resolves a template by (decision-15): a site theme is
|
|
89
|
+
* laid over the packaged one a file at a time and need only carry what it
|
|
90
|
+
* changes, so a theme that declares no areas has not overridden the
|
|
91
|
+
* declaration — and its inherited `layouts/base.njk` really is still rendering
|
|
92
|
+
* `menus.primary` and `menus.footer`. A screen that showed no areas for it
|
|
93
|
+
* would be offering nowhere to put the menus the site is visibly rendering.
|
|
94
|
+
*/
|
|
95
|
+
export declare function activeThemeAreas(options: {
|
|
96
|
+
themesDir: string;
|
|
97
|
+
chosen: string;
|
|
98
|
+
}): {
|
|
99
|
+
areas: readonly ThemeArea[];
|
|
100
|
+
themeName: string;
|
|
101
|
+
};
|
|
102
|
+
/** What {@link navigationScreen} needs. */
|
|
103
|
+
export interface NavigationScreenOptions {
|
|
104
|
+
/** Every menu the site stores, as `site.json` holds them. */
|
|
105
|
+
menus: NavigationMenus;
|
|
106
|
+
/** Where the site's themes are. */
|
|
107
|
+
themesDir: string;
|
|
108
|
+
/** The theme the site has chosen, empty for the packaged one. */
|
|
109
|
+
chosen: string;
|
|
110
|
+
/** What was typed into one box and refused, so the box shows it back. */
|
|
111
|
+
typed?: {
|
|
112
|
+
menu: string;
|
|
113
|
+
items: string;
|
|
114
|
+
problem: string;
|
|
115
|
+
} | undefined;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The two lists the screen draws, out of the stored menus and the theme.
|
|
119
|
+
*
|
|
120
|
+
* The areas come first and in the theme's order, because that is the order
|
|
121
|
+
* they appear on the site; the rest follow by name, which is the only order
|
|
122
|
+
* they have. A menu is in exactly one of the two lists, so nothing is drawn
|
|
123
|
+
* twice and nothing a site holds is left off.
|
|
124
|
+
*/
|
|
125
|
+
export declare function navigationScreen(options: NavigationScreenOptions): NavigationScreen;
|
|
126
|
+
/** What {@link mountNavigationScreen} needs from the admin around it. */
|
|
127
|
+
export interface MountNavigationOptions {
|
|
128
|
+
/** The admin's renderer, which injects the chrome, the CSRF token and the flash. */
|
|
129
|
+
render: AdminRender;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Register Navigation: the screen, the save of one menu, the add and the
|
|
133
|
+
* delete.
|
|
134
|
+
*
|
|
135
|
+
* Three POSTs rather than one, for the reason a settings page's credential
|
|
136
|
+
* form is its own: a refused add must not lose an edit somebody had typed into
|
|
137
|
+
* a box further up the page, and a delete must not depend on every box on the
|
|
138
|
+
* screen parsing. Each writes `content/_data/site.json` through the same
|
|
139
|
+
* atomic update every settings save uses, applied to the file as re-read
|
|
140
|
+
* inside the write (decision-9), so two people editing two menus at once both
|
|
141
|
+
* land.
|
|
142
|
+
*/
|
|
143
|
+
export declare function mountNavigationScreen(app: Hono<GeekityEnv>, options: MountNavigationOptions): void;
|
|
144
|
+
/**
|
|
145
|
+
* What is wrong with a name the Add form submitted, or `undefined` when
|
|
146
|
+
* nothing is.
|
|
147
|
+
*
|
|
148
|
+
* The spelling rule comes from {@link menuNameProblem}, which is where it is
|
|
149
|
+
* written down; the only thing this adds is that the site does not already
|
|
150
|
+
* hold one. Adding a name it does hold is refused rather than shrugged at,
|
|
151
|
+
* because the box for that menu is already on the screen and an Add that
|
|
152
|
+
* silently did nothing would read as one that had failed.
|
|
153
|
+
*/
|
|
154
|
+
export declare function addMenuProblem(name: string, menus: NavigationMenus): string | undefined;
|
|
155
|
+
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/admin/navigation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAO5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,KAAK,EAAS,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMlD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,sBAA+B,CAAC;AAE5D,uCAAuC;AACvC,eAAO,MAAM,aAAa,0BAA2B,CAAC;AAEtD,mCAAmC;AACnC,eAAO,MAAM,gBAAgB,6BAA8B,CAAC;AAE5D,0DAA0D;AAC1D,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C,uCAAuC;AACvC,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC,iDAAiD;AACjD,eAAO,MAAM,iBAAiB;IAC5B,wDAAwD;aACxD,IAAI,EAAE,MAAM;IACZ,oDAAoD;aACpD,KAAK,EAAE,OAAO;IACd,sCAAsC;aACtC,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX,uCAAuC;AACvC,MAAM,WAAW,OAAO;IACtB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,QAAQ,EAAE,OAAO,CAAC;IAClB,6DAA6D;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,gDAAgD;IAChD,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAChF,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB,CAeA;AAED,2CAA2C;AAC3C,MAAM,WAAW,uBAAuB;IACtC,6DAA6D;IAC7D,KAAK,EAAE,eAAe,CAAC;IACvB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACtE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CA2BnF;AAED,yEAAyE;AACzE,MAAM,WAAW,sBAAsB;IACrC,oFAAoF;IACpF,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,OAAO,EAAE,sBAAsB,GAC9B,IAAI,CAsKN;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAOvF"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation: every menu this site holds, and what renders it.
|
|
3
|
+
*
|
|
4
|
+
* A menu is a named thing the site stores and the theme asks for (TASK-107),
|
|
5
|
+
* and this is where somebody manages them. It is a top-level section after
|
|
6
|
+
* Pages rather than a settings page, on purpose: a menu is content a site
|
|
7
|
+
* arranges, the way its pages are, rather than a switch that changes how the
|
|
8
|
+
* site behaves — and the shape of this screen comes from the active theme,
|
|
9
|
+
* which is not something a page of fields can be.
|
|
10
|
+
*
|
|
11
|
+
* The screen is the cross product of two lists. The theme declares the areas
|
|
12
|
+
* it renders, in `theme.json`, each a name and a label; the site stores menus
|
|
13
|
+
* by name, in `content/_data/site.json`. An area with no stored menu is an
|
|
14
|
+
* empty box to fill in, not a missing one. A stored menu no area names is
|
|
15
|
+
* kept, rendered nowhere, and listed under a heading that says so — and this
|
|
16
|
+
* is the only screen that can show it, because nothing on the public site ever
|
|
17
|
+
* will.
|
|
18
|
+
*
|
|
19
|
+
* Adding a menu asks for a name, and that is the whole of adding one: a name
|
|
20
|
+
* the theme declares moves the box up into place, and a name it does not is a
|
|
21
|
+
* block waiting for the theme that will use it, which is what somebody writing
|
|
22
|
+
* a menu before switching themes wants. Deleting is offered only for the
|
|
23
|
+
* second kind, because an area the theme declares is emptied rather than
|
|
24
|
+
* removed — the theme would render nothing there either way, and the box has
|
|
25
|
+
* to stay for the next thing typed into it.
|
|
26
|
+
*/
|
|
27
|
+
import { menuItemLineProblem, menuItemsFromText, menuItemsText, menuNameProblem, } from '../web/navigation.js';
|
|
28
|
+
import { chooseTheme, PACKAGED_THEME_DIR, readTheme } from '../web/themes.js';
|
|
29
|
+
import { flash } from './flash.js';
|
|
30
|
+
import { ADMIN_PREFIX } from './session.js';
|
|
31
|
+
import { readSiteSettings, updateSiteSettings } from './settings.js';
|
|
32
|
+
import { ADMIN_TEMPLATES } from './templates.js';
|
|
33
|
+
/**
|
|
34
|
+
* Where the Navigation screen lives.
|
|
35
|
+
*
|
|
36
|
+
* `/admin/navigation` itself rather than `/admin/navigation/menus`, the way
|
|
37
|
+
* Tools is `/admin/tools`: a section's heading lands on its first child, and
|
|
38
|
+
* this is the only one. It is also where one menu's items are saved.
|
|
39
|
+
*/
|
|
40
|
+
export const NAVIGATION_PATH = `${ADMIN_PREFIX}/navigation`;
|
|
41
|
+
/** Where the Add a menu form posts. */
|
|
42
|
+
export const ADD_MENU_PATH = `${NAVIGATION_PATH}/add`;
|
|
43
|
+
/** Where a Delete button posts. */
|
|
44
|
+
export const DELETE_MENU_PATH = `${NAVIGATION_PATH}/delete`;
|
|
45
|
+
/** The navigation section the screen marks as current. */
|
|
46
|
+
export const NAVIGATION_SECTION = 'navigation';
|
|
47
|
+
/** The child of that section it is. */
|
|
48
|
+
export const MENUS_CHILD = 'menus';
|
|
49
|
+
/** The fields the forms on the screen submit. */
|
|
50
|
+
export const NAVIGATION_FIELDS = {
|
|
51
|
+
/** Which menu a save or a delete is about: its name. */
|
|
52
|
+
menu: 'menu',
|
|
53
|
+
/** One menu's items, one `Label | URL` per line. */
|
|
54
|
+
items: 'items',
|
|
55
|
+
/** The name the Add form asks for. */
|
|
56
|
+
name: 'name',
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* The theme whose areas this screen offers, and what it is called.
|
|
60
|
+
*
|
|
61
|
+
* The first theme on the render's own search path that declares any areas,
|
|
62
|
+
* which for a site on the packaged theme is the packaged theme itself. That is
|
|
63
|
+
* the same rule Nunjucks resolves a template by (decision-15): a site theme is
|
|
64
|
+
* laid over the packaged one a file at a time and need only carry what it
|
|
65
|
+
* changes, so a theme that declares no areas has not overridden the
|
|
66
|
+
* declaration — and its inherited `layouts/base.njk` really is still rendering
|
|
67
|
+
* `menus.primary` and `menus.footer`. A screen that showed no areas for it
|
|
68
|
+
* would be offering nowhere to put the menus the site is visibly rendering.
|
|
69
|
+
*/
|
|
70
|
+
export function activeThemeAreas(options) {
|
|
71
|
+
const chosen = chooseTheme({ themesDir: options.themesDir, name: options.chosen });
|
|
72
|
+
const packaged = readTheme(PACKAGED_THEME_DIR);
|
|
73
|
+
const themes = [
|
|
74
|
+
...(chosen.theme === undefined ? [] : [chosen.theme]),
|
|
75
|
+
...(packaged.ok ? [packaged.theme] : []),
|
|
76
|
+
];
|
|
77
|
+
const declaring = themes.find((theme) => theme.areas.length > 0);
|
|
78
|
+
const first = themes[0];
|
|
79
|
+
return {
|
|
80
|
+
areas: declaring?.areas ?? [],
|
|
81
|
+
themeName: first?.name ?? 'The theme in use',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The two lists the screen draws, out of the stored menus and the theme.
|
|
86
|
+
*
|
|
87
|
+
* The areas come first and in the theme's order, because that is the order
|
|
88
|
+
* they appear on the site; the rest follow by name, which is the only order
|
|
89
|
+
* they have. A menu is in exactly one of the two lists, so nothing is drawn
|
|
90
|
+
* twice and nothing a site holds is left off.
|
|
91
|
+
*/
|
|
92
|
+
export function navigationScreen(options) {
|
|
93
|
+
const { areas, themeName } = activeThemeAreas(options);
|
|
94
|
+
const declared = new Set(areas.map((area) => area.name));
|
|
95
|
+
const box = (name, label, declaredHere) => {
|
|
96
|
+
const stored = options.menus[name];
|
|
97
|
+
const typed = options.typed?.menu === name ? options.typed : undefined;
|
|
98
|
+
return {
|
|
99
|
+
name,
|
|
100
|
+
label,
|
|
101
|
+
items: typed === undefined ? menuItemsText(stored ?? []) : typed.items,
|
|
102
|
+
declared: declaredHere,
|
|
103
|
+
stored: stored !== undefined,
|
|
104
|
+
count: stored?.length ?? 0,
|
|
105
|
+
...(typed === undefined ? {} : { problem: typed.problem }),
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
themeName,
|
|
110
|
+
areas: areas.map((area) => box(area.name, area.label, true)),
|
|
111
|
+
others: Object.keys(options.menus)
|
|
112
|
+
.filter((name) => !declared.has(name))
|
|
113
|
+
.sort((left, right) => left.localeCompare(right))
|
|
114
|
+
.map((name) => box(name, name, false)),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Register Navigation: the screen, the save of one menu, the add and the
|
|
119
|
+
* delete.
|
|
120
|
+
*
|
|
121
|
+
* Three POSTs rather than one, for the reason a settings page's credential
|
|
122
|
+
* form is its own: a refused add must not lose an edit somebody had typed into
|
|
123
|
+
* a box further up the page, and a delete must not depend on every box on the
|
|
124
|
+
* screen parsing. Each writes `content/_data/site.json` through the same
|
|
125
|
+
* atomic update every settings save uses, applied to the file as re-read
|
|
126
|
+
* inside the write (decision-9), so two people editing two menus at once both
|
|
127
|
+
* land.
|
|
128
|
+
*/
|
|
129
|
+
export function mountNavigationScreen(app, options) {
|
|
130
|
+
const { render } = options;
|
|
131
|
+
app.get(NAVIGATION_PATH, (c) => render(c, ADMIN_TEMPLATES.navigation, screen(c)));
|
|
132
|
+
// Saving one menu's items. The name comes from a hidden field rather than
|
|
133
|
+
// the URL because that is what the form around the box already carries, and
|
|
134
|
+
// a name that is not on the screen is refused rather than created: adding a
|
|
135
|
+
// menu is the Add form's job, and a save that quietly invented one would
|
|
136
|
+
// make a typo into a menu nothing renders.
|
|
137
|
+
app.post(NAVIGATION_PATH, async (c) => {
|
|
138
|
+
const body = await c.req.parseBody();
|
|
139
|
+
const name = field(body[NAVIGATION_FIELDS.menu]).trim();
|
|
140
|
+
const items = field(body[NAVIGATION_FIELDS.items]);
|
|
141
|
+
const settings = readSiteSettings(c.var.config.contentDir);
|
|
142
|
+
const shown = navigationScreen({
|
|
143
|
+
menus: settings.menus,
|
|
144
|
+
themesDir: c.var.config.themesDir,
|
|
145
|
+
chosen: settings.theme,
|
|
146
|
+
});
|
|
147
|
+
const box = [...shown.areas, ...shown.others].find((entry) => entry.name === name);
|
|
148
|
+
if (box === undefined) {
|
|
149
|
+
flash(c, 'error', `Nothing was saved. This site has no menu called “${name}”.`);
|
|
150
|
+
return c.redirect(NAVIGATION_PATH, 303);
|
|
151
|
+
}
|
|
152
|
+
// The box comes back holding exactly what was typed into it, so a line to
|
|
153
|
+
// fix is still there to fix and nothing else on the screen has moved.
|
|
154
|
+
const problem = menuItemLineProblem(items);
|
|
155
|
+
if (problem !== undefined) {
|
|
156
|
+
c.status(400);
|
|
157
|
+
return render(c, ADMIN_TEMPLATES.navigation, {
|
|
158
|
+
...screen(c, { menu: name, items, problem }),
|
|
159
|
+
hasProblems: true,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const parsed = menuItemsFromText(items);
|
|
163
|
+
await updateSiteSettings({
|
|
164
|
+
contentDir: c.var.config.contentDir,
|
|
165
|
+
change: (current) => ({ ...current, menus: { ...current.menus, [name]: parsed } }),
|
|
166
|
+
});
|
|
167
|
+
flash(c, 'notice', `${box.label} saved: ${count(parsed.length, 'item')}.`);
|
|
168
|
+
return c.redirect(NAVIGATION_PATH, 303);
|
|
169
|
+
});
|
|
170
|
+
// Adding a menu is adding a name. It starts empty, and it starts stored, so
|
|
171
|
+
// a menu written for a theme the site has not switched to yet is a menu the
|
|
172
|
+
// file really holds rather than a box that forgets itself.
|
|
173
|
+
app.post(ADD_MENU_PATH, async (c) => {
|
|
174
|
+
const body = await c.req.parseBody();
|
|
175
|
+
const name = field(body[NAVIGATION_FIELDS.name]).trim();
|
|
176
|
+
const settings = readSiteSettings(c.var.config.contentDir);
|
|
177
|
+
const problem = addMenuProblem(name, settings.menus);
|
|
178
|
+
if (problem !== undefined) {
|
|
179
|
+
c.status(400);
|
|
180
|
+
return render(c, ADMIN_TEMPLATES.navigation, {
|
|
181
|
+
...screen(c),
|
|
182
|
+
newName: name,
|
|
183
|
+
nameProblem: problem,
|
|
184
|
+
hasProblems: true,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
// An empty menu under that name, and only if the file still has none: the
|
|
188
|
+
// re-read inside the write is the same guard the check above is, against
|
|
189
|
+
// the same name added twice in the moment between them.
|
|
190
|
+
await updateSiteSettings({
|
|
191
|
+
contentDir: c.var.config.contentDir,
|
|
192
|
+
change: (current) => ({
|
|
193
|
+
...current,
|
|
194
|
+
menus: { ...current.menus, [name]: current.menus[name] ?? [] },
|
|
195
|
+
}),
|
|
196
|
+
});
|
|
197
|
+
const { areas } = activeThemeAreas({
|
|
198
|
+
themesDir: c.var.config.themesDir,
|
|
199
|
+
chosen: settings.theme,
|
|
200
|
+
});
|
|
201
|
+
const declared = areas.some((area) => area.name === name);
|
|
202
|
+
flash(c, 'notice', declared
|
|
203
|
+
? `The “${name}” menu is ready to fill in, and this theme renders it.`
|
|
204
|
+
: `The “${name}” menu is ready to fill in. This theme renders nothing under that name, so it is kept and rendered nowhere until a theme asks for it.`);
|
|
205
|
+
return c.redirect(NAVIGATION_PATH, 303);
|
|
206
|
+
});
|
|
207
|
+
// Deleting is the only way a menu is removed, and it is offered only for a
|
|
208
|
+
// menu the theme renders nowhere. An area the theme declares is emptied
|
|
209
|
+
// instead: deleting it would take away the box that is the only place its
|
|
210
|
+
// links can be typed, and the theme would go on asking for the name.
|
|
211
|
+
app.post(DELETE_MENU_PATH, async (c) => {
|
|
212
|
+
const body = await c.req.parseBody();
|
|
213
|
+
const name = field(body[NAVIGATION_FIELDS.menu]).trim();
|
|
214
|
+
const settings = readSiteSettings(c.var.config.contentDir);
|
|
215
|
+
const shown = navigationScreen({
|
|
216
|
+
menus: settings.menus,
|
|
217
|
+
themesDir: c.var.config.themesDir,
|
|
218
|
+
chosen: settings.theme,
|
|
219
|
+
});
|
|
220
|
+
if (shown.areas.some((area) => area.name === name)) {
|
|
221
|
+
flash(c, 'error', `Nothing was deleted. This theme renders “${name}”, so it is emptied rather than removed: clear its box and save.`);
|
|
222
|
+
return c.redirect(NAVIGATION_PATH, 303);
|
|
223
|
+
}
|
|
224
|
+
if (!shown.others.some((other) => other.name === name)) {
|
|
225
|
+
flash(c, 'error', `Nothing was deleted. This site has no menu called “${name}”.`);
|
|
226
|
+
return c.redirect(NAVIGATION_PATH, 303);
|
|
227
|
+
}
|
|
228
|
+
await updateSiteSettings({
|
|
229
|
+
contentDir: c.var.config.contentDir,
|
|
230
|
+
change: (current) => {
|
|
231
|
+
const menus = { ...current.menus };
|
|
232
|
+
delete menus[name];
|
|
233
|
+
return { ...current, menus };
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
flash(c, 'notice', `The “${name}” menu is gone.`);
|
|
237
|
+
return c.redirect(NAVIGATION_PATH, 303);
|
|
238
|
+
});
|
|
239
|
+
/** Everything the template renders. */
|
|
240
|
+
function screen(c, typed) {
|
|
241
|
+
const settings = readSiteSettings(c.var.config.contentDir);
|
|
242
|
+
const shown = navigationScreen({
|
|
243
|
+
menus: settings.menus,
|
|
244
|
+
themesDir: c.var.config.themesDir,
|
|
245
|
+
chosen: settings.theme,
|
|
246
|
+
typed,
|
|
247
|
+
});
|
|
248
|
+
return {
|
|
249
|
+
section: NAVIGATION_SECTION,
|
|
250
|
+
child: MENUS_CHILD,
|
|
251
|
+
heading: 'Navigation',
|
|
252
|
+
navigationUrl: NAVIGATION_PATH,
|
|
253
|
+
addUrl: ADD_MENU_PATH,
|
|
254
|
+
deleteUrl: DELETE_MENU_PATH,
|
|
255
|
+
fields: NAVIGATION_FIELDS,
|
|
256
|
+
areas: shown.areas,
|
|
257
|
+
others: shown.others,
|
|
258
|
+
themeName: shown.themeName,
|
|
259
|
+
newName: '',
|
|
260
|
+
nameProblem: '',
|
|
261
|
+
hasProblems: false,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* What is wrong with a name the Add form submitted, or `undefined` when
|
|
267
|
+
* nothing is.
|
|
268
|
+
*
|
|
269
|
+
* The spelling rule comes from {@link menuNameProblem}, which is where it is
|
|
270
|
+
* written down; the only thing this adds is that the site does not already
|
|
271
|
+
* hold one. Adding a name it does hold is refused rather than shrugged at,
|
|
272
|
+
* because the box for that menu is already on the screen and an Add that
|
|
273
|
+
* silently did nothing would read as one that had failed.
|
|
274
|
+
*/
|
|
275
|
+
export function addMenuProblem(name, menus) {
|
|
276
|
+
const problem = menuNameProblem(name);
|
|
277
|
+
if (problem !== undefined)
|
|
278
|
+
return problem;
|
|
279
|
+
if (menus[name] !== undefined) {
|
|
280
|
+
return `This site already has a menu called “${name}”. Its box is on this page.`;
|
|
281
|
+
}
|
|
282
|
+
return undefined;
|
|
283
|
+
}
|
|
284
|
+
/** "1 item", "2 items". */
|
|
285
|
+
function count(howMany, singular) {
|
|
286
|
+
return `${String(howMany)} ${howMany === 1 ? singular : `${singular}s`}`;
|
|
287
|
+
}
|
|
288
|
+
/** One submitted field as a string. */
|
|
289
|
+
function field(value) {
|
|
290
|
+
return typeof value === 'string' ? value : '';
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/admin/navigation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/admin/preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/admin/preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,MAAM,CAAC;AAO1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAS5C,8DAA8D;AAC9D,eAAO,MAAM,YAAY,mBAA4B,CAAC;AAEtD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAqBxD"}
|