References
A reference lets one part of your document use a value that is defined
somewhere else. Instead of repeating content, you give a component a name
and then refer back to it with the $ symbol. A reference is not a copy you
edit separately — it points at the original, so when the original changes, the
reference updates too.
References are the main way components share information in DoenetML. The essential concepts page introduces the idea alongside components, attributes, and properties; this page covers writing references, how they resolve, and referencing repeated content.
Writing references
The different ways to write a reference and what each form points at.
Referencing a component with $
To reference a component, first give it a name, then write $ followed by
that name. The reference inserts the named component at that location.
Try dragging the point on the graph: the coordinates shown above update to
match, because $p is the same point as p — a reference, not a separate
copy.
DoenetML naming convention:
- Can only contain numbers, letters, and underscores
- Cannot start with an underscore or a number
- Is case-sensitive
Referencing a property with .
Every component stores properties — computed information you can read back.
Write $name.propertyName to reference one property of a named component. The
whole expression is a single reference: it points at the propertyName property
of the component named name.
In $myMath.splitSymbols, myMath selects the component and splitSymbols
selects which of its properties to read. The available properties vary by
component — see a component’s reference page for
the full list, and the
Properties and Lists
tutorial for more worked examples.
Marking where a name ends with $(...)
When a reference is followed immediately by other letters, numbers, or
underscores, wrap the name in parentheses so DoenetML knows where the name
ends. For example, $(a)b references the component named a and then prints a
literal b, whereas $ab would look for a component named ab.
How references are resolved
How DoenetML decides which component a reference points at — and what happens when it can’t.
Resolving to the nearest match
A reference looks for its referent starting where it is written and working
outward through the enclosing components. The nearest matching name wins, so
the same $n can mean different things in different places. Below, each $n
finds the <number name="n"> defined in its own section.
When a reference is ambiguous
If a name matches more than one component and none is nearer than the others,
the reference is ambiguous, so DoenetML reports a warning rather than guessing
which one you meant. Here, $n written outside both sections could equally
mean either section’s n, so it fails.
Nothing is rendered for $n, because DoenetML won’t guess which n you meant.
The editor surfaces the problem in the Warnings panel — its tab is marked
with a icon — reporting
Multiple referents found for reference: $n. The same message also appears
in a tooltip when you hover over $n in the editor.
Disambiguating with a named ancestor
If two components with the same name are in different ancestors, you can create
unique references to them by giving those ancestors unique names and
referencing through the ancestor names. Naming the two sections s1 and s2
lets you reach each n unambiguously with $s1.n and $s2.n.
When a name doesn’t exist
If nothing with the referenced name can be found, the reference fails. A common cause is a typo in the name.
As with an ambiguous reference, $total renders nothing and DoenetML reports a
warning — here, No referent found for reference: $total — shown in the
Warnings panel and as a tooltip on hover.
Referencing repeated content
A <repeat> (or
<repeatForSequence>) generates several
copies of its content. Use a bracketed index to reference one iteration, the
valueName/indexName bindings to reference the per-iteration values inside
the repeat, and a name on a component in the body to reach that component in a
chosen iteration.
Here $rep[2] references the second iteration of the repeat and
$rep[2].squared the <math name="squared"> defined inside it, while
$rep[1].v references the valueName binding v from the first iteration.