Hi Armant, welcome to the forum.
I'm afraid that you've slightly misinterpreted how things are working with uibuilder. The picture you posted is of the file editor which is a convenience feature of uibuilder. The files being edited are just that, files, those files will be served by the uibuilder web server.
So that means that those files can't use Mustache in the same way that the template node does for example. The template node is NOT a file editor. The code is server code and so the Mustache variables are replaced on the server before being presented to the client front-end.
However, all is not lost by any means. You can certainly use Mustache if you wish. The difference being that you will need to load the appropriate mustache client library in your index.html file. Then in your index.js file, add the code to do the mustache replacements inside the onChange
function for when a msg arrives.
As of uibuilder v5, there is another possibility. While not Mustache, uibuilder v5 does allow you to turn on server-side processing using EJS. Details of how to do that in the tech docs.
However, generally, this isn't really needed since dynamic updates in the browser client is so simple with uibuilder. In fact, it isn't hard to use uibuilder with just plain DOM without needing any other libraries.
In index.html
<div>
<p id="elementid">This is static text</p>
</div>
In index.js
// Pseudo jQuery-like selector
if (!window.$) {
window.$ = document.querySelector.bind(document)
}
$('#elementid').innerText = 'Oooh, dynamically set'
or, more completely
// Pseudo jQuery-like selector
if (!window.$) {
window.$ = document.querySelector.bind(document)
}
uibuilder.start()
uibuilder.onChange('msg', (msg) => {
$('#elementid').innerText = msg.payload
})
UPDATE 18:10 - a quick and dirty example of using mustache with uibuilder in the front-end:
flow
[
{
"id": "dafceb486bae652c",
"type": "inject",
"z": "c90d1cebe99c8390",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "Msg from Node-RED",
"payload": "{\"name\":\"Fred\"}",
"payloadType": "json",
"x": 330,
"y": 140,
"wires": [
[
"9416d117d9b657d2"
]
]
},
{
"id": "0779feee345e245a",
"type": "debug",
"z": "c90d1cebe99c8390",
"name": "debug 1",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "counter",
"x": 715,
"y": 120,
"wires": [],
"l": false
},
{
"id": "1e42f5c66891576e",
"type": "debug",
"z": "c90d1cebe99c8390",
"name": "debug 2",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": true,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "counter",
"x": 715,
"y": 180,
"wires": [],
"l": false
},
{
"id": "9416d117d9b657d2",
"type": "uibuilder",
"z": "c90d1cebe99c8390",
"name": "",
"topic": "",
"url": "mustache",
"fwdInMessages": false,
"allowScripts": false,
"allowStyles": false,
"copyIndex": true,
"templateFolder": "blank",
"extTemplate": "",
"showfolder": false,
"reload": false,
"sourceFolder": "src",
"deployedVersion": "5.0.2",
"x": 590,
"y": 140,
"wires": [
[
"0779feee345e245a"
],
[
"1e42f5c66891576e"
]
]
}
]
index.html
<!doctype html>
<html lang="en"><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Blank template - Node-RED uibuilder</title>
<meta name="description" content="Node-RED uibuilder - Blank template">
<link rel="icon" href="./images/node-blue.ico">
<!-- Your own CSS -->
<link type="text/css" rel="stylesheet" href="./index.css" media="all">
</head><body class="uib">
<script id="mp_template" type="text/template">
<p>Hello {{ name }}</p>
<p>This was from a script template</p>
</script>
<h1>uibuilder Mustache</h1>
<div id="mypanel">This will be updated from a script templatewhen a msg is received.</div>
<div id="mypanel2">This will be updated from a JS template when a msg is received.</div>
<button onclick="fnSendToNR('A message from the sharp end!')">Send a msg back to Node-RED</button>
<pre id="msg" class="syntax-highlight">Waiting for a message from Node-RED</pre>
<!-- #region Supporting Scripts. These MUST be in the right order. Note no leading / -->
<script src="../uibuilder/vendor/socket.io/socket.io.js">/* REQUIRED: Socket.IO is loaded only once for all instances. Without this, you don't get a websocket connection */</script>
<script src="./uibuilderfe.min.js">/* REQUIRED: remove 'min.' to use dev version */</script>
<script src="https://cdn.jsdelivr.net/npm/mustache/mustache.min.js"></script>
<script src="./index.js">/* OPTIONAL: Put your custom code here */</script>
<!-- #endregion -->
</body></html>
index.js
/* eslint-disable strict */
/* jshint browser: true, esversion: 6, asi: true */
/* globals uibuilder */
// @ts-nocheck
/** Minimalist code for uibuilder and Node-RED */
'use strict'
// return formatted HTML version of JSON object
window.syntaxHighlight = function (json) {
json = JSON.stringify(json, undefined, 4)
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number'
if ((/^"/).test(match)) {
if ((/:$/).test(match)) {
cls = 'key'
} else {
cls = 'string'
}
} else if ((/true|false/).test(match)) {
cls = 'boolean'
} else if ((/null/).test(match)) {
cls = 'null'
}
return '<span class="' + cls + '">' + match + '</span>'
})
return json
} // --- End of syntaxHighlight --- //
// Send a message back to Node-RED
window.fnSendToNR = function fnSendToNR(payload) {
uibuilder.send({
'topic': 'msg-from-uibuilder-front-end',
'payload': payload,
})
}
// Set up a Mustache template in JavaScript
var template = '<p>This is from a template defined in JavaScript</p><p>Hello {{ name }}</p>'
// Start up uibuilder - see the docs for the optional parameters
uibuilder.start()
// Listen for incoming messages from Node-RED
uibuilder.onChange('msg', function(msg){
console.info('[indexjs:uibuilder.onChange] msg received from Node-RED server:', msg)
// dump the msg as text to the "msg" html element
const eMsg = document.getElementById('msg')
eMsg.innerHTML = window.syntaxHighlight(msg)
// Update mypanel with templated output
var template = document.getElementById('mp_template').innerHTML
var text = Mustache.render(template, msg.payload)
console.log('Script Template text: ', text)
document.getElementById('mypanel').innerHTML = text
// Update mypanel2 with templated output
document.getElementById('mypanel2').innerHTML = Mustache.render(template, msg.payload)
})