RuledWDLRuledWDL

Docs

Language reference

Core 0.3.5. REGISTRY v2.1 and COMPONENTS v2.0 are JSON Schema contracts. DATA is an envelope, and the author supplies DATA_SCHEMA.

Page model

A WDL page is JSON. REGISTRY, COMPONENTS, and DATA are the document. DATA_SCHEMA sits beside DATA and describes the author fields. The host-agnostic renderer turns the document into HTML given an injected store.

Shape

{
  // REGISTRY: semantic id to a utility entry or CSS rules
  "REGISTRY": {},
  // COMPONENTS: layers trees or component refs
  "COMPONENTS": [],
  // DATA: author fields plus reserved keys
  "DATA": {},
  // DATA_SCHEMA: Draft-07 schema for those author fields
  "DATA_SCHEMA": {}
}

COMPONENTS and Layers

Each COMPONENTS entry is a layers tree or a component reference. A node is tag.semantic_id, with one semantic id. Child >, sibling +, climb <, repeat *N, and data loops *items. <@N climbs to a depth and the digit is required: <@0 is the root and <@1 is depth 1. A bare <@ climbs one level and core prints the tag <@name></@name>.

Forms

{ "layers": "section>div.hero>h1.title+p.lead",
  "attr": {
    ".title": { "text": "Hello ${name}" },
    ".lead":  { "text": "${tagline}" }
  }
}

{ "component": "card",
  "data_overrides": { "title": "..." },
  "style_overrides": { ".card": { "class": "..." } }
}

// Bare <@ climbs one. Printed tag keeps the @.
// div.drawer>aside.panel>div.header>button.close<@vertical-menu

Layers restrictions

Parse throws with a hint on unsupported syntax. Extra CSS classes belong in REGISTRY or attr.class.

Not allowed

.class1.class2   // a second dot class
{ }              // inline text
[ ]              // inline attributes
^                // climb with ^, use <
( )              // grouping

REGISTRY

v2.1 is the active registry. The normative file is specifications/registry/v2.1.schema.json. An entry is a utility class string, an attribute object, or a structured entry. states, breakpoints, and containers prefix the map key onto every class. rules compile to @scope (.semantic_id). The HTML tag stays in the layers string. scopes is not a registry key.

Utility and CSS together

"card": {
  "base": "shadow-md",
  "states": { "hover": "shadow-lg" },
  "breakpoints": { "md": "p-8 hover:bg-blue" },
  "rules": [
    { "selector": ":scope", "css": { "display": "flex" } },
    { "selector": "& .button", "css": { "background": "#e5e7eb" } }
  ]
}

// class: shadow-md hover:shadow-lg md:p-8 md:hover:bg-blue
// css:   @scope (.card) { :scope { display:flex } }

The attr object

Keyed by .semantic_id or a tag name. tag.semantic_id never matches. Special keys: class, text, attr-ref, alpine, htmx.

Matchers

attr: {
  ".project-title": { "text": "**${title}**" },
  "meta": { }
}

{ "layers": "meta.charset+meta.viewport",
  "attr": {
    ".charset":  { "charset": "UTF-8" },
    ".viewport": { "name": "viewport", "content": "width=device-width, initial-scale=1" }
  }
}

DATA and DATA_SCHEMA

${key} and ${nested.path} bind values. A loop value is an array of objects. Core does not publish a schema of your fields. Write Draft-07 DATA_SCHEMA beside DATA for those fields. Core reads only the reserved keys.

Author schema

DATA: {
  "name": "World",
  "tags": [ { "label": "Workers" }, { "label": "Edge" } ]
}

DATA_SCHEMA: {
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": { "name": { "type": "string" } },
  "required": ["name"]
}

// layers: span.tag*tags
// attr: { ".tag": { "text": "${label}" } }

Layouts and fullPage

A page may set layout. Layouts chain with extends. The slot is the literal string {{content}}. fullPage true skips the default document shell.

Slot

{ "layers": "div.shell",
  "attr": { ".shell": { "text": "{{content}}" } }
}

Reserved DATA keys

These keys are read by the renderer. Other DATA keys belong to the author. Brand tokens are emitted after design tokens. The shell injection is skipped when fullPage is true.

Keys

__seo             object
__head            string or string[]
__design_tokens   string or string[]
__brand_tokens    string or string[]
DATA_SCHEMA       Draft-07 schema, beside DATA

Contracts

The registry schema, the component schema, and this reference are in the v0.3.5 repository.