feat(cms): U4 one-command site build + local preview
Add tools/build_site.py: runs the full pipeline in dependency order (build_content -> build_listings -> seo_inject --all --sitemap -> build_botlinks -> build_search_index), each as a subprocess so a failing step aborts the build before anything downstream runs (no partial deploy). --check verifies non-destructively; --images also runs optimize_images. This is what CI will run in U5. Fix a build_content idempotence bug found via U4: the hero and article-header regions were emitted with leading indentation while the regex left the template's pre-tag whitespace in place, so indentation compounded (+16 spaces) on every rebuild. First line is now unindented; the full build is verified idempotent (identical git tree across two runs). Added a fixpoint test (re-rendering a page's own output is byte-identical) so this can't regress. docs/local-preview.md: build + serve on :8000 in all three languages. tools/README.md: document build_site + build_content. 26 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
8ff968739a
commit
2d535db7d5
5 files changed
+175
-2
No files matched your search
@@ -0,0 +1,62 @@
|
||||
# Local preview
|
||||
|
||||
How to build the site from `content/` and preview it on your machine, so you
|
||||
can see blog / news / event changes before they go live.
|
||||
|
||||
## 1. Build
|
||||
|
||||
From the repo root:
|
||||
|
||||
```sh
|
||||
python tools/build_site.py
|
||||
```
|
||||
|
||||
This runs the whole pipeline in order (renders detail pages from `content/`,
|
||||
rebuilds the News hub + homepage, injects SEO + sitemap, regenerates the
|
||||
bot-discovery files, and rebuilds the offline search index). Any failing step
|
||||
aborts the build, so a broken step never produces half-built output.
|
||||
|
||||
Options:
|
||||
|
||||
```sh
|
||||
python tools/build_site.py --check # verify pages match content/, write nothing
|
||||
python tools/build_site.py --images # also convert new images to WebP + fix refs
|
||||
```
|
||||
|
||||
The build is **idempotent** — running it again with no content change produces
|
||||
no file changes.
|
||||
|
||||
## 2. Preview
|
||||
|
||||
Serve the repo root over HTTP (opening the files directly with `file://` breaks
|
||||
absolute paths and the language switcher):
|
||||
|
||||
```sh
|
||||
python -m http.server 8000
|
||||
```
|
||||
|
||||
Then open:
|
||||
|
||||
- English: <http://localhost:8000/en/>
|
||||
- Македонски: <http://localhost:8000/mk/>
|
||||
- Slovenščina: <http://localhost:8000/si/>
|
||||
|
||||
Blog / news / event pages live under, e.g.,
|
||||
`http://localhost:8000/en/blog/<slug>/`.
|
||||
|
||||
## 3. Requirements
|
||||
|
||||
Python 3 with `beautifulsoup4`, `pyyaml`, and `Pillow` (only needed for
|
||||
`--images`):
|
||||
|
||||
```sh
|
||||
python -m pip install beautifulsoup4 pyyaml pillow
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- `content/` is the **source of truth** for blog/news/events; the detail pages
|
||||
under `en|mk|si/{blog,news,projects}/` are build output. Edit content in
|
||||
`content/` (or, once it is wired up, the CMS), not the generated pages.
|
||||
- See `docs/content-model.md` for the front-matter schema and
|
||||
`docs/plans/2026-08-08-001-feat-no-code-cms-plan.md` for the overall design.
|
||||
Reference in new issue
Block a user