fossbook 0.0.6 → 0.0.8

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 CHANGED
@@ -1,6 +1,7 @@
1
1
  # Fossbook
2
2
 
3
3
  A lightweight static blog site generator for GitHub Pages, similar to Hugo but built with Node.js.
4
+ It was originally part of the [F/OSS Comics blog](https://fosscomics.com) and is now an independent, installable package that anyone can use.
4
5
 
5
6
  ## Features
6
7
 
@@ -85,6 +86,18 @@ module.exports = {
85
86
  image: "https://example.com/default-image.png",
86
87
  theme: "archie",
87
88
 
89
+ // Optional: URL prefix for posts. Defaults to "posts" -> /posts/<slug>/.
90
+ // Set to "" to serve posts at the site root, /<slug>/.
91
+ postsPath: "posts",
92
+
93
+ // Optional comments (see "Comments" below)
94
+ comments: {
95
+ provider: "utterances",
96
+ repo: "you/your-blog",
97
+ issueTerm: "pathname",
98
+ theme: "github-light",
99
+ },
100
+
88
101
  // Directory overrides (defaults shown)
89
102
  content: "./content",
90
103
  postsDir: "./content/posts",
@@ -119,6 +132,21 @@ content/posts/My Post Title/
119
132
  └── feature.png
120
133
  ```
121
134
 
135
+ ### Post URLs
136
+
137
+ By default, posts are served under `/posts/`, e.g. `/posts/my-post-title/`. To
138
+ change the prefix or move posts to the site root, set `postsPath` in
139
+ `fossbook.config.js`:
140
+
141
+ ```js
142
+ postsPath: "", // serves the post above at /my-post-title/ (site root)
143
+ // postsPath: "blog", // or use a different prefix: /blog/my-post-title/
144
+ ```
145
+
146
+ This affects the generated output directory, the post URL, post links on the
147
+ home/all-posts/tag pages, and image paths. The on-disk source layout under
148
+ `content/posts/` does not change.
149
+
122
150
  ## CLI Reference
123
151
 
124
152
  ```
@@ -148,6 +176,46 @@ Fossbook ships with the Archie theme by default. To use a custom theme:
148
176
 
149
177
  Theme resolution order: user project `themes/` → built-in `themes/`.
150
178
 
179
+ ## Comments
180
+
181
+ Fossbook supports [utterances](https://utteranc.es) — a commenting widget that
182
+ stores comments as GitHub issues. When enabled, a comment box is rendered at the
183
+ bottom of every post page.
184
+
185
+ ### Setup
186
+
187
+ 1. Make the repository that backs the comments **public**.
188
+ 2. Install the [utterances GitHub App](https://github.com/apps/utterances) on
189
+ that repository so the bot can create issues.
190
+ 3. Add a `comments` block to `fossbook.config.js`:
191
+
192
+ ```js
193
+ comments: {
194
+ provider: "utterances", // currently the only supported provider
195
+ repo: "you/your-blog", // owner/repo that stores the comment issues
196
+ issueTerm: "pathname", // how a post maps to an issue (see below)
197
+ theme: "github-light", // any utterances theme, e.g. "github-dark"
198
+ },
199
+ ```
200
+
201
+ Omit the `comments` block (or set it to `null`) to disable comments.
202
+
203
+ ### Options
204
+
205
+ | Field | Required | Default | Description |
206
+ | ----------- | -------- | ---------------- | ---------------------------------------------------------------- |
207
+ | `provider` | yes | — | Must be `"utterances"`. |
208
+ | `repo` | yes | — | `owner/repo` whose issues store the comments. |
209
+ | `issueTerm` | no | `"pathname"` | Mapping between a page and its issue: `pathname`, `url`, `title`, `og:title`. |
210
+ | `theme` | no | `"github-light"` | Any [utterances theme](https://utteranc.es/#configuration). |
211
+
212
+ ### Mapping notes
213
+
214
+ With `issueTerm: "pathname"`, each post is matched to a GitHub issue whose title
215
+ equals the page's pathname (with the leading slash stripped). If you change a
216
+ post's URL, the existing comment thread no longer matches — rename the issue
217
+ title to the new pathname to keep the old comments.
218
+
151
219
  ### Required layout files
152
220
 
153
221
  ```
package/lib/deploy.js CHANGED
@@ -44,6 +44,7 @@ async function deploy(config, options = {}) {
44
44
  }).trim();
45
45
  if (!unpushed) {
46
46
  console.log("No changes to commit and no unpushed commits.");
47
+ printSiteUrl(config);
47
48
  return;
48
49
  }
49
50
  console.log("No new changes to commit, but found unpushed commits. Pushing...");
@@ -156,6 +157,7 @@ async function waitForDeployment(cwd, config) {
156
157
  if (runs.length === 0) {
157
158
  console.log("No workflow runs found. The deployment may not be configured yet.");
158
159
  console.log("Enable GitHub Pages: Settings → Pages → Source → GitHub Actions");
160
+ printSiteUrl(config);
159
161
  return;
160
162
  }
161
163
 
package/lib/init.js CHANGED
@@ -41,6 +41,8 @@ jobs:
41
41
 
42
42
  - name: Setup Pages
43
43
  uses: actions/configure-pages@v4
44
+ with:
45
+ enablement: true
44
46
 
45
47
  - name: Upload artifact
46
48
  uses: actions/upload-pages-artifact@v3
package/lib/mod/config.js CHANGED
@@ -17,6 +17,7 @@ const defaults = {
17
17
  image: "",
18
18
  theme: "archie",
19
19
  basePath: "", // auto-detected for GitHub Pages project sites, e.g. "/repo-name/"
20
+ postsPath: "posts", // URL prefix for posts: "posts" serves articles at /posts/<slug>/; set "" for root
20
21
  comments: null, // { provider: "utterances", repo: "user/repo", issueTerm: "pathname", theme: "github-light" }
21
22
  content: "./content",
22
23
  postsDir: "./content/posts",
@@ -91,6 +92,9 @@ function loadConfig(configPath) {
91
92
  merged.basePath += "/";
92
93
  }
93
94
 
95
+ // Normalize postsPath into a bare segment without surrounding slashes
96
+ merged.postsPath = (merged.postsPath || "").replace(/^\/+|\/+$/g, "");
97
+
94
98
  return merged;
95
99
  }
96
100
 
package/lib/mod/page.js CHANGED
@@ -26,6 +26,9 @@ module.exports = class Page extends PageBase {
26
26
  // If there's no .md extension, just get the last part of the path
27
27
  this.path = path.basename(filePath);
28
28
  }
29
+ // The source folder name, used to locate the post's images on disk.
30
+ // this.path may later be prefixed (e.g. "posts/<slug>") for output/URLs.
31
+ this.slug = this.path;
29
32
  // parsed content by fields and body
30
33
  const content = fm(mdContent);
31
34
 
@@ -75,7 +78,7 @@ module.exports = class Page extends PageBase {
75
78
  recursive: true,
76
79
  });
77
80
 
78
- fs.mkdirSync(outPath);
81
+ fs.mkdirSync(outPath, { recursive: true });
79
82
  } else {
80
83
  // remove the outputPath file if it exists
81
84
  const outPath = path.join(this.config.dev.outdir, this.path);
@@ -96,7 +99,7 @@ module.exports = class Page extends PageBase {
96
99
  );
97
100
 
98
101
  // if there is the images folder in the output directory.
99
- const srcImagesDir = path.join(this.config.dev.postsdir, this.path, "images");
102
+ const srcImagesDir = path.join(this.config.dev.postsdir, this.slug, "images");
100
103
  if (
101
104
  fs.existsSync(srcImagesDir) &&
102
105
  this.path !== ""
@@ -104,7 +107,7 @@ module.exports = class Page extends PageBase {
104
107
  // Copy images folder from postsdir to outdir
105
108
  const destImagesDir = path.join(this.config.dev.outdir, this.path, "images");
106
109
  if (!fs.existsSync(destImagesDir))
107
- fs.mkdirSync(destImagesDir);
110
+ fs.mkdirSync(destImagesDir, { recursive: true });
108
111
 
109
112
  fs.readdirSync(srcImagesDir).forEach(
110
113
  (image) => {
package/lib/posts.js CHANGED
@@ -23,6 +23,10 @@ module.exports = class Posts {
23
23
  }
24
24
  const post = new Page(this.config);
25
25
  post.readSource(path.join(this.config.dev.postsdir, postPath));
26
+ // Optionally nest posts under a URL prefix (e.g. "posts" -> /posts/<slug>/).
27
+ // post.slug stays the source folder name so image lookups remain correct.
28
+ const prefix = this.config.postsPath ? `${this.config.postsPath}/` : "";
29
+ post.path = `${prefix}${post.slug}`;
26
30
  post.url = `${this.config.blogsite}/${post.path}/`;
27
31
  post.imageURL = `${this.config.blogsite}/${post.path}/images/${post.image}`;
28
32
  this.posts.push(post);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fossbook",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "A lightweight static blog site generator for GitHub Pages",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {