FHEM Forum

FHEM => Frontends => TabletUI => Thema gestartet von: jsChris am 23 Oktober 2016, 10:47:20

Titel: FTUI mit Logic-Full Template Engine - Interesse?
Beitrag von: jsChris am 23 Oktober 2016, 10:47:20
Liebe ftui Gemeinde, liebe ftui Entwickler,

ich habe nun endlich damit begonnen, die ftui auszuprobieren, bzw. meine alten Floorpläne damit zu "upgraden". Das macht wirklich Spaß, ihr habt hier einen super Job gemacht und ich möchte mich gerne für die vielen Stunden, die das sicher gekostet hat, bedanken. Nicht nur das Interface, auch der Aufbau mit den data-Attributes gefällt mir sehr gut und ich finde ihn auch sehr intuitiv.

Die ersten Schritte gingen wirklich leicht von der Hand, so sehr, dass ich nun gerne "alle" Devices steuern möchte. Viele davon ähneln sich sehr und hier komme ich auch zu meinem Anliegen. Während man in smartvisu solche ähnliches Devices sehr schön über die Template Engine Twig lösen kann, fehlt mir genau das in der ftui.

Ein Beispiel: in meinem, doch sehr gemischten - ich-probiere-gern-mal-alles-aus -  "Setup" befinden sich doch sehr unterschiedliche Lösungen, die im Grunde aber doch sehr ähnlich sind: RGB(W/W) Stripes und Lampen. Dazu gehört Milight, Lightify, HUE und vor allem einige Fibaros, die wiederum unterschiedliche Stripes steuern, wenige nur RGB-Stripes, die anderen RGBW. In Smartvisu hatte ich dafür ein einziges Template, das nach außen hin völlig gleich aussah, aber natürlich unterschiedlich konfiguriert war: Im Grunde enthielt es einen Switch für an/aus, Dimmer, Colorwheel und ein paar Buttons um direkt Farbe, bzw. das "richtige" weiß zu schalten. Schon ein paar Zeilen Code, die ich ungern immer wieder in die ftui copy/pasten möchte. Wäre auch viel Arbeit, fehleranfällig, mal ganz zu schweigen davon, wenn man mal was ändern möchte...

Ich weiß, es gibt bereits die Möglichkeit Templates einzubinden, aber hier fehlt mir doch die Logik, die sich, meiner Meinung nach, auch nur sehr umständlich dort unterbringen lässt.

Mein Vorschlag: eine Logic-Full Template Engine einzubinden. Eigentlich dachte ich, ich könnte das über ein Widget lösen. Funktioniert auch, gefällt mir aber nicht so gut. Zum einen weil ftui.initPage(); schon beim Start mindestens doppelt laufen müsste, zum anderen hatte ich mit Kleinigkeiten bei meinen eingebundenen Templates auch kleinere Probleme, z.B. wurden Farben nicht immer sofort aktualisiert (mit ftui.initWidgets(area) nur auf den Parent meines eingebundenen Templates hatte ich auch nur mäßigen Erfolg). Ich bin da nicht tiefer eingedrungen, wahrscheinlich ließe sich das schon lösen, aber am Ende wäre die Beste Stelle doch die, an der auch jetzt die Templates eingebunden werden.

Bevor ich also bei dem Widget weitermache oder mir einen fork der git repo erstelle, wollte ich deshalb mal fragen, ob nicht vielleicht grundsätzlich das Interesse bestünde eine Template Engine einzubauen.

Ausgewählt hätte ich jetzt mal http://underscorejs.org/.
Meine Implementierung war wirklich simpel:

- underscore-min.js, underscore-min.map kommen in /lib/underscore.
- underscore-min.js wird in der index.html referenziert (<script src="/fhem/tablet/lib/underscore/underscore-min.js" defer></script>), möglichst zuerst.
- (die Erweiterung underscore-string könnte man auch gleich mit einbinden http://gabceb.github.io/underscore.string.site/)

Der Patch für die initPage wäre recht übersichtlich:

ftui.initPage = function(area){

(...)
if (total>0){
$('[data-template]',area).each(function(index) {
var tempelem = $(this);
$.get(
tempelem.data('template'),
{},
function (data) {

[b]if(tempelem.data('template-type') === 'underscore') {
ftui.loadUnderscoreTemplate(tempelem,data);
}[/b] else {
var parValues = tempelem.data('parameter');
for (var key in parValues) {
data = data.replace(new RegExp(key, 'g'), parValues[key]);
}
tempelem.html(data);
}

if (index === total - 1) {
//continue after loading the includes
ftui.initWidgets(area);
}
}
);
});
}
else{
//continue immediately with initWidgets
ftui.initWidgets(area);
}
};




Der Code zur Function, die oben aufgerufen würde (kann man noch kürzen...)

ftui.loadUnderscoreTemplate = function(tempelem,data) {

var attributes = {};
var template;
var replace = true; // I would prefer to replace the original dom of tempelem

ftui.log(1,'LOADING TEMPLATE '+tempelem.data('template'));

tempelem.each(function() {
$.each(this.attributes, function() {
if(this.specified) {
switch(this.name) {
case'data-template-type':
case'data-template':
if(!replace) {
tempelem.removeAttr(this.name);
}
break;
default:
if(this.name.indexOf('data-') === 0) {
attributes[this.name] = this.value;
if(!replace) {
tempelem.removeAttr(this.name);
}
}
}

}
});
});

template = _.template(data);

if(replace) {
tempelem.replaceWith(template(attributes));
} else {
tempelem.html(template(attributes));
}
};



Was mir dabei besonders gut gefallen würde, ist, dass man die Templateaufrufe genauso gestalten kann, wie auch die "normalen" widget Aufrufe, alle data-Atributes werden 1:1 an das Template weiter gereicht. "data-template" ist klar, data-template-type="underscore" wird von dem if oben in der ftui.initPage interpretiert. Hier mal ein, zugegebenermaßen etwas doofes, aber dafür kurzes, Beispiel:

index.html

<div data-template="templates/label.html" data-template-type="underscore" data-device="Sonnenaufgang" data-class="inline Sonnenaufgang"></div>


templates/label.html

<%
    obj['data-class'] = (typeof(obj['data-class']) === "undefined") ? 'inline medium' : obj['data-class'];
    obj['data-get'] = (typeof(obj['data-get']) === "undefined") ? 'state' : obj['data-get'];
%>
<div class="<%= obj['data-class'] %>"
    data-type="label"
    data-device="<%= obj['data-device'] %>"
    <% if(typeof(obj['data-unit']) !== 'undefined') { %>
        data-unit = "<%= obj['data-unit'] %>"
    <% } %>
    data-get="<%= obj['data-get'] %>"
>
</div>



Ich denke, an dem Beispiel kann man schon sehen, wie man z.B. ein recht komplexes RGB(W) Template, mit switch, dimmer, colorwheel, einzelnen Buttons für Farbschnellwahl aufbauen kann, das für verschiedene Devices funktioniert. Einmal programmiert. Übersichtlich, schnell zu ändern und mit den underscore und underscore.string Funktionen sehr schön zu individualisieren.

Interesse?

Viele Grüße
Chris


Titel: Antw:FTUI mit Logic-Full Template Engine - Interesse?
Beitrag von: jsChris am 28 Oktober 2016, 08:23:26
Schade, da scheint doch wenig Interesse zu sein. Dann werde ich noch mal die Widget Lösung ausprobieren.

Mittlerweile habe ich meine (komplexeren) Module mit underscore umgesetzt und bin der Meinung, dass das den Aufbau wesentlich vereinfacht und so ging es zum Beispiel sehr leicht, meine RGB(W) - Bulbs und Stripes alle über ein Template umzusetzen und das Design schnell und natürlich gleich für alle, anzupassen.

Wie macht ihr das denn mit wiederkehrenden, gleichen oder ähnlichen Komponenten?

Viele Grüße
Chris
Titel: Antw:FTUI mit Logic-Full Template Engine - Interesse?
Beitrag von: nigl am 28 Oktober 2016, 10:11:08
Also ich finde das schon sehr interessant. Ich stehe zwar noch ganz am Anfang mit FHEM und dem Tablet-UI im speziellen, aber mich hat es schon "gegruselt" als ich eine Copy-Paste-Orgie durchführen musste.

Die aktuelle Template-Lösung habe ich nur in der Doku angeschaut. Das würde mir zwar schon helfen geht aber nicht so weit wie die von dir skizzierte Lösung.

Ich finde den Ansatz vielversprechend. Und wenn du sagst, du hast das bei dir schon am Laufen, dann würde ich das gerne antesten. Ich habe halt im Moment nur Sensoren und schalte aktiv noch keine Geräte.

Damit das ganze trägt müsste es aber schon in das "eigentliche" GIT Repo rein - ein Fork wird sonst über kurz oder lang schwer zu pflegen...
Titel: Antw:FTUI mit Logic-Full Template Engine - Interesse?
Beitrag von: ext23 am 28 Oktober 2016, 13:20:44
Macht bei vielen gleichen Sachen Sinn, ob es jetzt übersichtlicher ist und besser als ein replace seih mal dahingestellt.

Ich hab bei TabletUI mit ganz anderen Problemen zu kämpfen als so ein bissel copy und paste ;-) Bei mir läd der ständig irgend welche Widgets nicht, dann muss man ständig ein Seitenrefresh machen und generell ist alles sehr langsam bei mir, auch bei schnelleren Tablets. Da ich wechselnde Menüs habe ist das auch schwer umzubauen das er die Seiten alle im Speicher behält, was da mittlerweile geht. Eventuell geht es dann ja schneller. Cyclemenüs sind auch sehr langsam.

Also von daher ist copy und paste bei mir eher Jammern auf hohem Niveaus :-) Aber deine Idee ist trotzdem gut ja, wenn Sie nicht noch mehr Performance frisst ;-)

/Daniel