Hype Data Magic

Hello @MaxZieb !

I wish I know how to include an external URL for a button or for an iFrame. Could you please offer me support?

Thank you!

Option 1: You can just write a Hype function that uses getData and get the URL and opens it

Option 2: You can write a custom handler for buttons


HypeDataMagic.addDataHandler('button', function (hypeDocument, element, event){
	if (event.data.label) element.innerHTML = event.data.label;
	if (event.data.url && !element.dataset.linked) {
		element.dataset.linked = true;
		var clickHandler = function(e){
			window.location = event.data.url;
		element.addEventListener('mousedown', clickHandler, false);
		element.addEventListener('touchstart', clickHandler, false);

HypeDataMagic-CustomHandler.hype.zip (19,1 KB)


Thank you so much @MaxZieb !

I was playing around with the following:


HypeDataMagic.addDataHandler('hypefunction', function (hypeDocument, element, event){
	var hypeFunctionName = element.getAttribute('data-hype-function');
	if (hypeFunctionName && hypeDocument.functions) {
		var hypeFunction = hypeDocument.functions()[hypeFunctionName];
		if(hypeFunction) hypeFunction(hypeDocument, element, event);

Allowing to forward any data to a Hype function… there might be use cases for this, but it lacks a live preview as Hype functions only can be called in preview. It might be useful for people not wanting to get into creating handlers or for complex use-cases that don't require a preview anyway.

The following example only shows how the data is received… nothing really useful apart from demonstrating the concept: HypeDataMagic-CustomHandler-hypeFunction.hype.zip (17,8 KB)

Crude visualization how this handler forwards a call:

Update: The workaround and approach in this reply isn't needed anymore since version 1.3.4 now supports native forwarding to Hype functions. Just add () to the end of a handler name… see below!


Thanks @MaxZieb this example is a useful visual overview.


↑ look at project
1.3.4 Ending handler with () forwards them to hypeDocument.functions, exposed resolveObjectByKey and added and exposed resolveKeyToArray (keys can now be arrays), fixed append/prepend bug

Release notes:

Ending handler with () forwards them to hypeDocument.functions
Hence, now you can just specify a handler ending in () to redirect it to hypeDocument.functions. For example, setting the data-magic-handler to myFunction() allows you to use a Hype function to process. Obviously, these types of handlers don't give you any preview in the IDE as the Hype API and hypeDocument.functions isn't present in the web view. These functions are only applied when previewing. Although, one thing you can always is set multiple handlers like setting data-magic-handler to text, myFunction(). That way you will get the regular text output and additionally myFunction() will be triggered on previews/exports. In the following example, a Hype function is used to make the output uppercase. This would make more sense with a regular handler as it also provides a live preview, but either way, here is a simple example:

Custom handler upper() as Hype function with a second handler doing the default text output

Assigning the custom handler as Hype function. Also, demonstrating how handlers can be chained by returning the event object

Leads to the following output as the first handler applies upper() and text adds it to innerHTML (text is the default handler if not declared, so we need to apply it if we use data-magic-handler and also want the regular output)

exposed resolveObjectByKey and added and exposed resolveKeyToArray
These are low-level functions that have been rewritten and are now exposed to the API allowing you to use them to process the key notations used in Hype Data Magic. You can use them to resolve a key on an object and process a key to retrieve its parent, or any other kind of use case. Another thing that has been added is the ability to actually provide arrays instead of only strings as a key. They can even be nested or consist of an array of key notations. For example, given data like this …

var obj = {
	deeply: {
		nested: {
			node: "Hello World"

// using string 'deeply.nested.node'
console.log( HypeDataMagic.resolveObjectByKey(obj, 'deeply.nested.node') );

// using array ['deeply', 'nested', 'node']
console.log( HypeDataMagic.resolveObjectByKey(obj,  ['deeply', 'nested', 'node']) );

// using mixed notation in array ['deeply.nested', 'node']
console.log( HypeDataMagic.resolveObjectByKey(obj, ['deeply.nested', 'node']) );

// using nested arrays [['deeply', 'nested'], 'node']
console.log( HypeDataMagic.resolveObjectByKey(obj, [['deeply', 'nested'], 'node']) );

... the result is always resolved. It can actually nest recursively if ever needed. This is done, so one can easily combine any kind of key (string or array or a mixed form). This is certainly a special case scenario, but should add to the robustness as it originates from rewritten and much simpler functions.

To resolve a key directly, you can retrieve it in its flat array notation using HypeDataMagic.resolveKeyToArray. Meaning, all the above key notation can be used with HypeDataMagic.resolveKeyToArray leading to the following array ['deeply', 'nested', 'node'] (given the same example data as above). You can now process a key in any way you see fit (compare, replace and tweak). You could change a specific level or retrieve a parent data node, like in the following example:

// logs out ['deeply', 'nested', 'node']
console.log( HypeDataMagic.resolveKeyToArray('deeply.nested.node'));

// removes last element and logs out ['deeply', 'nested']
var keyArr = HypeDataMagic.resolveKeyToArray('deeply.nested.node');

fixed append/prepend bug
There was an error when only one of the two special tags data-magic-prefix or data-magic-append have been used, adding a 'Null' string to the output. This was overlooked as I always used it in conjunction or with numbers. This error now has been rectified.

Additional note :memo:

HypeDataMagic.getData now also allow an optional second parameter, being a key. Hence, you can now fetch a specific key using that interface. Forgot to mention that in the short form of the release note.

HypeDataMagic.getData(null, "some.key.here");

The parameter null is the data source and if not passed in defaults to the “shared” one. If you use multiple sources (even as shortcuts) you know what this means, else just use null.

1 Like

Example loading data from a JSON file

Example loading data through CSV (simple splitting)

In addition to the older example showing how to use the fetch supported JSON format, here is the same example using fetch to load external data and parse it from a CSV format:

Example with basic CSV processing based on splitting text at the delimiter:
fetch_hype_data_magic_advanced_CSV_version.hype.zip (46,6 KB)*


Example loading data through CSV (parser, comma)

This example uses a parsing example and allows quoted content and detects line endings and separators. They also can be manually specified:

fetch_hype_data_magic_advanced_CSV_parser_comma.hype.zip (47,8 KB)

Example loading data through CSV (parser, semicolon)

In this variation, the only difference is that the data is semicolon separated. This is the case when exporting from Apple Numbers:

fetch_hype_data_magic_advanced_CSV_parser_semicolon.hype.zip (46,7 KB)

Example loading data through CSV (Google Docs, comma)

This example uses a public Google Docs table as a data source. Just create a table and make it public. Take the link for the table and replace /edit?usp=sharing with /export?format=csv and then fetch the data from that endpoint.

fetch_hype_data_magic_advanced_CSV_parser_google_docs.hype.zip (46,4 KB)


Would it in theory also be possible to change element colors etc through this? or even load different scenes or timelines depending on the feed?

2 posts were merged into an existing topic: Hype Data Parser

text and imageswapping are builtin.
for advanced usage – like changing colors – have a look at the wiki:

Example using Hype Data Magic for multilingual exports

and with images

1 Like

Example using Hype Data Magic with customData

One can also use Hype Data Magic to bind a rectangle to a variable in a data source. The default data source is used when using HypeDataMagic.setData(({lorem:'ipsum'}), but one can use arbitrary source names like HypeDataMagic.setData({lorem:'ipsum'}, 'myData'). It is even possible to use hypeDocument.customData with the keyword customData as seen in the following example:

Example_Hype_Data_Magic_bind_customData_to_rectangle.hype.zip (20,6 KB)


↑ look at project
1.3.5 Function in data constructs are now resolved, new handler 'variables' resolves to customData, exposed default 'handler', to change use HypeDataMagic.setDefault('handler', 'text'), new default 'customData' is used to init hypeDocument.customData (in addition to old 'customDataForPreview'), new default 'allowDataFunctions' is set to true and allows for functions in data, new default 'allowVariables' is set to true and allows for variables in default handlers image and text, exposed low-level functions resolveVariablesInString, resolveVariablesInObject and cloneObject

This release adds another layer of data in form of custom data variables (can also be tweaked to use other sources using the default 'variables'). Given some data like:

    greeting: 'Hello ${userName}, welcome!',

You can assign greeting as usual to a rectangle by assigning it with data-magic-key set to greeting. New is the possibility to update partial strings with variables.

The variable ${userName} will be substituted from the default variable source hypeDocument.customData. So, if you set hypeDocument.customData.userName = 'Max' and subsequently refresh using hypeDocument.refresh() the display will be updated.

Variables are mapped to hypeDocument.customData and can also be set from outside Hype using the already established

HypeDataMagic.setDefault('customDataForPreview', {
    userName: 'Max'

and the now new

HypeDataMagic.setDefault('customData', {
    userName: 'Max'

The difference being that the new option sets the custom data beyond only the preview.

The new variable allows nested notation. Given some custom data like:

HypeDataMagic.setDefault('customData', {
    user: {
        name: 'Max',
        age: 46,
        gender: 'male',
        loves: [
            "Tumult Hype",
            "classical music"

variables can reference the data as follows, ${user.name}, ${user.age}, ${user.gender}, ,${user.loves[0]}, ${user.loves[1]}. As you can see, you can mix object and array notation just like in magic keys.

Another new thing is that data can contain functions. This is totally optional and can also be disallowed if you feel strongly about it. Given you assign your data through JavaScript, defining a branch using a function allows creating data or sub-branches dynamically. These functions don't accept any parameters, but given the context you define them in (like Hype function or Hype Events) you can even use hypeDocument in the function itself.

    dynamic: function(){
        return {
            data: 'I am a random number: '+Math.round(Math.random()*100)

The data-magic-key would be dynamic.data and result in the text I am a random number: 34'… with the number changing on every refresh. The same also works for variables.

${resourcesFolderName} is now substituted if found in an unresolved form. Hype currently doesn't resolve the variable in external JS files, and at least this little workaround resolves it as a variable inside of Hype Data Magic keys when displayed with default handlers. If you have a custom handler, you can just chain your handler behind the new variables handler.

Just set data-magic-handler and set it to variables, myhandler for example.

I just realized that the ${variable} syntax collides with template literals. But, I am keeping the syntax and for that special case my suggested workaround is…

To avoid immediate substitution in such cases, use a substitution like :sparkles: instead of $ and replace it:

var myLiteralString = `
✨{variable} is 
in this 
literal`.replace('✨', '$');

I might add an alternative like this for template literal built into Hype Data Magic in a future version.


Reactive custom data and multiple options for variables is coming in a couple of hours. Really happy about this one… Oh and I forgot the dataset variables features (really powerful).


↑ look at project
Version 1.3.6

  • Added dataset variables and the handler 'dataset',
  • Added data-magic-sets to enable comma separated queries for foreign datasets, parent(s) and closest()
  • Added default refreshOnCustomData and reactivity to custom data,
  • Exposed HypeDataMagic.enableReactiveObject (low-level) allowing to create you own reactive objects,
  • Exposed HypeDataMagic.disableReactiveObject (low-level) to revert a object back to normal,
  • Added HypeDataMagic.debounceByRequestFrame (helper) to create a function version that is debounced by rAF,
  • Added HypeDataMagic.createSequence (helper) as a function factory for sequences progress on demand,
  • Change default on all forceRedraws (Safari-Bugfix) to false, you can enable them if needed for IDE or exports only,
  • Added HypeDataMagic.setDefault('highlightDataMagic', true); to allow inspecting regions managed by Data Magic,
  • Added inline syntax for data-magic-key as source:key (this overrides any branch lookups),
  • Added inline syntax for variables as source:key, add %{} and (sparkles-emoji){} options for variable names,
  • Refactored observer in IDE portion, added plenty of comments to code

↑ look at project
Version 1.3.7

  • Reverted the observer in IDE portion (only affects preview in IDE, fixing quirks)

Version 1.3.8

Version 1.3.9

  • Refactored findMagicAttribute, exposed it as findAttribute,
  • Added the ability to traverse data-magic-braches further with +,
  • HypeDataMagic.setData now offers to set a key on a object
1 Like

5 posts were split to a new topic: Refreshing the view in Hype Data Magic

So did @MaxZieb make the TeamTumult yet @jonathan? :innocent:


Found solution on my HD… I thought I'd share…
Data handler to embed a video example:
HypeDataMagic-Video-Data-Handler.hype.zip (322,1 KB)

1 Like