fix(component): drop view from mixin attribute to load on Lucee 7#2
Merged
fix(component): drop view from mixin attribute to load on Lucee 7#2
Conversation
Lucee 7 enforces native trait composition on the `component mixin="..."`
attribute — it tries to load each comma-separated value as a CFML
component path at compile time. The previous declaration
component mixin="controller,view" output="false"
asks Lucee to load `view.cfc` as a trait. There is no `view.cfc` on the
component path (Wheels has no `view` mixin target — view helpers go
into `controller` mixins because views render in the controller's
variables scope). The missing trait makes the whole component fail to
compile.
The error surfaces with a misleading message:
invalid component definition, can't find component
[vendor.wheels-basecoat.Basecoat]
…which points at the OUTER component (Basecoat) rather than the
unresolved trait (view), making the actual cause hard to find. I spent
hours assuming the package directory's hyphen was the issue before
isolating this.
Net effect on Lucee 7: every `wheels packages add wheels-basecoat`
install resulted in a successful extract but no helper activation. The
package showed up in `application.wheels.failedPackages` rather than
`application.wheels.mixins`. `#uiButton(...)#`, `#uiCard(...)#`, etc.
all failed with `function UIBUTTON not found`.
Fix: drop `view` from the mixin attribute, leaving `mixin="controller"`.
The package's `package.json` already declares `provides.mixins:
"controller"` correctly — that's the actual source of truth for the
framework's PackageLoader. The component-level attribute is a
historical convention that's now obsolete.
Verified end-to-end on a fresh VM running 4.0.0-SNAPSHOT+1644 with
the matching framework fixes (wheels-dev/wheels#2373 + #2374) patched in:
Before:
$ wheels packages add wheels-basecoat
Installed wheels-basecoat@1.0.1
$ wheels stop && wheels start
$ curl localhost:8080/main/index # view calls #uiButton(...)#
ERROR: No matching function [UIBUTTON] found
After (with this fix):
$ ... same flow ...
<button type="button" class="btn">Save</button>
The same fix is needed in wheels-dev/wheels-hotwire (which has the
same `component mixin="controller,view"` declaration). PR for that
follows.
Lucee 5/6 may not enforce this strictly, which is why the bug went
undetected until Lucee 7 became the default in Wheels 4.0.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Apr 29, 2026
Merged
bpamiri
added a commit
to wheels-dev/wheels-hotwire
that referenced
this pull request
Apr 29, 2026
Same fix as wheels-dev/wheels-basecoat#2 — the component declaration component mixin="controller,view" output="false" asks Lucee 7 to load `view.cfc` as a trait via native mixin composition. There is no `view.cfc` on the component path (Wheels has no `view` mixin target — view helpers go into `controller` mixins because views render in the controller's variables scope). The missing trait makes the whole component fail to compile, with a misleading "can't find component [vendor.wheels-hotwire.Hotwire]" error that points at the outer component rather than the unresolved trait. Net effect: wheels-hotwire silently fails to activate on Lucee 7. No Turbo Drive, no Turbo Frames, no Turbo Streams, no Stimulus controllers. Package shows up in `application.wheels.failedPackages`. Fix: drop `view` from the mixin attribute. `package.json`'s `provides.mixins: "controller"` field is the actual source of truth for the framework's PackageLoader. The component-level attribute is a historical convention now obsolete on Lucee 7. Lucee 5/6 don't enforce native mixin composition the same way, which is why this went undetected until Lucee 7 became the default in Wheels 4.0. Pairs with wheels-dev/wheels#2368 + #2373 + #2374 (framework-side fixes that get the install path working) and wheels-dev/wheels-basecoat#2 (same fix in the basecoat package). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bpamiri
added a commit
to wheels-dev/wheels
that referenced
this pull request
Apr 29, 2026
Adds 08-bonus-basecoat.mdx, a 30-minute optional follow-up to Part 7
that walks through installing the wheels-basecoat package and
rewriting the post show view using uiCard, uiField, and uiButton
helpers. Lands the Wheels package system as a teachable end-to-end
flow rather than a chapter-3 conceptual aside.
Chapter shape follows the existing tutorial conventions:
- "Where we left off" recap so readers can resume from a clean
Part-7 state.
- "Why basecoat over simple.css" frames the choice as a tradeoff,
not a recommendation. Tutorial readers stay on simple.css; the
chapter is for when you've finished the tutorial and want a real
component kit.
- Steps blocks for install, CSS asset serving, layout wiring, and
view rewrite.
- Checkpoint with three concrete `curl | grep` verifications a
reader can run themselves.
- Troubleshooting with four real failure modes I hit during
end-to-end verification on a fresh VM, including the version-
detection edge case (`No version of 'wheels-basecoat' satisfies
runtime '0.0.0-dev'`) tied to PR #2373.
The install path uses `wheels packages add wheels-basecoat` (the
canonical verb after PR #2374), not `install`. The chapter explicitly
calls out the LuCLI interception with a caution Aside so readers
who reach for the historic verb get an immediate explanation.
Adjusts:
- tutorial/index.mdx — adds the bonus chapter as a row in the
parts table and as a card in the "Ready to start" CardGrid.
- 01-hello-wheels.mdx — the existing "On styling" Aside now links
to the bonus chapter for upgrade-path readers (was a bare GitHub
repo link).
- 07-testing-deploying.mdx — adds the bonus chapter as the
first card in "What to read next" (recommended next step
immediately after finishing the main tutorial).
Prerequisites for the chapter to actually work end-to-end:
- PR #2368: BuildInfo.isDev() self-substituting sentinel fix
(merged) — needed for runtime version reporting.
- PR #2373: $detectRuntime fix (merged) — CLI knows its runtime
version.
- PR #2374: `wheels packages install` → `add` rename (merged) —
canonical install command works.
- wheels-dev/wheels-basecoat#2: drop `view` from the mixin
component attribute (open) — required for Lucee 7 helper
activation. Tutorial reader's experience depends on basecoat
1.0.2 (or whatever ships this fix) being current in the
registry.
- wheels-dev/wheels-hotwire#2: same fix on the hotwire side.
Verified end-to-end on a fresh VM: with all five fixes in place,
`wheels packages add wheels-basecoat` followed by a full server
restart produces working `#uiButton(...)#`, `#uiCard(...)#`,
`#uiField(...)#` calls in views. The rendered HTML is shadcn/ui-
quality output.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bpamiri
added a commit
that referenced
this pull request
Apr 29, 2026
- Bump package.json version (1.0.1 → 1.0.2) - Bump box.json version (1.0.0 → 1.0.2; was lagging) - Add 1.0.2 CHANGELOG entry covering the Lucee 7 mixin attribute fix shipped in #2 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
bpamiri
added a commit
to wheels-dev/wheels-packages
that referenced
this pull request
Apr 29, 2026
Both packages ship the same fix: drop `view` from the component-level
`mixin` attribute on their entry CFCs. The previous
component mixin="controller,view" output="false"
asks Lucee 7 to load `view.cfc` as a trait via native mixin
composition. There is no `view.cfc` on the path, so the entry
component fails to compile and the package silently fails to activate.
After this fix:
- wheels-basecoat 1.0.2: helpers like #uiButton(...)#, #uiCard(...)#,
#uiField(...)# render correctly on Lucee 7.
- wheels-hotwire 1.0.2: Turbo Drive, Turbo Frames, Turbo Streams,
and Stimulus helpers all activate correctly on Lucee 7.
Lucee 5/6 don't enforce native mixin composition the same way, which
is why this went undetected until Wheels 4.0 made Lucee 7 the default.
This PR registers each version in the registry with `tarball: null`
and `sha256: null`. The `mirror-tarball` workflow will fill both in
on merge by cloning the tagged source, building a deterministic
tarball, uploading it as a release asset on this registry, and
committing the URL + sha back into the manifest.
Source PRs:
- wheels-dev/wheels-basecoat#2 (merged)
- wheels-dev/wheels-hotwire#2 (merged)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bpamiri
added a commit
to wheels-dev/wheels
that referenced
this pull request
Apr 29, 2026
Adds 08-bonus-basecoat.mdx, a 30-minute optional follow-up to Part 7
that walks through installing the wheels-basecoat package and
rewriting the post show view using uiCard, uiField, and uiButton
helpers. Lands the Wheels package system as a teachable end-to-end
flow rather than a chapter-3 conceptual aside.
Chapter shape follows the existing tutorial conventions:
- "Where we left off" recap so readers can resume from a clean
Part-7 state.
- "Why basecoat over simple.css" frames the choice as a tradeoff,
not a recommendation. Tutorial readers stay on simple.css; the
chapter is for when you've finished the tutorial and want a real
component kit.
- Steps blocks for install, CSS asset serving, layout wiring, and
view rewrite.
- Checkpoint with three concrete `curl | grep` verifications a
reader can run themselves.
- Troubleshooting with four real failure modes I hit during
end-to-end verification on a fresh VM, including the version-
detection edge case (`No version of 'wheels-basecoat' satisfies
runtime '0.0.0-dev'`) tied to PR #2373.
The install path uses `wheels packages add wheels-basecoat` (the
canonical verb after PR #2374), not `install`. The chapter explicitly
calls out the LuCLI interception with a caution Aside so readers
who reach for the historic verb get an immediate explanation.
Adjusts:
- tutorial/index.mdx — adds the bonus chapter as a row in the
parts table and as a card in the "Ready to start" CardGrid.
- 01-hello-wheels.mdx — the existing "On styling" Aside now links
to the bonus chapter for upgrade-path readers (was a bare GitHub
repo link).
- 07-testing-deploying.mdx — adds the bonus chapter as the
first card in "What to read next" (recommended next step
immediately after finishing the main tutorial).
Prerequisites for the chapter to actually work end-to-end:
- PR #2368: BuildInfo.isDev() self-substituting sentinel fix
(merged) — needed for runtime version reporting.
- PR #2373: $detectRuntime fix (merged) — CLI knows its runtime
version.
- PR #2374: `wheels packages install` → `add` rename (merged) —
canonical install command works.
- wheels-dev/wheels-basecoat#2: drop `view` from the mixin
component attribute (open) — required for Lucee 7 helper
activation. Tutorial reader's experience depends on basecoat
1.0.2 (or whatever ships this fix) being current in the
registry.
- wheels-dev/wheels-hotwire#2: same fix on the hotwire side.
Verified end-to-end on a fresh VM: with all five fixes in place,
`wheels packages add wheels-basecoat` followed by a full server
restart produces working `#uiButton(...)#`, `#uiCard(...)#`,
`#uiField(...)#` calls in views. The rendered HTML is shadcn/ui-
quality output.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lucee 7 enforces native trait composition on
component mixin="..."— it tries to load each comma-separated value as a CFML component path at compile time. The current declarationcomponent mixin="controller,view" output="false" {asks Lucee to load
view.cfcas a trait. There is noview.cfcon the component path (Wheels has noviewmixin target — view helpers go intocontrollermixins because views render in the controller's variables scope). The missing trait makes the whole component fail to compile.The error surfaces with a misleading message that points at the outer component:
…rather than the unresolved trait. Hours of debugging assumed the package directory's hyphen was the cause before isolating this.
Net effect on Lucee 7
Every
wheels packages add wheels-basecoatinstall resulted in a successful extract but no helper activation. The package showed up inapplication.wheels.failedPackagesrather thanapplication.wheels.mixins.#uiButton(...)#,#uiCard(...)#, etc. all failed withfunction UIBUTTON not found.Fix
Drop
viewfrom the mixin attribute.package.jsonalready declaresprovides.mixins: "controller"correctly — that's the actual source of truth for the framework's PackageLoader. The component-levelmixinattribute is a legacy convention that's now obsolete and harmful on Lucee 7.One line.
Verification
Fresh VM running
wheels 4.0.0-SNAPSHOT+1644with framework PRs wheels-dev/wheels#2373 and #2374 patched in:End-to-end working integration on Lucee 7.
Cross-engine concerns
Lucee 5 and Lucee 6 don't enforce native
mixintrait composition the same way as Lucee 7, which is why this bug went undetected until Lucee 7 became the default in Wheels 4.0. The fix is backward-compatible —mixin="controller"is valid syntax across all Lucee versions, Adobe CF, and BoxLang.Related
wheels-dev/wheels-hotwire(samecomponent mixin="controller,view"declaration). Separate PR follows.$detectRuntimereads.module-version), #2374 (renamewheels packages install→addto dodge LuCLI's verb interceptor).Test plan
wheels packages add wheels-basecoatproduces a working integration on Lucee 7 with framework #2373 + #2374 in place.viewtarget was never functional anyway).