Skip to content

Pages and page conditions

CMN language contract

This page describes the platform-independent CMN syntax and transformed Core Model. It deliberately does not define what a particular facility generates from a Page.

A Page combines current data, content and behavior for one modeled user interface view. A Page Condition gives a name to a Boolean value derived from that current Page context. It is useful for keeping visibility, availability and other UI rules understandable when the same condition controls more than one element.

The recommended modeling flow is:

text
current Page data
    -> named Page Condition
    -> UI property or Action condition

A Page Condition is not persisted domain state and is not a mutable variable. It is a Page-local, derived condition that must always evaluate to a Boolean value. How it is evaluated or represented in an application is part of the selected facility's contract.

Page structure

A Page is declared inside a Component. It can have profile-defined properties and can optionally extend another Page:

text
page PageName [properties] [extends BasePage] {
    ...
}

The groups inside a Page have a fixed order. In simplified form, a Page can contain:

  1. Page properties;
  2. data declarations such as use;
  3. slots, Page fields and operations;
  4. an optional content block;
  5. an optional conditions block; and
  6. Actions.

The complete example below places use draft before content, conditions after content, and the Action after conditions. This order is part of the CMN grammar.

Page data and content

A Page data declaration gives a local name to Resource-backed data. Content can then reference that data, individual fields, Widgets or Slots. In the complete model below, use draft: /draft declares the data and draft.title references one of its fields from content.

Properties written on Pages, Widgets or Content Elements are supplied by the active Profile or by model declarations. Names such as disabled, visible or readOnly are therefore not global CMN keywords and do not form a closed JoinedWorkz-wide property registry.

Page conditions

Each entry in conditions has the form:

text
name: value expression

The value expression must evaluate to Boolean. Use a Page field, property or data field whose effective type is Boolean, or a Boolean expression supported by the selected facility.

The starting value of an expression can be Page data, a Page field, a Page property or a Page Condition. The grammar also provides field evaluations, value transformations and Boolean continuations. Their generated effect is not defined by the CMN grammar; a facility may support only a documented subset.

During model transformation, each entry becomes a CmnCondition whose container is the current Page. Its value expressions retain their references and transformations for facilities to interpret. The documented basic form in the complete model derives editingLocked from the Page-data field draft.locked.

Complete model example

This model defines a Widget property locally, derives editingLocked once and reuses that Condition for the property and an Action condition:

cmn
package com.example.frontend

import org.joinedworkz.facilities.common.base

platform Base

type Draft {
    title: String
    locked: Boolean
}

widget Button {
    property visible: Boolean
    property disabled: Boolean
}

resource /draft as Draft {
}

component ExampleFrontend {
    page EditPage {
        use draft: /draft

        content {
            draft.title
            Button 'Save' disabled=editingLocked
            Button 'Unlock' visible=editingLocked -> unlockDraft()
        }

        conditions {
            editingLocked: draft.locked
        }

        action unlockDraft {
            if (editingLocked) {
                draft.locked = false
            }
        }
    }
}

visible and disabled belong to the Button declaration in this example. The model demonstrates the relationship between Page data, a named Condition and its uses; it does not promise a particular UI control, binding syntax or runtime behavior.

Modeling UI and gray logic

For non-trivial UI rules, prefer giving the condition a meaningful Condition name and referencing that Condition from the affected Content Elements. This keeps the rule separate from individual Widget properties and avoids repeating the same expression throughout the Page.

The Unlock Button invokes unlockDraft(). Inside that Action, the same Condition is used again as the condition of an alternative through if (editingLocked). Conditions can therefore structure both UI properties and conditional Action code.

Which UI properties can reference the Condition, and whether direct Boolean or other values remain supported, is defined by the active Profile and facility.

Facility boundary

CMN defines the Page structure, references and transformed Page-local Condition. The selected facility defines:

  • which Page expressions and Widget properties it supports;
  • how it validates names, expressions and property combinations;
  • which source files or other artifacts it generates; and
  • how generated Condition values behave at runtime.

Parser and Core-Model success therefore do not prove that every facility can generate every syntactically valid expression, Widget or Action command. Consult the relevant facility page before relying on generated behavior.

The extends syntax is available, but inherited Conditions are not transferred into the transformed Page. Do not rely on Page-Condition inheritance.