BoxLang 馃殌 A New JVM Dynamic Language Learn More...
|:------------------------------------------------------: |
| 鈿★笌 B o x L a n g 鈿★笌
| Dynamic : Modular : Productive |
| :----------------------------: |
Copyright Since 2023 by Ortus Solutions, Corp
www.boxlang.io | www.ortussolutions.com
聽
Write your content in Markdown. BX Sites turns it into a complete, themed, searchable website - ready to deploy.
It's a general-purpose static site generator, not just for
documentation - docs, a blog, a marketing site, a knowledge base,
anything Markdown can express, all built the same way, with the same
themes, search and i18n. Built in BoxLang on top of bx-markdown,
in the spirit of mkdocs: point
it at a docs/ folder (or src/, if that reads
better for your project) and get a themed, searchable static site out.
Already on GitBook, mkdocs, or Notion, or just have a folder of
Markdown? bxSites migrate
--from=gitbook|mkdocs|markdown-zip|notion converts it straight
into a bx-sites project - see Migrating from
GitBook or Migrating from mkdocs.
bootstrap
(default), material, tailwind, and seven
more inspired by Docsy, Stripe, Docusaurus, Just the Docs, VuePress,
GitBook and Notion, all overridable via a project's own
.theme/ folder (inside its content root). See Themes.{{ variables }} and magic
functions - reference bxsites.yaml-defined
values or call a small BoxLang helper function straight from
Markdown, no plugin needed. See Variables &
Magic Functions.docs/blog/posts/ for authors/categories/RSS/drafts,
version:new to snapshot a release,
docs/i18n/<code>/ to translate. See Blog, Versioning, i18n.bxSites deploy to
S3 (and any S3-compatible service), Azure Blob Storage, GCS,
Firebase Hosting, FTP/SFTP, rsync, Netlify, Vercel, Cloudflare
Pages, a local directory, or GitHub Pages - one shared build, every
deployments/*.json target at once if you want,
bxSites publish to bxSites Cloud itself, or
bxSites package for a plain zip instead. See Deployment.install:plugin/install:theme pull
published ones from ForgeBox, and theme:import converts
an existing mkdocs/jekyll/hugo theme into a starting point. See Plugins.bxSites docbox turns your classes into themed,
searchable API pages via DocBox's JSON output, and bxSites
coldbox documents a whole ColdBox app - routes, handlers,
models and WireBox mappings, modules, interceptors, scheduled tasks
- straight from its conventions, without booting it. See DocBox API Reference and ColdBox Applications.bxSites
skills:install (or npx skills add
ortus-boxlang/bx-sites-skills, or coldbox ai skills
install) teaches Claude Code, Cursor, Codex, and other AI
coding assistants bx-sites' own conventions - content blocks, config
keys, deployment, and more. See AI Agent Skills.sitemap.xml, robots.txt (or your own
hand-authored one), canonical links, llms.txt, and
redirects that keep a moved/renamed page's old URL working instead
of 404ing.Needs the BoxLang runtime installed
first - either the quick installer (curl -fsSL
https://install.boxlang.io/ | bash) or BVM
(curl -fsSL https://install-bvm.boxlang.io/ | bash).
See Getting
Started for details.
# OS Binary
install-bx-module bx-sites
# CommandBox
box install bx-sites
# Scaffold a new docs project (docs/ + bxsites.yaml)
bxSites new my-docs
cd my-docs
# Build the static site to site/
bxSites build
# Or build and serve locally with live reload while you write
bxSites serve
See Getting Started for the full walkthrough.
box install drops a standalone bxSites
script on your PATH (via box.json's
boxlang.executable), so every verb can be run either that
short way, or as boxlang bxSites <verb> - both run
the exact same thing; use the longer form anywhere the
PATH shim isn't set up (a CI runner, a module registered
by hand):
bxSites <verb> [options]
# or, equivalently:
boxlang bxSites <verb> [options]
| Verb | Purpose |
|---|---|
new
| Scaffold a new project (docs|src/ +
bxsites.yaml, defaulting to the
bootstrap theme; --format=json for
bxsites.json instead) |
build
| Render docs|src/**.md into a static site in
site/, including the search index,
sitemap.xml, llms.txt and assets.
Needs bx-markdown, bx-esapi, bx-yaml and bx-image installed |
serve
| Build and serve the site locally with live reload (needs bx-markdown, bx-esapi, bx-yaml and bx-image too) |
search-index
| Rebuild site/search-index.json standalone
(also runs automatically during build) |
clean
| Remove site/ and any build cache |
migrate
| Convert an existing GitBook export, mkdocs project, plain
zip of Markdown, or Notion export into docs/ +
nav.json (--from=gitbook, the default,
--from=mkdocs, --from=markdown-zip, or --from=notion) |
audit
| CI-grade content check on a built site/:
broken internal links/images, missing alt text, orphaned pages |
stats
| Read-only summary report on a built site/:
page/word counts, versions/locales, blog, tags, search index,
site size |
doctor
| Environment/config health check: JVM, docs/
(or src/), config validity, required modules, theme override |
post:new
| Scaffold a new blog post at docs/blog/posts/<slug>.md
|
version:new
| Snapshot docs/ into a new docs/versions/<name>/
|
i18n:status
| Per-locale translation coverage report against the default tree |
i18n:new
| Scaffold a new docs/i18n/<code>/ locale |
page:new
| Scaffold a single docs page at an arbitrary path |
plugin:new
| Scaffold a plugin module skeleton |
install:plugin
| Download a plugin from ForgeBox into project-local boxlang_modules/
|
theme:new
| Eject a built-in theme into your content root's
.theme/ for customizing |
install:theme
| Download a theme from ForgeBox into your content root's .themes/<name>/
|
skills:install
| Install the official AI agent skill
pack (ortus-boxlang/bx-sites-skills) via
npx skills add
|
theme:import
| Best-effort convert a mkdocs/jekyll/hugo theme's own
template files into a .themes/<name>/ scaffold |
page:rename
| Move a docs page and rewrite every relative link that pointed at it |
blog:drafts
| List every blog post whose frontmatter sets draft: true
|
blog:find
| Filter blog posts by author/category/tag/date range |
search:query
| Query a built search-index.json and rank results |
lint
| Pre-build content checks: heading level skips, blog posts missing a valid date |
docbox
| Generate a BoxLang/CFML API reference from DocBox into the content
dir (needs the bx-docbox module) |
coldbox
| Document a ColdBox application from its conventions: routes, handlers, models, modules, interceptors, scheduled tasks |
gh-deploy
| Build and force-push site/ to a
gh-pages-style branch (--branch,
--remote, --message) |
deploy
| Build and ship site/ to a real target (s3,
azure, gcs, firebase, ftp, sftp, rsync, netlify, vercel,
cloudflare-pages, local, github-pages); no args deploys every
deployments/*.json entry; --verbose
|
publish
| Build and publish site/ to bxSites Cloud via
cloud.siteId/cloud.apiUrl in
bxsites.yaml (--token, overrides the
BXSITES_CLOUD_TOKEN env var) |
package
| Build and zip site/ into a single archive
(--output=<path>, defaults to site.zip) |
Every verb accepts --projectRoot=<path> (or a bare
positional path) to target a project other than the current directory.
Run bxSites help (or bxSites with no verb at
all) for full usage - -h/--help show
BoxLang's own generic runtime help instead, since BoxLang's CLI
reserves those as its own global flags before bxSites ever sees them;
see CLI Reference.
This repository documents itself with BX Sites - see
bxsites.yaml and docs/ at the repo root,
published at:
bxsites.yaml's own versions.default)Both are built with all ten built-in themes side by side
(bootstrap at the root, every other theme under
theme/<name>/) - this doubles as a theme gallery -
use the switcher next to the dark-mode toggle to flip between them on
any page. CI builds each theme as its own parallel job (see
.github/workflows/pages.yml);
./buildMultiTheme.sh reproduces the same gallery layout
locally for a quick preview.
Or read the source directly:
bxsites.yaml, the default, or bxsites.json)See MODULE_SPEC.md for the design spec driving this module's development.
.github/workflows - CI: tests (tests.yml),
PR checks (pr.yml), snapshot/release builds
(snapshot.yml, release.yml), and
publishing this repo's own docs to GitHub Pages (pages.yml)models - the module's own source:
models/cli (one dispatcher per bxSites
verb), models/config (site config loader/validator -
bxsites.yaml/.yml/.json),
models/build (project scaffolding + the
docs/nav/markdown/theme/search/sitemap build pipeline),
models/deploy (the deploy verb's pluggable
targets - S3, Azure, GCS, Firebase, FTP/SFTP, rsync, Netlify,
Vercel, Cloudflare Pages, local, GitHub Pages),
models/publish (the publish verb's own
bxSites Cloud client)resources/themes - built-in themes (native BoxLang
.bxm templates + assets), ten in total:
bootstrap (default), material,
tailwind, plus seven material-forked
themes (docsy, slate,
docusaurus, justthedocs,
vuepress, gitbook, notion) -
all with the BoxLang brand palette, dark mode, breadcrumbs and
code-copy buttons applied out of the box. A project can override any
of them via its own .theme/ folder inside its content
root (same layout.bxm + page.bxm contract
- see Themes)resources/assets - module-wide shared client-side
assets: the search widget (search.js, MiniSearch-backed
with a Cmd/Ctrl+K palette), the copy-code button, and per-feature
init scripts (tabs, Mermaid, math, OpenAPI, prompts, conditional
content, ...), plus every vendored third-party library under
vendor/ (Bootstrap, highlight.js, Alpine.js,
MiniSearch, Mermaid, Swagger UI) - no CDN, no outbound requests from
a built sitedocs / bxsites.yaml - this repository's
own docs, built by BX Sites itself (boxlang bxSites build)tests/specs - TestBox specs, one bundle per class under models/
box.json - package metadata used to publish to ForgeBoxModuleConfig.bx - this module's configuration/CLI entry point
Build.bx packages this module for distribution to
ForgeBox: it produces a zip in build/ containing
everything needed to run the module (box.json,
ModuleConfig.bx, and the rest of the module's own files).
It also produces a second, self-contained artifact -
build/artifacts/bx-sites-<version>-with-deps.zip -
that additionally bundles every runtime dependency from
box.json's dependencies block
(bx-markdown, bx-esapi,
bx-yaml, bx-image, bx-ftp,
bx-toml) inside a modules/ folder alongside
the module itself, using BoxLang's module
inception: a module's own modules/ folder is
discovered and activated before the module itself, so this artifact
needs nothing pre-installed to run standalone - just drop it into a
modules/ (or boxlang_modules/) folder on its
own. The primary bx-sites-<version>.zip artifact -
and the box forgebox publish step, which publishes from
build/module - are unaffected; the bundled dependencies
only ever land in the -with-deps artifact, built from a
separate build/module-with-deps copy.
boxlang Build.bx --version=1.1.0
| Option | Required | Default Value | Description |
|---|---|---|---|
version
| No | 1.0.0
| The version of the module. |
branch
| No | development
| The branch being built. |
buildId
| No | UUID (generated) | A unique identifier for the build. |
Copy .env.example to .env for the local
preview settings.
cp .env.example .env
Run the setup script once to create boxlang_modules/ and
register this checkout as boxlang_modules/bx-sites. If
the root modules/ folder is missing, it asks whether it
should run box install for you:
boxlang Setup.bx
With CommandBox installed, run tests using bash ./testbox/run.
To preview the dogfooded documentation site locally:
boxlang bxSites serve --host="$BXSITES_PREVIEW_HOST" --port="$BXSITES_PREVIEW_PORT"
Open http://$BXSITES_PREVIEW_HOST:$BXSITES_PREVIEW_PORT
in a browser. serve builds the site, watches source
files, and reloads the browser when changes are detected. Stop it with
Ctrl+C; the generated site/ directory is
ignored and should not be committed.
This module uses SemVer for
versioning. The version is stored in box.json, used to
publish to ForgeBox, and bumped automatically by the release workflow,
which also tags the repo for each release.
Development happens on development; a release is just
merging it into main - release.yml triggers
on that push and does the rest:
changelog.md's ## [Unreleased]
section under the real version/date, and generates a matching
docs/releases/vX.Y.Z.md "what's new" page
from it.Build.bx), tags the repo
vX.Y.Z, and publishes to ForgeBox, S3, and a GitHub Release.development's own box.json to the
next minor version and carries the finalized changelog/release-notes
content back onto it, so ## [Unreleased] is ready for
the next cycle immediately.A push to development instead builds and publishes a
-snapshot (steps 1-2 only, no version bump - see
snapshot.yml/release.yml's own
snapshot: true input).
This repository doesn't have a main branch yet - create
one from development (git checkout -b main
development && git push -u origin main) when you're
ready to cut the first release; every release after that is just
merging development into it.
pr.yml - runs the test suite against every pull requesttests.yml - the reusable test-suite workflow
(./testbox/run), called by both pr.yml and snapshot.yml
snapshot.yml - on every push to
development: runs tests, then builds and publishes a
snapshot releaserelease.yml - builds and publishes a release to
ForgeBox (a stable release from main, or a snapshot
when called from snapshot.yml); requires a
FORGEBOX_API_TOKEN secretpages.yml - builds and publishes this repo's own
dogfooded docs to GitHub Pages (see Deploying to GitHub Pages)cron.yml - runs the test suite daily against development
BoxLang is a professional open-source project and it is completely funded by the community and Ortus Solutions, Corp. Ortus Patreons get many benefits like a cfcasts account, a FORGEBOX Pro account and so much more. If you are interested in becoming a sponsor, please visit our patronage page: https://patreon.com/ortussolutions
"I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
docbox verb - generates a BoxLang/CFML API reference into the content
directory from DocBox's own JSON output, with the class metadata DocBox's
JSON strategy drops (declared properties, implemented interfaces,
class annotations, per-function @return text) merged back in. Needs the
bx-docbox module.coldbox verb - documents a ColdBox application from its conventions on
disk without booting it: routes (including resources() expansion and
module entry points), handlers with their actions and the routes that
reach them, models with their WireBox injections and the binder's own
mappings, modules, interceptors, and scheduled tasks.docbox and coldbox configuration blocks, with validation.bxSitesDocBoxDoc (Gradle) and bxsites:docbox (Maven) wrap the
docbox verb for JVM projects whose sources include BoxLang/CFML
classes. There is deliberately no ColdBox equivalent: a ColdBox
application is built through CommandBox, not a Java build tool.build/serve crashed on Windows with a PatternSyntaxException in any
project with a blog post or with responsive images enabled -
BlogDiscoverer, ContentLinter and ImageVariantGenerator derived a
file's docs-relative path by handing an absolute directory straight to
reReplace() as its pattern; a Windows path's backslashes (\U, \d,
...) are regex escapes, not literal separators. Fixed via a shared
PathRelativizer, the same safe substring-based approach DocsLoader
already used. serve's live-reload watcher had the same root cause in a
milder form - a mixed-separator prefix check that silently always missed
on Windows, degrading every edit to a full cache-clearing rebuild instead
of the fast single-page path.
The Gradle/Maven plugins' subprocess launcher never found java.home's
own java launcher on Windows (only java.exe exists there), so every
Windows invocation of build/serve/every other verb silently fell back
to a bare java PATH lookup instead of guaranteed relaunching on the
same JVM.
The OpenAPI output example guide (and its four translations) linked to
../assets/openapi/example.yaml, one directory level too shallow for the
page's own built (clean-URL) location - broken since the guide was
added.
coldbox told a reader to install bx-docbox whenever class metadata was
missing, including when the module was installed and the DocBox run had
simply failed. The failure is now reported with its real cause, on the
pages and in the verb's output, and the install advice is kept for the
case that actually calls for it.
Spring controller-scan pages emitted a raw table whose rows carried their
own Alpine x-show attributes; those never worked, because
TableWrapProcessor injects its own into every row of a table with ten
or more rows and the Markdown renderer entity-escapes a <tr>'s
attribute values. Those pages now use a plain pipe table, which picks up
bx-sites' own table filter.
$
box install bx-sites