Experimental CMS Technical Guide

Experimental CMS Guide

Experimental CMS Guide

By Leethaxor69

Table of Contents


Chapter 1: Chapter 1: Introduction to ExpCMS

What is ExpCMS?

ExpCMS is a lightweight, opinionated Content Management System built on a Flask backend, specifically designed to bridge the gap between dynamic administrative interfaces and static-site performance. Unlike bloated CMS platforms that require database servers (like MySQL or PostgreSQL) and complex CDNs, ExpCMS utilizes a Multi-File Database (MFDB) architecture based on BEJSON (Boehnen Elton JSON).

This means your entire data store—pages, categories, media metadata, and site configuration—lives in structured, human-readable JSON files. When you're ready to deploy, the built-in static site builder (EXPCMS_Builder.py) parses these MFDB files and compiles them into a fully portable, high-speed static HTML site. No database overhead, no runtime injection, and zero external CDN dependencies—just raw, server-side-rendered speed.

Core Architecture

ExpCMS isn't just another CRUD app; it’s a toolkit for data integrity. The system leverages the BEJSON ecosystem to ensure your content is as robust as it is portable.

  • MFDB Persistence: Your content isn't trapped in a proprietary database engine. It’s stored in Data/workspace/ as BEJSON 104 and 104a entity files. You can open them, audit them, and even edit them with a text editor if you're not a total noob.
  • Static-Site Builder: The system separates the "Admin" (Flask app) from the "Production" (static HTML). When you hit the build button, the builder interprets your MFDB entities through HTML_Skeletons/ to output a site into Processing/www/ that is ready to be served by Nginx, Apache, or even a local file system.
  • Modular Widgets: Need an interactive element? Use the widget registry (lib_bejson_ExpCMS_widgets.py) to inject portable snippets—like Social Links or YouTube embeds—that remain self-contained. They don't need external JS libraries that break your site when a CDN goes offline.

Why ExpCMS?

Listen up: if you’re tired of managing SQL migrations, worrying about DB crashes, or dealing with "plugins" that introduce more security holes than they close, this is for you.

The ExpCMS Edge:
  • Portability: Move your entire site by just moving the Data/ directory.
  • Integrity: MFDB uses strict positional integrity. If your data doesn't match the schema, the validators catch it before the site breaks.
  • Security: By rendering to static HTML, you remove the entire class of vulnerabilities associated with server-side processing (e.g., SQL injection, remote code execution) from the public-facing site.
  • No Black Boxes: The code style is clean, the libraries are isolated, and the data is transparent.

System Roles and Directory Logic

Don't go deleting files just because they look "stale." Here is the hierarchy you need to understand:

  • Data/workspace/: This is where your MFDB lives. It’s the source of truth.
  • Data/*.mfdb.zip: These are your master archives. When you use the "Repack" tool, the system syncs your workspace against these files. Keep them safe.
  • Lib_PY/: This directory contains the engine. The Core/ libraries are frozen—don't touch them unless you want to break the BEJSON validation contract. Application logic lives strictly in ExpCMS/.

If you're here to build, stick to the EXPCMS_Builder.py workflows and keep your MFDB structure clean. If you break the positional integrity of the BEJSON files, you’re on your own. Let's get into the install.


Chapter 2: Chapter 2: Installation and Environment Setup

Environment Prerequisites

Before you even think about running the admin app, make sure your machine isn't a total pile of junk. ExpCMS requires Python 3.10 or higher. If you’re still running legacy Python, do yourself a favor and upgrade before you waste my time with dependency errors.

You need to install the core dependencies before the system will even compile. Navigate to the root of your project directory and run:

pip install -r requirements.txt

This installs Flask, Jinja2, Werkzeug, and BeautifulSoup4. These are non-negotiable. If you try to bypass these or use mismatched versions, the MFDB loaders or the HTML parser will fail, and you’ll end up with a broken workspace. Don't be a noob—use a virtual environment if you don't want to pollute your system-wide Python installation.

Initializing the Workspace

ExpCMS relies on the Data/ directory for everything. If you cloned this repo, the directory structure should already be intact. If you deleted or moved anything, the system will fail to mount the MFDB archives.

Ensure your directory looks like this before proceeding:

Path Purpose
Data/workspace/db_global/ Global MFDB (Authors, Configs, Assets)
Data/workspace/db_content/ Content MFDB (Pages, Categories, Apps)
Data/*.mfdb.zip The master archive backups

If these are missing, the MFDB_CMS_Manager will throw a tantrum because it can't find the manifests (104a.mfdb.bejson). Do not attempt to "fix" this by creating empty files; restore from the provided zips or use the initialization tools if you’re doing a factory reset.

Running the Admin Dashboard

The admin app is a Flask-based server that handles your CRUD operations, media uploads, and widget configuration. It runs on port 5005 by default.

To start the service:

python3 EXPCMS.py

Once the server is live, point your browser to http://127.0.0.1:5005/. You should see the dashboard. If you see a 500 error, check your console—you likely messed up the MFDB mount or a Parent_Hierarchy link in one of your entity files.

Builder Environment

If you’re just here to compile the static site and skip the admin interface, you’ll use the EXPCMS_Builder.py script. This script doesn't need the Flask server to be running, but it does need valid MFDB data.

Run it directly from the terminal to trigger a full site build:

python3 EXPCMS_Builder.py

This script reads your MFDB workspace, runs the builders, and dumps the final HTML into Processing/www/.

Troubleshooting Common Setup Failures

I’ve seen too many people cry about "missing data" or "invalid JSON." Read this carefully:

  1. Positional Integrity Failures: If your Values arrays don't match the Fields count defined in your .bejson files, the system will reject the file. If you’ve been manually editing your MFDB files with a text editor and you removed a field, stop. You need to pad with null or the parser will choke.
  2. Permissions: If you’re on a Linux box, make sure the user running the script has read/write access to the Data/ directory. If the app can't write the .mfdb_lock files during a mount, it won't let you edit anything.
  3. Ghost Apps: If you import a ZIP app and it doesn't show up, ensure your entry_file path matches what's inside the uploaded ZIP. The system validates this at import—if you mess with the files on disk manually, you’ll break the path.

That’s it. If you can’t get this running, you shouldn't be managing a CMS. Keep your workspace clean, keep your paths relative, and don't touch the Lib_PY/Core/ files unless you want to invite disaster.


Chapter 3: Chapter 3: The Admin Dashboard Interface

The Dashboard Layout

Once you’ve actually managed to start the Flask server without breaking everything, the admin dashboard is where you’ll spend your time. It’s built on a standard Jinja2 layout using admin_base.html as the anchor. The UI is split into two primary regions: the c-sidebar and the main c-bejson-form__container.

If you’re a noob, don't try to "customize" the CSS via the browser inspector. Everything is served via the lib_bejson_HTML_bejson_html3_component_css.py logic. If the dashboard looks broken, your browser cache is probably holding onto an old version of the component assets. Hard refresh (Ctrl+F5) and move on.

Navigating the Admin Modules

The sidebar is your command center. Every link here triggers an MFDB_CMS_Manager action, which pulls data directly from the Data/workspace/ MFDB files. Here is what you’re actually looking at when you click these:

Module MFDB Context Functionality
Pages db_content CRUD for content entities.
Categories db_content Feed management and categorization.
Media Library db_global Asset ingestion and metadata.
Build & Tools system Triggers EXPCMS_Builder and repacks.
System Config db_global Site-wide settings and social links.

The Data-Table and Form Logic

Almost every page in the dashboard uses two shared components: the Data-Table and the Form-Row. These are injected via Jinja2 fragments from templates/components/backend/.

  • Data-Table: This is just a visual layer over your BEJSON Values arrays. If you see a column missing, it’s because the Fields array in your relevant entity file doesn't match the table header definition. It does NOT do magic. If you aren't seeing your data, check the MFDB entity file for that record type.
  • Form-Row: This is how you push changes back to the MFDB. When you hit "Save," the app doesn't just "update a database"—it performs an atomic file operation. It reads the existing BEJSON file, performs the mutation in memory, and writes it back using os.rename to ensure the file isn't partially written if the system crashes mid-save. If you’re manually editing the .bejson files while the server is running, expect race conditions. Don't do it.

The "Build & Tools" Page (/system)

This is the only part of the interface that doesn't just manage data—it manages the system state.

  1. Build: Runs the EXPCMS_Builder logic. It renders your HTML_Skeletons and components into Processing/www/. If your CSS isn't showing up, it's because you haven't triggered a build after updating your widget snippets in Lib_PY/ExpCMS/.
  2. Repack: This runs MFDBArchive.commit(). It takes the live Data/workspace/ state and zips it into the master archives (global_master.mfdb.zip, etc.). If you’ve spent all day editing pages and don't click this, your backups are stale.
  3. Factory Reset: This nukes the workspace. Do not touch this unless you have a separate backup of your zips, because once it clears the Data/workspace/ folders and re-mounts from the master, any unsaved work is gone forever.

Handling Previews and Widgets

The dashboard includes an integrated widget picker. When you edit a page body, you aren't just typing raw HTML—the MFDB_CMS_Manager allows you to inject portable widget snippets (CTA boxes, YouTube embeds).

Warning: The preview in the admin dashboard renders these using the same components as the final static site. If a widget looks fine in the preview but breaks in the build, you have a mismatch between the admin_base.html CSS and the Global_Skeleton.html token set. Remember, the dashboard and the static site are two independent token sets aliased to the same variables—if you change the site's dark-mode tokens, you must verify the aliases are still syncing correctly in your HTML_Skeletons.


Chapter 4: Chapter 4: Managing Pages and Content

Page Lifecycle and CRUD Operations

Stop messing around with raw JSON files if you don't know what you’re doing. The Pages module in the admin dashboard is the high-level interface for the db_content MFDB. When you create or update a page, you’re hitting the MFDB_CMS_Manager.

Every page entry in the pages.bejson file contains a unique page_uuid. Do not touch this. If you think you’re being clever by manually editing these UUIDs, you’ll break the relational integrity of your entire build. Pages are linked to categories via the category_fk field; if you enter a value here that doesn't exist as a category_slug in your categories.bejson file, the static site builder will fail to resolve the link, and your page will effectively vanish from the navigation.

HTML Import and Sanitization

One of the few "pro" features here is the HTML/Word import. If you’re importing existing docs, the system uses BeautifulSoup to strip the garbage. It doesn't just strip tags; it executes a destructive cleanup of scripts, inline styles, and those pathetic AI-generated watermarks some of you keep pasting into the CMS.

Security Warning: The import tool is designed to sanitize, but it is not a silver bullet. Always verify your source files. If you bypass the import tool and push raw HTML into the `body_html` field of your BEJSON entity file, you are responsible for any XSS vulnerabilities you introduce into your own static site. The builder renders this field `| safe` to preserve your layout, so don't be an idiot—don't inject unsanitized `
leethaxor69
Article Author

leethaxor69

Elite Security Researcher & Autonomous Systems Engineer


Related Content