poops 1.2.0 → 1.2.2

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
@@ -507,6 +507,7 @@ Then use Tailwind utility classes directly in your markup templates. Tailwind v4
507
507
  - `site` (optional) - global data that will be available to all templates in the markup directory. Like site title, description, social media links, etc. You can then use this data in your templates `{{ site.title }}` for instance.
508
508
  - `data` (optional) - is an array of JSON or YAML data files, that once loaded will be available to all templates in the markup directory. If you provide a path to a file for instance `links.json` with a `facebook` property, you can then use this data in your templates `{{ links.facebook }}`. The base name of the file will be used as the variable name, with spaces, dashes and dots replaced with underscores. So `the awesome-links.json` will be available as `{{ the_awesome_links.facebook }}` in your templates. The root directory of the data files is `in` directory. So if you have a `data` directory in your `in` directory, you can specify the data files like this `data: ["data/links.json"]`. The same goes for the YAML files.
509
509
  - `includePaths` - an array of paths to directories that will be added to the template engine's include paths. Useful if you want to separate template partials and layouts. For instance, if you have a `_includes` directory with a `header.njk` (or `header.liquid`) partial that you want to include in your markup, you can add it to the include paths and then include the templates like this `{% include "header.njk" %}`, without specifying the full path to the partial.
510
+ - `baseURL` (optional) - a base URL prefix to use instead of relative path prefixes. When set, `{{ relativePathPrefix }}` will always resolve to this value (with a trailing slash ensured) instead of being computed relative to each page's depth. Useful when deploying under a subdirectory (e.g. `"/blog"` for `domain.com/blog/`). When not set, relative prefixes (`./`, `../`, etc.) are used, which work for any deployment location including subdirectories and `file://` URLs.
510
511
 
511
512
  **💡 NOTE:** If, for instance, you are building a simple static onepager for your library, and want to pass a version variable from your `package.json`, Poops automatically reads your `package.json` if it exists in your working directory and sets the global variable `package` to the parsed JSON. So you can use it in your markup files, for example like this: `{{ package.version }}`.
512
513
 
@@ -527,7 +528,8 @@ Here is a sample markup configuration using the default Nunjucks engine:
527
528
  ],
528
529
  "includePaths": [
529
530
  "_includes"
530
- ]
531
+ ],
532
+ "baseURL": "/blog"
531
533
  }
532
534
  }
533
535
  ```
@@ -182,7 +182,7 @@ export function getCollectionIndexFile(markupInDir, collectionName) {
182
182
  return indexFiles[0]
183
183
  }
184
184
 
185
- export function generateCollectionPaginationPages(collectionData, markupInDir, markupOutDir, compileEntryFn) {
185
+ export function generateCollectionPaginationPages(collectionData, markupInDir, markupOutDir, compileEntryFn, baseURL) {
186
186
  if (!collectionData) return []
187
187
 
188
188
  const compilePromises = []
@@ -201,7 +201,7 @@ export function generateCollectionPaginationPages(collectionData, markupInDir, m
201
201
  const pageUrl = pageNumber === 1 ? collection.name : `${collection.name}/${pageNumber}`
202
202
  const nextPage = pageNumber === collection.totalPages ? null : pageNumber + 1
203
203
  const nextPageUrl = pageNumber === collection.totalPages ? null : `${collection.name}/${pageNumber + 1}`
204
- let prevPage = pageNumber === 1 ? null : pageNumber - 1
204
+ const prevPage = pageNumber === 1 ? null : pageNumber - 1
205
205
  let prevPageUrl = pageNumber === 1 ? null : `${collection.name}/${pageNumber - 1}`
206
206
  if (prevPage === 1) {
207
207
  prevPageUrl = collection.name
@@ -228,7 +228,7 @@ export function generateCollectionPaginationPages(collectionData, markupInDir, m
228
228
  const context = {
229
229
  ...collectionData,
230
230
  [collectionName]: pageSnapshot,
231
- relativePathPrefix: getRelativePathPrefix(markupOutDirFull, fromPath),
231
+ relativePathPrefix: getRelativePathPrefix(markupOutDirFull, fromPath, baseURL),
232
232
  _url: getPageUrl(markupOut)
233
233
  }
234
234
 
@@ -148,7 +148,11 @@ export function getUpDirPrefix(relativeDir) {
148
148
  return upDir
149
149
  }
150
150
 
151
- export function getRelativePathPrefix(outputDir, fromDir) {
151
+ export function getRelativePathPrefix(outputDir, fromDir, baseURL) {
152
+ if (baseURL != null) {
153
+ return baseURL.endsWith('/') ? baseURL : baseURL + '/'
154
+ }
155
+
152
156
  let relativeDir = path.relative(process.cwd(), outputDir)
153
157
  const fromRelativeDir = fromDir ? path.relative(process.cwd(), fromDir) : ''
154
158
 
@@ -156,7 +160,7 @@ export function getRelativePathPrefix(outputDir, fromDir) {
156
160
  relativeDir = relativeDir.replace(fromRelativeDir, '')
157
161
  }
158
162
 
159
- return getUpDirPrefix(relativeDir)
163
+ return getUpDirPrefix(relativeDir) || './'
160
164
  }
161
165
 
162
166
  export function getPageUrl(outputPath) {
package/lib/markups.js CHANGED
@@ -35,6 +35,7 @@ export default class Markups {
35
35
  this.includePaths = moduleConfig.includePaths || moduleConfig.options.includePaths || []
36
36
  this.searchIndexConfig = moduleConfig.options.searchIndex || moduleConfig.searchIndex
37
37
  this.sitemapConfig = moduleConfig.options.sitemap || moduleConfig.sitemap
38
+ this.baseURL = moduleConfig.baseURL || moduleConfig.options.baseURL || null
38
39
  this.dataFiles = []
39
40
 
40
41
  // Instantiate engine
@@ -196,7 +197,7 @@ export default class Markups {
196
197
 
197
198
  const fileContext = {
198
199
  ...collectionData,
199
- relativePathPrefix: getRelativePathPrefix(markupOutDir, fromPath),
200
+ relativePathPrefix: getRelativePathPrefix(markupOutDir, fromPath, this.baseURL),
200
201
  _url: getPageUrl(markupOut)
201
202
  }
202
203
 
@@ -254,7 +255,7 @@ export default class Markups {
254
255
 
255
256
  const fileContext = {
256
257
  ...collectionData,
257
- relativePathPrefix: getRelativePathPrefix(markupOutDir),
258
+ relativePathPrefix: getRelativePathPrefix(markupOutDir, null, this.baseURL),
258
259
  _url: getPageUrl(markupOut)
259
260
  }
260
261
 
@@ -321,7 +322,7 @@ export default class Markups {
321
322
  const pageEntries = shouldIndex ? [] : null
322
323
 
323
324
  buildCollectionPaginationData(collectionData)
324
- const collectionPromises = generateCollectionPaginationPages(collectionData, this.markupIn, this.markupOut, this.compileEntry.bind(this))
325
+ const collectionPromises = generateCollectionPaginationPages(collectionData, this.markupIn, this.markupOut, this.compileEntry.bind(this), this.baseURL)
325
326
 
326
327
  await Promise.all(collectionPromises)
327
328
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "poops",
3
3
  "description": "Straightforward, no-bullshit bundler for the web.",
4
- "version": "1.2.0",
4
+ "version": "1.2.2",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "poops.js",
package/poops.js CHANGED
@@ -206,11 +206,22 @@ async function startServer() {
206
206
  await poops() // Initial compilation before starting the server
207
207
  const app = connect()
208
208
 
209
- if (config.serve.base && pathExists(cwd, config.serve.base)) {
210
- app.use(serveStatic(path.join(cwd, config.serve.base)))
211
- } else {
212
- app.use(serveStatic(cwd))
213
- }
209
+ const base = config.serve.base && pathExists(cwd, config.serve.base)
210
+ ? path.join(cwd, config.serve.base)
211
+ : cwd
212
+
213
+ app.use(serveStatic(base))
214
+
215
+ // Serve 404.html for unmatched routes
216
+ const notFoundPage = path.join(base, '404.html')
217
+ app.use((req, res) => {
218
+ res.statusCode = 404
219
+ if (pathExists(notFoundPage)) {
220
+ fs.createReadStream(notFoundPage).pipe(res)
221
+ } else {
222
+ res.end('Not Found')
223
+ }
224
+ })
214
225
 
215
226
  let port = overridePort || config.serve.port || 4040
216
227
  if (!overridePort) port = await getAvailablePort(port, port + 10)