Merge pull request 'Fix configuration management' (#2) from claude into main
Reviewed-on: Astronomicka_Expedice/cmjs#2
This commit was merged in pull request #2.
This commit is contained in:
commit
62f909ead8
8 files changed
+73
-32
No files matched your search
@@ -1 +1,2 @@
|
||||
/articles/
|
||||
/js/config.js
|
||||
@@ -58,7 +58,8 @@ 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, ARTICLES_URL (all via import.meta.url)
|
||||
│ ├── config-default.js # Shipped defaults for BASE_URL, MARKED_URL, ARTICLES_URL
|
||||
│ ├── config.js # Optional local overrides — gitignored; see "Local configuration" below
|
||||
│ ├── frontmatter.js # parseFrontmatter() — pure YAML-front parser
|
||||
│ ├── templates.js # loadTemplates(), templates cache
|
||||
│ ├── discovery.js # discoverArticles(), fetchJson(), article cache
|
||||
@@ -86,6 +87,26 @@ from the library — not something an embedding page needs to bring along.
|
||||
└── slug~DDMMYYYY~tag1+tag2.md # One file per article — see "Adding an article"
|
||||
```
|
||||
|
||||
## Local configuration
|
||||
|
||||
`js/config-default.js` holds the shipped defaults (`BASE_URL`, `MARKED_URL`, `ARTICLES_URL`) and
|
||||
is tracked in git; every other module imports from it. It also loads an optional `js/config.js`
|
||||
— gitignored, not part of cmjs's own git history — to override any of them. **Nothing needs to
|
||||
be created before first use**: if `js/config.js` doesn't exist, the shipped defaults apply as-is.
|
||||
|
||||
The split exists for using cmjs as a git submodule (or otherwise pulling in a newer version some
|
||||
other way): since `config.js` is gitignored, updating cmjs never touches it, so any override
|
||||
you've made survives. Only `config-default.js` gets updated.
|
||||
|
||||
To override a setting, create `js/config.js` and export just the constant(s) you want to change —
|
||||
anything you don't export falls back to `config-default.js`. For example, to move where articles
|
||||
live (see "Pointing articles/ somewhere else" below for the matching nginx-side change this
|
||||
needs):
|
||||
|
||||
```js
|
||||
export const ARTICLES_URL = new URL('/blog-content/articles/', location.origin).href;
|
||||
```
|
||||
|
||||
## Adding an article
|
||||
|
||||
An article is a single Markdown file placed directly in its author's directory. Its *file name*
|
||||
@@ -393,14 +414,10 @@ server {
|
||||
|
||||
### 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;
|
||||
```
|
||||
By default the crawler looks for articles at `articles/` next to the rest of cmjs (`ARTICLES_URL`,
|
||||
computed as a sibling of the `js/` folder). Articles don't have to live there — override
|
||||
`ARTICLES_URL` in your local `js/config.js` (see "Local configuration" above) to point anywhere
|
||||
under the same origin (or a different one, CORS permitting).
|
||||
|
||||
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:
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// Shipped defaults for BASE_URL, MARKED_URL, ARTICLES_URL, plus the loader
|
||||
// that lets an optional local js/config.js (gitignored — not part of this
|
||||
// repo's history; see "Local configuration" in the README) override any of
|
||||
// them. Every other module imports from THIS file, not config.js directly —
|
||||
// config.js might not exist at all (nothing has created one yet, or it was
|
||||
// deleted), and a plain `import ... from './config.js'` would then break
|
||||
// the whole module graph with no way to catch it. A dynamic import() can be
|
||||
// caught, so that's what resolves it below; top-level await makes every
|
||||
// module that imports this one wait for that resolution before it runs,
|
||||
// same as if these were plain synchronous exports.
|
||||
//
|
||||
// config.js, if present, only needs to export whichever of these it wants
|
||||
// to change — anything it doesn't export falls back to the default here.
|
||||
// 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.
|
||||
|
||||
const DEFAULT_BASE_URL = new URL('../', import.meta.url).href;
|
||||
const DEFAULT_MARKED_URL = new URL('../vendor/marked.min.js', import.meta.url).href;
|
||||
const DEFAULT_ARTICLES_URL = new URL('articles/', DEFAULT_BASE_URL).href;
|
||||
|
||||
let overrides = {};
|
||||
try {
|
||||
overrides = await import('./config.js');
|
||||
} catch {
|
||||
// No local config.js (or it failed to load) — shipped defaults stand.
|
||||
}
|
||||
|
||||
// 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 = overrides.BASE_URL ?? DEFAULT_BASE_URL;
|
||||
|
||||
// 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 = overrides.MARKED_URL ?? DEFAULT_MARKED_URL;
|
||||
|
||||
// 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 — override it in config.js to point
|
||||
// anywhere under the same origin, 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 = overrides.ARTICLES_URL ?? DEFAULT_ARTICLES_URL;
|
||||
@@ -1,19 +0,0 @@
|
||||
// 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 — 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;
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { parseFrontmatter } from './frontmatter.js';
|
||||
import { BASE_URL, ARTICLES_URL } from './config.js';
|
||||
import { BASE_URL, ARTICLES_URL } from './config-default.js';
|
||||
import { mapWithConcurrency } from './concurrency.js';
|
||||
import { getAllCacheEntries, setCacheEntry, pruneCache } from './cache.js';
|
||||
import { t } from './i18n.js';
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
// locale, that file is fetched too and merged on top — a translation file
|
||||
// only needs to cover the keys it actually translates, missing ones still
|
||||
// render in English rather than breaking.
|
||||
import { BASE_URL } from './config.js';
|
||||
import { BASE_URL } from './config-default.js';
|
||||
|
||||
const FALLBACK_LOCALE = 'en';
|
||||
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
// 4 segments, first = "category", third = "page" → category filter, page N (#category/linux/page/2)
|
||||
// 4 segments, first = "tag", third = "page" → tag filter, page N (#tag/guides/page/2)
|
||||
|
||||
import { MARKED_URL } from './config.js';
|
||||
import { MARKED_URL } from './config-default.js';
|
||||
import { loadTemplates } from './templates.js';
|
||||
import { loadStrings, t } from './i18n.js';
|
||||
import { loadArticleList, loadAuthorView, loadCategoryView, loadTagView, loadArticle, loadSearch } from './views.js';
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
// Each template needs its own <template> element — reusing one would overwrite
|
||||
// the shared DocumentFragment, leaving both pointing to the last HTML assigned.
|
||||
|
||||
import { BASE_URL } from './config.js';
|
||||
import { BASE_URL } from './config-default.js';
|
||||
|
||||
export const templates = {};
|
||||
|
||||
|
||||
Reference in new issue
Block a user