Skip to content

super<name> originals are only registered for model overrides — controller/view helper overrides get no superLinkTo() #3325

Description

@bpamiri

Context

Discussion #3323: a user followed the v3 guide Overriding Core Methods, overrode linkTo(), and called superLinkTo() — HTTP 500, because that function never exists in controller/view context.

Root cause

The super<name> convention is implemented asymmetrically:

vendor/wheels/Model.cfc$integrateFunctions() (~line 598) — when the mixin method name already exists on the target (i.e. the app overrode it), the else branch registers the framework original as super<name>:

if (!(StructKeyExists(variables, local.name) || StructKeyExists(this, local.name))) {
    variables[local.name] = local.ref;
    this[local.name] = local.ref;
} else {
    local.superName = "super" & local.name;
    variables[local.superName] = local.ref;
    this[local.superName] = local.ref;
}

vendor/wheels/Controller.cfc$integrateFunctions() (~line 400) — no else branch. super<name> is only registered when a registered plugin/package mixin overrides the name (overrideSet). App-level overrides of controller/view helpers (defined in app/controllers/Controller.cfc or app/views/helpers.cfm) silently get nothing.

vendor/wheels/Mapper.cfc has its own $integrateFunctions() variant (~line 403) — worth checking for the same gap while in there.

Repro (verified live on develop, Lucee)

  1. In app/views/helpers.cfm define an override:
    public string function linkTo() {
        return superLinkTo(argumentCollection = arguments);
    }
  2. Render any view that calls linkTo() → error, superLinkTo is undefined.
  3. StructKeyExists(variables, "superLinkTo") in the view returns false. The equivalent model-side override does get superFindAll() etc.

Proposed fix

  1. Add the same else branch to Controller.cfc::$integrateFunctions() (and Mapper.cfc if applicable) so controller/view overrides get super<name> parity with models. ~5 lines + a spec.
  2. Docs: the v3 guide presents the convention as general (it is model-only today), and the v4-0-0 guide tree has no "Overriding Core Methods" page at all — port + correct it once the parity fix lands.

Workaround for users today

Capture the original reference manually (late-binding — same trick $integrateFunctions itself uses); posted in #3323:

variables.coreLinkTo = CreateObject("component", "wheels.view.links").linkTo;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions