Skip to content
Public template

Latest commit

Β 

History

423 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ KnowFlux

KnowFlux is a self-published fiction & poetry platform β€” a literary hub with a bold, Nintendo-inspired visual identity. Two serialized books (Exploded and The Pinnacle of Reality), an ever-growing poetry archive, and an interactive character database called the Omni-Dex.

🌐 Live site: knowflux.ink


✨ Features

πŸ“– Books

  • Two serialized books: Exploded and The Pinnacle of Reality
  • Fully dynamic β€” there are no per-page HTML files. Every page lives in books.json and is rendered by reader.html?book=<id>&page=<n>

πŸ–‹οΈ Poetry

  • Curated poetry archive with sections (Haikus, Triplets, …)
  • Unlike books, each poem is a standalone static HTML file in Poetry/, listed by poetry.html

πŸƒ Omni-Dex & Lore Lens

  • Interactive character/universe database (omni-dex.html):
    • Universe & type filtering (tabs + pills)
    • Animated stat bars
    • Modal detail view with stats sidebar and keyboard navigation (←/β†’/Esc)
  • Lore Lens β€” site-wide hover popovers that scan the rendered page for Omni-Dex entry names and show that card inline
  • Both features read from omni-dex-data.json

πŸ“š Reading Experience

  • Customizable display: text size, font family (Normal / Garamond / Lora), line width
  • Dark mode & Focus mode
  • Bookmarks β€” "Continue reading" links adapt to where you left off
  • Word count + estimated reading time per page
  • Scroll progress bar, keyboard navigation (← / β†’), chapter-completion toast
  • Drop caps on chapter-open pages

πŸ” Search

  • Instant client-side search powered by Algolia
  • The SDK is loaded from a CDN in search.html (v4); keys are inlined there
  • The index is built from sitemap.xml by Backend/algolia-build-index.py into algolia_records.json

πŸ› οΈ Admin Panel

  • Password-protected content generator at /admin
  • Add book pages or poems without touching the filesystem:
    • Book pages β†’ parsed with [dream], [thought], [underline] markers and written to books.json
    • Poems β†’ generates a static HTML page in Poetry/ and updates the poetry.html grid
  • Regenerates sitemap.xml and auto-commits & pushes to GitHub

πŸ—οΈ Architecture

A static Jamstack site with a thin Python dev/ops layer. Nothing renders on a server at request time β€” the backend exists purely to author content.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           Browser                                β”‚
β”‚  index Β· reader Β· poetry Β· contents Β· omni-dex Β· search Β· admin  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ static HTML + CSS + JS                   β”‚ form posts / fetch
               β–Ό                                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      Static Assets       β”‚                 β”‚   Backend (Python stdlib)β”‚
β”‚  HTML / CSS / JS / JSON  β”‚                 β”‚  server.py β€” dev server  β”‚
β”‚  books.json Β· poetry.htmlβ”‚                 β”‚  + admin content API     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚                                          β”‚
               β–Ό                                          β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        External Services                         β”‚
β”‚  Algolia (search) Β· Kit (newsletter) Β· GitHub (host + commits)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The one rule: books.json is the source of truth for books

Books used to be generated from exploded-page*.html files on disk. They aren't anymore β€” those files are gone. books.json is the database, and the admin panel is the only thing that should write to it.

Never let a script rebuild books.json from HTML. save_books_json() in server.py deliberately loads the existing file, rebuilds only the poetry section, and writes it back. That distinction is the difference between an edit and a data-loss event.

Tech Stack

Layer Technology
Frontend Zero frameworks β€” pure HTML5, CSS3, Vanilla JS
CSS Modular system under css/ (main.css aggregates the rest)
JS ES5-style modules concatenated into js/bundle.js by Backend/build.py
Backend Python standard library only (http.server, socketserver, json, re)
Search Algolia β€” algoliasearch v4 from CDN in search.html
Newsletter Kit (ConvertKit)
Hosting GitHub Pages (CNAME β†’ knowflux.ink) + auto-commit content pipeline

auto_commit() still honours a RENDER_GIT_BRANCH env var from an earlier Render deployment. Harmless β€” it defaults to main.


πŸš€ Getting Started

Prerequisites

  • Python 3.12+
  • No npm step. No external Python packages are required (see requirements.txt).
    • ⚠️ Exception: Backend/algolia-build-index.py imports certifi, which is neither installed nor declared. That script fails on import today.

1. Build the JS bundle

cd Backend
python build.py

Concatenates the modules listed in JS_MODULES into js/bundle.js (and mirrors the output to root script.js for the legacy poetry pages).

js/omni-dex.js is not in that list β€” it is loaded separately with defer on omni-dex.html only, so the rest of the site doesn't pay for it.

2. Start the dev server

cd Backend
python server.py

Serves on http://localhost:5001 (override with PORT).

To unlock the admin panel, create a .env in the repo root:

ADMIN_PASSWORD=your_password_here
GITHUB_TOKEN=your_token_here   # optional: enables auto-commit on publish

πŸ”’ If ADMIN_PASSWORD is unset, /admin/login accepts an empty password. The env var defaults to "" and the check is a plain ==. Always set it before exposing the server.

3. Regenerate the poetry index (optional)

python Backend/generate_books_json.py   # ⚠️ currently broken β€” see Known Issues
python Backend/algolia-build-index.py   # ⚠️ currently broken β€” missing certifi

πŸ—‚οΈ Project Structure

KnowFlux/
β”œβ”€β”€ index.html                 # Home page
β”œβ”€β”€ reader.html                # Dynamic book reader (?book=<id>&page=<n>)
β”œβ”€β”€ aboutbook.html             # Book overview
β”œβ”€β”€ contents.html              # Chapter contents (tabbed by book)
β”œβ”€β”€ poetry.html                # Poetry grid β€” the index AND the source for books.json poetry
β”œβ”€β”€ omni-dex.html              # Interactive character database
β”œβ”€β”€ search.html                # Algolia-powered search (SDK from CDN)
β”œβ”€β”€ feedback.html              # Reader feedback
β”œβ”€β”€ admin.html                 # Password-protected content generator
β”œβ”€β”€ comingsoon.html            # Legacy splash page β€” linked from nothing
β”œβ”€β”€ 404.html                   # Custom error page (GitHub Pages serves this automatically)
β”œβ”€β”€ books.json                 # πŸ“– THE content source β€” all book pages live here
β”œβ”€β”€ omni-dex-data.json         # Character/universe data for Omni-Dex + Lore Lens
β”œβ”€β”€ sitemap.xml                # Regenerated on publish
β”œβ”€β”€ algolia_records.json       # Generated search records
β”œβ”€β”€ CNAME                      # knowflux.ink
β”œβ”€β”€ css/                       # Modular CSS, aggregated by main.css
β”‚   β”œβ”€β”€ main.css               # ← imports everything below
β”‚   β”œβ”€β”€ base.css
β”‚   β”œβ”€β”€ layout.css
β”‚   β”œβ”€β”€ components.css
β”‚   β”œβ”€β”€ navigation.css
β”‚   β”œβ”€β”€ reading.css
β”‚   β”œβ”€β”€ poetry.css
β”‚   β”œβ”€β”€ omni-dex.css
β”‚   β”œβ”€β”€ lore-lens.css
β”‚   β”œβ”€β”€ search.css
β”‚   β”œβ”€β”€ about.css
β”‚   β”œβ”€β”€ 404.css
β”‚   β”œβ”€β”€ darkmode.css
β”‚   └── responsive.css
β”œβ”€β”€ js/
β”‚   β”œβ”€β”€ bundle.js              # Built output β€” do not edit by hand
β”‚   β”œβ”€β”€ reader.js              # Fetches books.json, renders a page
β”‚   β”œβ”€β”€ navigation.js          # Menu, mobile overlay, promo cycling
β”‚   β”œβ”€β”€ reading.js             # Reading experience controller
β”‚   β”œβ”€β”€ contents.js            # Contents tabs + bookmark-aware links
β”‚   β”œβ”€β”€ main.js                # Shared bootstrap
β”‚   β”œβ”€β”€ random.js              # "Random poem/book" buttons
β”‚   β”œβ”€β”€ footer.js              # Copyright year (CST) + footer reveal
β”‚   β”œβ”€β”€ lore-lens.js           # Site-wide Omni-Dex hover popovers
β”‚   └── omni-dex.js            # Omni-Dex grid, filters, modal (page-specific)
β”œβ”€β”€ Backend/
β”‚   β”œβ”€β”€ server.py              # Dev server + admin content API
β”‚   β”œβ”€β”€ build.py               # JS bundler
β”‚   β”œβ”€β”€ generate_books_json.py # Poetry regeneration (⚠️ broken path)
β”‚   β”œβ”€β”€ algolia-build-index.py # Algolia records from sitemap (⚠️ missing certifi)
β”‚   └── config.py              # Shared ROOT_DIR constant
β”œβ”€β”€ Images/                    # Static images
└── Poetry/                    # Generated poem HTML files (static, one per poem)

✍️ Publishing Workflow

  1. Log into /admin, enter the password.
  2. Pick a tab β€” Pinnacle, Exploded, or Poetry.
  3. Fill in the form:
    • Book pages: page number, chapter title, content (with markers)
    • Poems: title, section (existing or new), stanzas separated by blank lines
  4. Hit Generate β€” the server:
    • Writes to books.json via add_page_to_books_json(), or creates a poem HTML file and rewrites the poetry.html grid
    • Regenerates sitemap.xml
    • Auto-commits and pushes to GitHub (if GITHUB_TOKEN is set)
  5. GitHub Pages redeploys. πŸŽ‰

Content Markers (book pages)

Marker Renders as
[thought]…[/thought] Blue italic inline thought (works anywhere, including inside other blocks)
[dream]…[/dream] Horizontal rule + styled italic memory card
[underline] / [/underline] Orange horizontal divider

⚠️ Known bug: [underline] is parsed as an opening tag but rendered as a divider. Any paragraphs written after a bare [underline] are silently discarded, because the renderer never emits them. Always close it with [/underline].

Content model

{
  "page_number": 13,
  "chapter_title": "Ch. 2 | Scarlet",
  "content": "      <p>…</p>\n\n      <div class=\"underline\"></div>\n\n",
  "file": "",
  "url": "reader.html?book=exploded&page=13"
}

content is pre-rendered HTML, not markdown. Marker parsing happens once, at save time, through parse_content_blocks() β†’ render_content_blocks().


πŸ”§ Configuration

Variable Purpose
PORT Server port (default 5001)
ADMIN_PASSWORD Admin panel password. Unset = no protection.
GITHUB_TOKEN Enables auto-commit/push on publish
GIT_REPO_URL Override repo URL for auto-commit (defaults to origin)
GIT_NAME / GIT_EMAIL Commit author (defaults to KnowFlux Bot <bot@knowflux.ink>)

Algolia keys are inlined in search.html β€” swap them for your own fork.


πŸ“„ License

Β© 2026 KnowFlux β€” Keep Blooming, Keep Flying