Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,17 @@ jobs:
run: boxlang --version

- name: Install Dev Dependencies
run: box install id=testbox --verbose --nosave
run: |
# Pinned to the bleeding-edge channel rather than the default
# latest-stable release - testbox@be picks up
# Ortus-Solutions/TestBox#201's fix for a real TestBox bug
# (server.cli.parsed.positionals leaking the runner's own
# invocation path as argv[0], misread as a bundle argument -
# ClassNotFoundBoxLangException on BoxLangRunner.bx) before that
# fix has made it into a tagged stable release. Revert to the
# unpinned `id=testbox` once a stable TestBox release carrying
# the fix ships.
box install id=testbox@be --verbose --nosave

- name: Test Module
run: |
Expand Down
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

* Pinned `tests.yml`'s `box install id=testbox` (this repo's own CI test-suite dependency) to `testbox@be` (bleeding-edge) instead of the unpinned default. CI was intermittently failing before a single test spec ran, with `ClassNotFoundBoxLangException` on TestBox's own `BoxLangRunner.bx` - traced to a real TestBox bug ([Ortus-Solutions/TestBox#201](https://github.com/Ortus-Solutions/TestBox/pull/201)): `server.cli.parsed.positionals` on current BoxLang engine builds leaks the runner's own invocation path as its first entry (an argv[0] leak), which `BoxLangRunner.bx` misread as a user-supplied bundle argument whenever no real one was given. `testbox@be` picks up that fix ahead of a tagged stable release - revert to the unpinned `id=testbox` once one ships it.
* Fixed `FunctionsLoader.bx` and `ThemeRenderer.bx` intermittently failing a real `bxSites build` with `functions.bxs at [...] failed to load: The template path [...] could not be found` (or the same for a theme's `layout.bxm`), even though the file genuinely exists - observed on this repository's own "Publish Docs" CI, where roughly a third of ten otherwise-identical theme-matrix jobs hit this on `functionsLoader.load()` (the very first `include` the whole build performs), immediately after `fileExists()` on that same path had just confirmed it was there. Root cause: a bare `include` statement doesn't resolve an OS absolute filesystem path at all - BoxLang coerces an absolute-looking path against registered mappings/webroot instead, so `include functionsPath`/`include arguments.themeDir & "/layout.bxm"` were never a reliably supported way to reach an arbitrary, runtime-computed directory, not a timing race. Both now register a runtime mapping (`getBoxRuntime().getConfiguration().registerMapping()`) for the target directory and include through that mapping-prefixed path instead - the actually-supported mechanism.
* Fixed `.github/workflows/pages.yml` (this repo's own GitHub Pages deploy) never actually running since the `versions.default` cutover - its trigger/deploy condition was changed to `main`, a branch that doesn't exist yet in this repository (`development` is still this project's only real branch, actively working toward the 1.0.0 release; `main` will only come into being once `development` is later merged into it to cut that release, at which point `main` becomes the frozen `1.0.x` line). Moved the trigger and the `Deploy to the site root` step's condition back to `development` so the versioned site (1.0.x at the root, `/next/` for work in progress) actually publishes again.
* **A page's own frontmatter is now available to `{{ }}` variable expressions, no `bxsites.yaml` entry needed.** Previously `{{ dotted.path }}` only ever resolved against `bxsites.yaml`'s site-wide `variables` block; a page's own frontmatter values (title, summary, or any custom key a project defines) were reachable from a magic function's bare `page` reference but not from plain `{{ }}` markdown. `DocsLoader.bx`/`BlogDiscoverer.bx` now also preserve the raw, unfiltered frontmatter struct on every loaded page/post as `page.frontmatter` (previously only a fixed, named set of fields survived - a custom key like `product: BoxLang` was silently dropped); `BuildPipeline.bx`'s `convertMarkdown()` merges that page's own struct into `VariablesProcessor.bx`'s lookup scope under a reserved `page` key, so `{{ page.title }}` and `{{ page.frontmatter.product }}` resolve through the exact same dotted-path mechanism `{{ company }}` already does, with zero changes needed inside `VariablesProcessor.bx` itself. `page` joins the existing reserved "supporting variable" names (already reserved for a magic function's own bare reference) - a `variables.page` entry, if a project somehow declared one, is shadowed by the current page's own struct. See `docs/guides/variables-and-functions.md#page-variables`

Expand Down
20 changes: 19 additions & 1 deletion models/build/FunctionsLoader.bx
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,27 @@ class {
return {}
}

// `include` doesn't resolve a bare OS absolute path against the real
// filesystem - BoxLang coerces an absolute-looking path against
// registered mappings/webroot instead, so `include functionsPath`
// here intermittently threw "The template path [...] could not be
// found" for this exact path, moments after `fileExists()` just
// above had already confirmed it was there - not a race, just an
// unsupported way to reach an arbitrary, runtime-computed
// directory. Registering a mapping for `dir` and including through
// that instead is the supported path (see
// `getBoxRuntime().getConfiguration().registerMapping()` - BoxLang
// docs' "Includes"/"Mappings & Class Resolution" pages). A fixed,
// module-namespaced prefix is safe to re-register on every call
// (cheap, and this class's own singleton is reused with a
// potentially different `docsDir` across `bxSites serve` rebuilds) -
// it simply repoints the same prefix at the current `dir`.
var mappingPrefix = "/bxsitesFunctionsInclude"
getBoxRuntime().getConfiguration().registerMapping( mappingPrefix, dir )

var before = structKeyArray( variables )
try {
include functionsPath
include "#mappingPrefix#/functions.bxs"
} catch ( any e ) {
throw(
type : "BxSites.InvalidFunctions",
Expand Down
16 changes: 15 additions & 1 deletion models/build/ThemeRenderer.bx
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,23 @@ class {
variables[ fnName ] = arguments.functions[ fnName ]
}

// Same fix as FunctionsLoader.bx's own `load()` - a bare `include`
// statement doesn't resolve an OS absolute path against the real
// filesystem (BoxLang coerces it against registered mappings/webroot
// instead), so `include arguments.themeDir & "/layout.bxm"`
// intermittently threw "The template path [...] could not be found"
// for a path this class's own caller already resolved to a real,
// existing directory. Registering a mapping and including through
// that instead is the supported path. Cheap to re-register on every
// call (this method runs once per page) - a fixed, module-namespaced
// prefix simply gets repointed at the current page's own themeDir,
// which never actually changes mid-build (one theme per build).
var themeMappingPrefix = "/bxsitesThemeInclude"
getBoxRuntime().getConfiguration().registerMapping( themeMappingPrefix, arguments.themeDir )

var html = ""
bx:savecontent variable="html" {
include arguments.themeDir & "/layout.bxm"
include "#themeMappingPrefix#/layout.bxm"
}
return html
}
Expand Down
Loading