@geekity/cms 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +870 -0
  3. package/admin/layouts/_flash.njk +5 -0
  4. package/admin/layouts/base.njk +27 -0
  5. package/admin/layouts/dashboard.njk +78 -0
  6. package/admin/layouts/document-conflict.njk +49 -0
  7. package/admin/layouts/document-editor.njk +167 -0
  8. package/admin/layouts/document-list.njk +92 -0
  9. package/admin/layouts/federation.njk +145 -0
  10. package/admin/layouts/login.njk +23 -0
  11. package/admin/layouts/placeholder.njk +10 -0
  12. package/admin/layouts/settings.njk +116 -0
  13. package/admin/layouts/setup.njk +27 -0
  14. package/admin/layouts/shell.njk +37 -0
  15. package/admin/layouts/users.njk +91 -0
  16. package/admin/static/admin.css +726 -0
  17. package/admin/static/editor.js +30 -0
  18. package/dist/admin/assets.d.ts +26 -0
  19. package/dist/admin/assets.d.ts.map +1 -0
  20. package/dist/admin/assets.js +38 -0
  21. package/dist/admin/assets.js.map +1 -0
  22. package/dist/admin/credentials.d.ts +28 -0
  23. package/dist/admin/credentials.d.ts.map +1 -0
  24. package/dist/admin/credentials.js +39 -0
  25. package/dist/admin/credentials.js.map +1 -0
  26. package/dist/admin/documents.d.ts +134 -0
  27. package/dist/admin/documents.d.ts.map +1 -0
  28. package/dist/admin/documents.js +613 -0
  29. package/dist/admin/documents.js.map +1 -0
  30. package/dist/admin/federation.d.ts +194 -0
  31. package/dist/admin/federation.d.ts.map +1 -0
  32. package/dist/admin/federation.js +299 -0
  33. package/dist/admin/federation.js.map +1 -0
  34. package/dist/admin/flash.d.ts +24 -0
  35. package/dist/admin/flash.d.ts.map +1 -0
  36. package/dist/admin/flash.js +31 -0
  37. package/dist/admin/flash.js.map +1 -0
  38. package/dist/admin/index.d.ts +23 -0
  39. package/dist/admin/index.d.ts.map +1 -0
  40. package/dist/admin/index.js +15 -0
  41. package/dist/admin/index.js.map +1 -0
  42. package/dist/admin/passwords.d.ts +49 -0
  43. package/dist/admin/passwords.d.ts.map +1 -0
  44. package/dist/admin/passwords.js +122 -0
  45. package/dist/admin/passwords.js.map +1 -0
  46. package/dist/admin/preview.d.ts +18 -0
  47. package/dist/admin/preview.d.ts.map +1 -0
  48. package/dist/admin/preview.js +83 -0
  49. package/dist/admin/preview.js.map +1 -0
  50. package/dist/admin/routes.d.ts +54 -0
  51. package/dist/admin/routes.d.ts.map +1 -0
  52. package/dist/admin/routes.js +383 -0
  53. package/dist/admin/routes.js.map +1 -0
  54. package/dist/admin/session.d.ts +44 -0
  55. package/dist/admin/session.d.ts.map +1 -0
  56. package/dist/admin/session.js +69 -0
  57. package/dist/admin/session.js.map +1 -0
  58. package/dist/admin/settings.d.ts +194 -0
  59. package/dist/admin/settings.d.ts.map +1 -0
  60. package/dist/admin/settings.js +470 -0
  61. package/dist/admin/settings.js.map +1 -0
  62. package/dist/admin/store.d.ts +407 -0
  63. package/dist/admin/store.d.ts.map +1 -0
  64. package/dist/admin/store.js +704 -0
  65. package/dist/admin/store.js.map +1 -0
  66. package/dist/admin/templates.d.ts +36 -0
  67. package/dist/admin/templates.d.ts.map +1 -0
  68. package/dist/admin/templates.js +43 -0
  69. package/dist/admin/templates.js.map +1 -0
  70. package/dist/admin/uploads.d.ts +96 -0
  71. package/dist/admin/uploads.d.ts.map +1 -0
  72. package/dist/admin/uploads.js +179 -0
  73. package/dist/admin/uploads.js.map +1 -0
  74. package/dist/admin/users.d.ts +95 -0
  75. package/dist/admin/users.d.ts.map +1 -0
  76. package/dist/admin/users.js +233 -0
  77. package/dist/admin/users.js.map +1 -0
  78. package/dist/cli.d.ts +85 -0
  79. package/dist/cli.d.ts.map +1 -0
  80. package/dist/cli.js +424 -0
  81. package/dist/cli.js.map +1 -0
  82. package/dist/config.d.ts +172 -0
  83. package/dist/config.d.ts.map +1 -0
  84. package/dist/config.js +184 -0
  85. package/dist/config.js.map +1 -0
  86. package/dist/content/document.d.ts +66 -0
  87. package/dist/content/document.d.ts.map +1 -0
  88. package/dist/content/document.js +13 -0
  89. package/dist/content/document.js.map +1 -0
  90. package/dist/content/index.d.ts +17 -0
  91. package/dist/content/index.d.ts.map +1 -0
  92. package/dist/content/index.js +10 -0
  93. package/dist/content/index.js.map +1 -0
  94. package/dist/content/markdown.d.ts +3 -0
  95. package/dist/content/markdown.d.ts.map +1 -0
  96. package/dist/content/markdown.js +39 -0
  97. package/dist/content/markdown.js.map +1 -0
  98. package/dist/content/media.d.ts +65 -0
  99. package/dist/content/media.d.ts.map +1 -0
  100. package/dist/content/media.js +143 -0
  101. package/dist/content/media.js.map +1 -0
  102. package/dist/content/parser.d.ts +24 -0
  103. package/dist/content/parser.d.ts.map +1 -0
  104. package/dist/content/parser.js +165 -0
  105. package/dist/content/parser.js.map +1 -0
  106. package/dist/content/save.d.ts +60 -0
  107. package/dist/content/save.d.ts.map +1 -0
  108. package/dist/content/save.js +103 -0
  109. package/dist/content/save.js.map +1 -0
  110. package/dist/content/slug.d.ts +25 -0
  111. package/dist/content/slug.d.ts.map +1 -0
  112. package/dist/content/slug.js +75 -0
  113. package/dist/content/slug.js.map +1 -0
  114. package/dist/content/store.d.ts +133 -0
  115. package/dist/content/store.d.ts.map +1 -0
  116. package/dist/content/store.js +411 -0
  117. package/dist/content/store.js.map +1 -0
  118. package/dist/content/sync.d.ts +146 -0
  119. package/dist/content/sync.d.ts.map +1 -0
  120. package/dist/content/sync.js +421 -0
  121. package/dist/content/sync.js.map +1 -0
  122. package/dist/content/writer.d.ts +37 -0
  123. package/dist/content/writer.d.ts.map +1 -0
  124. package/dist/content/writer.js +97 -0
  125. package/dist/content/writer.js.map +1 -0
  126. package/dist/env.d.ts +48 -0
  127. package/dist/env.d.ts.map +1 -0
  128. package/dist/env.js +2 -0
  129. package/dist/env.js.map +1 -0
  130. package/dist/federation/actor.d.ts +55 -0
  131. package/dist/federation/actor.d.ts.map +1 -0
  132. package/dist/federation/actor.js +101 -0
  133. package/dist/federation/actor.js.map +1 -0
  134. package/dist/federation/article.d.ts +83 -0
  135. package/dist/federation/article.d.ts.map +1 -0
  136. package/dist/federation/article.js +169 -0
  137. package/dist/federation/article.js.map +1 -0
  138. package/dist/federation/delivery.d.ts +90 -0
  139. package/dist/federation/delivery.d.ts.map +1 -0
  140. package/dist/federation/delivery.js +289 -0
  141. package/dist/federation/delivery.js.map +1 -0
  142. package/dist/federation/federation.d.ts +75 -0
  143. package/dist/federation/federation.d.ts.map +1 -0
  144. package/dist/federation/federation.js +190 -0
  145. package/dist/federation/federation.js.map +1 -0
  146. package/dist/federation/followers.d.ts +43 -0
  147. package/dist/federation/followers.d.ts.map +1 -0
  148. package/dist/federation/followers.js +69 -0
  149. package/dist/federation/followers.js.map +1 -0
  150. package/dist/federation/inbox.d.ts +68 -0
  151. package/dist/federation/inbox.d.ts.map +1 -0
  152. package/dist/federation/inbox.js +171 -0
  153. package/dist/federation/inbox.js.map +1 -0
  154. package/dist/federation/index.d.ts +14 -0
  155. package/dist/federation/index.d.ts.map +1 -0
  156. package/dist/federation/index.js +10 -0
  157. package/dist/federation/index.js.map +1 -0
  158. package/dist/federation/keys.d.ts +27 -0
  159. package/dist/federation/keys.d.ts.map +1 -0
  160. package/dist/federation/keys.js +60 -0
  161. package/dist/federation/keys.js.map +1 -0
  162. package/dist/federation/mount.d.ts +23 -0
  163. package/dist/federation/mount.d.ts.map +1 -0
  164. package/dist/federation/mount.js +71 -0
  165. package/dist/federation/mount.js.map +1 -0
  166. package/dist/federation/paths.d.ts +85 -0
  167. package/dist/federation/paths.d.ts.map +1 -0
  168. package/dist/federation/paths.js +97 -0
  169. package/dist/federation/paths.js.map +1 -0
  170. package/dist/index.d.ts +106 -0
  171. package/dist/index.d.ts.map +1 -0
  172. package/dist/index.js +148 -0
  173. package/dist/index.js.map +1 -0
  174. package/dist/init.d.ts +71 -0
  175. package/dist/init.d.ts.map +1 -0
  176. package/dist/init.js +125 -0
  177. package/dist/init.js.map +1 -0
  178. package/dist/web/assets.d.ts +65 -0
  179. package/dist/web/assets.d.ts.map +1 -0
  180. package/dist/web/assets.js +152 -0
  181. package/dist/web/assets.js.map +1 -0
  182. package/dist/web/context.d.ts +121 -0
  183. package/dist/web/context.d.ts.map +1 -0
  184. package/dist/web/context.js +112 -0
  185. package/dist/web/context.js.map +1 -0
  186. package/dist/web/documents.d.ts +28 -0
  187. package/dist/web/documents.d.ts.map +1 -0
  188. package/dist/web/documents.js +39 -0
  189. package/dist/web/documents.js.map +1 -0
  190. package/dist/web/feeds.d.ts +122 -0
  191. package/dist/web/feeds.d.ts.map +1 -0
  192. package/dist/web/feeds.js +229 -0
  193. package/dist/web/feeds.js.map +1 -0
  194. package/dist/web/index.d.ts +17 -0
  195. package/dist/web/index.d.ts.map +1 -0
  196. package/dist/web/index.js +10 -0
  197. package/dist/web/index.js.map +1 -0
  198. package/dist/web/negotiate.d.ts +219 -0
  199. package/dist/web/negotiate.d.ts.map +1 -0
  200. package/dist/web/negotiate.js +409 -0
  201. package/dist/web/negotiate.js.map +1 -0
  202. package/dist/web/pagination.d.ts +48 -0
  203. package/dist/web/pagination.d.ts.map +1 -0
  204. package/dist/web/pagination.js +30 -0
  205. package/dist/web/pagination.js.map +1 -0
  206. package/dist/web/render.d.ts +72 -0
  207. package/dist/web/render.d.ts.map +1 -0
  208. package/dist/web/render.js +73 -0
  209. package/dist/web/render.js.map +1 -0
  210. package/dist/web/routes.d.ts +31 -0
  211. package/dist/web/routes.d.ts.map +1 -0
  212. package/dist/web/routes.js +366 -0
  213. package/dist/web/routes.js.map +1 -0
  214. package/dist/web/templates.d.ts +34 -0
  215. package/dist/web/templates.d.ts.map +1 -0
  216. package/dist/web/templates.js +106 -0
  217. package/dist/web/templates.js.map +1 -0
  218. package/package.json +68 -0
  219. package/templates/site/content/_data/site.json +8 -0
  220. package/templates/site/content/pages/about.md +11 -0
  221. package/templates/site/content/pages/pages.json +3 -0
  222. package/templates/site/content/posts/2026-01-01-hello-world.md +34 -0
  223. package/templates/site/content/posts/posts.json +4 -0
  224. package/templates/site/geekity.config.ts +11 -0
  225. package/templates/site/gitignore +3 -0
  226. package/templates/site/server.ts +20 -0
  227. package/templates/site/tsconfig.json +18 -0
  228. package/themes/default/README.md +148 -0
  229. package/themes/default/layouts/404.njk +9 -0
  230. package/themes/default/layouts/base.njk +59 -0
  231. package/themes/default/layouts/home.njk +9 -0
  232. package/themes/default/layouts/page.njk +13 -0
  233. package/themes/default/layouts/post.njk +30 -0
  234. package/themes/default/layouts/tag.njk +19 -0
  235. package/themes/default/partials/pagination.njk +14 -0
  236. package/themes/default/partials/post-list.njk +24 -0
  237. package/themes/default/partials/tags.njk +12 -0
  238. package/themes/default/static/style.css +327 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/web/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { Environment } from 'nunjucks';
2
+ /**
3
+ * The theme that ships inside the package, resolved from this module rather
4
+ * than from the working directory, so it is found whether the CMS is running
5
+ * from `src/` under tsx or from `dist/` as an installed dependency.
6
+ */
7
+ export declare const PACKAGED_THEME_DIR: string;
8
+ /** Where a {@link createTemplateEnvironment} looks, and how it caches. */
9
+ export interface CreateTemplateEnvironmentOptions {
10
+ /** The site's own theme directory. Searched first. It need not exist. */
11
+ themeDir: string;
12
+ /** Public origin, for the `url` and `absoluteUrl` filters. */
13
+ baseUrl: string;
14
+ /**
15
+ * Recompile a template on every render instead of caching it. On while the
16
+ * content watcher is on, so editing a template in development shows up
17
+ * without a restart.
18
+ */
19
+ noCache?: boolean | undefined;
20
+ }
21
+ /**
22
+ * A Nunjucks environment whose loader searches the site theme first and the
23
+ * packaged default theme second, one file at a time.
24
+ *
25
+ * That is the whole override mechanism: a site that ships only
26
+ * `theme/layouts/post.njk` replaces the post layout and keeps receiving
27
+ * updates to every other template.
28
+ */
29
+ export declare function createTemplateEnvironment(options: CreateTemplateEnvironmentOptions): Environment;
30
+ /** How `date` renders a value. */
31
+ export type DateFormat = 'readable' | 'iso' | 'html' | 'year';
32
+ /** `date` filter. An unparseable value renders as the empty string. */
33
+ export declare function formatDate(value: unknown, format: string): string;
34
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/web/templates.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAoB,MAAM,UAAU,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAEhC,CAAC;AAEF,0EAA0E;AAC1E,MAAM,WAAW,gCAAgC;IAC/C,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gCAAgC,GAAG,WAAW,CAahG;AAED,kCAAkC;AAClC,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AA0D9D,uEAAuE;AACvE,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBjE"}
@@ -0,0 +1,106 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import { Environment, FileSystemLoader } from 'nunjucks';
3
+ /**
4
+ * The theme that ships inside the package, resolved from this module rather
5
+ * than from the working directory, so it is found whether the CMS is running
6
+ * from `src/` under tsx or from `dist/` as an installed dependency.
7
+ */
8
+ export const PACKAGED_THEME_DIR = fileURLToPath(new URL('../../themes/default/', import.meta.url));
9
+ /**
10
+ * A Nunjucks environment whose loader searches the site theme first and the
11
+ * packaged default theme second, one file at a time.
12
+ *
13
+ * That is the whole override mechanism: a site that ships only
14
+ * `theme/layouts/post.njk` replaces the post layout and keeps receiving
15
+ * updates to every other template.
16
+ */
17
+ export function createTemplateEnvironment(options) {
18
+ const loader = new FileSystemLoader([options.themeDir, PACKAGED_THEME_DIR], {
19
+ noCache: options.noCache === true,
20
+ });
21
+ const environment = new Environment(loader, {
22
+ autoescape: true,
23
+ throwOnUndefined: false,
24
+ trimBlocks: true,
25
+ lstripBlocks: true,
26
+ });
27
+ return addFilters(environment, options.baseUrl);
28
+ }
29
+ /**
30
+ * The filter set, which is part of the semver contract because site templates
31
+ * are written against it.
32
+ *
33
+ * Dates are formatted in UTC. A date in the front matter keeps its offset in
34
+ * the file and in the JSON representation; what a theme prints is the same
35
+ * instant expressed as UTC, which is what an Eleventy site using Luxon with
36
+ * `zone: 'utc'` prints too.
37
+ */
38
+ function addFilters(environment, baseUrl) {
39
+ const base = new URL(baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`);
40
+ const basePath = base.pathname === '/' ? '' : base.pathname.replace(/\/$/, '');
41
+ environment.addFilter('date', (value, format = 'readable') => formatDate(value, typeof format === 'string' ? format : 'readable'));
42
+ // Eleventy's `url` filter: make a site-root path absolute against the base
43
+ // path, so a site served from a subdirectory links correctly.
44
+ const withBasePath = (value) => {
45
+ const pathname = typeof value === 'string' ? value : '';
46
+ return pathname.startsWith('/') ? `${basePath}${pathname}` : pathname;
47
+ };
48
+ environment.addFilter('url', withBasePath);
49
+ // A fully qualified URL, for canonical links, feeds and ActivityPub ids.
50
+ // The base path goes on first, because a root-relative URL resolved against
51
+ // an origin would otherwise throw the subdirectory away.
52
+ environment.addFilter('absoluteUrl', (value) => {
53
+ const pathname = withBasePath(value);
54
+ try {
55
+ return new URL(pathname, base).href;
56
+ }
57
+ catch {
58
+ return pathname;
59
+ }
60
+ });
61
+ return environment;
62
+ }
63
+ const MONTHS = [
64
+ 'January',
65
+ 'February',
66
+ 'March',
67
+ 'April',
68
+ 'May',
69
+ 'June',
70
+ 'July',
71
+ 'August',
72
+ 'September',
73
+ 'October',
74
+ 'November',
75
+ 'December',
76
+ ];
77
+ /** `date` filter. An unparseable value renders as the empty string. */
78
+ export function formatDate(value, format) {
79
+ const date = toDate(value);
80
+ if (date === undefined)
81
+ return '';
82
+ const year = String(date.getUTCFullYear());
83
+ const month = String(date.getUTCMonth() + 1).padStart(2, '0');
84
+ const day = String(date.getUTCDate()).padStart(2, '0');
85
+ switch (format) {
86
+ case 'iso':
87
+ return date.toISOString();
88
+ case 'html':
89
+ return `${year}-${month}-${day}`;
90
+ case 'year':
91
+ return year;
92
+ case 'readable':
93
+ default:
94
+ return `${String(date.getUTCDate())} ${MONTHS[date.getUTCMonth()] ?? ''} ${year}`;
95
+ }
96
+ }
97
+ function toDate(value) {
98
+ if (value instanceof Date)
99
+ return Number.isNaN(value.getTime()) ? undefined : value;
100
+ if (typeof value === 'string' || typeof value === 'number') {
101
+ const parsed = new Date(value);
102
+ return Number.isNaN(parsed.getTime()) ? undefined : parsed;
103
+ }
104
+ return undefined;
105
+ }
106
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/web/templates.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@geekity/cms",
3
+ "version": "0.3.0",
4
+ "type": "module",
5
+ "description": "A file-first CMS: Markdown content, a SQLite index, a Hono server that is both the editor and the public site.",
6
+ "license": "MIT",
7
+ "engines": {
8
+ "node": ">=24"
9
+ },
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ },
17
+ "./package.json": "./package.json"
18
+ },
19
+ "bin": {
20
+ "geekity": "./dist/cli.js"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "admin",
25
+ "themes",
26
+ "templates",
27
+ "README.md",
28
+ "LICENSE"
29
+ ],
30
+ "dependencies": {
31
+ "@fedify/fedify": "^2.3.6",
32
+ "@fedify/hono": "^2.3.6",
33
+ "@fedify/vocab": "^2.3.6",
34
+ "@hono/node-server": "^2.1.1",
35
+ "@js-temporal/polyfill": "^0.5.1",
36
+ "chokidar": "^5.0.0",
37
+ "gray-matter": "^4.0.3",
38
+ "hono": "^4.13.5",
39
+ "js-yaml": "^5.4.1",
40
+ "markdown-it": "^15.0.1",
41
+ "markdown-it-footnote": "^4.0.0",
42
+ "nunjucks": "^3.2.4"
43
+ },
44
+ "devDependencies": {
45
+ "@11ty/eleventy": "^3.1.6",
46
+ "@codemirror/lang-markdown": "^6.5.2",
47
+ "@fedify/cli": "2.3.6",
48
+ "@types/markdown-it-footnote": "^3.0.4",
49
+ "@types/node": "^24.13.3",
50
+ "@types/nunjucks": "^3.2.6",
51
+ "codemirror": "^6.0.2",
52
+ "esbuild": "^0.28.2",
53
+ "tsx": "^4.23.13",
54
+ "typescript": "^7.0.2"
55
+ },
56
+ "scripts": {
57
+ "build": "tsc -p tsconfig.build.json && node scripts/build-editor.js",
58
+ "build:editor": "node scripts/build-editor.js",
59
+ "dev": "tsc -p tsconfig.build.json --watch",
60
+ "test": "tsx --test \"src/**/*.test.ts\"",
61
+ "test:11ty": "tsx --test \"test/*.test.ts\"",
62
+ "fed:smoke": "tsx scripts/fed-smoke.ts",
63
+ "test:coverage": "tsx --test --experimental-test-coverage \"src/**/*.test.ts\"",
64
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p editor/tsconfig.json --noEmit",
65
+ "lint": "eslint .",
66
+ "lint:fix": "eslint . --fix"
67
+ }
68
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "title": "A Geekity site",
3
+ "tagline": "Markdown on disk, served straight",
4
+ "url": "http://localhost:3000",
5
+ "author": "You",
6
+ "postsPerPage": 10,
7
+ "feedSize": 20
8
+ }
@@ -0,0 +1,11 @@
1
+ ---
2
+ title: About
3
+ permalink: /about/
4
+ ---
5
+
6
+ This is a page. Pages live in `content/pages/` and, unless the front matter
7
+ says otherwise, are served at `/{slug}/`.
8
+
9
+ Edit this file and save it. The change is live before you can switch back to
10
+ the browser: the CMS watches `content/` and re-indexes a file the moment it
11
+ changes.
@@ -0,0 +1,3 @@
1
+ {
2
+ "layout": "page"
3
+ }
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: Hello, world
3
+ date: '2026-01-01T09:00:00Z'
4
+ permalink: /2026/01/hello-world/
5
+ tags:
6
+ - introductions
7
+ description: The first post of a new Geekity site, and where to go from here.
8
+ ---
9
+
10
+ This post is the file `content/posts/2026-01-01-hello-world.md`. The files are
11
+ the source of truth; the SQLite index under `data/` is derived from them, so
12
+ deleting it is safe and the next boot rebuilds it.
13
+
14
+ ## Where things are
15
+
16
+ - `content/posts/` and `content/pages/` hold the documents. Everything else in
17
+ `content/` is left alone.
18
+ - `content/_data/site.json` is the site title, tagline, author and how many
19
+ posts a listing page holds. It is the `site` global in every template.
20
+ - `theme/` does not exist yet. Create it to override one template at a time;
21
+ anything you do not override still comes from the package.
22
+ - `geekity.config.ts` is the port, the directories and the public base URL.
23
+
24
+ ## Two things to try
25
+
26
+ Add a tag to the front matter above and reload `/tags/introductions/`. Then ask
27
+ this page for its other representations:
28
+
29
+ ```sh
30
+ curl -H 'Accept: text/markdown' http://localhost:3000/2026/01/hello-world/
31
+ curl http://localhost:3000/2026/01/hello-world/index.json
32
+ ```
33
+
34
+ Same URL, three bodies.
@@ -0,0 +1,4 @@
1
+ {
2
+ "layout": "post",
3
+ "tags": ["post"]
4
+ }
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from '@geekity/cms';
2
+
3
+ export default defineConfig({
4
+ port: 3000,
5
+ contentDir: 'content',
6
+ dataDir: 'data',
7
+ themeDir: 'theme',
8
+ baseUrl: 'http://localhost:3000',
9
+ watch: true,
10
+ sessionLifetime: 60 * 60 * 24 * 14,
11
+ });
@@ -0,0 +1,3 @@
1
+ node_modules/
2
+ data/
3
+ .env
@@ -0,0 +1,20 @@
1
+ import { createCms } from '@geekity/cms';
2
+
3
+ import config from './geekity.config.ts';
4
+
5
+ const cms = createCms(config);
6
+
7
+ // Routes of your own go here. They are registered before the CMS resolves a
8
+ // path against the content index, so a route always wins over a permalink that
9
+ // would collide with it. Delete this one once you have your own.
10
+ cms.app.get('/hello/', (c) => c.text('a route of my own'));
11
+
12
+ const { port } = await cms.serve();
13
+
14
+ console.log(`listening on http://localhost:${String(port)}`);
15
+
16
+ for (const signal of ['SIGINT', 'SIGTERM'] as const) {
17
+ process.once(signal, () => {
18
+ void cms.close().then(() => process.exit(0));
19
+ });
20
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2023",
4
+ "lib": ["ES2023"],
5
+ "module": "nodenext",
6
+ "moduleResolution": "nodenext",
7
+ "moduleDetection": "force",
8
+ "types": ["node"],
9
+ "strict": true,
10
+ "verbatimModuleSyntax": true,
11
+ "allowImportingTsExtensions": true,
12
+ "rewriteRelativeImportExtensions": true,
13
+ "skipLibCheck": true,
14
+ "esModuleInterop": true,
15
+ "noEmit": true
16
+ },
17
+ "include": ["*.ts", "theme/**/*.ts"]
18
+ }
@@ -0,0 +1,148 @@
1
+ # Default theme
2
+
3
+ Templates ship here, inside the published package, so every site gets them
4
+ without copying anything.
5
+
6
+ ```
7
+ themes/default/
8
+ layouts/
9
+ base.njk the page every other layout extends
10
+ home.njk the post archive, paginated
11
+ post.njk one post
12
+ page.njk one page
13
+ tag.njk a tag archive, paginated
14
+ 404.njk nothing at this URL
15
+ partials/
16
+ post-list.njk a list of documents
17
+ pagination.njk previous/next pager
18
+ tags.njk macros for tag links
19
+ static/
20
+ style.css served at /theme/style.css
21
+ ```
22
+
23
+ Plain Nunjucks and plain CSS. There is no build step and no dependency: a site
24
+ that wants Tailwind or anything else brings its own.
25
+
26
+ ## Overriding a template
27
+
28
+ Resolution order for any template is the site's own `themeDir` (`theme/` by
29
+ default) first, then this directory, one file at a time. A site that ships only
30
+
31
+ ```
32
+ theme/layouts/post.njk
33
+ ```
34
+
35
+ replaces the post layout and keeps receiving updates to every other template.
36
+ `theme/static/style.css` replaces the stylesheet the same way — assets under
37
+ `/theme/` resolve in the same order.
38
+
39
+ An override is a normal Nunjucks template, so it can extend or include the
40
+ packaged ones by name:
41
+
42
+ ```njk
43
+ {% extends "layouts/base.njk" %}
44
+
45
+ {% block content %}
46
+ <article>
47
+ <h1>{{ title }}</h1>
48
+ {{ content | safe }}
49
+ </article>
50
+ {% endblock %}
51
+ ```
52
+
53
+ `layouts/base.njk` defines the blocks `title`, `head`, `alternates`, `header`,
54
+ `content`, `footer` and `scripts`, so most sites never have to copy it.
55
+
56
+ ## Template context
57
+
58
+ The context mirrors what an Eleventy layout receives, so a layout ported from
59
+ an Eleventy build needs few edits. It is part of the package's semver contract.
60
+
61
+ Every template gets:
62
+
63
+ | Key | What it holds |
64
+ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
65
+ | `site` | `content/_data/site.json`, if the site has one, over the defaults `title` and `url`. Any key in the file is readable, so `site.tagline`, `site.author` and anything else a site adds are all available. |
66
+
67
+ A document — one post, one page, or one entry of a listing — adds:
68
+
69
+ | Key | What it holds |
70
+ | ----------------------------------------------------- | --------------------------------------------------------------------------------- |
71
+ | `title` | Display title. |
72
+ | `date` | Publish date, a JavaScript `Date`. Absent when the document has none. |
73
+ | `updated` | Last modified date, a `Date`, when the front matter has one. |
74
+ | `tags` | The document's tags, in file order. |
75
+ | `content` | The Markdown body rendered to HTML. Print it with `\| safe`. |
76
+ | `url` | The document's URL path, the same value as `page.url`. |
77
+ | `page.url` | The document's URL path. Always ends in `/`. |
78
+ | `page.date` | The same `Date` as `date`. |
79
+ | `page.fileSlug` | The permalink's last segment. |
80
+ | `page.inputPath` | The source file, relative to the content directory. |
81
+ | `type` | `post` or `page`. |
82
+ | `permalink`, `slug`, `draft`, `description`, `author` | Straight from the front matter. |
83
+ | `activityStreams` | The post's ActivityPub object id, absolute. Only on a rendered published post. |
84
+ | everything else | Any front matter key the CMS does not model is on the context under its own name. |
85
+
86
+ A listing — the home page or a tag archive — adds:
87
+
88
+ | Key | What it holds |
89
+ | ------------------------------------------ | --------------------------------------------------------------------------------- |
90
+ | `title` | The site title on the home page, the tag on a tag archive. |
91
+ | `posts` | The documents on this page of the listing, newest first, each in the shape above. |
92
+ | `pagination.items` | The same array, under the name Eleventy gives it. |
93
+ | `pagination.pageNumber` | Zero-based index of this page, as in Eleventy. |
94
+ | `pagination.totalPages`, `.total`, `.size` | How many pages, how many documents, how many per page. |
95
+ | `pagination.href.first/last/next/previous` | Pager URLs. `next` and `previous` are `null` at the ends. |
96
+ | `pagination.pages` | Every page's URL, in order. |
97
+ | `tag` | The tag, on a tag archive only. |
98
+
99
+ How many posts a listing page holds comes from `postsPerPage` in
100
+ `content/_data/site.json`, and defaults to 10. How many entries a feed holds
101
+ comes from `feedSize` in the same file, and defaults to 20.
102
+
103
+ ## Feeds
104
+
105
+ `layouts/base.njk` fills the `alternates` block with the `rel="alternate"`
106
+ links for `/feed.xml` and `/feed.json`, so every page that extends it
107
+ advertises both feeds. On a published post it adds a third, pointing at the
108
+ post's ActivityPub object:
109
+
110
+ ```html
111
+ <link
112
+ rel="alternate"
113
+ type="application/activity+json"
114
+ href="https://example.com/ap/posts/hello"
115
+ />
116
+ ```
117
+
118
+ That link is what lets a fediverse client find the post from its permalink. It
119
+ comes from `activityStreams`, which is only on the context of a rendered
120
+ published post, so a layout that overrides the block and does not call
121
+ `super()` has to emit it itself.
122
+
123
+ `layouts/tag.njk` overrides that block, calls `super()` and adds the tag's own
124
+ two feeds:
125
+
126
+ ```njk
127
+ {% set tagRoot = "/tags/" + (tag | urlencode) + "/" %}
128
+ {% block alternates %}
129
+ {{ super() }}
130
+ <link rel="alternate" type="application/atom+xml" href="{{ (tagRoot + "feed.xml") | url }}">
131
+ {% endblock %}
132
+ ```
133
+
134
+ A layout that does not extend the base one has to emit the links itself. The
135
+ feeds are generated by the CMS, not by a template, so nothing here decides what
136
+ goes in them.
137
+
138
+ ## Filters
139
+
140
+ | Filter | What it does |
141
+ | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
142
+ | `date(format)` | Formats a `Date` or a date string. `readable` (the default) gives `2 September 2026`, `html` gives `2026-09-02` for a `<time datetime>`, `year` gives `2026`, `iso` gives the full ISO 8601 instant. Formatting is in UTC. A value that is not a date renders as the empty string. |
143
+ | `url` | Prefixes a root-relative path with the base URL's path, so a site served from a subdirectory links correctly. Eleventy's filter of the same name. |
144
+ | `absoluteUrl` | The same path as a fully qualified URL against the site's `baseUrl`. |
145
+
146
+ Nunjucks' own filters — `default`, `join`, `urlencode`, `safe` and the rest —
147
+ are all available. Autoescaping is on, so rendered Markdown is the one thing
148
+ that has to be passed through `safe`.
@@ -0,0 +1,9 @@
1
+ {% extends "layouts/base.njk" %}
2
+
3
+ {% block content %}
4
+ <article class="not-found">
5
+ <h1 class="page-title">Not found</h1>
6
+ <p>There is nothing at <code>{{ url }}</code>.</p>
7
+ <p><a href="{{ "/" | url }}">Back to {{ site.title }}</a></p>
8
+ </article>
9
+ {% endblock %}
@@ -0,0 +1,59 @@
1
+ {#
2
+ The page every other layout extends.
3
+
4
+ Blocks a site can override without copying the whole file:
5
+ title the contents of <title>
6
+ head extra tags at the end of <head>
7
+ alternates <link rel="alternate"> tags, where the feeds go
8
+ header the site header
9
+ content the page body
10
+ footer the site footer
11
+ scripts scripts at the end of <body>
12
+ #}<!doctype html>
13
+ <html lang="{{ site.language | default("en") }}">
14
+ <head>
15
+ <meta charset="utf-8">
16
+ <meta name="viewport" content="width=device-width, initial-scale=1">
17
+ <title>{% block title %}{% if title %}{{ title }} &middot; {% endif %}{{ site.title }}{% endblock %}</title>
18
+ {% if description %}
19
+ <meta name="description" content="{{ description }}">
20
+ {% endif %}
21
+ <link rel="canonical" href="{{ (page.url or "/") | absoluteUrl }}">
22
+ <link rel="stylesheet" href="{{ "/theme/style.css" | url }}">
23
+ {% block alternates %}
24
+ <link rel="alternate" type="application/atom+xml" title="{{ site.title }}" href="{{ "/feed.xml" | url }}">
25
+ <link rel="alternate" type="application/feed+json" title="{{ site.title }}" href="{{ "/feed.json" | url }}">
26
+ {% if activityStreams %}
27
+ <link rel="alternate" type="application/activity+json" href="{{ activityStreams }}">
28
+ {% endif %}
29
+ {% endblock %}
30
+ {% block head %}{% endblock %}
31
+ </head>
32
+ <body>
33
+ <a class="skip-link" href="#main">Skip to content</a>
34
+
35
+ {% block header %}
36
+ <header class="site-header">
37
+ <p class="site-title"><a href="{{ "/" | url }}">{{ site.title }}</a></p>
38
+ {% if site.tagline %}
39
+ <p class="site-tagline">{{ site.tagline }}</p>
40
+ {% endif %}
41
+ </header>
42
+ {% endblock %}
43
+
44
+ <main id="main" class="site-main">
45
+ {% block content %}{% endblock %}
46
+ </main>
47
+
48
+ {% block footer %}
49
+ <footer class="site-footer">
50
+ <p>
51
+ {% if site.author %}&copy; {{ site.author }}{% endif %}
52
+ <span class="site-colophon">Published with Geekity.</span>
53
+ </p>
54
+ </footer>
55
+ {% endblock %}
56
+
57
+ {% block scripts %}{% endblock %}
58
+ </body>
59
+ </html>
@@ -0,0 +1,9 @@
1
+ {% extends "layouts/base.njk" %}
2
+
3
+ {% block title %}{% if pagination.pageNumber > 0 %}Page {{ pagination.pageNumber + 1 }} &middot; {% endif %}{{ site.title }}{% endblock %}
4
+
5
+ {% block content %}
6
+ <h1 class="page-title">{{ title }}</h1>
7
+ {% include "partials/post-list.njk" %}
8
+ {% include "partials/pagination.njk" %}
9
+ {% endblock %}
@@ -0,0 +1,13 @@
1
+ {% extends "layouts/base.njk" %}
2
+
3
+ {% block content %}
4
+ <article class="page h-entry">
5
+ <header class="page-header">
6
+ <h1 class="page-title p-name">{{ title }}</h1>
7
+ </header>
8
+
9
+ <div class="page-body e-content">
10
+ {{ content | safe }}
11
+ </div>
12
+ </article>
13
+ {% endblock %}