Skip to content

ALTER PAGE: column property aliases are case-sensitive (caption fails, Caption works) #560

@ako

Description

@ako

Summary

ALTER PAGE column property SET fails for lowercase property names — set caption = '…' on grid.col returns column property "caption" not found, while set Caption = '…' on grid.col works. The columnPropertyAliases map in mdl/backend/mpr/page_mutator.go is case-sensitive on the MDL-facing side, but the skill docs and natural MDL style use lowercase.

Reproduction

alter page MyMod.Product_Overview {
  set caption = 'Name' on dgProducts.Name
};

Error:

Error: failed to set: failed to set caption on dgProducts.Name: column property "caption" not found

Works:

alter page MyMod.Product_Overview {
  set Caption = 'Name' on dgProducts.Name
};

Mismatch with docs

.claude/skills/mendix/alter-page.md (line 135) shows:

-- SET a column property
set caption = 'Product SKU' on dgProducts.Code

The skill example doesn't work; the actual implementation requires Caption.

Root cause

mdl/backend/mpr/page_mutator.go:1437columnPropertyAliases is keyed by capitalized MDL names mapping to lowercase BSON property keys:

var columnPropertyAliases = map[string]string{
    "Caption":       "header",       // MDL → BSON
    "Visible":       "visible",
    "Alignment":     "alignment",
    "ShowContentAs": "showContentAs",
    // …
}

The lookup at line 1454 is exact-match, so caption (lowercase) falls through to internalKey = "caption" and doesn't resolve to the internal header key.

Suggested fix

The BSON-internal property keys (right side of the map) must stay case-sensitive — those are dictated by the DataGrid2 widget schema (header, visible, showContentAs, etc.) and cannot be changed.

The MDL-facing property names (left side) should be case-insensitive. Users will reasonably type either caption or Caption. Fix:

// One-time init: build lowercase-keyed alias map for case-insensitive lookup.
var columnPropertyAliasesCI = func() map[string]string {
    m := make(map[string]string, len(columnPropertyAliases))
    for k, v := range columnPropertyAliases {
        m[strings.ToLower(k)] = v
    }
    return m
}()

func setColumnPropertyMut(...) error {
    internalKey := columnPropertyAliasesCI[strings.ToLower(propName)]
    if internalKey == "" {
        internalKey = propName
    }
    // …
}

BSON storage stays exactly as-is; only the lookup becomes case-insensitive.

Discovered

While building `mdl-examples/doctype-tests/33-alter-page-examples.mdl` (commit 01ad80e0).

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