Samuel fiedler: Bester Weg für statische Seiten zum "Einbetten" von bspw. einem Header

Hallo an alle!

Ich habe mich heute gefragt, was die beste Methode wäre, in einer statischen HTML-Seite einen Header einzubetten, den ich dann auch in mehreren Seiten einbetten kann, aber nur in einer Datei für eine Änderung am Header bearbeiten muss.
Ist dafür aktuell tatsächlich, wie es auf der ein oder anderen Webseite steht, am besten, einfach den HTML-Quellcode in einer JavaScript-Datei zu schreiben?
Oder gibt es dafür schon neue Techniken (meinetwegen das Einfügen eines versteckten IFrames und das Klonen von Template-Content aus dem IFrame), die besser den Inhalt, das Aussehen und das Verhalten voneinander trennen?

Au revoir,
Samuel Fiedler

--
Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...

akzeptierte Antworten

  1. Lieber Samuel,

    Du willst also Teile Deiner Website auslagern?

    Liebe Grüße

    Felix Riesterer

    1. Hallo Felix!

      Genau. Ich will Teile meiner Webseite auslagern, allerdings statisch (also ohne PHP).
      Der Header einer Webseite war allerdings eher ein Beispiel. Eigentlich plane ich einige Web-Apps, bei denen die Inhaltsaufteilung mit Templates sehr nützlich wäre. Allerdings sind alle Templates in einem HTML-Dokument nicht gerade von Vorteil, wenn man die Web-App später auch verbessern und pflegen will.

      Au revoir,
      Samuel Fiedler

      --
      Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...
      1. Hallo Samuel,

        Genau. Ich will Teile meiner Webseite auslagern, allerdings statisch (also ohne PHP).

        • Server Site Includes (SSI), werden aber nicht von allen Servern unterstützt.
        • Ein "Editor", der Include unterstützt (da kenne ich jetzt leider keinen).
        • Du schreibst dir ein kleines Programm, das eine Steuersequenz durch die einzufügende Datei ersetzt. Das kann in C oder Fortran (😀), aber auch in Python, PHP, Javascript etc. programmiert werden.

        Gruß
        Jürgen

        1. Ein Editor, der Includes unterstützt? Nur eine Vermutung, denn damit gespielt habe ich (jedenfalls noch) nicht. Aber: in BBEdit (und damit ziemlich sicher auch in EMACS) taucht so etwas auf. Aus dem aktuellen BBEdit-User-Manual, Seite 425:

          Include Files
          An include file, or just an “include,” is a special form of placeholder whose substitution happens to be the contents of another file. …”

  2. Hallo Samuel!

    Ich stelle diese Frage für die Programmierung von Web-Apps, bei denen für die Template-Lieferung möglichst nichts serverseitiges (PHP etc.) nötig sein sollte.

    (kleine Anmerkung zum Ursprungsthread)

    Au revoir,
    Samuel Fiedler

    --
    Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...
    1. Lieber Samuel,

      Ich stelle diese Frage für die Programmierung von Web-Apps,

      also nicht für „eine statische HTML-Seite“ wie im OP? Warum hast Du dann im OP von einer statischen HTML-Seite gesprochen, wenn Du in Wirklichkeit Hilfe zu einer App wolltest?

      bei denen für die Template-Lieferung möglichst nichts serverseitiges (PHP etc.) nötig sein sollte.

      Kennst Du schon <template>?

      (kleine Anmerkung zum Ursprungsthread)

      Wer so sorgfältig formulierte Fragen stellt, bekommt auch zielgerichtet die passende(n) Antwort(en) dazu.

      Liebe Grüße

      Felix Riesterer

      1. Hallo Felix Riesterer!

        also nicht für „eine statische HTML-Seite“ wie im OP? Warum hast Du dann im OP von einer statischen HTML-Seite gesprochen, wenn Du in Wirklichkeit Hilfe zu einer App wolltest?

        Die Web-App soll nichts serverseitiges enthalten (also auch über das lokale Dateisystem oder einen einfachen localhost-Server ohne PHP und co. funktionieren können).

        Kennst Du schon <template>?

        Ja, <template> kenne ich und wollte ich auch genau verwenden.
        Ich wollte einfach HTML-Dateien einbinden, die das Template enthalten. Sonst müssten alle Templates in der index.html stehen, was aber genau so les- und pflegbar wie (any complicated program in one file) ist.
        Es ist verrückt, dass man Stylesheets und JavaScript auslagern kann, aber nicht den einfachsten Teil einer Webseite: Das Markup.

        Au revoir,
        Samuel Fiedler

        --
        Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...
        1. Hallo Samuel fiedler,

          <template>-Inhalte musst Du eh per JavaScript einbinden. Dann fetche den Kram halt. Für eine Web-App brauchst Du einen ServiceWorker. Der kann das cachen.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Hallo Rolf B!

            Dann fetche ich eine .html-Datei und mach Zeug mit HTMLElement.innerHTML?

            Au revoir,
            Samuel Fiedler

            --
            Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...
            1. Hallo Samuel fiedler,

              wenn Du nur ein einziges Element hast, das Du befüllen willst, geht das sicherlich.

              Die einfachste Version davon sähe wohl so aus:

              async function loadComponent(element, url) {
                 const response = await fetch(url);
                 if (!response.ok)
                    throw new TypeError("Kann " + url + " nicht laden");
                 element.innerHTML = await.response.text();
                 return element;
              }
              
              ...
              
              loadComponent(document.getElementById("header"), "header.html");
              

              loadComponent arbeitet asynchron - nicht wegen des async vor dem function, sondern weil fetch einfach asynchron ist. Dadurch, dass die Funktion als async markiert ist, kannst Du await verwenden, um auf die Promises von fetch zu warten. Die Rückgabe von loadComponent ist - wegen des async - ebenfalls ein Promise.

              Fall 1: Du rufst loadComponent aus einer weiteren async-Funktion auf oder aus einem type="module"-Script. Dann kannst Du den Returncode mit await erwarten. Wenn der fetch fehlschlägt oder der HTTP-Statuscode nicht im 200er Bereich liegt, fliegt in loadComponent ein Error, den Du mit einem try/catch-Block erwischen kannst.

              Fall 2: Du verwendest die Promise-Methoden .then und .catch. Im Fehlerfall läufst Du dann in den Catch-Handler.

              loadComponent(element, "dings.html")
              .then(element => {
                 // Element initialisieren, zum Beispiel
              })
              .catch(function(fehler) {
                 // Fehler behandeln
              });
              

              Da gibt's viele mögliche Varianten.

              Wenn Du aber mehrere Komponenten hast, dann solltest Du Dir etwas überlegen, wie Du mehr als ein Template auf einmal vom Server holen kannst. Du könntest 4 Templates in ein .html legen, und nach der .innerHTML Zuweisung kannst Du diese Templates dann an Hand ihrer ID finden.

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Hallo Rolf B!

                Perfekt! Genau so etwas wäre auch meine Idee zum JS-Fetching gewesen, aber ich war mir nicht sicher, ob ich alles richtig verstanden habe…

                Au revoir,
                Samuel Fiedler

                --
                Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert…
              2. @@Rolf B

                Die einfachste Version davon sähe wohl so aus:

                Und die allereinfachste verwendet statt

                      throw new TypeError("Kann " + url + " nicht laden");
                
                      throw new TypeError(`Kann ${url} nicht laden`);
                

                🖖 Живіть довго і процвітайте

                --
                Ad astra per aspera
        2. Lieber Samuel,

          Die Web-App soll nichts serverseitiges enthalten (also auch über das lokale Dateisystem oder einen einfachen localhost-Server ohne PHP und co. funktionieren können).

          eine WebApp ist definitiv keine statische HTML-Seite, sondern ein mit JavaScript dynamisch sich veränderndes Gebilde. Da krachen zwei Welten aufeinander: Netz der Dokumente (WWW) und Applikation. Dass man mittlerweile Apps in einem Browser bauen kann, ist das Ergebnis einer langen Entwicklung. Eine statische HTML-Seite gab es, seit Tim Berners-Lee das WWW erfunden hat. WebApps (genauer PWA) sind dagegen etwas sehr neues. Deine Formulierung war definitiv irreführend!

          Ich wollte einfach HTML-Dateien einbinden, die das Template enthalten. Sonst müssten alle Templates in der index.html stehen, was aber genau so les- und pflegbar wie (any complicated program in one file) ist.

          Du darfst Dich anstellen wie der erste Mensch. Das ist Dein gutes Recht. Aber warum ist es für Dich angenehmer, Markup aus zig Dateien zu fetchen (welche Datei genau was enthält muss ja auch verwaltet werden, dazu die vielen Requests, bis der ServiceWorker das alles im Cache hat), anstatt das Markup aus entpsrechend mit ID versehenen Template-Elementen zu holen?

          Es ist verrückt, dass man Stylesheets und JavaScript auslagern kann, aber nicht den einfachsten Teil einer Webseite: Das Markup.

          Lädtst Du Dein JavaScript auch in Modulen? Und das CSS? Vielleicht ist es für den Client besser, wenn er alles in einem Dokument bekommt?

          Du kannst das vom Server zusammenbauen lassen, wenn der Client die App lädt. Dann kannst Du auf dem Server Deine Fragmentierung haben und alles schön in einzelnen HTML-, CSS- und JavaScript-Dateien, damit es für Dich als Entwickler so ist, wie Du das gerne hättest. Aber wenn der Client die App ausführen soll, muss er sie ja anfangs von einem Server laden, welcher diese Fragmentierung auflösen und das gesamte Markup in einem HTML-Dokument liefern kann. Und wenn Du schon dabei bist, kannst Du das CSS und das JavaScript gleich auch noch ins Dokument schreiben.

          Liebe Grüße

          Felix Riesterer

        3. Hallo Samuel,

          … also auch über das lokale Dateisystem oder einen einfachen localhost-Server ohne PHP und co. funktionieren können).

          fetch oder xmlhttp-Request funktioniert im lokalen Dateisystem nur, wenn dieses dem Browser in seiner Konfiguration (about:config) erlaubt wird.

          Gruß
          Jürgen

          1. Hallo JürgenB,

            und auch nur, wenn der Browser ein Fuchs ist. In Chrome geht das meines Wissens gar nicht.

            Für eine von file:/// geladene Seite hilft nur, alles in ein Dokument zusammenzupappen. Oder per <script> Statement nachzuladen, sozusagen JSONP.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hallo Rolf B!

              und auch nur, wenn der Browser ein Fuchs ist. In Chrome geht das meines Wissens gar nicht.

              Wobei ich das lokale Dateisystem hauptsächlich für das Testen verwende. Bereitgestellt wird die Web-App ja dann über den ein oder anderen Web-Server, wo dann nur die Wenigsten die App herunterladen wollen. Und die, die das wirklich wollen (und können), benutzen dann wahrscheinlich auch die richtigen Werkzeuge.

              Au revoir,
              Samuel Fiedler

              --
              Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...
              1. Lieber Samuel,

                Web-Server, wo dann nur die Wenigsten die App herunterladen wollen. Und die, die das wirklich wollen (und können), benutzen dann wahrscheinlich auch die richtigen Werkzeuge.

                das liest sich so, als wäre da einiges konzeptuell im Argen. Warum sollten diejenigen, die sich die App herunterladen wollen, das nicht wirklich können sollen? Und welche richtigen Werkzeuge muss ich benutzen, um eine App nutzen zu wollen (und können)?

                Du erzählst uns halt nach wie vor nicht die ganze Geschichte. Deshalb finden wir nur scheibchenweise den Unsinn heraus. Das ist mir zu mühsam. Ich bin raus.

                Liebe Grüße

                Felix Riesterer

                1. Hallo Felix Riesterer!

                  Web-Server, wo dann nur die Wenigsten die App herunterladen wollen. Und die, die das wirklich wollen (und können), benutzen dann wahrscheinlich auch die richtigen Werkzeuge.

                  das liest sich so, als wäre da einiges konzeptuell im Argen. Warum sollten diejenigen, die sich die App herunterladen wollen, das nicht wirklich können sollen? Und welche richtigen Werkzeuge muss ich benutzen, um eine App nutzen zu wollen (und können)?

                  Wenn du eine X-beliebige „Web App“ auf dein lokales Dateisystem herunterladen willst (meinetwegen SVG-Edit), wird sicher der ein oder andere Fetch gebraucht. Wir hatten gerade eben darüber geredet, dass für das Fetchen vom lokalen Dateisystem ein Eintrag im Firefox about:config notwendig ist. All das wissen die Leute, die SVG-Edit (oder was auch immer) herunterladen wollen (und sich daher schlau gemacht haben sollten).

                  Du erzählst uns halt nach wie vor nicht die ganze Geschichte. Deshalb finden wir nur scheibchenweise den Unsinn heraus. Das ist mir zu mühsam. Ich bin raus.

                  Die Hauptfrage ist eigentlich schon geklärt…

                  Au revoir,
                  Samuel Fiedler

                  --
                  Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...
                  1. Hallo

                    Wenn du eine X-beliebige „Web App“ auf dein lokales Dateisystem herunterladen willst (meinetwegen SVG-Edit) …

                    Ich sehe dort nirgendwo eine Möglichkeit, diese Webapp herunterzuladen. Gibt es die tatsächlich?

                    … wird sicher der ein oder andere Fetch gebraucht.

                    Deshalb wird sie ja auch als Webapp betrieben.

                    Tschö, Auge

                    --
                    „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
                    1. Hallo Auge!

                      Ich sehe dort nirgendwo eine Möglichkeit, diese Webapp herunterzuladen. Gibt es die tatsächlich?

                      Tatsächlich hat SVG-Edit, glaube ich, kein Manifest und ServiceWorker. Dennoch gibt es [CTRL/CMD] + [U] und co. zum Herunterladen…
                      Und wenn da der ein oder andere Fetch verwendet wird, braucht man im Firefox security.fileuri.strict_origin_policy auf false oder einen Webserver…

                      Au revoir,
                      Samuel Fiedler

                      --
                      Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...
              2. Hallo Samuel fiedler,

                eine Web App - wenn es denn wirklich eine Web App sein soll, die man installieren kann - braucht ein Manifest und einen Serviceworker. Ein Manifest geht vielleicht noch via file:///, ein Serviceworker nicht.

                Entwickle mit einem einfachen Webserver. Selbst PHP -S genügt oft schon.

                Rolf

                --
                sumpsi - posui - obstruxi
                1. Hallo Rolf B!

                  eine Web App - wenn es denn wirklich eine Web App sein soll, die man installieren kann - braucht ein Manifest und einen Serviceworker. Ein Manifest geht vielleicht noch via file:///, ein Serviceworker nicht.

                  Das stimmt auch wieder.

                  Entwickle mit einem einfachen Webserver. Selbst PHP -S genügt oft schon.

                  Für den ServiceWorker werde ich irgendeine Art von Webserver starten.

                  Au revoir,
                  Samuel Fiedler

                  --
                  Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...
                  1. Moin Samuel,

                    Für den ServiceWorker werde ich irgendeine Art von Webserver starten.

                    dann hast du aber auch wieder alle möglichen (und unmöglichen) Wege offen in Bezug auf deine Includes 😉

                    Viele Grüße
                    Robert

                    1. Hallo Robert B.!

                      Für den ServiceWorker werde ich irgendeine Art von Webserver starten.

                      dann hast du aber auch wieder alle möglichen (und unmöglichen) Wege offen in Bezug auf deine Includes 😉

                      Was aber immer noch wenig daran ändert, dass die meisten Menschen faul sind und somit möglichst wenig neues lernen wollen 😉

                      Ich lerne zwar gerne, aber es sollte schon irgendeinen Sinn haben. 10000 Programmiersprachen zu lernen mag spaßig sein, hat aber keinen Sinn. Daher können wir auch bei HTML + CSS + JavaScript bleiben.

                      Au revoir,
                      Samuel Fiedler

                      --
                      Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...
                      1. Moin Samuel,

                        Was aber immer noch wenig daran ändert, dass die meisten Menschen faul sind und somit möglichst wenig neues lernen wollen 😉

                        als Akademiker kenne ich tatsächlich eher die Philosophie des lebenslangen Lernens bzw. dass es vorbei ist, wenn man nichts Neues mehr lernt/lernen möchte.

                        Ich lerne zwar gerne, aber es sollte schon irgendeinen Sinn haben. 10000 Programmiersprachen zu lernen mag spaßig sein, hat aber keinen Sinn. Daher können wir auch bei HTML + CSS + JavaScript bleiben.

                        Wenn man einen Hammer hat, ist jedes Problem ein Nagel 😉

                        Viele Grüße
                        Robert

  3. Hallo Samuel,

    wenn Du Teile wiederverwenden möchtest, musst Du irgendeinen Tod sterben.

    • In der IDE zusammenbauen

      • Es gibt Webseitengeneratoren, in denen Du die Stellen zum Einbinden der Templates markierst, und die Dir dann die statischen Seiten generieren.
    • Beim Seitenabruf serverseitig zusammenbauen

      • mit SSI
      • low-level mit PHP oder einer anderen Programmiersprache
      • high-level mit einem Website-Framework, z.B. ASP.NET, JSP, Elixir
    • Am Client zusammenbauen

      • mit JavaScript, handgeschnitzt oder verframeworkt (z.B. React)
      • mit Hilfe von <link rel="import" src="....html">

    Eins aus dieser Liste gibt's leider nicht mehr. Und es hätte auch zu der Zeit, wo es das gab (Chrome 36-79), nicht ohne JavaScript funktioniert (siehe hier). Offenbar sieht niemand einen Grund dafür, das dynamische Zusammensetzen von Seiten als native Browserfähigkeit zu implementieren.

    Grundsätzlich gibt es zwei Ansätze für komponentenbasierende Seiten-

    1. Eine Rahmenseite enthält alle wiederverwendbaren Teile und bindet den individuellen Teil als Komponente ein (z.B. ASP.NET Masterpages)
    2. Jede individuelle Seite enthält einen vollständigen HTML Rahmen und bindet die wiederverwendeten Teile ein (z.B. Header, Footer, Navigation).

    Du scheinst Variante 2 anzustreben, aber die Variante 1 ist eigentlich die bessere, weil Du dann weniger Boilerplate-Kram zusammenschustern musst. Wenn Du das rein clientseitig erledigen willst, müsstest Du die Seite in dieser Art abrufen:

    https://example.org/mysite/index.html?subpage3

    Oder ähnlich. Und in index.html ist Code, der aus der Location den Querystring ausliest und die entsprechende Komponente nachlädt und in den Komponentenplatzhalter einsetzt.

    Du kannst auch "schicke" URLs verwenden und die mittels mod_rewrite im Apache in die index.html umwandeln. Dann musst Du aber mittels Cookie mitteilen, welcher Seiteninhalt gewünscht ist (siehe Flag-Übersicht hier). D.h. der Server muss mithelfen - und dann würde ich eher anstreben, SSI zu verwenden.

    Nachteilig an jeglicher clientseitigen Seitenkonstruktion ist allerdings, dass es zu einem FOMC kommen kann (Flash Of Missing Content), denn das Nachladen kostet ja Zeit. In einer Web-Application, die über einen Serviceworker gecached wird, ist das nicht so schlimm. Wenn die Inhaltskomponente vom Server kommt, musst Du den FOMC mit einer sinnvollen visuellen Wartemusik überbrücken. Solche Seiten sieht man durchaus öfters, diesen Kummer sind Seitenbesucher gewöhnt.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf B!

      Also gab es mal früher HTML Imports. Die hätten sich besonders gut für meine Web-Apps (eigentliche Intention; siehe meine Nachricht) geeignet.
      Da es die jetzt nicht mehr gibt, werde ich das wohl in JavaScript selber zusammenschnitzen.

      Au revoir,
      Samuel Fiedler

      --
      Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...
  4. Moin Samuel,

    Ich habe mich heute gefragt, was die beste Methode wäre, in einer statischen HTML-Seite einen Header einzubetten, den ich dann auch in mehreren Seiten einbetten kann, aber nur in einer Datei für eine Änderung am Header bearbeiten muss.

    eine weitere Möglichkeit besteht in der Verwendung von XInclude, wenn

    • dein HTML XML-konform ist
    • du einen XML- oder XSLT-Prozessor wie xmllint oder xsltproc verwenden kannst.

    Viele Grüße
    Robert

    1. Hallo Robert B.!

      Das hätte eine Lösung für einen Präprozessor sein können, ich hatte es aber für das clientseitige Laden geplant.

      Au revoir,
      Samuel Fiedler

      --
      Es mag GUIs (graphical user interfaces) oder TUIs (text user interfaces) geben. Oftmals wird mit HTML, CSS und JavaScript allerdings leider eine SUI (sh!t user interface) produziert...