@geekity/cms 0.21.0 → 0.23.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 +42 -4
- package/admin/components/admin-bar.njk +27 -6
- package/admin/components/alert.njk +28 -0
- package/admin/components/badge.njk +58 -0
- package/admin/components/button.njk +56 -0
- package/admin/components/card.njk +40 -0
- package/admin/components/collapse.njk +36 -0
- package/admin/components/copy.njk +20 -0
- package/admin/components/dropdown.njk +32 -0
- package/admin/components/fields.njk +81 -45
- package/admin/components/flash.njk +12 -5
- package/admin/components/menu.njk +51 -0
- package/admin/components/navbar.njk +23 -0
- package/admin/components/pagination.njk +47 -0
- package/admin/components/public-admin-bar.njk +4 -41
- package/admin/components/stat.njk +35 -0
- package/admin/components/table.njk +74 -0
- package/admin/components/tabs.njk +33 -0
- package/admin/components/theme-choice.njk +18 -0
- package/admin/layouts/base.njk +9 -16
- package/admin/layouts/settings-page.njk +15 -10
- package/admin/layouts/shell.njk +23 -31
- package/admin/pages/account/forgot.njk +39 -33
- package/admin/pages/account/login.njk +22 -16
- package/admin/pages/account/reset.njk +34 -25
- package/admin/pages/account/setup.njk +21 -15
- package/admin/pages/appearance/themes.njk +50 -44
- package/admin/pages/comments/all.njk +88 -106
- package/admin/pages/dashboard/home.njk +50 -62
- package/admin/pages/documents/conflict.njk +29 -24
- package/admin/pages/documents/editor.njk +173 -275
- package/admin/pages/documents/list.njk +60 -69
- package/admin/pages/documents/syndication.njk +98 -60
- package/admin/pages/documents/taxonomy.njk +36 -32
- package/admin/pages/error.njk +8 -5
- package/admin/pages/federation/followers.njk +91 -97
- package/admin/pages/federation/settings.njk +10 -11
- package/admin/pages/indieauth/consent.njk +60 -44
- package/admin/pages/indieauth/refused.njk +6 -3
- package/admin/pages/media/library.njk +86 -107
- package/admin/pages/messages/all.njk +71 -77
- package/admin/pages/navigation/menus.njk +90 -85
- package/admin/pages/placeholder.njk +13 -8
- package/admin/pages/settings/discussion.njk +30 -29
- package/admin/pages/settings/email.njk +26 -28
- package/admin/pages/settings/general.njk +10 -4
- package/admin/pages/settings/permalinks.njk +8 -9
- package/admin/pages/settings/privacy.njk +3 -3
- package/admin/pages/settings/reading.njk +3 -3
- package/admin/pages/tools/content-index.njk +79 -73
- package/admin/pages/tools/personal-data.njk +61 -55
- package/admin/pages/users/activity-entry.njk +12 -12
- package/admin/pages/users/activity.njk +13 -19
- package/admin/pages/users/apps.njk +112 -100
- package/admin/pages/users/edit.njk +65 -58
- package/admin/pages/users/list.njk +26 -24
- package/admin/pages/users/new.njk +11 -7
- package/admin/src/admin.css +174 -0
- package/admin/static/admin-bar.css +33 -31
- package/admin/static/admin-bar.js +22 -0
- package/admin/static/admin.css +7388 -1195
- package/admin/static/copy.js +1 -1
- package/admin/static/editor.js +18 -18
- package/dist/admin/accounts.d.ts +20 -0
- package/dist/admin/accounts.d.ts.map +1 -1
- package/dist/admin/accounts.js +25 -0
- package/dist/admin/accounts.js.map +1 -1
- package/dist/admin/admin-theme.d.ts +157 -0
- package/dist/admin/admin-theme.d.ts.map +1 -0
- package/dist/admin/admin-theme.js +52 -0
- package/dist/admin/admin-theme.js.map +1 -0
- package/dist/admin/assets.d.ts +4 -3
- package/dist/admin/assets.d.ts.map +1 -1
- package/dist/admin/assets.js +4 -3
- package/dist/admin/assets.js.map +1 -1
- package/dist/admin/comments.js +2 -2
- package/dist/admin/comments.js.map +1 -1
- package/dist/admin/documents.d.ts +36 -7
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +141 -30
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/editor-layout.d.ts +1 -1
- package/dist/admin/editor-layout.d.ts.map +1 -1
- package/dist/admin/editor-layout.js +6 -1
- package/dist/admin/editor-layout.js.map +1 -1
- package/dist/admin/event-field.d.ts +26 -0
- package/dist/admin/event-field.d.ts.map +1 -0
- package/dist/admin/event-field.js +74 -0
- package/dist/admin/event-field.js.map +1 -0
- package/dist/admin/federation.js +3 -3
- package/dist/admin/federation.js.map +1 -1
- package/dist/admin/headers.js +1 -1
- package/dist/admin/headers.js.map +1 -1
- package/dist/admin/media.js +2 -2
- package/dist/admin/media.js.map +1 -1
- package/dist/admin/preview.d.ts.map +1 -1
- package/dist/admin/preview.js +16 -1
- package/dist/admin/preview.js.map +1 -1
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +17 -8
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/store.d.ts +9 -0
- package/dist/admin/store.d.ts.map +1 -1
- package/dist/admin/store.js +16 -5
- package/dist/admin/store.js.map +1 -1
- package/dist/admin/templates.d.ts +6 -3
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +25 -3
- package/dist/admin/templates.js.map +1 -1
- package/dist/admin/users.d.ts +4 -0
- package/dist/admin/users.d.ts.map +1 -1
- package/dist/admin/users.js +37 -1
- package/dist/admin/users.js.map +1 -1
- package/dist/avatars/avatars.js +1 -1
- package/dist/avatars/avatars.js.map +1 -1
- package/dist/comments/policy.d.ts +10 -0
- package/dist/comments/policy.d.ts.map +1 -1
- package/dist/comments/policy.js +12 -0
- package/dist/comments/policy.js.map +1 -1
- package/dist/comments/records.d.ts +5 -1
- package/dist/comments/records.d.ts.map +1 -1
- package/dist/comments/records.js +16 -2
- package/dist/comments/records.js.map +1 -1
- package/dist/content/event.d.ts +40 -0
- package/dist/content/event.d.ts.map +1 -0
- package/dist/content/event.js +51 -0
- package/dist/content/event.js.map +1 -0
- package/dist/content/handles.d.ts +22 -0
- package/dist/content/handles.d.ts.map +1 -0
- package/dist/content/handles.js +68 -0
- package/dist/content/handles.js.map +1 -0
- package/dist/content/markdown.d.ts +8 -2
- package/dist/content/markdown.d.ts.map +1 -1
- package/dist/content/markdown.js +55 -5
- package/dist/content/markdown.js.map +1 -1
- package/dist/content/parser.d.ts +3 -0
- package/dist/content/parser.d.ts.map +1 -1
- package/dist/content/parser.js +1 -1
- package/dist/content/parser.js.map +1 -1
- package/dist/content/post-type.d.ts +12 -8
- package/dist/content/post-type.d.ts.map +1 -1
- package/dist/content/post-type.js +19 -4
- package/dist/content/post-type.js.map +1 -1
- package/dist/content/rsvp.d.ts +29 -0
- package/dist/content/rsvp.d.ts.map +1 -0
- package/dist/content/rsvp.js +49 -0
- package/dist/content/rsvp.js.map +1 -0
- package/dist/content/save.d.ts +2 -1
- package/dist/content/save.d.ts.map +1 -1
- package/dist/content/save.js +10 -3
- package/dist/content/save.js.map +1 -1
- package/dist/content/store.d.ts +11 -4
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +15 -4
- package/dist/content/store.js.map +1 -1
- package/dist/content/sync.d.ts.map +1 -1
- package/dist/content/sync.js +7 -6
- package/dist/content/sync.js.map +1 -1
- package/dist/env.d.ts +3 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/federation/article.d.ts +9 -3
- package/dist/federation/article.d.ts.map +1 -1
- package/dist/federation/article.js +90 -34
- package/dist/federation/article.js.map +1 -1
- package/dist/federation/cited-post.d.ts +13 -0
- package/dist/federation/cited-post.d.ts.map +1 -0
- package/dist/federation/cited-post.js +75 -0
- package/dist/federation/cited-post.js.map +1 -0
- package/dist/federation/delivery.d.ts.map +1 -1
- package/dist/federation/delivery.js +31 -2
- package/dist/federation/delivery.js.map +1 -1
- package/dist/federation/handles.d.ts +28 -0
- package/dist/federation/handles.d.ts.map +1 -0
- package/dist/federation/handles.js +65 -0
- package/dist/federation/handles.js.map +1 -0
- package/dist/federation/inbox.d.ts +2 -1
- package/dist/federation/inbox.d.ts.map +1 -1
- package/dist/federation/inbox.js +11 -3
- package/dist/federation/inbox.js.map +1 -1
- package/dist/federation/mount.d.ts.map +1 -1
- package/dist/federation/mount.js +18 -2
- package/dist/federation/mount.js.map +1 -1
- package/dist/federation/profiles.d.ts.map +1 -1
- package/dist/federation/profiles.js +2 -8
- package/dist/federation/profiles.js.map +1 -1
- package/dist/federation/site-loaders.d.ts +15 -0
- package/dist/federation/site-loaders.d.ts.map +1 -0
- package/dist/federation/site-loaders.js +19 -0
- package/dist/federation/site-loaders.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -1
- package/dist/index.js.map +1 -1
- package/dist/indieauth/client.js +2 -2
- package/dist/indieauth/client.js.map +1 -1
- package/dist/micropub/create.d.ts +2 -1
- package/dist/micropub/create.d.ts.map +1 -1
- package/dist/micropub/create.js +57 -8
- package/dist/micropub/create.js.map +1 -1
- package/dist/micropub/endpoint.d.ts.map +1 -1
- package/dist/micropub/endpoint.js +12 -4
- package/dist/micropub/endpoint.js.map +1 -1
- package/dist/micropub/update.d.ts +3 -0
- package/dist/micropub/update.d.ts.map +1 -1
- package/dist/micropub/update.js +29 -4
- package/dist/micropub/update.js.map +1 -1
- package/dist/web/admin-bar.d.ts +4 -4
- package/dist/web/admin-bar.d.ts.map +1 -1
- package/dist/web/admin-bar.js +11 -34
- package/dist/web/admin-bar.js.map +1 -1
- package/dist/web/context.d.ts +32 -4
- package/dist/web/context.d.ts.map +1 -1
- package/dist/web/context.js +28 -1
- package/dist/web/context.js.map +1 -1
- package/dist/web/conversation.d.ts +26 -1
- package/dist/web/conversation.d.ts.map +1 -1
- package/dist/web/conversation.js +67 -10
- package/dist/web/conversation.js.map +1 -1
- package/dist/web/documents.d.ts +12 -0
- package/dist/web/documents.d.ts.map +1 -1
- package/dist/web/documents.js +20 -0
- package/dist/web/documents.js.map +1 -1
- package/dist/web/feed-item.d.ts.map +1 -1
- package/dist/web/feed-item.js +8 -3
- package/dist/web/feed-item.js.map +1 -1
- package/dist/web/render.d.ts +3 -0
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +39 -6
- package/dist/web/render.js.map +1 -1
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +16 -3
- package/dist/web/routes.js.map +1 -1
- package/dist/web/templates.d.ts +4 -1
- package/dist/web/templates.d.ts.map +1 -1
- package/dist/web/templates.js +11 -0
- package/dist/web/templates.js.map +1 -1
- package/dist/webmention/cited-picture.d.ts +11 -4
- package/dist/webmention/cited-picture.d.ts.map +1 -1
- package/dist/webmention/cited-picture.js +22 -13
- package/dist/webmention/cited-picture.js.map +1 -1
- package/dist/webmention/cited-start.d.ts +10 -0
- package/dist/webmention/cited-start.d.ts.map +1 -0
- package/dist/webmention/cited-start.js +21 -0
- package/dist/webmention/cited-start.js.map +1 -0
- package/dist/webmention/fetch-public.d.ts +2 -2
- package/dist/webmention/fetch-public.d.ts.map +1 -1
- package/dist/webmention/fetch-public.js +1 -1
- package/dist/webmention/fetch-public.js.map +1 -1
- package/dist/webmention/html.d.ts +2 -0
- package/dist/webmention/html.d.ts.map +1 -1
- package/dist/webmention/html.js +6 -0
- package/dist/webmention/html.js.map +1 -1
- package/dist/webmention/index.d.ts +2 -1
- package/dist/webmention/index.d.ts.map +1 -1
- package/dist/webmention/index.js +1 -0
- package/dist/webmention/index.js.map +1 -1
- package/dist/webmention/microformats.d.ts +25 -2
- package/dist/webmention/microformats.d.ts.map +1 -1
- package/dist/webmention/microformats.js +38 -4
- package/dist/webmention/microformats.js.map +1 -1
- package/dist/webmention/pingback.d.ts +42 -0
- package/dist/webmention/pingback.d.ts.map +1 -0
- package/dist/webmention/pingback.js +229 -0
- package/dist/webmention/pingback.js.map +1 -0
- package/dist/webmention/receive.d.ts +20 -2
- package/dist/webmention/receive.d.ts.map +1 -1
- package/dist/webmention/receive.js +25 -16
- package/dist/webmention/receive.js.map +1 -1
- package/dist/webmention/reply-context.d.ts +65 -18
- package/dist/webmention/reply-context.d.ts.map +1 -1
- package/dist/webmention/reply-context.js +403 -99
- package/dist/webmention/reply-context.js.map +1 -1
- package/dist/webmention/reply-contexts.d.ts +3 -1
- package/dist/webmention/reply-contexts.d.ts.map +1 -1
- package/dist/webmention/reply-contexts.js +53 -17
- package/dist/webmention/reply-contexts.js.map +1 -1
- package/dist/webmention/routes.d.ts.map +1 -1
- package/dist/webmention/routes.js +2 -0
- package/dist/webmention/routes.js.map +1 -1
- package/dist/webmention/service.d.ts +11 -0
- package/dist/webmention/service.d.ts.map +1 -1
- package/dist/webmention/service.js +27 -6
- package/dist/webmention/service.js.map +1 -1
- package/dist/webmention/syndication.d.ts +6 -0
- package/dist/webmention/syndication.d.ts.map +1 -1
- package/dist/webmention/syndication.js +12 -0
- package/dist/webmention/syndication.js.map +1 -1
- package/package.json +10 -6
- package/themes/default/README.md +130 -38
- package/themes/default/layouts/410.njk +10 -0
- package/themes/default/layouts/base.njk +3 -0
- package/themes/default/layouts/page.njk +7 -0
- package/themes/default/layouts/post.njk +7 -4
- package/themes/default/layouts/search.njk +1 -1
- package/themes/default/partials/cited-page.njk +7 -0
- package/themes/default/partials/conversation.njk +25 -5
- package/themes/default/partials/event.njk +27 -0
- package/themes/default/partials/jsonld.njk +28 -0
- package/themes/default/partials/post-list.njk +5 -2
- package/themes/default/partials/reply-context.njk +24 -4
- package/themes/default/partials/rsvp.njk +7 -0
- package/themes/default/src/style.css +20 -0
- package/themes/default/static/style.css +35 -0
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
{% extends "layouts/base.njk" %}
|
|
2
2
|
{% import "components/fields.njk" as field %}
|
|
3
|
+
{% from "components/button.njk" import button %}
|
|
4
|
+
{% from "components/card.njk" import card %}
|
|
3
5
|
|
|
4
6
|
{% block title %}Log in{% endblock %}
|
|
5
7
|
|
|
6
8
|
{% block content %}
|
|
7
|
-
|
|
9
|
+
{% call card() %}
|
|
10
|
+
<h1 class="card-title text-2xl">Log in</h1>
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
{% endif %}
|
|
12
|
-
|
|
13
|
-
<form method="post" action="{{ loginUrl }}">
|
|
14
|
-
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
15
|
-
{% if returnTo %}
|
|
16
|
-
<input type="hidden" name="return_to" value="{{ returnTo }}" />
|
|
12
|
+
{% if error %}
|
|
13
|
+
{{ field.summary(error) }}
|
|
17
14
|
{% endif %}
|
|
18
15
|
|
|
19
|
-
{{
|
|
20
|
-
|
|
16
|
+
<form class="flex flex-col gap-2" method="post" action="{{ loginUrl }}">
|
|
17
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
18
|
+
{% if returnTo %}
|
|
19
|
+
<input type="hidden" name="return_to" value="{{ returnTo }}" />
|
|
20
|
+
{% endif %}
|
|
21
|
+
|
|
22
|
+
{{ field.text('username', 'username', 'Username', username,
|
|
23
|
+
autocomplete='username', required=true, autofocus=true) }}
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
{{ field.password('password', 'password', 'Password',
|
|
26
|
+
autocomplete='current-password', required=true) }}
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
<div class="mt-4">
|
|
29
|
+
{{ button('Log in', type='submit', color='primary', shape='block') }}
|
|
30
|
+
</div>
|
|
31
|
+
</form>
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
<p class="text-sm"><a class="link" href="{{ forgotUrl }}">Forgotten your password?</a></p>
|
|
34
|
+
{% endcall %}
|
|
29
35
|
{% endblock %}
|
|
@@ -6,35 +6,44 @@
|
|
|
6
6
|
passwords. #}
|
|
7
7
|
{% extends "layouts/base.njk" %}
|
|
8
8
|
{% import "components/fields.njk" as field %}
|
|
9
|
+
{% from "components/alert.njk" import alert %}
|
|
10
|
+
{% from "components/button.njk" import button %}
|
|
11
|
+
{% from "components/card.njk" import card %}
|
|
9
12
|
|
|
10
13
|
{% block title %}Set a new password{% endblock %}
|
|
11
14
|
|
|
12
15
|
{% block content %}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
{% if problem %}
|
|
20
|
-
{% call field.summary('The password was not set.') %}
|
|
21
|
-
{{ field.problem('password', problem) }}
|
|
16
|
+
{% call card() %}
|
|
17
|
+
<h1 class="card-title text-2xl">Set a new password</h1>
|
|
18
|
+
|
|
19
|
+
{% if invalid %}
|
|
20
|
+
{% call alert(color='error') %}
|
|
21
|
+
<span>That link is no longer valid. A reset link lasts an hour and works once, and asking for a new password again invalidates the old one.</span>
|
|
22
22
|
{% endcall %}
|
|
23
|
+
<p><a class="link" href="{{ forgotUrl }}">Ask for another one</a></p>
|
|
24
|
+
{% else %}
|
|
25
|
+
{% if problem %}
|
|
26
|
+
{% call field.summary('The password was not set.') %}
|
|
27
|
+
{{ field.problem('password', problem) }}
|
|
28
|
+
{% endcall %}
|
|
29
|
+
{% endif %}
|
|
30
|
+
|
|
31
|
+
<form class="flex flex-col gap-2" method="post" action="{{ resetUrl }}">
|
|
32
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
33
|
+
<input type="hidden" name="{{ fields.token }}" value="{{ token }}" />
|
|
34
|
+
|
|
35
|
+
{{ field.password('password', fields.password, 'New password', error=problem,
|
|
36
|
+
autocomplete='new-password', required=true, autofocus=true) }}
|
|
37
|
+
|
|
38
|
+
{{ field.password('password_confirmation', fields.passwordConfirmation,
|
|
39
|
+
'Repeat the password', autocomplete='new-password', required=true) }}
|
|
40
|
+
|
|
41
|
+
<p class="text-sm">Every browser signed in as you is signed out, and this link stops working.</p>
|
|
42
|
+
|
|
43
|
+
<div class="mt-4">
|
|
44
|
+
{{ button('Set the password', type='submit', color='primary', shape='block') }}
|
|
45
|
+
</div>
|
|
46
|
+
</form>
|
|
23
47
|
{% endif %}
|
|
24
|
-
|
|
25
|
-
<form method="post" action="{{ resetUrl }}">
|
|
26
|
-
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
27
|
-
<input type="hidden" name="{{ fields.token }}" value="{{ token }}" />
|
|
28
|
-
|
|
29
|
-
{{ field.password('password', fields.password, 'New password', error=problem,
|
|
30
|
-
autocomplete='new-password', required=true, autofocus=true) }}
|
|
31
|
-
|
|
32
|
-
{{ field.password('password_confirmation', fields.passwordConfirmation,
|
|
33
|
-
'Repeat the password', autocomplete='new-password', required=true) }}
|
|
34
|
-
|
|
35
|
-
<p class="admin-hint">Every browser signed in as you is signed out, and this link stops working.</p>
|
|
36
|
-
|
|
37
|
-
<button type="submit">Set the password</button>
|
|
38
|
-
</form>
|
|
39
|
-
{% endif %}
|
|
48
|
+
{% endcall %}
|
|
40
49
|
{% endblock %}
|
|
@@ -1,28 +1,34 @@
|
|
|
1
1
|
{% extends "layouts/base.njk" %}
|
|
2
2
|
{% import "components/fields.njk" as field %}
|
|
3
|
+
{% from "components/button.njk" import button %}
|
|
4
|
+
{% from "components/card.njk" import card %}
|
|
3
5
|
|
|
4
6
|
{% block title %}Set up{% endblock %}
|
|
5
7
|
|
|
6
8
|
{% block content %}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
{% call card() %}
|
|
10
|
+
<h1 class="card-title text-2xl">Create the first admin</h1>
|
|
11
|
+
<p>Nobody can sign in to this site yet. Pick a username and a password.</p>
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
{% if error %}
|
|
14
|
+
{{ field.summary(error) }}
|
|
15
|
+
{% endif %}
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
<form class="flex flex-col gap-2" method="post" action="{{ setupUrl }}">
|
|
18
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
{{ field.text('username', 'username', 'Username', username,
|
|
21
|
+
autocomplete='username', required=true, autofocus=true) }}
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
{{ field.password('password', 'password', 'Password',
|
|
24
|
+
autocomplete='new-password', required=true) }}
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
{{ field.password('password_confirmation', 'password_confirmation', 'Repeat the password',
|
|
27
|
+
autocomplete='new-password', required=true) }}
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
<div class="mt-4">
|
|
30
|
+
{{ button('Create admin', type='submit', color='primary', shape='block') }}
|
|
31
|
+
</div>
|
|
32
|
+
</form>
|
|
33
|
+
{% endcall %}
|
|
28
34
|
{% endblock %}
|
|
@@ -1,67 +1,73 @@
|
|
|
1
1
|
{# /admin/appearance/themes: the theme the site is wearing, everything else on
|
|
2
2
|
disk, and the one button that changes it (decision-15).
|
|
3
3
|
|
|
4
|
-
The packaged theme comes first because it is the floor
|
|
5
|
-
over rather than a peer in the list: a site theme ships
|
|
6
|
-
inherits the rest. The themes directory is read on
|
|
7
|
-
copied in over ssh or pulled down by git is here
|
|
4
|
+
One card per theme. The packaged theme comes first because it is the floor
|
|
5
|
+
the others are laid over rather than a peer in the list: a site theme ships
|
|
6
|
+
what it changes and inherits the rest. The themes directory is read on
|
|
7
|
+
every request, so a theme copied in over ssh or pulled down by git is here
|
|
8
|
+
without a restart. #}
|
|
8
9
|
{% extends "layouts/shell.njk" %}
|
|
10
|
+
{% from "components/badge.njk" import badge, status %}
|
|
11
|
+
{% from "components/button.njk" import button %}
|
|
12
|
+
{% from "components/card.njk" import card, cardActions %}
|
|
9
13
|
|
|
10
14
|
{% block title %}{{ heading }}{% endblock %}
|
|
11
15
|
|
|
12
16
|
{% block content %}
|
|
13
|
-
<h1>{{ heading }}</h1>
|
|
17
|
+
<h1 class="mb-6 text-2xl font-bold">{{ heading }}</h1>
|
|
14
18
|
|
|
15
|
-
<ul class="
|
|
19
|
+
<ul class="mb-8 grid grid-cols-1 gap-6 md:grid-cols-2 2xl:grid-cols-3">
|
|
16
20
|
{% for theme in themes %}
|
|
17
|
-
<li
|
|
18
|
-
|
|
21
|
+
<li>
|
|
22
|
+
{% call card(title=theme.name, style=('border' if theme.active else none)) %}
|
|
23
|
+
<p class="flex flex-wrap items-center gap-2">
|
|
24
|
+
<code>{{ theme.id }}</code>
|
|
25
|
+
{% if theme.active %}
|
|
26
|
+
{{ status('active', 'Active') }}
|
|
27
|
+
{% endif %}
|
|
28
|
+
{% if theme.packaged %}
|
|
29
|
+
{{ badge('the theme this package ships', style='outline') }}
|
|
30
|
+
{% endif %}
|
|
31
|
+
</p>
|
|
19
32
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
{% endif %}
|
|
23
|
-
|
|
24
|
-
{% if theme.description %}
|
|
25
|
-
<p class="admin-theme-description">{{ theme.description }}</p>
|
|
26
|
-
{% endif %}
|
|
27
|
-
|
|
28
|
-
<p class="admin-theme-id">
|
|
29
|
-
<code>{{ theme.id }}</code>
|
|
30
|
-
{% if theme.packaged %}
|
|
31
|
-
<span class="admin-status">the theme this package ships</span>
|
|
33
|
+
{% if theme.description %}
|
|
34
|
+
<p>{{ theme.description }}</p>
|
|
32
35
|
{% endif %}
|
|
33
|
-
</p>
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
{% if not theme.active %}
|
|
38
|
+
<form method="post" action="{{ themesUrl }}">
|
|
39
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
40
|
+
<input type="hidden" name="{{ fields.theme }}" value="{{ theme.value }}" />
|
|
41
|
+
{% call cardActions() %}
|
|
42
|
+
{{ button('Activate', type='submit', color='primary') }}
|
|
43
|
+
{% endcall %}
|
|
44
|
+
</form>
|
|
45
|
+
{% endif %}
|
|
46
|
+
{% endcall %}
|
|
42
47
|
</li>
|
|
43
48
|
{% endfor %}
|
|
44
49
|
</ul>
|
|
45
50
|
|
|
46
51
|
{% if unreadable.length %}
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
52
|
+
<div class="mb-8 max-w-2xl">
|
|
53
|
+
{% call card(title='Not themes') %}
|
|
54
|
+
<p class="text-sm">
|
|
55
|
+
These are directories in <code class="break-all">{{ themesDir }}</code> that were meant to be themes and
|
|
56
|
+
are not. They are listed rather than skipped, so a typo in a <code>theme.json</code> is
|
|
57
|
+
something you can see rather than a theme that quietly stopped appearing. None of them
|
|
58
|
+
can be activated.
|
|
59
|
+
</p>
|
|
60
|
+
<ul class="list-disc ps-5">
|
|
61
|
+
{% for entry in unreadable %}
|
|
62
|
+
<li class="break-all"><code>{{ entry.id }}</code> — {{ entry.reason }}</li>
|
|
63
|
+
{% endfor %}
|
|
64
|
+
</ul>
|
|
65
|
+
{% endcall %}
|
|
66
|
+
</div>
|
|
61
67
|
{% endif %}
|
|
62
68
|
|
|
63
|
-
<p class="
|
|
64
|
-
A theme is a directory in <code>{{ themesDir }}</code> with a <code>theme.json</code> in it,
|
|
69
|
+
<p class="max-w-prose text-sm">
|
|
70
|
+
A theme is a directory in <code class="break-all">{{ themesDir }}</code> with a <code>theme.json</code> in it,
|
|
65
71
|
named by that directory. It is laid over the theme this package ships, one file at a time, so
|
|
66
72
|
it need only carry what it changes. Activating one writes the directory name into
|
|
67
73
|
<code>content/_data/site.json</code>; the next request is already wearing it.
|
|
@@ -1,133 +1,115 @@
|
|
|
1
|
-
{# /admin/comments: the moderation queue
|
|
2
|
-
so this screen is the notification — which is why the dashboard carries the
|
|
3
|
-
pending count and why this list opens on Pending.
|
|
1
|
+
{# /admin/comments: the moderation queue, opening on Pending.
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
One card per comment: who wrote it, where and when, what it says, and a row
|
|
4
|
+
of buttons, each a form of its own so the screen works with JavaScript
|
|
5
|
+
switched off. Reply is a collapse holding its own form, folded until it is
|
|
6
|
+
opened. #}
|
|
7
7
|
{% extends "layouts/shell.njk" %}
|
|
8
|
+
{% import "components/fields.njk" as field %}
|
|
9
|
+
{% from "components/badge.njk" import badge, status as statusBadge %}
|
|
10
|
+
{% from "components/button.njk" import button %}
|
|
11
|
+
{% from "components/card.njk" import card %}
|
|
12
|
+
{% from "components/collapse.njk" import collapse %}
|
|
13
|
+
{% from "components/pagination.njk" import pagination %}
|
|
14
|
+
{% from "components/tabs.njk" import tabs as tabsNav %}
|
|
8
15
|
|
|
9
16
|
{% block title %}{{ heading }}{% endblock %}
|
|
10
17
|
|
|
18
|
+
{% macro rowFields(row, fields, status, csrfToken) %}
|
|
19
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
20
|
+
<input type="hidden" name="{{ fields.id }}" value="{{ row.id }}" />
|
|
21
|
+
<input type="hidden" name="{{ fields.status }}" value="{{ status }}" />
|
|
22
|
+
{% endmacro %}
|
|
23
|
+
|
|
11
24
|
{% block content %}
|
|
12
|
-
<h1>{{ heading }}</h1>
|
|
25
|
+
<h1 class="mb-6 text-2xl font-bold">{{ heading }}</h1>
|
|
13
26
|
|
|
14
|
-
<
|
|
15
|
-
<ul>
|
|
16
|
-
{% for tab in tabs %}
|
|
17
|
-
<li>
|
|
18
|
-
<a href="{{ tab.url }}"{% if tab.current %} aria-current="page"{% endif %}>
|
|
19
|
-
{{ tab.label }} ({{ tab.count }})
|
|
20
|
-
</a>
|
|
21
|
-
</li>
|
|
22
|
-
{% endfor %}
|
|
23
|
-
</ul>
|
|
24
|
-
</nav>
|
|
27
|
+
<div class="mb-6">{{ tabsNav(tabs, 'Comment status') }}</div>
|
|
25
28
|
|
|
26
29
|
{% if rows.length == 0 %}
|
|
27
|
-
<p class="
|
|
30
|
+
<p class="mb-6">Nothing here.</p>
|
|
28
31
|
{% else %}
|
|
29
|
-
<ul class="
|
|
32
|
+
<ul class="mb-6 flex max-w-3xl flex-col gap-4">
|
|
30
33
|
{% for row in rows %}
|
|
31
|
-
<li
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
<li>
|
|
35
|
+
{% call card() %}
|
|
36
|
+
<p class="flex flex-wrap items-center gap-x-3 gap-y-1">
|
|
37
|
+
<span class="font-semibold">{{ row.author }}</span>
|
|
38
|
+
{% if row.url %}
|
|
39
|
+
<a class="link break-all" href="{{ row.url }}" rel="nofollow ugc noopener noreferrer">{{ row.url }}</a>
|
|
40
|
+
{% endif %}
|
|
41
|
+
{% if row.email %}
|
|
42
|
+
<span class="break-all">{{ row.email }}</span>
|
|
43
|
+
{% endif %}
|
|
44
|
+
{{ statusBadge(row.status, row.status | capitalize) }}
|
|
45
|
+
{% if row.source != 'comment' %}
|
|
46
|
+
{{ badge(row.source | capitalize, style='outline') }}
|
|
47
|
+
{% endif %}
|
|
48
|
+
</p>
|
|
45
49
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
50
|
+
<p class="text-sm">
|
|
51
|
+
<time>{{ row.submitted }}</time>
|
|
52
|
+
on
|
|
53
|
+
{% if row.editUrl %}
|
|
54
|
+
<a class="link" href="{{ row.editUrl }}">{{ row.post }}</a>
|
|
55
|
+
{% else %}
|
|
56
|
+
{{ row.post }}
|
|
57
|
+
{% endif %}
|
|
58
|
+
{% if row.postUrl %}
|
|
59
|
+
· <a class="link" href="{{ row.postUrl }}#comment-{{ row.id }}">View</a>
|
|
60
|
+
{% endif %}
|
|
61
|
+
{% if row.inReplyTo %}
|
|
62
|
+
· a reply to another comment
|
|
63
|
+
{% endif %}
|
|
64
|
+
{% if row.address %}
|
|
65
|
+
· <code title="A salted hash of the address it came from">{{ row.address }}</code>
|
|
66
|
+
{% endif %}
|
|
67
|
+
{% if row.removed %}
|
|
68
|
+
· {{ row.removed }}
|
|
69
|
+
{% endif %}
|
|
70
|
+
</p>
|
|
67
71
|
|
|
68
|
-
|
|
72
|
+
<div class="space-y-2 break-words">{{ row.html | safe }}</div>
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
<div class="flex flex-wrap gap-1">
|
|
75
|
+
{% if row.status != 'approved' %}
|
|
76
|
+
<form method="post" action="{{ moderateUrl }}">
|
|
77
|
+
{{ rowFields(row, fields, status, csrfToken) }}
|
|
78
|
+
{{ button('Approve', type='submit', style='ghost', size='xs', name=fields.action, value='approve') }}
|
|
79
|
+
</form>
|
|
80
|
+
{% endif %}
|
|
81
|
+
{% if row.status != 'spam' %}
|
|
82
|
+
<form method="post" action="{{ moderateUrl }}">
|
|
83
|
+
{{ rowFields(row, fields, status, csrfToken) }}
|
|
84
|
+
{{ button('Spam', type='submit', style='ghost', size='xs', name=fields.action, value='spam') }}
|
|
85
|
+
</form>
|
|
86
|
+
{% endif %}
|
|
72
87
|
<form method="post" action="{{ moderateUrl }}">
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<input type="hidden" name="{{ fields.status }}" value="{{ status }}" />
|
|
76
|
-
<button type="submit" name="{{ fields.action }}" value="approve">Approve</button>
|
|
88
|
+
{{ rowFields(row, fields, status, csrfToken) }}
|
|
89
|
+
{{ button('Delete', type='submit', color='error', style='ghost', size='xs', name=fields.action, value='delete') }}
|
|
77
90
|
</form>
|
|
78
|
-
|
|
91
|
+
</div>
|
|
79
92
|
|
|
80
|
-
{%
|
|
81
|
-
<form method="post" action="{{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
93
|
+
{% call collapse('Reply') %}
|
|
94
|
+
<form method="post" action="{{ replyUrl }}">
|
|
95
|
+
{{ rowFields(row, fields, status, csrfToken) }}
|
|
96
|
+
{% set replyLabel %}Reply to {{ row.author }}{% endset %}
|
|
97
|
+
{{ field.textarea('reply-' + loop.index, fields.body, replyLabel, rows='4', required=true,
|
|
98
|
+
hint='Markdown, rendered the same way a visitor’s comment is. It is posted approved, under this one.') }}
|
|
99
|
+
<div class="mt-2">{{ button('Post reply', type='submit', color='primary') }}</div>
|
|
86
100
|
</form>
|
|
87
|
-
{%
|
|
88
|
-
|
|
89
|
-
<form method="post" action="{{ moderateUrl }}">
|
|
90
|
-
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
91
|
-
<input type="hidden" name="{{ fields.id }}" value="{{ row.id }}" />
|
|
92
|
-
<input type="hidden" name="{{ fields.status }}" value="{{ status }}" />
|
|
93
|
-
<button type="submit" name="{{ fields.action }}" value="delete">Delete</button>
|
|
94
|
-
</form>
|
|
95
|
-
</div>
|
|
96
|
-
|
|
97
|
-
<details class="admin-comment-reply">
|
|
98
|
-
<summary>Reply</summary>
|
|
99
|
-
<form method="post" action="{{ replyUrl }}">
|
|
100
|
-
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
101
|
-
<input type="hidden" name="{{ fields.id }}" value="{{ row.id }}" />
|
|
102
|
-
<input type="hidden" name="{{ fields.status }}" value="{{ status }}" />
|
|
103
|
-
<label class="admin-visually-hidden" for="reply-{{ loop.index }}">
|
|
104
|
-
Reply to {{ row.author }}
|
|
105
|
-
</label>
|
|
106
|
-
<textarea id="reply-{{ loop.index }}" name="{{ fields.body }}" rows="4" required></textarea>
|
|
107
|
-
<p class="admin-hint">Markdown, rendered the same way a visitor’s comment is. It is posted approved, under this one.</p>
|
|
108
|
-
<p class="admin-settings-buttons">
|
|
109
|
-
<button type="submit">Post reply</button>
|
|
110
|
-
</p>
|
|
111
|
-
</form>
|
|
112
|
-
</details>
|
|
101
|
+
{% endcall %}
|
|
102
|
+
{% endcall %}
|
|
113
103
|
</li>
|
|
114
104
|
{% endfor %}
|
|
115
105
|
</ul>
|
|
116
106
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
<a rel="prev" href="{{ previousUrl }}">Newer</a>
|
|
121
|
-
{% endif %}
|
|
122
|
-
<span>Page {{ page }} of {{ pages }}</span>
|
|
123
|
-
{% if nextUrl %}
|
|
124
|
-
<a rel="next" href="{{ nextUrl }}">Older</a>
|
|
125
|
-
{% endif %}
|
|
126
|
-
</nav>
|
|
127
|
-
{% endif %}
|
|
107
|
+
<div class="mb-6">
|
|
108
|
+
{{ pagination(page, pages=pages, previousUrl=previousUrl, nextUrl=nextUrl) }}
|
|
109
|
+
</div>
|
|
128
110
|
{% endif %}
|
|
129
111
|
|
|
130
|
-
<p class="
|
|
112
|
+
<p class="max-w-prose text-sm">
|
|
131
113
|
Comments live as one JSON file per post under <code>content/_data/comments/</code>, so they
|
|
132
114
|
are in git beside the posts and an Eleventy build of the same directory shows them. Everything
|
|
133
115
|
here rewrites that file; the database is only an index of it. Spam is kept rather than deleted,
|
|
@@ -1,72 +1,60 @@
|
|
|
1
1
|
{% extends "layouts/shell.njk" %}
|
|
2
|
+
{% from "components/stat.njk" import stats, stat %}
|
|
3
|
+
{% from "components/card.njk" import card %}
|
|
4
|
+
{% from "components/table.njk" import table %}
|
|
5
|
+
{% from "components/badge.njk" import status %}
|
|
2
6
|
|
|
3
7
|
{% block title %}Dashboard{% endblock %}
|
|
4
8
|
|
|
5
9
|
{% block content %}
|
|
6
|
-
<h1>Dashboard</h1>
|
|
10
|
+
<h1 class="mb-6 text-2xl font-bold">Dashboard</h1>
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<div>
|
|
17
|
-
<dt>Drafts</dt>
|
|
18
|
-
<dd>{{ counts.drafts }}</dd>
|
|
19
|
-
</div>
|
|
20
|
-
<div>
|
|
21
|
-
<dt>Pages</dt>
|
|
22
|
-
<dd>{{ counts.pages }}</dd>
|
|
23
|
-
</div>
|
|
24
|
-
<div>
|
|
25
|
-
<dt>Followers</dt>
|
|
26
|
-
<dd><a href="{{ federationUrl }}">{{ followers }}</a></dd>
|
|
27
|
-
</div>
|
|
28
|
-
<div>
|
|
29
|
-
<dt>Comments waiting</dt>
|
|
30
|
-
<dd><a href="{{ commentsUrl }}?status=pending">{{ pendingComments }}</a></dd>
|
|
31
|
-
</div>
|
|
32
|
-
<div>
|
|
33
|
-
<dt>Messages unread</dt>
|
|
34
|
-
<dd><a href="{{ messagesUrl }}">{{ unreadMessages }}</a></dd>
|
|
35
|
-
</div>
|
|
36
|
-
</dl>
|
|
37
|
-
</section>
|
|
12
|
+
{% set glance = [
|
|
13
|
+
{ label: 'Published posts', value: counts.posts },
|
|
14
|
+
{ label: 'Drafts', value: counts.drafts },
|
|
15
|
+
{ label: 'Pages', value: counts.pages },
|
|
16
|
+
{ label: 'Followers', value: followers, href: federationUrl },
|
|
17
|
+
{ label: 'Comments waiting', value: pendingComments, href: commentsUrl + '?status=pending' },
|
|
18
|
+
{ label: 'Messages unread', value: unreadMessages, href: messagesUrl }
|
|
19
|
+
] %}
|
|
38
20
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
21
|
+
<section class="@container mb-8">
|
|
22
|
+
<h2 class="mb-3 text-lg font-semibold">At a glance</h2>
|
|
23
|
+
<div class="grid grid-cols-2 gap-4 @2xl:grid-cols-3 @5xl:grid-cols-6">
|
|
24
|
+
{% for count in glance %}
|
|
25
|
+
{% call stats() %}{{ stat(count.label, count.value, href=count.href) }}{% endcall %}
|
|
26
|
+
{% endfor %}
|
|
27
|
+
</div>
|
|
28
|
+
</section>
|
|
29
|
+
|
|
30
|
+
{% call card(title='Recent posts') %}
|
|
31
|
+
{% if recent.length %}
|
|
32
|
+
{% call table('Recent posts', inCard=true) %}
|
|
33
|
+
<thead>
|
|
34
|
+
<tr>
|
|
35
|
+
<th scope="col">Title</th>
|
|
36
|
+
<th scope="col">Date</th>
|
|
37
|
+
<th scope="col">Status</th>
|
|
38
|
+
</tr>
|
|
39
|
+
</thead>
|
|
40
|
+
<tbody>
|
|
41
|
+
{% for post in recent %}
|
|
45
42
|
<tr>
|
|
46
|
-
<
|
|
47
|
-
<
|
|
48
|
-
<
|
|
43
|
+
<td><a class="link link-hover" href="{{ post.editUrl }}">{{ post.title }}</a></td>
|
|
44
|
+
<td class="whitespace-nowrap">{{ post.date | date('html') }}</td>
|
|
45
|
+
<td>
|
|
46
|
+
{% if post.draft %}
|
|
47
|
+
{{ status('draft', 'Draft') }}
|
|
48
|
+
{% else %}
|
|
49
|
+
{{ status('published', 'Published') }}
|
|
50
|
+
{% endif %}
|
|
51
|
+
</td>
|
|
49
52
|
</tr>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
{% if post.draft %}
|
|
58
|
-
<span class="admin-status admin-status-draft">Draft</span>
|
|
59
|
-
{% else %}
|
|
60
|
-
<span class="admin-status">Published</span>
|
|
61
|
-
{% endif %}
|
|
62
|
-
</td>
|
|
63
|
-
</tr>
|
|
64
|
-
{% endfor %}
|
|
65
|
-
</tbody>
|
|
66
|
-
</table>
|
|
67
|
-
{% else %}
|
|
68
|
-
<p class="admin-empty">Nothing written yet.</p>
|
|
69
|
-
{% endif %}
|
|
70
|
-
</section>
|
|
71
|
-
</div>
|
|
53
|
+
{% endfor %}
|
|
54
|
+
</tbody>
|
|
55
|
+
{% endcall %}
|
|
56
|
+
{% else %}
|
|
57
|
+
<p>Nothing written yet.</p>
|
|
58
|
+
{% endif %}
|
|
59
|
+
{% endcall %}
|
|
72
60
|
{% endblock %}
|