2.4 | The Cubbles Tag API



Purpose

To initialise a cubble at runtime the RTE provides a so-called tag api. This page provides describes the api and related usage scenarios.


Prerequisites

  1. The RTE is available within the web page.
  2. The configured store contains the components needed on the web page.


Create a Cubble

To have cubble available at runtime, simply put a (custom) html-tag named as the component itself into the html body. The attribute cubx-webpackage-id points to the webpackage containing the component.


 Behind the scene ...

If the page has been loaded by on a client the RTE automatically

  1. identifies html tags that declare cubbles,
  2. identifies all resources the component depends on,
    ... this is one of the unique features of the Cubbles RTE
  3. extends the header section of the html element with references to those resources
    ... and lets the browser download them all
  4. creates each cubble a declaration has been been found for,
  5. creates connections between the cubbles,
  6. initializes the cubbles with
    1. default values (defined by the component developer)
    2. init values (defined by the page editor)
      Note: If a (input) slot initialization lead to a change of output slot value, the RTE propagates this value over all it's outgoing connections.

webpackage.modelVersion >= 9
<body>
	//...

	<first-demo-component cubx-webpackage-id="demo-package@0.2"></first-demo-component>

	//...
</body> 
webpackage.modelVersion < 9
<body>
	//...

	// if the webpackage is of modelVersion < 9, an endpoint reference is required
	<first-demo-component cubx-webpackage-id="demo-package@0.1" cubx-endpoint-id="main></first-demo-component>

	//...
</body>


Cubble / Slot Initializations

In many cases an initial configuration of a cubble is needed. This can be done using the input slots exposed.

The <cubx-core-init> element allows to declare any number of child tags <cubx-core-slot-init> to declare initial values for input slots. The slot initializations are done in the same order they were declared.

Note that

  1. String values need to be enclosed in double quotation marks: "Hello World"
  2. Number values are expected to be written as "plain" characters: 5
  3. Boolean values are expected to be written as true or false
  4. Objects values need be written as valid json into one or multiple lines: {"label": "Name", "value": "..."}


cubx-core-init > cubx-core-slot-init
<first-demo-component cubx-webpackage-id="demo-package@0.2">
	<cubx-core-init style="display:none">
  		<cubx-core-slot-init slot="message">"Hello World!"</cubx-core-slot-init>
  		<cubx-core-slot-init slot="count">5</cubx-core-slot-init>
  		<cubx-core-slot-init slot="on">true</cubx-core-slot-init>
  		<cubx-core-slot-init slot="config">{"label": "Name", 
											"value" : "Max Musternamm"}
		</cubx-core-slot-init>
	</cubx-core-init>
</first-demo-component>


Cubble / Connection Declarations

To let multiple cubbles on a web page interact with each other, the tag api allows to declare connections between them.

A connection is like a point-to-point message channel - transferring slot values from a source to a target.

  • Source: The output slot of a Cubble.
  • Target: The input slot of another cubble.

Each time a output slot value changes, the new value is propagated automatically over all its outgoing connections.

cubx-core-connections > cubx-core-connection
<first-demo-component id="first" cubx-webpackage-id="demo-package@0.2">
	<cubx-core-init style="display:none">
  		<cubx-core-slot-init slot="message">"Hello World!"</cubx-core-slot-init>
	</cubx-core-init>
	<cubx-core-connections style="display:none">
			<cubx-core-connection connection-id="connection1" source="message", destination="second:textInput"></cubx-core-connection>
	</cubx-core-connections>
</first-demo-component>
<second-demo-component id="second" cubx-webpackage-id="demo-package@0.2"></second-demo-component>

The example declares

  1. for cubble "first" an init for the input slot "message",
  2. a connection
    1. from output slot "message" of cubble "first"
    2. to input slot "textInput" of cubble "second".

If both cubbles are initialized

  • cubble "first" > slot "message" has the value "Hello World!"
  • cubble "second" > slot "textInput" has the value "Hello World!".

Connection: hook-function

You might have noticed that - if you can connect a cubble's output slot with any input slot of any cubble - there is no guarantee for the interfaces to be semantically interoperable (even if you take care both slots are of the same type).

Basically this is ok and similar to the real world where no one has a global data model defined yet. To make different instance be able to understand each other messages need to be translated / transformed.

To do the same in the "Cubbles World" you can (optionally) define a hook-function per connection:

function(value,next){
	var newValue = value; 
	// do something with newValue
	next(newValue);
}
cubx-core-connections > cubx-core-connection
<first-demo-component id="first" cubx-webpackage-id="demo-package@0.2">
	<cubx-core-init style="display:none">
  		<cubx-core-slot-init slot="message">"Hello World!"</cubx-core-slot-init>
	</cubx-core-init>
	<cubx-core-connections style="display:none">
			<cubx-core-connection connection-id="connection1" source="message", destination="second:textInput" hook-function="function(value,next){var newValue = value +' - added by hook function'; next(newValue);}"></cubx-core-connection>
	</cubx-core-connections>
</first-demo-component>
<second-demo-component id="second" cubx-webpackage-id="demo-package@0.2"></second-demo-component>

The important part is the hook-function

<cubx-core-connection ... hook-function="function(value,next){var newValue = value +' - added by hook function'; next(newValue);}"></cubx-core-connection>

Connection: repeated-values (default="false")

In case the value of an output slot is renewed without changing the value itself, the value ist NOT propagated to the connected slots. This is the default behaviour.

There are situation another behaviour is desired, e.g., in case if clicking a button is expected to trigger an action on a connected cubble. In this case each button-click will not produce different values but the action is expected to be executed each time.

<cubx-core-connection ... repeated-values="true"></cubx-core-connection>

Connection: copy-value (default="true")

By default the destination slot of a connection will receive a copy of the propagated value. This isolates the models of different cubbles of each other. In most cases this is the expected behaviour.

In case the source (the output slot) is of type 'object', a connection can optionally be configured to transfer a reference. This

  1. is more efficient as it avoids to create a copy of the object,
  2. allows to implement scenarios where different cubbles share individual parts of their model - without the need to explicitely call the 'set' method on the output slot, each time any property of the object has been changed.

But take care, partially shared models allow each cubble to change the state of all the other cubbles.

<cubx-core-connection ... copy-value="false"></cubx-core-connection>