Make the articles/ folder location independently configurable (AI)
Added ARTICLES_URL to js/config.js, defaulting to the current
behavior (a sibling of js/ at the repo root) but editable to point
anywhere under the same origin (or a different one, CORS permitting)
-- articles no longer have to live alongside the rest of cmjs.
discovery.js's three hardcoded `${BASE_URL}articles/...` usages
(author listing, per-author directory, author bio fetch) now all go
through ARTICLES_URL instead.
Documented in README's nginx configuration section, including that
whatever ARTICLES_URL points at needs its own matching autoindex
location block.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AXSVPS3UmmASiiprPfcnUd
This commit is contained in:
1 parent
e739c7cf8c
commit
22f17a748b
3 files changed
+38
-7
No files matched your search
@@ -58,7 +58,7 @@ from the library — not something an embedding page needs to bring along.
|
||||
│ ├── toc.css # Auto-generated table of contents
|
||||
│ └── author-profile.css # Author profile card (avatar, bio, social links)
|
||||
├── js/
|
||||
│ ├── config.js # BASE_URL, MARKED_URL (all via import.meta.url)
|
||||
│ ├── config.js # BASE_URL, MARKED_URL, ARTICLES_URL (all via import.meta.url)
|
||||
│ ├── frontmatter.js # parseFrontmatter() — pure YAML-front parser
|
||||
│ ├── templates.js # loadTemplates(), templates cache
|
||||
│ ├── discovery.js # discoverArticles(), fetchJson(), article cache
|
||||
@@ -353,6 +353,28 @@ server {
|
||||
> `autoindex_format json` is ever lost (config drift, an older nginx), the crawler falls back
|
||||
> to parsing nginx's default HTML directory listing instead of breaking outright.
|
||||
|
||||
### Pointing articles/ somewhere else
|
||||
|
||||
By default the crawler looks for articles at `articles/` next to the rest of cmjs (`ARTICLES_URL`
|
||||
in `js/config.js`, computed as a sibling of the `js/` folder). Articles don't have to live there —
|
||||
edit `ARTICLES_URL` in `js/config.js` to point anywhere under the same origin (or a different one,
|
||||
CORS permitting), e.g.:
|
||||
|
||||
```js
|
||||
export const ARTICLES_URL = new URL('/blog-content/articles/', location.origin).href;
|
||||
```
|
||||
|
||||
Whatever it resolves to needs its own matching `location` block enabling the JSON (or HTML)
|
||||
autoindex — it doesn't have to be named `articles/` or nested under wherever cmjs itself lives:
|
||||
|
||||
```nginx
|
||||
location /blog-content/articles/ {
|
||||
autoindex on;
|
||||
autoindex_format json;
|
||||
autoindex_localtime off;
|
||||
}
|
||||
```
|
||||
|
||||
### Compression
|
||||
|
||||
Markdown and directory-listing JSON are both plain text, so gzip shrinks them well — and since
|
||||
|
||||
+11
-2
@@ -1,10 +1,19 @@
|
||||
// All paths are derived from this module's own location via import.meta.url,
|
||||
// so they resolve correctly regardless of where the embedding HTML page lives.
|
||||
|
||||
// Base URL of the repo root — articles/, strings/, and templates/ all live
|
||||
// here, one level up from this file (e.g. https://example.com/).
|
||||
// Base URL of the repo root — strings/ and templates/ live here, one level
|
||||
// up from this file (e.g. https://example.com/).
|
||||
export const BASE_URL = new URL('../', import.meta.url).href;
|
||||
|
||||
// Path to the marked.js vendor script — lives in vendor/, a sibling of this
|
||||
// file's own js/ directory, not alongside the app's own modules.
|
||||
export const MARKED_URL = new URL('../vendor/marked.min.js', import.meta.url).href;
|
||||
|
||||
// Base URL of the articles/ folder. Defaults to a sibling of this file's own
|
||||
// js/ directory (the repo root's own articles/), but articles don't have to
|
||||
// live anywhere near the rest of cmjs — replace this line to point anywhere
|
||||
// under the same origin (`new URL('/blog-content/articles/', location.origin).href`)
|
||||
// or even a different one, CORS permitting. Whatever it resolves to must
|
||||
// still be a directory nginx serves a JSON (or HTML) autoindex listing for
|
||||
// — see "nginx configuration" in the README.
|
||||
export const ARTICLES_URL = new URL('articles/', BASE_URL).href;
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
import { parseFrontmatter } from './frontmatter.js';
|
||||
import { BASE_URL } from './config.js';
|
||||
import { BASE_URL, ARTICLES_URL } from './config.js';
|
||||
import { mapWithConcurrency } from './concurrency.js';
|
||||
import { getAllCacheEntries, setCacheEntry, pruneCache } from './cache.js';
|
||||
import { t } from './i18n.js';
|
||||
@@ -280,7 +280,7 @@ async function runCrawl() {
|
||||
const cacheSnapshotPromise = getAllCacheEntries();
|
||||
|
||||
// Wave 1 (root) — always fetched live: the author directories.
|
||||
const authorEntries = await fetchJson(`${BASE_URL}articles/`);
|
||||
const authorEntries = await fetchJson(ARTICLES_URL);
|
||||
const authors = authorEntries.filter(entry => entry.type === 'directory' && !entry.name.startsWith('.'));
|
||||
|
||||
// Wave 2 — always fetched live, in full, for every author (not just the
|
||||
@@ -301,7 +301,7 @@ async function runCrawl() {
|
||||
// silently producing an empty article list.
|
||||
let authorsFailed = 0;
|
||||
const authorFileLists = await Promise.all(authors.map(async author => {
|
||||
const authorRoot = `${BASE_URL}articles/${encodeURIComponent(author.name)}/`;
|
||||
const authorRoot = `${ARTICLES_URL}${encodeURIComponent(author.name)}/`;
|
||||
const bioFileName = `${author.name}.md`;
|
||||
try {
|
||||
const entries = await fetchJson(authorRoot);
|
||||
@@ -357,7 +357,7 @@ export async function findArticle(hash) {
|
||||
}
|
||||
|
||||
export async function fetchAuthorProfile(author) {
|
||||
const path = `${BASE_URL}articles/${encodeURIComponent(author)}/${encodeURIComponent(author)}.md`;
|
||||
const path = `${ARTICLES_URL}${encodeURIComponent(author)}/${encodeURIComponent(author)}.md`;
|
||||
try {
|
||||
const response = await fetch(path);
|
||||
if (!response.ok) return null;
|
||||
|
||||
Reference in new issue
Block a user