Skip to content

Examples โ€‹

A single, worked example โ€” the Northline intake ladder โ€” showing how registry defaults become theme overrides, runtime state, scripts, and rendered form text. It uses one prepress intake form and one registry.

The ladder at a glance โ€‹

StepLayerExampleResult
1Registry default$.variable.companyName, $.image.logo_h, $.fn.estimateTurnaroundReusable defaults and registry-owned functions exist before any theme is selected
2Theme overridetheme.custom.companyName, theme.images.logo_hThe active theme changes values and assets without changing form references
3Form load script$state('ticketTitle', $.variable.companyName + ' / ' + $.form.name)Form metadata and resolved registry values become temporary runtime state
4Field / default rendering$.state.ticketTitle, $.image.logo_hLabels, defaults, image sources, and compare values read direct namespace paths
5User input script$.fn.estimateTurnaround($get('quantity'), $get('rush'))Scripts read fields, call read-only functions, then decide what to $set or $state
6Text Display summary{{ Number($sum('line_total') || 0).toFixed(2) }}Read-only expressions combine fields, state, helpers, and registry values for display

Step 1 โ€” Registry defaults โ€‹

Start with one prepress intake form and one registry. These values are the global defaults every theme can inherit.

// Registry rows:
$.variable.companyName           -> "Northline Print"
$.variable.printPlantName        -> "Main Street Prepress"
$.variable.printRushSlaDays      -> 1
$.variable.printStandardSlaDays  -> 3
$.variable.printProofWindowHours -> 24
$.variable.allowRushJobs         -> true
$.variable.availableFinishes     -> ["Matte", "Gloss", "Fold", "Bind"]
$.image.logo_h                   -> "sl://assets/system/northline-logo-h.png"

// Text variable:
$.variable.proofFooter
// "Proofs prepared by $.variable.companyName. Reply within $.variable.printProofWindowHours hours."

// Function variable:
$.fn.estimateTurnaround(quantity, rush)
// returns { days, label } using $.variable.printRushSlaDays and $.variable.printStandardSlaDays

Step 2 โ€” Theme overrides โ€‹

A customer or department theme changes values and assets, while the form still reads the same keys.

// "Northline Packaging" theme override values:
theme.custom.companyName = "Northline Packaging"
theme.custom.printPlantName = "Packaging Prepress Desk"
theme.custom.printRushSlaDays = "2"
theme.custom.availableFinishes = "[\"Matte\",\"Gloss\",\"Foil\",\"Die cut\"]"
theme.images.logo_h = "sl://assets/northline-packaging/logo-h.png"

// The form does not change:
$.variable.companyName
$.variable.printRushSlaDays
$.image.logo_h

Step 3 โ€” Runtime state on form load โ€‹

When the form opens, scripts combine session data, form metadata, and active theme-resolved registry values into short-lived state.

js
// onLoad script for the prepress intake form
$set('operator_name', $.self.fullName);
$set('operator_email', $.self.email);

$state('ticketTitle', $.variable.companyName + ' / ' + $.form.name);
$state('openedBy', $.self.fullName + ' (' + $.self.email + ')');
$state('rushAllowed', $.self.role === 'admin' || $.variable.allowRushJobs === true);

// Later references:
// $.state.ticketTitle
// $.state.openedBy
// $.state.rushAllowed

Step 4 โ€” Field defaults, images, and labels โ€‹

Fields and media use direct tokens. They do not need helper syntax unless the value is computed in Text Display.

// Field label:
Prepared for $.variable.companyName by $.self.fullName

// Field default:
$.state.ticketTitle

// Static image source:
$.image.logo_h

// Visibility compare value:
$.state.rushAllowed

Step 5 โ€” User input becomes calculated state โ€‹

A button or onChange script reads field values, calls registry functions, writes fields, and saves reusable runtime state.

js
// Quantity / rush fields are normal form data
const estimate = $.fn.estimateTurnaround(
  $get('quantity'),
  $get('rush')
);

$set('turnaround_days', estimate.days);
$state('turnaroundLabel', estimate.label);

// Repeating grid totals
const lineTotal = $sum('line_total');
$set('estimated_total', lineTotal);
$state('lineItemSummary', $count('line_description') + ' line items');

Step 6 โ€” Text Display renders the final summary โ€‹

The Text Display element can mix direct lookups and read-only helper expressions to show the resolved job story.

Header:
$.state.ticketTitle

Body:
Opened by $.state.openedBy
Plant: $.variable.printPlantName
Logo: $.image.logo_h
Turnaround: $.state.turnaroundLabel
Line items: $.state.lineItemSummary

// Computed inside Text Display:
{{ Number($sum('line_total') || 0).toFixed(2) }}
{{ $selected('finishing') || 'No finish selected' }}

What changes per theme โ€‹

The same script and form produce different output because the active theme changes the registry-backed inputs.

// System theme output:
$.variable.companyName -> "Northline Print"
$.image.logo_h -> "sl://assets/system/northline-logo-h.png"
$.fn.estimateTurnaround(500, true).label -> "1 business day"

// Northline Packaging theme output:
$.variable.companyName -> "Northline Packaging"
$.image.logo_h -> "sl://assets/northline-packaging/logo-h.png"
$.fn.estimateTurnaround(500, true).label -> "2 business days"

// The form still references the same keys in both cases.

Function registry rule โ€‹

Functions do not own side effects. They return values; the caller decides whether to write a field or state. A function body receives its arguments as an args array.

js
// Registry function body: estimateTurnaround
const quantity = Number(args[0] || 0);
const rush = Boolean(args[1]);
const rushDays = Number($.variable.printRushSlaDays || 1);
const standardDays = Number($.variable.printStandardSlaDays || 3);
const days = rush ? rushDays : standardDays + (quantity > 5000 ? 1 : 0);

return {
  days,
  label: days + ' business day' + (days === 1 ? '' : 's'),
};

// Caller decides the mutation:
const estimate = $.fn.estimateTurnaround($get('quantity'), $get('rush'));
$set('turnaround_days', estimate.days);
$state('turnaroundLabel', estimate.label);

Text-variable boundary โ€‹

Text-type registry variables compose registry values only. Form / session / state tokens resolve later, when a form renders.

// Text variable "proofFooter" stored in registry:
//   "Proofs prepared by $.variable.companyName. Reply within $.variable.printProofWindowHours hours."
//
// At registry resolution:
//   "Proofs prepared by Northline Print. Reply within 24 hours."

// Use in Text Display body:
$.variable.proofFooter

// Use runtime-only values directly in Text Display:
Prepared by $.self.fullName
Ticket: $.state.ticketTitle

// Use helpers only inside {{ ... }}:
{{ $.fn.estimateTurnaround($get('quantity'), $get('rush')).label }}

See also: Scripts overview ยท Code Helpers ยท Runtime Variables ยท Variable Reference