Skip to content
Phero Lang
Menu

.ifml

Interaction flow

Views, navigation and CLI commands

Validated

No in-tree backend — the artifact is validated and committed, not consumed.

Interaction flows over a composed pattern library: views, containers, components, events, navigation, and the declaration-backed control/route manifest.

Why it exists

What .ifml is for

An .ifml file describes the interaction model: views and containers, the components inside them, the events those components raise, and where navigation goes — semantically aligned with OMG IFML 1.0, in a C-like, expression-heavy syntax instead of XML.

The domain defines the data; the flow defines what the user sees and does with it. Entity and field references are checked against the imported .mox domains and .actor policies, the reference pattern library is composed with use, and a declaration-backed control and route manifest is derived after checking, so every route target in it exists by construction.

Vocabulary

What it models

The concepts .ifml declares, and what each one means to the compiler.

view
A top-level interaction unit, with params and a label; containers nest inside it.
component
list, table, details, form and the chart kinds, with data: bound to a domain type.
fields / column
A component’s bindings (fields: [ticketNo, title]), and computed columns such as column "Refund" -> expr refundCents / 100.
on <event> -> …
A component event whose handler navigates, or invokes a declared action. An if guard may filter it.
navigate(…)
A target view or container, with parameter bindings.
action
A declared action with a domain target:. The declaration is what makes an event’s action reference resolve.
use
Instantiates a module from the reference pattern library with input bindings.
command
A CLI command declaration with typed arguments and options: the binary’s command surface.
manifest
The control and route manifest, derived after checking — never parsed, and declaration-backed by construction.

Source

A working example

Quoted from the example this page's artifact was compiled from — not a snippet written for the website.

Lines 12–29 of examples/support/support.ifml, reproduced byte for byte, read from the file at build time:

examples/support/support.ifml · lines 12–29
view "Inbox" {
    params { tickets: Ticket, folders: Ticket };
    label "Support Inbox";
    landmark: true;

    use "Inbox" as inbox { messages: tickets; folders: folders; };

    component "escalations" {
        type: list;
        data: Ticket;
        fields: [ticketNo, title, refundCents];
        filter: refundCents > 0;

        on select(row) -> navigate("Queue", {
            ticket: row.ticketNo
        });
    }
}

The `Inbox` view: parameters bound to the domain, a `use` of the library’s Inbox module, and a list component whose `select` event navigates to the queue with a row binding.

The whole file is CI-tested: pherolang check examples/ checks every surface in the tree, and the example harness compiles each one on every run. What you see above is the input to the artifact below.

Neighbours

How it relates to the other surfaces

Flows are checked against the rest of the stack: .mox types the data bindings, .actor supplies the capabilities and actors that requires: and roles: resolve against (an empty policy set skips the authorization pass entirely), and .dmn decision services supply data a details component can bind. .deploy binds a frontend component to a flow by path, and the control and route manifest is derived from the checked model.

Read alongside

Commands

How to compile and validate

Three commands, one file. They run from the repository root against the example on this page.

bash
pherolang check examples/support/support.ifml
pherolang ir examples/support/support.ifml -o site/data/artifacts/ifml.json
pherolang artifact check site/data/artifacts/ifml.json

check parses, resolves, validates and type-checks the file and printsOK examples/support/support.ifml. ir writes the artifact and prints nothing on success. artifact check then validates the serialized JSON on its own — no model, no import resolution, no compiler — and prints OK site/data/artifacts/ifml.json.

Directories work too: pherolang check examples/ enters project mode and checks every supported surface under the tree, each file's imports resolving from the snapshot.

Artifact

What it produces

One versioned JSON artifact, emitted by the compiler and consumed by whatever reads this surface.

One IfmlModel: views with their containers, components, events and navigation, plus the declared actions, commands and module imports.

The artifact is site/data/artifacts/ifml.json, and it is committed here exactly as the released pherolang binary emits it. Its top-level shape:

  • views5 entries
  • actions6 entries
  • imports4 entries

Jump to the compiled artifact

Provenance

formatVersion = 2
The compatibility gate. A reader accepts this number or refuses the file.
pheroVersion — not present
This standalone surface artifact is versioned on its ownformatVersion; only the domain model artifact carries the compiler-version stamp.
11,255 bytes
487 lines, two-space indented, in the file's own key order.

The compiled artifact

The first 30 of 487 lines, verbatim — the exact bytes pherolang ir writes, not a hand-written sample. The slice stops at a JSON boundary; the ellipsis marker is outside the JSON, and the full file is site/data/artifacts/ifml.json.

artifacts/ifml.json · lines 1–30
{
  "formatVersion": 2,
  "views": [
    {
      "name": "Inbox",
      "label": "Support Inbox",
      "isLandmark": true,
      "isXor": false,
      "isModal": false,
      "params": [
        {
          "name": "tickets",
          "typeRef": "Ticket",
          "default": null
        },
        {
          "name": "folders",
          "typeRef": "Ticket",
          "default": null
        }
      ],
      "properties": [
        {
          "key": "landmark",
          "value": {
            "type": "bool",
            "value": true
          }
        }
      ],

… 457 more lines in site/data/artifacts/ifml.json

Regenerate it from the repository root — the second command validates the serialized bytes with no compiler in the loop:

bash
pherolang ir examples/support/support.ifml -o site/data/artifacts/ifml.json
pherolang artifact check site/data/artifacts/ifml.json

The whole data directory is regenerated by node scripts/sync-model.mjs (run from site/) with the released binary; CI fails on a one-byte difference.

Reference

Documentation

The normative reference for this surface, rendered from the repository's own documentation.