Template in Template

Begonnen von TWART016, 22 Februar 2017, 23:59:53

Vorheriges Thema - Nächstes Thema

TWART016

Hallo,

ich möchte in einem Template ein weiteres Template aufrufen.

In der index html rufe ich die Datei m_avr_einstellungen.html im Ordner template auf
<section class="halbTransparent">
<div data-template="template/m_avr_einstellungen.html"></div>
</section>


In der m_avr_einstellungen.html möchte ich ein anderes Template aus dem gleichen Ordner aufrufen. Jedoch wird das nicht angezeigt.

<html>
<body>
        <header></header>


<div class="hbox">
<div class="vbox grow-2 big left-space-5 items-left">
<div style="font-size:20px">Quelle AV Receiver</div>
</div>

<div class="vbox right-space">
<div data-type="select" data-device="avr" data-set="input" data-get="input" data-items='["video6","12","dvd","video2","video3","fm","network","2E"]' data-alias='["PC","TV","Intel NUC","mobil","KODI","Radio","AV Receiver Media","Bluetooth"]' data-on-background-color="#0066FF" class="w2x dark"></div>
</div>
</div>


<div data-template="m_avr_input.html"></div>


<div class="hbox">
<div class="vbox grow-2 big left-space-5 items-left">
<div style="font-size:20px">Sound Modus</div>
</div>

<div class="vbox top-space right-space">
<div data-type="select" data-device="avr" data-set="listening-mode" data-get="listening-mode" data-items='["all-ch-stereo","pliix-movie"]' data-alias='["Stereo","5.1"]' class="w2x dark"></div>
</div>
</div>


</body>
</html>



m_avr_input.html
<html>
<body>

<div class="hbox items-space-around top-space">
<div data-type="switch" data-device="avr" data-get="input" data-get-on="video6" data-get-off="!on" data-set="input" class="" data-icon="oa-it_pc" data-on-background-color="rgb(191, 191, 191)"></div>
<div data-type="switch" data-device="avr" data-get="input" data-get-on="12" data-get-off="!on" data-set="input" class="" data-icon="mi-tv" data-on-background-color="rgb(191, 191, 191)"></div>
<div data-type="switch" data-device="avr" data-get="input" data-get-on="2E" data-get-off="!on" data-set="input" class="" data-icon="fa-bluetooth-b" data-off-color="white" data-on-background-color="rgb(191, 191, 191)" data-off-background-color="rgb(0, 113, 187)"></div>
<div data-type="switch" data-device="avr" data-get="input" data-get-on="fm" data-get-off="!on" data-set="input" class="" data-icon="oa-it_radio" data-on-background-color="rgb(191, 191, 191)"></div>
<div data-type="image" data-size="56px" data-url="./images/Intel_NUC.png" onclick="ftui.setFhemStatus('set avr input dvd')" class="" ></div>
<div data-type="image" data-size="46px" data-url="./images/Kodi_logo.png" onclick="ftui.setFhemStatus('set avr input video3')" class="" ></div>
</div>


</body>
</html>



Gruß

Standarduser

Ich nehme an, dass Du nach einer Lösung dafür fragen wolltest, die Frage fehlt nämlich  ;)

Ich würde mich da mal anschließen, weil ich das auch schonmal probiert habe. Erfolg hatte ich leider keinen dabei.

Kennt jemand eine Möglichkeit, wie man ein Template im Template aufrufen kann?
Oder würde setstate das vielleicht gerne einbauen?  ;D

setstate

das geht, soweit ich das überblicke, nicht.
Auf meiner ToDo Liste ist das aber ganz, ganz weit unten positioniert. Also, wenn das jemand bauen will und andere es danach als funktionierend abnicken, dann übernehme ich das gerne.

Sorry

Standarduser

Ja schade. Aber vielleicht findet sich ja jemand.
Danke für die Info.

TWART016

Zitat von: Standarduser am 24 Februar 2017, 20:11:14
Ich nehme an, dass Du nach einer Lösung dafür fragen wolltest, die Frage fehlt nämlich  ;)
Ähhh ja :D

Zitat von: setstate am 24 Februar 2017, 20:20:20
das geht, soweit ich das überblicke, nicht.
Auf meiner ToDo Liste ist das aber ganz, ganz weit unten positioniert. Also, wenn das jemand bauen will und andere es danach als funktionierend abnicken, dann übernehme ich das gerne.

Sorry
Schade. Natürlich gibt es wichtigere Dinge ;)

Clyde

Ich komme auch regelmäßig an den Punkt Templates in Templates verwenden zu wollen. Hole deshalb die Idee nochmal vor.
Proxmox auf MINIX-Z100, LXC: FHEM, FS20, FHT, HM, Tradfri, Alexa, Anker Solix Solarbank 2

Grishn

Hallo,

auch ich stehe gerade vor dem selben Problem.

Probiere mich gerade an einem Design mit Flex und habe mich dort am Beispiel mit einem seitlichen Menü orientiert.

Wollte hier z.B für jeden Raum eine eigene Unterseite definieren.

Hierbei werden die einzelnen Seiten ja bereits per "data-template" aufgerufen.
So ist es mir jetzt nicht möglich für die einzelnen Räume wiederum templates für die sich wiederholenden Widgets zu nutzen.

Das Beispiel bei github ( https://github.com/knowthelist/fhem-tablet-ui/tree/master/examples/flexbox -> index_flex_demo_menu.html ) funktioniert ja so nicht ohne "data-template" im "main"-Bereich.

Oder mache ich hier etwas absolut falsch und/oder habe ich das Beispiel nicht verstanden ?

jemu75

Zitat von: Grishn am 18 August 2017, 22:06:50
Hallo,

auch ich stehe gerade vor dem selben Problem.

Probiere mich gerade an einem Design mit Flex und habe mich dort am Beispiel mit einem seitlichen Menü orientiert.

Wollte hier z.B für jeden Raum eine eigene Unterseite definieren.

Hierbei werden die einzelnen Seiten ja bereits per "data-template" aufgerufen.
So ist es mir jetzt nicht möglich für die einzelnen Räume wiederum templates für die sich wiederholenden Widgets zu nutzen.

Das Beispiel bei github ( https://github.com/knowthelist/fhem-tablet-ui/tree/master/examples/flexbox -> index_flex_demo_menu.html ) funktioniert ja so nicht ohne "data-template" im "main"-Bereich.

Oder mache ich hier etwas absolut falsch und/oder habe ich das Beispiel nicht verstanden ?

Ich habe das Thema ähnlich angegangen und komme mit einer "Template-Stufe" aus.
Die Struktur sieht bei mir wie folgt aus: index.html -> responsive-menü -> Unterseite -> Template

index.html

<!DOCTYPE html>
<html>

<!-- FHEM Tablet UI 2.6 -->

<head>
<link rel="icon" href="favicon.ico" type="image/x-icon" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="debug" content="3"> <!-- verbose level 1-6 = output to console;0 = not output -->
<meta name='toast' content='0'> <!-- keine Ausgabe von Protokollmeldungen -->

    <script src="js/fhem-tablet-ui.js" defer></script>

<style>
@media screen and (max-width: 900px) and (min-width: 480px) {
.menu {
width: 90px !important;
}
.menu ul li {
height: 43px;
position: relative;
padding: 0.5em 1em 0.5em 2.1em;
}
}

@media screen and (max-width: 480px) {
.menu ~ main > .page {
padding-left: 0px;
}

}
</style>

    <title>SmartHome</title>
</head>

<body>
<nav class="menu">
<div class="menu-trigger"></div>
<header class="">Menu</header>
        <ul>
<li>
<div data-type="link" data-url="#content_home.html"
data-color="white"
data-active-color="blue"
data-width="115"
data-load="#content_home"
data-text-align="left"
data-active-pattern="(.*index.html|.*#content_home.html)"
data-icon="fa-home" class="large"><span>&Uuml;bersicht</span></div>
</li>
<li>
<div data-type="link" data-url="#content_klima.html"
data-color="white"
data-active-color="blue"
data-width="115"
data-load="#content_klima"
data-text-align="left"
data-active-pattern="(.*#content_klima.html)"
data-icon="fa-thermometer-3" class="large"><span>Heizung</span></div>
</li>
<li>
<div data-type="link" data-url="#content_outdoor.html"
data-color="white"
data-active-color="blue"
data-width="115"
data-load="#content_outdoor"
data-text-align="left"
data-active-pattern="(.*#content_outdoor.html)"
data-icon="mi-cloud_queue" class="large"><span>Umgebung</span></div>
</li>
<li>
<div data-type="link" data-url="#content_licht.html"
data-color="white"
data-active-color="blue"
data-width="115"
data-load="#content_licht"
data-text-align="left"
data-active-pattern="(.*#content_licht.html)"
data-icon="mi-lightbulb_outline" class="large"><span>Licht</span></div>
</li>
<li>
<div data-type="link" data-url="#content_kontakte.html"
data-color="white"
data-active-color="blue"
data-width="115"
data-load="#content_kontakte"
data-text-align="left"
data-active-pattern=".*(#content_kontakte.html)"
data-icon="ftui-door" class="large"><span>Fenster T&uuml;ren</span></div>
</li>
<li>
<div data-type="link" data-url="#content_jalousie.html"
data-color="white"
data-active-color="blue"
data-width="115"
data-load="#content_jalousie"
data-text-align="left"
data-active-pattern=".*(#content_jalousie.html)"
data-icon="mi-line_weight" class="large"><span>Jalousien</span></div>
</li>
<li>
<div data-type="link" data-url="#content_rauch.html"
data-color="white"
data-active-color="blue"
data-width="115"
data-load="#content_rauch"
data-text-align="left"
data-active-pattern=".*(#content_rauch.html)"
data-icon="oa-secur_smoke_detector" class="large"><span>Rauchmelder</span></div>
</li>
<li>
<div data-type="link" data-url="#content_phone.html"
data-color="white"
data-active-color="blue"
data-width="115"
data-load="#content_phone"
data-text-align="left"
data-active-pattern=".*(#content_phone.html)"
data-icon="mi-phone" class="large"><span>Anrufe</span></div>
</li>
<li>
<div data-type="link" data-url="#content_cam.html"
data-color="white"
data-active-color="blue"
data-width="115"
data-load="#content_cam"
data-text-align="left"
data-active-pattern=".*(#content_cam.html)"
data-icon="mi-videocam" class="large"><span>Kameras</span></div>
</li>
<li>
<div data-type="link" data-url="#content_settings.html"
data-color="white"
data-active-color="blue"
data-width="115"
data-load="#content_settings"
data-text-align="left"
data-active-pattern=".*(#content_settings.html)"
data-icon="mi-settings" class="large"><span>Einstellungen</span></div>
</li>
</ul>
</nav>

<main>
<div class="page" id="content_home"></div>
<div class="page" id="content_klima"></div>
<div class="page" id="content_outdoor"></div>
<div class="page" id="content_licht"></div>
<div class="page" id="content_kontakte"></div>
<div class="page" id="content_jalousie"></div>
<div class="page" id="content_rauch"></div>
<div class="page" id="content_phone"></div>
<div class="page" id="content_cam"></div>
<div class="page" id="content_settings"></div>
</main>
</body>
</html>


Beispiel Content-Seite (Temperatursteuerung)

<!DOCTYPE html>
<html>
<body>
    <div class="page" id="content_klima">
<div class="hbox">
<div class="vbox phone-width">
<div class="card">
<header>Wohnzimmer</header>
<div class="hbox items-center">
<div data-template="template_thermostat.html" data-parameter='{"var_device1":"HM_xxxxxx","var_temp_day":"22.0","var_temp_night":"17.0","var_device2":"HM_xxxxxx_Sw_03"}'></div>
</div>
</div>

<div class="card">
<header>Flur</header>
<div class="hbox items-center">
<div data-template="template_thermostat.html" data-parameter='{"var_device1":"HM_xxxxxx","var_temp_day":"21.0","var_temp_night":"17.0","var_device2":"HM_xxxxxx_Sw_04"}'></div>
</div>
</div>

<div class="card">
<header>WC</header>
<div class="hbox items-center">
<div data-template="template_thermostat.html" data-parameter='{"var_device1":"HM_xxxxxx","var_temp_day":"21.0","var_temp_night":"17.0","var_device2":"HM_xxxxxx_Sw_03"}'></div>
</div>
</div>

<div class="card">
<header>Bad</header>
<div class="hbox items-center">
<div data-template="template_thermostat.html" data-parameter='{"var_device1":"HM_xxxxxx","var_temp_day":"22.0","var_temp_night":"17.0","var_device2":"HM_xxxxxx_Sw_02"}'></div>
</div>
</div>
</div>

<div class="vbox phone-width">
<div class="card">
<header>Schlafzimmer</header>
<div class="hbox items-center">
<div data-template="template_thermostat.html" data-parameter='{"var_device1":"HM_xxxxxx","var_temp_day":"21.0","var_temp_night":"17.0","var_device2":"HM_xxxxxx_Sw_02"}'></div>
</div>
</div>

<div class="card">
<header>B&uuml;ro</header>
<div class="hbox items-center">
<div data-template="template_thermostat.html" data-parameter='{"var_device1":"HM_xxxxxx","var_temp_day":"21.0","var_temp_night":"17.0","var_device2":"HM_xxxxxx_Sw_02"}'></div>
</div>
</div>

<div class="card">
<header>Kiara</header>
<div class="hbox items-center">
<div data-template="template_thermostat.html" data-parameter='{"var_device1":"HM_xxxxxx","var_temp_day":"21.0","var_temp_night":"17.0","var_device2":"HM_xxxxxx_Sw_03"}'></div>
</div>
</div>

<div class="card">
<header>Lea</header>
<div class="hbox items-center">
<div data-template="template_thermostat.html" data-parameter='{"var_device1":"HM_xxxxxx","var_temp_day":"21.0","var_temp_night":"17.0","var_device2":"HM_xxxxxx_Sw_01"}'></div>
</div>
</div>
</div>
</div>
</div>
</body>

</html>


und hier das Template:

<!DOCTYPE html>
<html>
<head>
<!-- FHEM Tablet UI V2.6 -->
<!-- Template für Homematic Schaltaktor 4-fach HM-LC-SW4-DR zur Schaltung des Heizkreises (Fußbodenheizung) in Verbindung mit Wandthermostat HM-TC-IT-WM-W-EU -->
</head>
<body>
<div class="row">
<div class="cell">
<div data-type="symbol" data-device="var_device2" data-states='["off","on"]' data-colors='["blue","red"]'  data-icon="fa-thermometer-3" class="big"></div>
</div>
<div class="cell-50 left-align">
<div data-type="label" data-device="var_device1_Climate" data-get="measured-temp" data-unit="&deg;C" class="bigger thin inline"></div>
<div data-type="label" data-device="var_device1_Climate" data-get="humidity" data-unit="%" class="bigger thin inline"></div>
</div>
<div class="cell">
<div data-type="symbol" data-device="var_device1" data-get="desired-temp" data-states='["var_temp_night","var_temp_day"]' data-icons='["fa-moon-o","mi-wb_sunny"]' data-colors='["gray","blue"]' class="small newline"></div>
<div data-type="label" data-device="var_device1" data-get="desired-temp" data-unit="&deg;C" class="small newline"></div>
</div>
<div class="cell right-space">
<div data-type="checkbox" data-device="var_device1_Climate" data-get="desired-temp" data-set="desired-temp" data-get-on="var_temp_day" data-get-off="var_temp_night" data-set-on="var_temp_day" data-set-off="var_temp_night" class="blue"></div>
</div>
</div>
<div class="row">
<div class="cell left-space">
<div data-type="symbol" data-device="var_device1" data-get="Activity" data-states='["((?!alive).)*","alive"]' data-colors='["red","gray"]' data-icons='["blink mi-sync_problem","mi-sync"]' class="tiny compressed inline"></div>
<div data-type="label" data-device="var_device1_Climate" data-get="measured-temp" class="darker small timestamp inline"></div>
<div data-type="symbol" data-device="var_device1" data-get="batteryLevel" data-states='["0","2.1","2.3","2.7","3.0"]' data-icons='["blink fa-battery-0","fa-battery-1","fa-battery-2","fa-battery-3","fa-battery-4"]' data-colors='["red","red","gray","gray","gray"]' class="tiny compressed inline"></div>
<div data-type="label" data-device="var_device1" data-get="batteryLevel" data-unit="V" class="darker small inline"></div>
</div>
</div>
</body>
</html>

Grishn

Hallo jemu75,

danke für die schnelle Antwort.

Dann scheint bei mir etwas nicht zu funktionieren.

Wenn ich dort einen Aufruf nach Art <div class="page" id="content_settings"></div> nutze, wird meine Unterseiten, die ich angelegt habe, nicht aufgerufen.
Da Du sagst es funktioniert so ohne Probleme, muss ich da wohl was falsch gemacht haben. Ich tippe auf Syntaxfehler ;) Ich habe dies hier nicht gesetzt:

<!DOCTYPE html>
<html>
<body>
    <div class="page" id="content_settings">


Ich habe es jetzt so gelöst, das ich die Grundstruktur im <main>-Bereich aufgebaut habe und nur die einzelnen Widgets per Template aufrufe, dass klappt auch.
Ich glaube nur, dass ich so ganz schöne Performanceprobleme bekommen könnte, da ja alles schon vorgeladen wird, was bei Unterseiten nicht der Fall ist, soweit ich weis.

Dann werde ich hier noch mal weiter probieren.

Grishn

Meine Probleme mit dem Seitenaufruf lagen wirklich an meiner fehlerhaften Syntax  ::) .

ich hatte bei den Unterseiten den Bereich <div class="page" id="content_settings"> vergessen.

Nun klappt alles. Danke @jemu75, deine Beispiele haben mir sehr geholfen.

Trotzdem wäre es schön, wenn Templates in Templates funktionieren würden ;) .

jody

Hallo setstate,

ich beschäftige mich auch gerade mit diesem tollen Framework. Dabei bin ich auch auf das Problem mit den verschachtelten Templates gestoßen. Ich hab mir jetzt mal den Code etwas angesehen und auch mit einem Lösungsansatz begonnen. Leider hab ich mich jetzt etwas festgefahren. Evtl hast du noch eine Idee wie ich bei meinem Problem weiter komme. Was ich suche, wäre ein eindeutiges Event, dass gefeuert wird, wenn die Seite komplett geladen ist (mit allen Widgets, etc). Ich habe schon den Eventlistener auf "initWidgetsDone" entdeckt, der feuert bei mir jetzt aber immer zu oft, weil jedesmal wenn Verschachtelte Widgets gerendert werden die Routine erneut anspringt.

Das "pageFullyRendered - Event" (wenns sowas gibt) müsste ich an dieser Stelle noch einfügen. Aktuell mache ich das zu Testzwecken mit einem Timeout.


setTimeout(function() {
    resolve(htmlArr);
}, 1000)


Ich hänge dir auch noch meinen Code mit an, damit du es evtl besser nachvollziehen kannst.


    processNestedTemplates: function(templElem, counter, callback) {

        var tTemplateElement;

        // TODO Limit recursion => performance
        console.log("counter: ", counter);

        new Promise(function(resolve) {

            $.get(templElem.data('template'), {}, function (data) {
                var parValues = templElem.data('parameter');
                for (var key in parValues) {
                    data = data.replace(new RegExp(key, 'g'), parValues[key]);
                }
                tTemplateElement = templElem.html(data);
                resolve(tTemplateElement);
            })
        })
        .then(function(tTemplate) {

            // Check if there are nested data-template Attributes
            if ($(tTemplate).find('[data-template]').length > 0) {
                $.map($('[data-template]', tTemplate), function (templ, i) {

                    var templElem = $(templ);

                    ftui.processNestedTemplates(templElem, counter++, callback);
                })
                // console.log("tTemplate: ", $(tTemplate).find('[data-template]').length);
            }
            else {
                return callback(tTemplate)
            }
        })
    },


    initPage: function (area) {

        //hideWidgets
        ftui.hideWidgets(area);

        //init gridster
        area = (ftui.isValid(area)) ? area : '';
        console.time('initPage');
        ftui.log(2, 'initPage - area=' + area);

        ftui.initGridster(area);

        var that = this;

        var htmlArr = [];

        new Promise(function(resolve) {
            $.map($('[data-template]', area), function (templ, i) {

                var templElem = $(templ);

                // console.log("i: ", i);

                ftui.processNestedTemplates(templElem, 0, function(html) {
                    htmlArr.push(html);
                    console.log("htmlArr: ", htmlArr.length);
                })

                console.log("area: ", area);

                $(document).on("initWidgetsDone", function () {
                    console.log("init Widgets Done juhuuuuu!!!")
                })

                // if (i + 1 == htmlArr.length) {
                //
                // }
                setTimeout(function() {
                    resolve(htmlArr);
                }, 1000)
            });
        })
        .then(function(deferredArr) {

            //get current values of readings not before all widgets are loaded
            $.when.apply(this, deferredArr).then(function () {
                console.log("go on");
                ftui.initWidgets(area);
                ftui.log(1, 'init templates - Done');
                // continue after loading the includes
            });
        })
    },


Ich bin für jeden Tipp dankbar.

Gruß Jody
Cubietruck
CUL SlowRF
CUL Homematic
ZWave

Gunther

Ich hänge mich mal mit dem Wunsch nach verschachtelten Templates hier an. Wäre mega-praktisch.

Seid Ihr da schon weitergekommen?
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden

Gunther

und einen Verbesserungsvorschlag für die Angabe der Variable hätte ich noch.
Besteht die Möglichkeit diese durch einen Anfangs- und Endtag zu kennzeichnen?

z. B.

$$Variable$$


Damit könnte man sich später etwas Arbeit sparen, wenn man auf unterschiedliche Devices zugreift.
Versuche mal ein Beispiel zu machen:

Wenn ich eine Seite mit unterschiedlichen Homematic-Kanälen aufbaue, könnte ich im Template

$$variable$$_Climate
$$variable$$_Weather
$$variable$$_WindowRec


festlegen.

In der Seite, wo ich das Template verwende bräuchte dann nur
data-parameter='{"variable":"homematic"}'
statt drei Variablen angegeben werden.

Oder übersehe ich eine Möglichkeit?
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden

Standarduser

Zitat von: Gunther am 02 Dezember 2017, 15:59:23
Oder übersehe ich eine Möglichkeit?

Das bisherige Verhalten entspricht genau dem, was du dir hier wünschst. Die Variable wird einfach mit suchen und ersetzen im Template angewendet. Wenn da im Code noch irgendwas angehängt wird, dann ist das auch danach noch da. Ein besonderes Trennzeichen wird nicht benötigt.

Wenn Du zur besseren Lesbarkeit trotzdem ein Trennzeichen haben möchtest, dann solltest du nicht unbedingt $ verwenden, denn das kann zu Problemen führen.
Ich mag das auch und nutze immer §.

Gunther

Super, das hatte ich bisher anders verstanden. Danke.

Template in Template wäre super...  ;)
Stelle mich als Tester zur Verfügung.
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden