Repository navigation
Temme inheritance
Inheritance is one of Temme’s main composition features. It allows one hierarchy object to reuse options from another object or template so you can reduce duplication and keep your hierarchy definitions concise.
Temme supports four inheritance patterns:
- Object to Object: a rendered hierarchy object inherits from another rendered hierarchy object in a valid scope.
- Object to Template: a rendered hierarchy object inherits from a template.
- Template to Template: a template inherits from another template.
-
Outer element: an object or a template inherits from an element already in the page, with
@followed by a CSS selector.
Templates are never rendered directly, which makes them ideal for reusable presets and shared definitions.
The primary inheritable options are:
attributeschildNodesclassescontentdatasetidname
const hierarchy = {
ref: "parent",
childNodes: [
{
from: {
ref: "parent"
}
}
]
};A referencing hierarchy object uses the from option to describe what it inherits and how the inheritance should behave.
The from option supports:
-
ref: the referenced object or template -
mode: inheritance mode (appendoroverride) -
include: inherit only specific options -
exclude: ignore specific options -
children: control whether inherited children are included and where they are placed
const hierarchy = {
ref: "parent",
attributes: { visible: true },
classes: ["red", "blue"],
childNodes: [
{
ref: "sibling",
name: "h1",
classes: ["yellow"],
dataset: {
id: 100,
title: "Some title"
},
from: {
ref: "parent"
}
},
{
name: "p",
from: {
ref: "sibling"
}
}
]
};In this example:
- the first child inherits from
parent - the second child inherits from
sibling - inherited values accumulate as references are resolved
Temme also normalizes inherited arrays such as classes by removing duplicates and sorting values.
const hierarchy = {
templates: [
{
ref: "temp-1",
classes: ["bold", "dup", "dup"]
},
{
ref: "temp-2",
from: {
ref: "temp-1"
},
classes: ["orange", "dup"]
}
],
from: {
ref: "temp-2"
}
};Here:
-
temp-2inherits fromtemp-1 - the root hierarchy inherits from
temp-2 - duplicate class values are removed during normalization
Templates can inherit from templates, but templates cannot reference non-template rendered objects.
from.ref values starting with @ reference an element outside the hierarchy, found with a CSS selector in the target's document:
<nav id="menu" class="dark" aria-label="Main">Links</nav>const hierarchy = {
childNodes: [
{
name: "nav",
from: {
ref: "@#menu",
exclude: ["id"]
}
}
]
};The new nav inherits the classes, attributes, dataset and content (as HTML) of #menu. include and exclude work as usual, but the tag name and the child nodes are never read from the page. If no element matches, Temme throws an InvalidReferenceOptionValueError.
References are resolved in dependency order, whatever the declaration order: if a inherits from b and b inherits from c, b first inherits from c, then a inherits the result.
const hierarchy = {
childNodes: [
{ name: "i", from: { ref: "b" } },
{ ref: "b", from: { ref: "c" } },
{ ref: "c", classes: ["shared"] }
]
};
// All three elements end up with the "shared" class.Some references are rejected:
- a reference to an object nested deeper than the referencing one throws a
ReferenceOutOfScopeError(templates count as being at the depth of the object that declares them) - circular inheritance, such as
ainheriting frombinheriting froma, throws aCircularReferenceError; so does inheriting the children of an ancestor, which would include the object itself - a template referencing a rendered object throws an
InvalidTemplateReferencingError
Inherited values are copies, so changing one object never changes another.
Temme lets you control inheritance scope through include and exclude.
const hierarchy = {
templates: [
{
ref: "temp-1",
attributes: {
visible: true,
counter: 56
},
classes: ["some-class"],
dataset: { id: 814 }
}
],
from: {
ref: "temp-1",
include: ["classes", "dataset"]
}
};This inherits only classes and dataset.
const hierarchy = {
templates: [
{
ref: "temp-1",
attributes: {
visible: true,
counter: 56
},
classes: ["some-class"],
dataset: { id: 814 }
}
],
from: {
ref: "temp-1",
exclude: ["dataset"]
}
};This inherits everything except dataset.
include and exclude can't both restrict inheritance: giving both with entries throws an InvalidReferencingOptionError.
Child inheritance is controlled through the children sub-option inside from.
const hierarchy = {
childNodes: [
{
ref: "list",
name: "ul",
childNodes: [
{ name: "li" },
{ name: "li" }
]
},
{
from: {
ref: "list",
children: {
allow: true
}
},
childNodes: [
{
name: "span"
}
]
}
]
};When children.allow is true, the referenced node’s children are inherited as well. The inherited children are copies of the fully resolved originals, without their ref, so they never shadow the originals.
You can also control placement:
from: {
ref: "list",
children: {
allow: true,
placement: "before"
}
}placement accepts:
"before""after"
The default is "after".
Temme supports two inheritance modes:
This is the default mode.
- the tag name and an existing id are preserved
- classes are merged
- attributes and dataset entries are added without overwriting existing keys
- content is appended after the existing content, separated by a space (an empty content simply takes the inherited one)
- children are added before or after the existing ones, when allowed
- the tag name, the id and the content are replaced
- classes are replaced
- attributes and dataset entries overwrite matching keys and keep the others
- children are replaced, when allowed
Example:
const hierarchy = {
templates: [
{
ref: "base",
id: "main-id",
classes: ["one", "two"]
}
],
from: {
ref: "base",
mode: "override"
}
};Use append when you want additive composition, and override when you want the referenced structure to take precedence.
Temme gives you a declarative, object-based way to generate HTML with JavaScript.