Orientation · Lesson 04 of 05

Use relative and symbolic paths, then dataFormula

Organize bindings around a data context, resolve symbolic origins and calculate a value from reactive inputs.

4:31 · English7 sectionsPrerequisites: Orientation lessons 02–03: bindings, Data, Source, values and attributes.
Course contents
WATCH THE LESSON4:31 · English
Download MP4 ↓English captions ↓

Animated source edits and real browser results: relative paths, named/form/anchor origins, then a positional dataFormula with reactive price and quantity. Automatic Uvicorn reload and explicit refresh are synchronized with narration. AI-generated English voice, captions and exact runnable stages included.

Read the transcript / on-screen steps

00:00:00 In this lesson we will organize an order around its data context.

00:00:04 We will replace repeated absolute paths with relative ones, then read the same value

00:00:10 through symbolic origins.

00:00:11 Finally, we will introduce a data Formula that multiplies price by quantity, and

00:00:17 watch its result update.

00:00:20 We start with the small order Page from the examples download, in the same teaching

00:00:25 host.

00:00:25 Price and quantity are stored at order dot price and order dot quantity.

00:00:30 For now, each input uses its full absolute path.

00:00:34 Start Uvicorn with automatic reload.

00:00:36 Open the local address in the browser.

00:00:39 The two inputs show twelve and three; the row below the section reads the same price

00:00:44 by its absolute path.

00:00:47 Now give the section a data path, order, and make its initializers and input paths

00:00:52 relative.

00:00:53 The leading dot means start from this data context.

00:00:56 Inside this section, dot price resolves to order dot price, and dot quantity to

00:01:01 order dot quantity.

00:01:03 The caret still means a reactive pointer; the dot determines where its path begins.

00:01:08 Save the Page, wait for the server to reload, then refresh the browser.

00:01:12 The relative price row and the absolute row both show twelve.

00:01:17 Change Price to fifteen.

00:01:18 Both rows now show fifteen, because they read the same Data value.

00:01:24 Give the section the node ID order Form, then add a price display outside it.

00:01:29 This identifier has a purpose: it establishes the origin for the symbolic path.

00:01:35 The outside display uses caret, hash, order Form, dot price.

00:01:39 It finds that named Source node, then resolves price from the node’s order data

00:01:44 context.

00:01:45 Save, wait for automatic reload, and refresh.

00:01:50 The new outside row shows the same price as the relative and absolute rows.

00:01:55 Change Price to eighteen.

00:01:57 All three displays follow, even though the named display is outside the section.

00:02:03 Now mark this same section as a form context and an anchor, and add two more price

00:02:08 displays inside it.

00:02:10 Hash FORM starts at the nearest form ancestor; form ID establishes that context

00:02:15 here.

00:02:15 Hash ANCHOR starts at the nearest ancestor explicitly marked as an anchor.

00:02:20 These names are symbolic origins, not Data keys named FORM or ANCHOR.

00:02:25 Save and refresh after the server reloads.

00:02:31 All five rows currently read the same price, through relative, form, anchor, named

00:02:37 and absolute paths.

00:02:38 Change Price to eighteen again.

00:02:40 All five rows update together; their origins differ, but their resolved Data path is

00:02:46 the same.

00:02:48 Now add a data Formula and a heading for its result.

00:02:53 The first positional argument is the destination, dot total; the second is the

00:02:59 expression, price times quantity.

00:03:01 The named inputs connect price and quantity to their reactive relative pointers.

00:03:06 The init option requests an initial calculation.

00:03:09 The heading reads dot total; it does not repeat the calculation.

00:03:13 This downloaded teaching host permits inline JavaScript expressions; the strict

00:03:19 generated scaffold uses named Logic instead.

00:03:22 Save, wait for automatic reload, then refresh the browser.

00:03:26 The initial price is twelve, the quantity is three, and the total is thirty six.

00:03:33 Change Price to twenty.

00:03:35 The total becomes sixty, using the unchanged quantity of three.

00:03:39 Now change Quantity to four.

00:03:41 The total becomes eighty.

00:03:43 Change Quantity once more, to five.

00:03:45 The total becomes one hundred.

00:03:47 Each input updates Data, the formula recalculates order dot total, and the heading

00:03:53 follows that value.

00:03:54 No save, reload, or click handler is needed for these live input changes.

00:04:01 We have used a data context to resolve relative paths, then selected symbolic

00:04:06 origins explicitly.

00:04:08 We have declared a formula with a destination, an expression, and named reactive

00:04:13 inputs.

00:04:13 The result is stored separately in Data and displayed through a pointer.

00:04:18 Relative paths organize a region, symbolic paths find an established origin, and

00:04:23 formulas derive new values.

00:04:26 In the next lesson we will request Data and interface fragments from the server.

What we will learn

Start with a small order containing Price and Quantity. Give the section a data context, compare relative and symbolic paths, then calculate and display a total with dataFormula.

The video uses the same animated editor, scrolling terminal and live browser as the earlier lessons. Source edits are typed, saved and followed by automatic server reload and an explicit browser refresh. Live input changes update the page immediately.

Follow the recorded example

Use the downloadable orientation project, starting from stages/04_absolute.py. Run uvicorn app:application --reload, then open the printed local address. The teaching host and Pages use released Gramlot 0.3.8 with Python adapter 0.2.12.

The successive files are 04_absolute.py, 04_relative.py, 04_named.py, 04_paths.py and 04_formula.py. They contain exactly the literal declarations executed in the video. Labels contain their inputs; nodeId appears only when we introduce a named symbolic origin.

Resolve a path from its data context

Initially the fields bind to ^order.price and ^order.quantity. Set datapath="order" on their section, then change the local initializers to .price and .quantity and the inputs to ^.price and ^.quantity.

The caret makes the pointer reactive; the leading dot makes the path relative to the enclosing data context. Here .price resolves to order.price. Change Price to 15: both the relative row inside the section and the absolute row outside it show 15. A context controls address resolution; it does not copy values.

Choose a named, form or anchor origin

Add nodeId="orderForm" to the section and put a display outside it using ^#orderForm.price. The symbol finds the named Source node, then resolves price from that node’s order data context. Change Price to 18 and compare the named, relative and absolute displays.

Next establish formId="orderForm" and _anchor=True on the same section. Inside it, ^#FORM.price starts at the nearest form ancestor and ^#ANCHOR.price starts at the nearest marked anchor. FORM and ANCHOR are symbolic origins, not Data keys.

In this example all five displayed paths resolve to order.price. After saving and refreshing, change Price again: the relative, form, anchor, named and absolute rows update together. Nested contexts and changes of origin belong to the full course.

Declare a calculated value

Add order.dataFormula(".total", "price * quantity", price="^.price", quantity="^.quantity", _init=True). The first two positional arguments are the destination and expression. The named arguments connect the expression’s inputs to reactive pointers, and _init requests the first calculation.

The formula writes order.total into Data. A separate heading bound to ^.total displays it. After saving, waiting for automatic reload and refreshing, the initial values 12 and 3 produce 36.

This downloaded teaching host permits inline JavaScript expressions. The generated strict-CSP scaffold uses named Logic instead. Use the appropriate authoring form for your host; the full course explains that execution boundary.

Watch the dependencies update the result

Change Price to 20: the total becomes 60. Change Quantity to 4: it becomes 80. Change Quantity to 5: it becomes 100. Each change updates a Data dependency, the formula writes the new result, and the heading follows its pointer.

These live input edits do not save the Python file, restart the server or refresh the browser. Keep the destination separate from its input values so the formula does not depend on itself.

What we have learned

A data context resolves relative paths. A symbolic path selects an established origin. A dataFormula derives a separate Data value from named reactive inputs. A bound display reads that result without repeating the calculation. The next lesson introduces dataRpc and remote Source.

Your turn

Try it yourself

  1. Explain why ^.price inside datapath="order" and ^order.price outside it read the same value.
  2. Establish a named origin with nodeId and read its price from outside the section.
  3. Compare #FORM and #ANCHOR after establishing both contexts; identify the common Data path in this example.
  4. Add the positional dataFormula, predict the total, then change Price and Quantity independently.

Check your understanding

Does a relative path identify the same Data value in every container?

Show the answer and expected result

No. It is resolved against the enclosing data context. A symbolic path chooses an origin explicitly. After paths resolve, a formula reacts to changes in its reactive inputs and writes its result at the configured destination.

Working examples and reference