create-goodfellow 0.0.0-stage → 0.2.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 (150) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +15 -2
  3. package/bin/create-goodfellow.js +2 -0
  4. package/dist/cli.d.ts +1 -0
  5. package/dist/cli.js +220 -0
  6. package/dist/index.d.ts +34 -0
  7. package/dist/index.js +2 -0
  8. package/dist/scaffold-BGxzPdN1.js +150 -0
  9. package/package.json +55 -3
  10. package/templates/next/.github/workflows/deploy.yml +86 -0
  11. package/templates/next/.gitlab-ci.yml +28 -0
  12. package/templates/next/README.md +127 -0
  13. package/templates/next/_gitignore +5 -0
  14. package/templates/next/app/(site)/[[...path]]/page.tsx +8 -0
  15. package/templates/next/app/(site)/layout.tsx +5 -0
  16. package/templates/next/app/admin/demo-content.json/route.ts +5 -0
  17. package/templates/next/app/admin/layout.tsx +8 -0
  18. package/templates/next/app/admin/page.tsx +8 -0
  19. package/templates/next/app/layout.tsx +11 -0
  20. package/templates/next/app/not-found.tsx +4 -0
  21. package/templates/next/app/robots.ts +4 -0
  22. package/templates/next/app/site.css +11 -0
  23. package/templates/next/app/sitemap.ts +4 -0
  24. package/templates/next/blocks/installed/index.ts +7 -0
  25. package/templates/next/components.json +24 -0
  26. package/templates/next/content/collections/news/_collection.json +113 -0
  27. package/templates/next/content/collections/news/open-house.json +9 -0
  28. package/templates/next/content/collections/news/welcome.json +10 -0
  29. package/templates/next/content/layout/footer.json +55 -0
  30. package/templates/next/content/layout/header.json +54 -0
  31. package/templates/next/content/menus.json +25 -0
  32. package/templates/next/content/pages/404.json +73 -0
  33. package/templates/next/content/pages/about.json +59 -0
  34. package/templates/next/content/pages/index.json +215 -0
  35. package/templates/next/content/pages/news.json +55 -0
  36. package/templates/next/content/site.json +25 -0
  37. package/templates/next/content/styles/custom.css +4 -0
  38. package/templates/next/goodfellow.config.tsx +17 -0
  39. package/templates/next/lib/site.ts +5 -0
  40. package/templates/next/next.config.ts +7 -0
  41. package/templates/next/package.json +40 -0
  42. package/templates/next/postcss.config.mjs +3 -0
  43. package/templates/next/public/media/favicon.svg +1 -0
  44. package/templates/next/public/media/logo.svg +1 -0
  45. package/templates/next/public/media/placeholder.svg +1 -0
  46. package/templates/next/tsconfig.json +27 -0
  47. package/templates/parish/.github/workflows/deploy.yml +84 -0
  48. package/templates/parish/.gitlab-ci.yml +28 -0
  49. package/templates/parish/README.md +128 -0
  50. package/templates/parish/_gitignore +2 -0
  51. package/templates/parish/blocks/installed/index.ts +7 -0
  52. package/templates/parish/blocks/mass-times.tsx +59 -0
  53. package/templates/parish/blocks/notice.tsx +46 -0
  54. package/templates/parish/blocks/scripture.tsx +40 -0
  55. package/templates/parish/components.json +24 -0
  56. package/templates/parish/content/collections/bulletins/2026-09-27.json +8 -0
  57. package/templates/parish/content/collections/bulletins/2026-10-04.json +8 -0
  58. package/templates/parish/content/collections/bulletins/_collection.json +113 -0
  59. package/templates/parish/content/collections/events/_collection.json +156 -0
  60. package/templates/parish/content/collections/events/advent-penance-service.json +14 -0
  61. package/templates/parish/content/collections/events/all-souls.json +14 -0
  62. package/templates/parish/content/collections/events/christmas-concert.json +14 -0
  63. package/templates/parish/content/collections/events/fall-festival.json +14 -0
  64. package/templates/parish/content/collections/events/youth-group.json +23 -0
  65. package/templates/parish/content/collections/news/_collection.json +137 -0
  66. package/templates/parish/content/collections/news/bell-tower-repairs.json +13 -0
  67. package/templates/parish/content/collections/news/choir-new-voices.json +14 -0
  68. package/templates/parish/content/collections/news/food-drive.json +13 -0
  69. package/templates/parish/content/collections/news/new-website.json +13 -0
  70. package/templates/parish/content/collections/news/winter-coats.json +13 -0
  71. package/templates/parish/content/collections/news/youth-group.json +13 -0
  72. package/templates/parish/content/collections/news/youth-service-day.json +14 -0
  73. package/templates/parish/content/collections/staff/_collection.json +34 -0
  74. package/templates/parish/content/collections/staff/david-okafor.json +9 -0
  75. package/templates/parish/content/collections/staff/fr-thomas-reed.json +9 -0
  76. package/templates/parish/content/collections/staff/maria-chen.json +9 -0
  77. package/templates/parish/content/collections/staff/sarah-lindqvist.json +9 -0
  78. package/templates/parish/content/layout/footer.json +142 -0
  79. package/templates/parish/content/layout/header.json +54 -0
  80. package/templates/parish/content/menus.json +67 -0
  81. package/templates/parish/content/pages/404.json +85 -0
  82. package/templates/parish/content/pages/about.json +153 -0
  83. package/templates/parish/content/pages/bulletins.json +64 -0
  84. package/templates/parish/content/pages/calendar.json +59 -0
  85. package/templates/parish/content/pages/contact.json +180 -0
  86. package/templates/parish/content/pages/events.json +107 -0
  87. package/templates/parish/content/pages/index.json +390 -0
  88. package/templates/parish/content/pages/mass-times.json +168 -0
  89. package/templates/parish/content/pages/news.json +68 -0
  90. package/templates/parish/content/pages/sacraments.json +259 -0
  91. package/templates/parish/content/site.json +36 -0
  92. package/templates/parish/content/styles/custom.css +4 -0
  93. package/templates/parish/goodfellow.config.tsx +24 -0
  94. package/templates/parish/package.json +36 -0
  95. package/templates/parish/public/media/bulletin-example.pdf +32 -0
  96. package/templates/parish/public/media/candles.svg +22 -0
  97. package/templates/parish/public/media/church.svg +33 -0
  98. package/templates/parish/public/media/favicon.svg +5 -0
  99. package/templates/parish/public/media/gathering.svg +18 -0
  100. package/templates/parish/public/media/logo.svg +5 -0
  101. package/templates/parish/public/media/person.svg +5 -0
  102. package/templates/parish/public/media/placeholder.svg +5 -0
  103. package/templates/parish/src/styles.css +8 -0
  104. package/templates/parish/tsconfig.json +14 -0
  105. package/templates/parish/vercel.ts +65 -0
  106. package/templates/registry/accordion.json +17 -0
  107. package/templates/registry/alert.json +16 -0
  108. package/templates/registry/badge.json +17 -0
  109. package/templates/registry/button.json +17 -0
  110. package/templates/registry/card.json +16 -0
  111. package/templates/registry/carousel.json +19 -0
  112. package/templates/registry/custom-html.json +31 -0
  113. package/templates/registry/registry.json +364 -0
  114. package/templates/registry/shadcn-call-to-action.json +26 -0
  115. package/templates/registry/shadcn-cards.json +26 -0
  116. package/templates/registry/shadcn-carousel.json +29 -0
  117. package/templates/registry/shadcn-faq.json +30 -0
  118. package/templates/registry/shadcn-hero.json +25 -0
  119. package/templates/registry/shadcn-notice.json +27 -0
  120. package/templates/registry/shadcn-pricing.json +28 -0
  121. package/templates/registry/shadcn-tabs.json +30 -0
  122. package/templates/registry/shadcn-testimonials.json +25 -0
  123. package/templates/registry/tabs.json +17 -0
  124. package/templates/starter/.github/workflows/deploy.yml +84 -0
  125. package/templates/starter/.gitlab-ci.yml +28 -0
  126. package/templates/starter/README.md +108 -0
  127. package/templates/starter/_gitignore +2 -0
  128. package/templates/starter/blocks/installed/index.ts +7 -0
  129. package/templates/starter/components.json +24 -0
  130. package/templates/starter/content/collections/news/_collection.json +113 -0
  131. package/templates/starter/content/collections/news/open-house.json +9 -0
  132. package/templates/starter/content/collections/news/welcome.json +10 -0
  133. package/templates/starter/content/layout/footer.json +55 -0
  134. package/templates/starter/content/layout/header.json +54 -0
  135. package/templates/starter/content/menus.json +25 -0
  136. package/templates/starter/content/pages/404.json +73 -0
  137. package/templates/starter/content/pages/about.json +59 -0
  138. package/templates/starter/content/pages/index.json +215 -0
  139. package/templates/starter/content/pages/news.json +55 -0
  140. package/templates/starter/content/site.json +25 -0
  141. package/templates/starter/content/styles/custom.css +4 -0
  142. package/templates/starter/goodfellow.config.tsx +17 -0
  143. package/templates/starter/package.json +36 -0
  144. package/templates/starter/public/media/favicon.svg +1 -0
  145. package/templates/starter/public/media/logo.svg +1 -0
  146. package/templates/starter/public/media/placeholder.svg +1 -0
  147. package/templates/starter/src/styles.css +8 -0
  148. package/templates/starter/tsconfig.json +14 -0
  149. package/templates/starter/vercel.ts +65 -0
  150. package/templates/versions.json +13 -0
@@ -0,0 +1,215 @@
1
+ {
2
+ "version": 1,
3
+ "data": {
4
+ "content": [
5
+ {
6
+ "type": "Section",
7
+ "props": {
8
+ "id": "Section-hero",
9
+ "background": "primary",
10
+ "backgroundImage": "",
11
+ "className": "",
12
+ "content": [
13
+ {
14
+ "type": "Heading",
15
+ "props": {
16
+ "id": "Heading-hero",
17
+ "align": "left",
18
+ "className": "",
19
+ "level": "h1",
20
+ "text": "Welcome to my site"
21
+ }
22
+ },
23
+ {
24
+ "type": "Text",
25
+ "props": {
26
+ "id": "Text-hero",
27
+ "align": "left",
28
+ "className": "mt-4 max-w-2xl text-lg opacity-90",
29
+ "content": "<p>This page is stored as a file in your site's repository. Edit it in the admin panel, or change <code>content/pages/index.json</code> directly.</p>"
30
+ }
31
+ },
32
+ {
33
+ "type": "Flex",
34
+ "props": {
35
+ "id": "Flex-hero",
36
+ "align": "center",
37
+ "className": "mt-8",
38
+ "direction": "row",
39
+ "gap": "md",
40
+ "items": [
41
+ {
42
+ "type": "Button",
43
+ "props": {
44
+ "id": "Button-primary",
45
+ "className": "",
46
+ "href": "/about",
47
+ "label": "About us",
48
+ "newTab": false,
49
+ "size": "lg",
50
+ "variant": "secondary"
51
+ }
52
+ },
53
+ {
54
+ "type": "Button",
55
+ "props": {
56
+ "id": "Button-secondary",
57
+ "className": "",
58
+ "href": "/about",
59
+ "label": "Contact",
60
+ "newTab": false,
61
+ "size": "lg",
62
+ "variant": "outline"
63
+ }
64
+ }
65
+ ],
66
+ "justify": "start",
67
+ "wrap": true
68
+ }
69
+ }
70
+ ],
71
+ "padding": "lg",
72
+ "width": "normal"
73
+ }
74
+ },
75
+ {
76
+ "type": "Section",
77
+ "props": {
78
+ "id": "Section-features",
79
+ "background": "none",
80
+ "backgroundImage": "",
81
+ "className": "",
82
+ "content": [
83
+ {
84
+ "type": "Heading",
85
+ "props": {
86
+ "id": "Heading-features",
87
+ "align": "center",
88
+ "className": "mb-10",
89
+ "level": "h2",
90
+ "text": "Everything in one place"
91
+ }
92
+ },
93
+ {
94
+ "type": "Grid",
95
+ "props": {
96
+ "id": "Grid-features",
97
+ "className": "",
98
+ "columns": "3",
99
+ "gap": "md",
100
+ "items": [
101
+ {
102
+ "type": "Section",
103
+ "props": {
104
+ "id": "Section-feature-1",
105
+ "background": "none",
106
+ "backgroundImage": "",
107
+ "className": "rounded-lg border px-2 py-6",
108
+ "content": [
109
+ {
110
+ "type": "Heading",
111
+ "props": {
112
+ "id": "Heading-feature-1",
113
+ "align": "left",
114
+ "className": "",
115
+ "level": "h3",
116
+ "text": "Pages"
117
+ }
118
+ },
119
+ {
120
+ "type": "Text",
121
+ "props": {
122
+ "id": "Text-feature-1",
123
+ "align": "left",
124
+ "className": "mt-2 text-muted-foreground",
125
+ "content": "<p>Build pages from blocks: sections, columns, text, images and buttons.</p>"
126
+ }
127
+ }
128
+ ],
129
+ "padding": "none",
130
+ "width": "full"
131
+ }
132
+ },
133
+ {
134
+ "type": "Section",
135
+ "props": {
136
+ "id": "Section-feature-2",
137
+ "background": "none",
138
+ "backgroundImage": "",
139
+ "className": "rounded-lg border px-2 py-6",
140
+ "content": [
141
+ {
142
+ "type": "Heading",
143
+ "props": {
144
+ "id": "Heading-feature-2",
145
+ "align": "left",
146
+ "className": "",
147
+ "level": "h3",
148
+ "text": "Your design"
149
+ }
150
+ },
151
+ {
152
+ "type": "Text",
153
+ "props": {
154
+ "id": "Text-feature-2",
155
+ "align": "left",
156
+ "className": "mt-2 text-muted-foreground",
157
+ "content": "<p>Set colors and fonts once in the site settings, and every page follows.</p>"
158
+ }
159
+ }
160
+ ],
161
+ "padding": "none",
162
+ "width": "full"
163
+ }
164
+ },
165
+ {
166
+ "type": "Section",
167
+ "props": {
168
+ "id": "Section-feature-3",
169
+ "background": "none",
170
+ "backgroundImage": "",
171
+ "className": "rounded-lg border px-2 py-6",
172
+ "content": [
173
+ {
174
+ "type": "Heading",
175
+ "props": {
176
+ "id": "Heading-feature-3",
177
+ "align": "left",
178
+ "className": "",
179
+ "level": "h3",
180
+ "text": "No hosting bills"
181
+ }
182
+ },
183
+ {
184
+ "type": "Text",
185
+ "props": {
186
+ "id": "Text-feature-3",
187
+ "align": "left",
188
+ "className": "mt-2 text-muted-foreground",
189
+ "content": "<p>The whole site is static files, so free hosting is enough.</p>"
190
+ }
191
+ }
192
+ ],
193
+ "padding": "none",
194
+ "width": "full"
195
+ }
196
+ }
197
+ ]
198
+ }
199
+ }
200
+ ],
201
+ "padding": "lg",
202
+ "width": "normal"
203
+ }
204
+ }
205
+ ],
206
+ "root": {
207
+ "props": {
208
+ "className": "",
209
+ "description": "",
210
+ "image": "",
211
+ "title": "Welcome"
212
+ }
213
+ }
214
+ }
215
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "version": 1,
3
+ "data": {
4
+ "content": [
5
+ {
6
+ "type": "Section",
7
+ "props": {
8
+ "id": "Section-news-list",
9
+ "background": "none",
10
+ "backgroundImage": "",
11
+ "className": "",
12
+ "content": [
13
+ {
14
+ "type": "Heading",
15
+ "props": {
16
+ "id": "Heading-news",
17
+ "align": "left",
18
+ "className": "",
19
+ "level": "h1",
20
+ "text": "News"
21
+ }
22
+ },
23
+ {
24
+ "type": "CollectionList",
25
+ "props": {
26
+ "id": "CollectionList-news",
27
+ "className": "mt-8",
28
+ "collection": "news",
29
+ "columns": "3",
30
+ "dateField": "date",
31
+ "emptyText": "No news yet.",
32
+ "imageField": "image",
33
+ "layout": "cards",
34
+ "limit": 0,
35
+ "order": "default",
36
+ "show": "all",
37
+ "summaryField": "summary"
38
+ }
39
+ }
40
+ ],
41
+ "padding": "lg",
42
+ "width": "normal"
43
+ }
44
+ }
45
+ ],
46
+ "root": {
47
+ "props": {
48
+ "className": "",
49
+ "description": "The latest news.",
50
+ "image": "",
51
+ "title": "News"
52
+ }
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "version": 1,
3
+ "description": "A website built with Goodfellow.",
4
+ "favicon": "/media/favicon.svg",
5
+ "language": "en",
6
+ "logo": {
7
+ "alt": "My site",
8
+ "src": "/media/logo.svg"
9
+ },
10
+ "theme": {
11
+ "colors": {
12
+ "border": "#e2e8f0",
13
+ "muted": "#f1f5f9",
14
+ "mutedForeground": "#64748b",
15
+ "primary": "#1e3a8a",
16
+ "primaryForeground": "#ffffff"
17
+ },
18
+ "fonts": {
19
+ "body": "Inter",
20
+ "heading": "Fraunces"
21
+ }
22
+ },
23
+ "title": "My site",
24
+ "titleTemplate": "%s | My site"
25
+ }
@@ -0,0 +1,4 @@
1
+ /* Site-wide CSS. Anything here overrides the blocks' own styles. */
2
+ .gf-header {
3
+ border-bottom: 1px solid var(--color-border);
4
+ }
@@ -0,0 +1,17 @@
1
+ import { blocks, categories } from "@goodfellow-cms/blocks";
2
+ import { defineConfig } from "@goodfellow-cms/core";
3
+ // import { github } from "@goodfellow-cms/github";
4
+ // import { gitlab } from "@goodfellow-cms/gitlab";
5
+ import { installedBlocks, installedCategories } from "./blocks/installed";
6
+
7
+ export default defineConfig({
8
+ // The built-in blocks, and those installed from the admin panel's Blocks screen.
9
+ // Add your own here too, e.g. `blocks: { ...blocks, ...installedBlocks, MassTimes }`.
10
+ blocks: { ...blocks, ...installedBlocks },
11
+ categories: { ...categories, ...installedCategories },
12
+
13
+ // Where the site is stored. Once this is set, builds include the admin panel at /admin.
14
+ // See README.md for how to set up sign-in.
15
+ // backend: github({ repo: "your-name/your-site" }),
16
+ // backend: gitlab({ project: "your-name/your-site", clientId: "your-application-id" }),
17
+ });
@@ -0,0 +1,5 @@
1
+ import { goodfellowPages } from "@goodfellow-cms/next";
2
+ import config from "@/goodfellow.config";
3
+
4
+ /** The site's pages, shared by the routes that show them. */
5
+ export const site = goodfellowPages(config);
@@ -0,0 +1,7 @@
1
+ import { withGoodfellow } from "@goodfellow-cms/next/config";
2
+
3
+ // Builds the site as static files in out/. Add your own Next.js settings inside withGoodfellow({ ... }).
4
+ export default withGoodfellow({
5
+ // Stops `next dev` adding AGENTS.md and CLAUDE.md to the site.
6
+ agentRules: false,
7
+ });
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@goodfellow-cms/template-next",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "next dev --port 4321",
8
+ "build": "next build && goodfellow-next finish out",
9
+ "typecheck": "tsc -p tsconfig.json"
10
+ },
11
+ "dependencies": {
12
+ "@goodfellow-cms/admin": "workspace:*",
13
+ "@goodfellow-cms/blocks": "workspace:*",
14
+ "@goodfellow-cms/core": "workspace:*",
15
+ "@goodfellow-cms/github": "workspace:*",
16
+ "@goodfellow-cms/gitlab": "workspace:*",
17
+ "@goodfellow-cms/next": "workspace:*",
18
+ "@goodfellow-cms/react": "workspace:*",
19
+ "@puckeditor/core": "0.23.0",
20
+ "class-variance-authority": "0.7.1",
21
+ "clsx": "2.1.1",
22
+ "cn": "0.4.0",
23
+ "embla-carousel-react": "8.6.0",
24
+ "lucide-react": "1.52.0",
25
+ "next": "16.3.8",
26
+ "radix-ui": "1.7.0",
27
+ "react": "19.3.0",
28
+ "react-dom": "19.3.0",
29
+ "tailwind-merge": "3.7.0",
30
+ "tw-animate-css": "1.4.0"
31
+ },
32
+ "devDependencies": {
33
+ "@tailwindcss/postcss": "4.3.3",
34
+ "@types/node": "^22.19.0",
35
+ "@types/react": "^19.2.0",
36
+ "@types/react-dom": "^19.2.0",
37
+ "tailwindcss": "4.3.3",
38
+ "typescript": "5.9.3"
39
+ }
40
+ }
@@ -0,0 +1,3 @@
1
+ export default {
2
+ plugins: { "@tailwindcss/postcss": {} },
3
+ };
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" rx="10" fill="#1e3a8a"/><path d="M12 28V12h6.5a5 5 0 0 1 0 10H16v6zm4-9.5h2.4a1.75 1.75 0 0 0 0-3.5H16z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect width="40" height="40" rx="10" fill="#1e3a8a"/><path d="M12 28V12h6.5a5 5 0 0 1 0 10H16v6zm4-9.5h2.4a1.75 1.75 0 0 0 0-3.5H16z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 450"><rect width="800" height="450" fill="#e2e8f0"/><path d="M0 450 260 210l140 130 110-90 290 200z" fill="#cbd5e1"/><circle cx="600" cy="130" r="50" fill="#cbd5e1"/></svg>
@@ -0,0 +1,27 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "skipLibCheck": true,
6
+ "strict": true,
7
+ "noEmit": true,
8
+ "module": "esnext",
9
+ "moduleResolution": "bundler",
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true,
12
+ "jsx": "react-jsx",
13
+ "incremental": true,
14
+ "plugins": [
15
+ {
16
+ "name": "next"
17
+ }
18
+ ],
19
+ "allowJs": true,
20
+ "esModuleInterop": true,
21
+ "paths": {
22
+ "@/*": ["./*"]
23
+ }
24
+ },
25
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
26
+ "exclude": ["node_modules"]
27
+ }
@@ -0,0 +1,84 @@
1
+ # Builds the site and publishes it with GitHub Pages whenever the main branch
2
+ # changes (including every Publish in the admin panel), and once a night so
3
+ # date-based content stays current. Each night it first installs Goodfellow's
4
+ # newest fixes, and publishes them only if the site still builds with them,
5
+ # unless content/updates.json turns automatic updates off.
6
+ # In the repository's Settings → Pages, set "Source" to "GitHub Actions".
7
+ # See README.md.
8
+ name: Deploy to GitHub Pages
9
+
10
+ on:
11
+ push:
12
+ branches: [main]
13
+ schedule:
14
+ - cron: "17 4 * * *"
15
+ workflow_dispatch:
16
+ inputs:
17
+ update:
18
+ description: "Update Goodfellow first: fixes, latest, or a release such as 0.5.0 (an older one goes back to it). Leave empty to only build."
19
+ required: false
20
+ default: ""
21
+
22
+ permissions:
23
+ contents: read
24
+ pages: write
25
+ id-token: write
26
+
27
+ concurrency:
28
+ group: pages
29
+ cancel-in-progress: false
30
+
31
+ jobs:
32
+ update:
33
+ # Each night, and when the admin panel's Updates screen asks.
34
+ if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.update != '')
35
+ runs-on: ubuntu-latest
36
+ permissions:
37
+ contents: write
38
+ outputs:
39
+ sha: ${{ steps.update.outputs.sha }}
40
+ steps:
41
+ - uses: actions/checkout@v5
42
+ - uses: actions/setup-node@v5
43
+ with:
44
+ node-version: 22
45
+ cache: npm
46
+ - run: npm ci
47
+ - id: update
48
+ env:
49
+ TO: ${{ inputs.update || 'automatic' }}
50
+ run: npx goodfellow update --publish --to "$TO"
51
+
52
+ build:
53
+ needs: update
54
+ # Also when there was no update to run, or it didn't work: the site is built either way.
55
+ if: ${{ !cancelled() }}
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - uses: actions/checkout@v5
59
+ with:
60
+ # The update's commit, when it published one.
61
+ ref: ${{ needs.update.outputs.sha || github.sha }}
62
+ - uses: actions/setup-node@v5
63
+ with:
64
+ node-version: 22
65
+ cache: npm
66
+ - id: pages
67
+ uses: actions/configure-pages@v5
68
+ - run: npm ci
69
+ # Project sites live in a subfolder (/repository-name/); user and organization sites don't.
70
+ - run: npx goodfellow build --base "${{ steps.pages.outputs.base_path }}/"
71
+ - uses: actions/upload-pages-artifact@v4
72
+ with:
73
+ path: dist
74
+
75
+ deploy:
76
+ needs: build
77
+ if: ${{ !cancelled() && needs.build.result == 'success' }}
78
+ runs-on: ubuntu-latest
79
+ environment:
80
+ name: github-pages
81
+ url: ${{ steps.deployment.outputs.page_url }}
82
+ steps:
83
+ - id: deployment
84
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,28 @@
1
+ # Builds the site and publishes it with GitLab Pages whenever the default
2
+ # branch changes (including every Publish in the admin panel). On scheduled
3
+ # pipelines, which the admin panel's Updates screen sets up to run each night,
4
+ # it first installs Goodfellow's newest fixes, unless content/updates.json turns
5
+ # automatic updates off (or the release GOODFELLOW_UPDATE names), and publishes
6
+ # them only if the site still builds with them. That
7
+ # needs "Allow Git push requests to the repository" under Settings → CI/CD →
8
+ # Job token permissions, which the Updates screen turns on. See README.md.
9
+ pages:
10
+ image: node:22
11
+ cache:
12
+ key:
13
+ files: [package-lock.json]
14
+ paths: [.npm/]
15
+ script:
16
+ - npm ci --cache .npm --prefer-offline
17
+ - |
18
+ if [ "$CI_PIPELINE_SOURCE" = "schedule" ] || [ -n "$GOODFELLOW_UPDATE" ]; then
19
+ git remote set-url origin "https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_FQDN:-$CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"
20
+ npx goodfellow update --publish --to "${GOODFELLOW_UPDATE:-automatic}" || echo "The update wasn't published; building the site as it is."
21
+ fi
22
+ # Pages may serve the site from a subfolder, such as https://group.gitlab.io/site/.
23
+ - export GOODFELLOW_BASE="$(node -e 'console.log(new URL(process.env.CI_PAGES_URL).pathname)')"
24
+ - npx goodfellow build
25
+ pages:
26
+ publish: dist
27
+ rules:
28
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
@@ -0,0 +1,128 @@
1
+ # St. Joseph Parish (example)
2
+
3
+ An example parish website built with [Goodfellow](https://github.com/goodfellow-cms/goodfellow-cms). **St. Joseph Parish is made up**: its name, address, phone number, staff, history, Mass times and events are invented, and the pictures are simple drawings. Replace them all with your own before putting the site online.
4
+
5
+ Start a site from this example with `npm create goodfellow@latest my-parish -- --template parish`.
6
+
7
+ ## Working on the site
8
+
9
+ <!-- goodfellow-repository -->
10
+ > **In the Goodfellow repository**, this folder is part of a pnpm workspace, so `npm install` doesn't work here. From the repository's root, run `pnpm install` and `pnpm build` (get pnpm with `corepack enable`, or `npm install -g pnpm`), then `pnpm dev` in this folder. The `npm` commands below are for a site of your own, created with `npm create goodfellow`, which leaves this note out.
11
+ <!-- /goodfellow-repository -->
12
+
13
+ ```sh
14
+ npm install
15
+ npm run dev # site at http://localhost:4321, admin panel at http://localhost:4321/admin
16
+ npm run build # builds the site into dist/
17
+ npm run preview # serves dist/
18
+ ```
19
+
20
+ On your own computer, the admin panel saves straight to the files in `content/`.
21
+
22
+ ## What's in it
23
+
24
+ - **Pages:** home, Mass times, sacraments, events, news, bulletins, about us and contact, with a submenu under **Parish life**.
25
+ - **Collections**, edited under **Collections** in the admin panel:
26
+ - **Events**, with a date, time and place. The home page shows the next three, and the events page splits upcoming and past events. Lists of upcoming events change by date, so the site's nightly rebuild keeps them current.
27
+ - **News** stories, newest first.
28
+ - **Bulletins:** each one links to a PDF uploaded on the **Media** screen.
29
+ - **Staff**, listed on the About us page. They have no pages of their own, and the **Order** field sets who comes first.
30
+ - **Contact details** (address, phone and email) are set once in **Site settings → General**, and shown in the footer and on the contact page by the **Contact details** block.
31
+ - **More blocks**, such as an FAQ and tabs, can be added on the admin panel's **Blocks** screen. See [Add blocks](https://goodfellow-cms.github.io/goodfellow-cms/docs/add-blocks).
32
+ - **The parish's own blocks**, in `blocks/`, show how a developer adds blocks to a site. They're listed under **Parish** in the editor:
33
+ - **Mass times:** a list of days and times, each with an optional note.
34
+ - **Scripture quote:** a short passage with its reference. The example uses the Douay-Rheims Bible (Challoner revision), a Catholic translation in the public domain; most modern translations need permission to quote.
35
+ - **Notice:** an announcement that stands out from the text around it.
36
+
37
+ Each block is a React component plus the fields the editor shows for it. They're added to the editor in `goodfellow.config.tsx`. Never rename a block's key or its fields once pages use them, since content files refer to them by name. Parts of a block that respond to visitors, such as a button that shows more, go in a file starting with `"use client"`, and only pages that use them load JavaScript: see [Interactive blocks](https://goodfellow-cms.github.io/goodfellow-cms/docs/interactive-blocks).
38
+
39
+ ## Making it yours
40
+
41
+ 1. In **Site settings**, change the parish's name, contact details, logo, colors and fonts.
42
+ 2. Edit the Mass times on the home page and the Mass times page.
43
+ 3. Replace the example events, news, staff and bulletins under **Collections**, and the pictures on the **Media** screen.
44
+ 4. Rewrite the about us, sacraments and contact pages, and remove the note at the bottom of the footer (in **Header & footer**).
45
+
46
+ ## Putting the site online
47
+
48
+ Setup takes four steps. It's done once, usually by whoever set up the site.
49
+
50
+ ### 1. Store the site on GitHub or GitLab
51
+
52
+ Create an empty repository on GitHub or GitLab, without a README, and push this folder to it:
53
+
54
+ ```sh
55
+ git remote add origin https://github.com/your-name/your-site.git # unless origin is already set
56
+ git push -u origin main
57
+ ```
58
+
59
+ `create-goodfellow` makes the new site a git repository on the branch `main`, with everything, `package-lock.json` included, in its first commit, and sets `origin` when it's given the repository. Commit any changes since (`git add -A` and `git commit`) before pushing.
60
+
61
+ ### 2. Tell Goodfellow where the site is stored
62
+
63
+ If you gave the repository when creating the site with `npm create goodfellow`, this is already done. Otherwise, in `goodfellow.config.tsx`, uncomment one `backend` line and its `import`, and fill in your repository:
64
+
65
+ ```tsx
66
+ import { github } from "@goodfellow-cms/github";
67
+
68
+ export default defineConfig({
69
+ blocks,
70
+ categories,
71
+ backend: github({ repo: "your-name/your-site" }),
72
+ });
73
+ ```
74
+
75
+ Builds include the admin panel at `/admin` only once a backend is set. If the live site is built from a branch other than the repository's default branch, add `branch: "name"`.
76
+
77
+ Also set the site's address under **Site settings → General → Site address**, including any subfolder (such as `https://your-name.github.io/your-site`). It's used for the sitemap and for link previews.
78
+
79
+ ### 3. Choose a host
80
+
81
+ Each host's free plan has its own rules about business use. If the site is for a business, sells anything, shows ads, or is built or looked after by someone who's paid for it, check those rules first. As of October 2026, GitHub Pages and Vercel's free plan don't allow most of these, and GitLab Pages has no rule against them that we know of. See [Hosts and business sites](https://goodfellow-cms.github.io/goodfellow-cms/docs/hosts) in Goodfellow's documentation.
82
+
83
+ **GitHub Pages** (free for public repositories; not for online businesses or shops)
84
+
85
+ 1. In the repository on GitHub, go to **Settings → Pages** and set **Source** to **GitHub Actions**.
86
+ 2. Push. `.github/workflows/deploy.yml` builds and publishes the site on every change and once a night. If your main branch isn't called `main`, change it in that file.
87
+
88
+ **GitLab Pages** (free, including for private projects; no rule against business sites that we know of)
89
+
90
+ 1. Push. `.gitlab-ci.yml` builds and publishes the site on every change to the default branch.
91
+ 2. For nightly rebuilds, add a schedule under **Build → Pipeline schedules**.
92
+ 3. The site's address is under **Deploy → Pages**.
93
+
94
+ **Vercel** (works with GitHub and GitLab; the free plan is for non-commercial sites only)
95
+
96
+ 1. Import the repository in Vercel. `vercel.ts` already has the right settings, and has Vercel send the site's redirects itself.
97
+ 2. For nightly rebuilds, create a deploy hook under **Settings → Git → Deploy Hooks**, and call it from a scheduled GitHub Action or GitLab pipeline schedule.
98
+
99
+ Delete the setup files for the hosts you don't use.
100
+
101
+ ### 4. Set up sign-in
102
+
103
+ **GitHub:** nothing to set up. Editors sign in at `/admin` with an access token. The admin panel links to GitHub's token page with the right permissions already chosen. On that page, under **Repository access**, choose **Only select repositories** and pick the site.
104
+
105
+ - Editors who are collaborators on someone else's personal repository can't use that kind of token. They can use the "broader token" link instead. Alternatively, move the repository into a free GitHub organization and make editors members.
106
+
107
+ **GitLab:** editors can sign in with an access token straight away. For one-click **Sign in with GitLab**, register the admin panel with GitLab once:
108
+
109
+ 1. Go to your profile's **Preferences → Applications** (or the group's **Settings → Applications**) and add an application.
110
+ 2. Set:
111
+ - **Redirect URI:** the admin panel's address with a trailing slash, such as `https://your-site.example/admin/`.
112
+ - **Confidential:** leave this **off**.
113
+ - **Scopes:** `api`.
114
+ 3. Copy the **Application ID** into the config: `gitlab({ project: "your-name/your-site", clientId: "…" })`.
115
+
116
+ Every editor needs permission to change the repository: on GitHub, write access; on GitLab, the Developer role or higher.
117
+
118
+ ## Images and files
119
+
120
+ Upload images and files, such as the weekly bulletin, on the admin panel's **Media** screen, or with the **Choose image** button wherever an image goes. They're saved in `public/media/`, and large photos are made web-sized automatically.
121
+
122
+ ## Writing with AI
123
+
124
+ The admin panel's **AI** tab can draft pages, rewrite blocks and fill in events and news stories. Each editor picks an AI service there. Claude and some others need the editor's own API key and charge for use; there are free options, including copying the request into a chat app such as Claude.ai. To offer only some services, or to turn the assistant off, see `ai` in [Configuration](https://goodfellow-cms.github.io/goodfellow-cms/docs/configuration).
125
+
126
+ ## Publishing
127
+
128
+ Each **Publish** in the admin panel saves its changes as one commit to the main branch, which starts a new build. The admin panel shows when the live site has been updated, usually within a minute or two. If someone else changed the same page in the meantime, publishing stops and explains what happened, instead of overwriting their work.